Fixing hardcoded HTTP URLs in ASUS WL-500W web-ui
This allows router's web-ui to be accessed via HTTPS using reverse-proxy like CloudFlare.
This is done by replacing hardcoded http://
with combination of location.protocol
and protocol-relative URLS (//
).
This repository has two folders:
www-lp
- wherelocation.protocol
is used everywhere.www-pru
- where protocol-relative URLs (//
) are used mostly andlocation.protocol
is used only when absolutely necessary.
My tests show that both approaches work fine, but in case of issues there is something you can try.
I'm too lazy to recompile httpd
that comes with firmware, so it's binary patching all the way down.
There are *.cgi
pages that are served internally from httpd
via HTTP:
websWrite(wp, "<meta http-equiv=\"refresh\" content=\"0; url=http://%s/%s\">\r\n", next_host, url);
All we need is to search and replace this string in the httpd
binary:
content="0; url=http://%s/%s"
-- with --
content="0; url=//%s/%s"
Built-in httpd
server allows web-ui to be accessed only from one IP at time for the sake of "security" (related discussion). This doesn't work well with CloudFlare, so this check has to be disabled:
if (http_port==server_port && !http_login_check()) {
inet_ntop(login_ip.family, &login_ip.addr, straddr, sizeof(straddr));
sprintf(line, "Please log out user %s first or wait for session timeout(60 seconds).", straddr);
dprintf("resposne: %s \n", line);
send_error( 200, "Request is rejected", (char*) 0, line);
return;
}
It can be achieved by NOP
ing conditional jump at file offset 0x2CF0
. Just fill 4 bytes with 0
(MIPS NOP) and you're done:
.-----------------------------.
| [0x402ce0] ;[Bm] |
| lw v1, -0xfe8(a0) |
| lui a0, 0x42 |
| lw v0, -0xfe4(a0) |
| lui s6, 0x42 |
| beq v1, v0, 0x403064 ;[Bl] | <- this one!
| sw zero, -0xfec(s6) |
`-----------------------------'
To use modified files/folder you need to attach properly formatted USB flash drive to your router. This is usually done as a part of Entware installation.
Since wwww
folder and httpd
binary are stored in the readonly file system, the trick is to use bind mounts to override built-in files.
Assuming that you've copied httpd
to /opt/sbin/httpd
and www-xxx
to /var/www
:
mount -o bind /opt/sbin/httpd /usr/sbin/httpd
mount -o bind /opt/var/www /www
killall httpd
To remove mounts:
killall httpd
umount /usr/sbin/httpd
umount /www
To make changes permanent, you need to create shell script and run it from the cron
at boot.
- Script: https-webui.sh
- Crontab:
@reboot admin /path/to/https-webui.sh