Ultima modifica:
Ciao a tutti, cerco aiuto per la risoluzione della challenge WAFfle-y Order su HackTheBox.
La challenge è già stata ritirata ed ha difficoltà Medium.
Di seguito il download (password hackthebox):
La challenge si presenta come un sito web che permette di fare degli ordini relativi a gelati o waffles.
Di seguito l'interfaccia:
Il front-end comunica con il backend tramite richieste in JSON e utilizzano un cookie serializzato (che verrà poi deserializzato) per definire il nome dell'utente:
Il contenuto del cookie è
Di seguito trovate il link alle mie note con i miei appunti:
La challenge fornisce un docker, per cui è necessario installare docker sulla propria macchina ed aggiungere l'utente al gruppo docker.
Una volta fatto ciò basta eseguire il comando
I file che presentano informazioni o utilità interessanti sono Router.php (la classe che imposta le rotte dell'aaplicazione), index.php (entry point della challenge), XmlParserModel.php (parser XML), UserModel.php (la classe che imposta il valore dell'username) e OrderController.php (la classe che si occupa di elaborare gli ordini).
Di seguito i rispettivi codici sorgente:
Vedi: https://pastebin.com/Cy0pPyi4
Vedi: https://pastebin.com/ecPkUgzr
Vedi: https://pastebin.com/n1r0pqxw
Vedi: https://pastebin.com/LdyDCr2J
Vedi: https://pastebin.com/K8Eg0xVX
Da quel che posso vedere e presupporre, l'entry point per l'exploitation chain è la classe OrderController.php tramite la funzione unserialize(). E' possibile passare un cookie serializzato arbitrariamente in modo da fare PHP Object Injection ed eseguire i Magic Methods della classe XmlParserModel.php (nello specifico, la funzione
Potrebbe anche essere interessante questa porzione di codice, che però non mi è ancora chiaro cosa faccia esattamente:
I problemi però sono molteplici:
Per ora le primitive interessanti che ho trovato sono:
Qualche idea o qualcuno che abbia voglia di sbatterci la testa con me?
La challenge è già stata ritirata ed ha difficoltà Medium.
Di seguito il download (password hackthebox):
Per vedere questo contenuto, devi Accedere o Registrarti.
1 Summary
La challenge si presenta come un sito web che permette di fare degli ordini relativi a gelati o waffles.Di seguito l'interfaccia:
Il front-end comunica con il backend tramite richieste in JSON e utilizzano un cookie serializzato (che verrà poi deserializzato) per definire il nome dell'utente:
HTTP:
POST /api/order HTTP/1.1
Host: localhost:1337
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:1337/
Content-Type: application/json
Origin: http://localhost:1337
Content-Length: 37
Connection: close
Cookie: PHPSESSID=Tzo5OiJVc2VyTW9kZWwiOjE6e3M6ODoidXNlcm5hbWUiO3M6MTA6Imd1ZXN0XzYyNWQiO30%3D
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
{"table_num":"test","food":"WAFfles"}
Il contenuto del cookie è
Di seguito trovate il link alle mie note con i miei appunti:
WAFfle-y Order
Remember what's important in life: friends 🤝, WAFfles 🧇, work 💼. or 🧇 WAFfles. 🤝 friends. 💼 work. Doesn't matter. But work is third 🥉. This is why we launched our new WAFfle-y cute ordering system API for our beloved customers and friends! But remember, don't get all filled up on those regexes...
0xbro.notion.site
2 Set up
La challenge fornisce un docker, per cui è necessario installare docker sulla propria macchina ed aggiungere l'utente al gruppo docker.Una volta fatto ciò basta eseguire il comando
chmod +x build_docker.sh
ed eseguire lo script ./build_docker.sh
2.1 build_docker.sh
Bash:
#!/bin/bash
docker build -t web_waffley_order .
docker run --name=web_waffley_order --rm -p1337:80 -it web_waffley_order
2.2 Dockerfile
Bash:
FROM alpine:edge
# Setup usr
RUN adduser -D -u 1000 -g 1000 -s /bin/sh www
# Install system packages
RUN apk add --no-cache --update supervisor nginx
# Install PHP dependencies
RUN apk add --no-cache --update php7-fpm php7-xml php7-simplexml php7-json
# Configure php-fpm and nginx
COPY config/fpm.conf /etc/php7/php-fpm.d/www.conf
COPY config/supervisord.conf /etc/supervisord.conf
COPY config/nginx.conf /etc/nginx/nginx.conf
# Copy challenge files
COPY challenge /www
COPY flag /flag
# Setup permissions
RUN chown -R www:www /var/lib/nginx
# Expose the port nginx is listening on
EXPOSE 80
# Populate database and start supervisord
CMD /usr/bin/supervisord -c /etc/supervisord.conf
3 File interessanti dell'applicazione
I file che presentano informazioni o utilità interessanti sono Router.php (la classe che imposta le rotte dell'aaplicazione), index.php (entry point della challenge), XmlParserModel.php (parser XML), UserModel.php (la classe che imposta il valore dell'username) e OrderController.php (la classe che si occupa di elaborare gli ordini).Di seguito i rispettivi codici sorgente:
3.1 Router.php
Vedi: https://pastebin.com/Cy0pPyi4
3.2 index.php
Vedi: https://pastebin.com/ecPkUgzr
3.3 XmlParserModel.php
Vedi: https://pastebin.com/n1r0pqxw
3.4 UserModel.php
Vedi: https://pastebin.com/LdyDCr2J
3.5 OrderController.php
Vedi: https://pastebin.com/K8Eg0xVX
4 Osservazioni
Da quel che posso vedere e presupporre, l'entry point per l'exploitation chain è la classe OrderController.php tramite la funzione unserialize(). E' possibile passare un cookie serializzato arbitrariamente in modo da fare PHP Object Injection ed eseguire i Magic Methods della classe XmlParserModel.php (nello specifico, la funzione __wakeup()
in modo da abilitare la variabile d'ambiente $_ENV["debug"]
e poter quindi scrivere dentro /tmp/orders.log)Potrebbe anche essere interessante questa porzione di codice, che però non mi è ancora chiaro cosa faccia esattamente:
PHP:
spl_autoload_register(function ($name){
if (preg_match('/Controller$/', $name))
{
$name = "controllers/${name}";
}
if (preg_match('/Model$/', $name))
{
$name = "models/${name}";
}
include_once "${name}.php";
});
I problemi però sono molteplici:
- Come bypassiamo il controllo della funzione
safe_object()
? - Una volta bypassato il controllo, come otteniamo la flag?
- La strada della PHP Object Injection è giusta o ci sono altre vie che mi sono sfuggite?
${body}
(php extended syntax che potrebbe condurre a RCE in caso riuscissimo a bypassare il controllo su $order = json_decode($body);
)...Per ora le primitive interessanti che ho trovato sono:
__wakeup()
su XmlParserModule.php --> permette di parsare un XML arbitrario e valorizzare diverse variabili in$_ENV
file_put_contents('/tmp/orders.log', "[${date}] ${body} by {$user->username}\n", FILE_APPEND);
--> scrittura su un file noto'message' => "Hello {$user->username}, your {$order->food} order has been submitted successfully."
-->$user->username
è controllabile tramite il cookie serializzatoif ($_ENV['debug'])
--> bypassabile con un cookie serializzato con la classe XmlParserModuleinclude __DIR__."/views/${view}.php";
--> la funzioneview()
di Router.php utilizza un include che potrebbe fare comodo, ma non ho idea se si possa realmente utilizzare
Qualche idea o qualcuno che abbia voglia di sbatterci la testa con me?