Write-up of the challenge “Web – Sticky! Sticky! ” of Nuit du Hack 2016 Wargame
The weekend of 02-03 july 2016 is the WARGAME of the Nuit du Hack 2016 as a Jeopardy CTF. Having had the opportunity and the time to participate with some colleagues and friends, here’s a write-up resolution of the challenges which we could participate.
- Category: Web
- Name: Sticky! Sticky!
- Description : HEY! Welcome back!
- Hint 1 : check all the cookies!!!
- Hint 2 : resolution is in base32
- URL : http://sticky.wargame.ndh
- Points : 250
Given the name of the challenge, “sticky”, we doubt that a notion of cookie and “persistence” will come into play …
By going to the URL of the challenge, we were invited to enter a user name:
Once a login was entered a simple page “Welcome back” was displayed with the login reflected:
By observing in more detail requests, we have a cookie set:
GET /index.php HTTP/1.1 Host: sticky.wargame.ndh User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Cookie: user_id=553241; validator=validator.wargame.ndh; resolution="YCUAACI=" Connection: close
- user_id : the identifier of the user (generated server-side)
- validator : a private hostname of “validation”
- resolution : a value encoded in base64? (after obtaining the second “hint” of the challenge it’s Base32…).
By testing various encoding / decoding base64 value for “resolution”, no relevant information is disclosed, but interesting errors (also visible after multiple query execution):
In case you change the value of the cookie “validator”, we get an error attempting to hijack:
Testing was continued by trying to inject a payload through the login. A small persistent XSS is here, but nothing exploitable:
The presence of this XSS, stored server side (although responses appeared behind a load balancer), allowed a malicious troll to inject a false-flag that has baffled more than one ^^! Good game 😉 !
Based on previous errors and hints, we deduce several things:
- The frontend is a simple connection of web application and reflection of a login
- Login (and privileges) appear checked with an inaccessible third-party server “validator.wargame.ndh” defined via cookie.
- We can change the “user_id” via cookies. Set to “1” it displays a “Welcome admin!”
- The host of validation “validator.wargame.ndh” seems listening on port “8888” as shown in the previous error message
- When altering the encoded value “resolution” through cookies there is an error related to the host DNS resolution of “validator.wargame.com”.
Trying to query the server “sticky.wargame.ndh” on port 8888 itself:
GET / HTTP/1.1 Host: sticky.wargame.ndh:8888 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Cookie: user_id=553241; validator=validator.wargame.ndh; resolution="YCUAACI=" Connection: close
Response:
HTTP/1.1 200 OK Server: nginx/1.6.2 Date: Sun, 03 Jul 2016 01:32:06 GMT Content-Type: text/plain; charset=utf-8 Connection: close Content-Length: 25 {"admin": 0, "name": "0"}
Solving the challenge requires definitely close this answer with an “admin: 1”!
We focus more on the value of the cookie “resolution”, which, following the issuance of the second “hint”, is in Base32:
- Default value : YCUAACI=
- Base32 to Hex : C0A80009
- ASCII : [192][168][0][9]
It is an IP that is encoded in the “resolution” cookie!
A request sent to the application with the cookie generates the following:
- The web server queries the name server (NS) whose IP is Base32 encoded, transmitted in the “resolution” cookie. Default: 192.168.0.9.
- The server requests the NS for the corresponding IP to the specified domain in the cookie “validator”: “What is the corresponding IP of validator.wargame.ndh domain?”
- The corresponding IP is queried on port 8888 to validate the user name. This web server returns JSON like:
{"admin": 0, "name": "admin"}
On the client side, we have to take the role of the name server (NS), the validation server and force a JSON response with:
{"admin": 1, "name": "admin"}
My computer, connected to the Wargame network of the NDH, has the IP: 172.16.16.250, or in hexadecimal: AC1010FA and therefore Base32: VQIBB6Q= (converter available here).
The new value of the cookie “resolution” will be VQIBB6Q=. The web server will seek to resolve the host name in “validator” of the NS that will ultimately my machine : 172.16.16.250.
I must therefore turn my post as a DNS server :
apt-get install dnsmasq echo validator.wargame.ndh 172.16.16.250 >> /etc/hosts /etc/init.d/dnsmasq start
Done !
Now the DNS resolution of the host “validator.wargame.ndh” is made by my computer, and point to my computer itself. It only remains to deploy a small web server on port 8888 that will return the JSON “admin:1”:
mkdir sticky cd sticky vi 1 # {"admin":1,"name":"admin"} python -m SimpleHTTPServer 8888
Our web server is running on port 8888, and a “1” file delivers the appropriate JSON to become admin.
It only remains to realize the last request to “sticky.wargame.ndh”, with the cookie:
- user_id=1 : admin user id
- validator=validator.wargame.ndh : which will be solved by our own name server
- resolution=VQIBB6Q= : IP Base 32 of our name server
Bingo ! Flag : ndh2k16_e5f3eb90c4438c1a062125e3f74c2b41
Thank you to all the team of the NDH2K16 for this event and for the whole organization!
Greeting to nj8, St0rn, Emiya, Mido, downgrade, Ryuk@n and rikelm, ? // Gr3etZ
Sources & resources :