[Pwn2own] [Back to 2023] It still hid from me
TL;DR
2023 is not the first time for trying with Pwn2own contest. But it hid from by someways. I targeted SOHO Smashup category and TPLink is the cheapest router in the list. I wrote this blog after nearly 2 years. I think should publish some things for my soul :). The contest required a WAN side vulnerability to access LAN side, but I only mention about a LAN side unauthentication RCE vuln. This is a very simple one, also show that a simple make a serious one.
Vulnerability
Web management is using uhttpd service. But most API will be forward to luci backend for processing. Login is processed by luci/controller/login.lua. There is an alert function to log by calling ubus command which contains username in the data. The alert function will be trigged when an username attemp more than a threshold time.
function login(d){
....
data = luci.request.json.decoded(d["data"]) -- get data from "data" field from request POST
params = data["params"]
username = params["username"] -- get "username" from json request
password = params["password"]
...
this_device = get_devicecode()
attemp[this_device] = 0
if check_login(username, password){
...
}
else{
attemp[this_device] += 1
if(attemp[this_device] == 10){
cmd = string.format("ubus ... {\\\"userName\\\":\\\"%s\\\"",
username,
...
) -- prepare the command with "username" is inserted
luci.sys.exec(cmd) -- run vulnerable command
}
}
It uses the username from user’s input to insert to call a ubus call event.
Can insert the command to username for login submit to get run arbitrary command without authentication.
Fix release
A hot fix released for V2 before contest starting day. The fix firmware also released for other hardware version after the contest. It is also the cause make pwn2own still hid from me :(. The fix version add the special characters checking for username before calling luci.sys.exec.
Affect version:
- V1 hardware version with firmware < ER605(UN)_V1_1.3.1 Build 20231207
- V2 hardware version with firmware < ER605(UN)_V2_2.2.2 Build 20231017
Conclusion
This is really simple one, but it almost helped me win pwn2own. The hardest step is fixing tools to deassembly the lua bytecode. If you are interested in it, visit my previous blog