Party Cat0%

29/04/25

SSTI,SQLiiPathTraversal

5 reptes web | CIT CTF 2025

Thanks for sharing!

بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيمِ

SSTI, SQLi i Path Traversal
I know your browser history
Hola i benvinguts de nou a una altra guia! El bolet és aquí i avui cobriré tots els reptes web de CIT CTF 2025 que vaig jugar amb l'equip Lil L3ak. Hem pogut aconseguir el 2n lloc amb tots els reptes resolts, excepte un repte criptogràfic. També assegurant +13k$ en premis!💰💎
Leader Board
Prizes
Comencem de seguida 🚀

Reptes


Trencant l'autenticació

Breaking Authentication
En visitar l'URL, he rebut un formulari d'inici de sessió
Login
Primer va pensar en injecció SQL i, de fet, ho va ser. Simplement vaig iniciar sessió amb admin' -- i em van redirigir al Tauler d'administració però la bandera no hi era
Com que hi ha una vulnerabilitat d'injecció SQL, la marca pot ser emmagatzemada a la base de dades. Tanmateix, ens enfrontem a un repte: no hi ha cap sortida visible, només una redirecció. Això indica una injecció SQL cega, ja sigui basada en errors o basada en temps, ambdues explotables. Per accelerar les coses, vaig utilitzar SQLMap, una eina automatitzada per a l'explotació d'injecció SQL
No m'aprofundiré en explicar l'eina, podeu buscar-la
Vaig veure una taula anomenada secrets, així que a continuació deixem les dades:
Flag
CIT{36b0efd6c2ec7132}

Unitat de control de versions de confirmació i comanda

Chal
A partir del nom... això té alguna cosa a veure amb git que s'utilitza sovint per al control de versions. De vegades, els desenvolupadors el deixen obert per error a la natura i hi podeu accedir mitjançant /.git/
Accedir-hi em va fer Prohibit
Forbidden
Però l'accés a altres camins de fitxer bàsics com /.git/HEAD em va donar resposta
Success
Per tant, sembla que el desenvolupador impedeix l'accés als directoris però no als fitxers en si.
Ara, sempre que tingueu un git exposat com aquest, podeu bolcar-lo amb eines com git-dumper. Simplement executeu:
Ara inspeccionant aquest repo podem veure 2 fitxers: admin.php i index.php. index.php em va aconseguir una contrasenya:
pass
Alerta de spoiler: aquesta passada 9f3IC3uj9^zZ s'utilitzarà en un altre repte
No he pogut iniciar sessió amb aquesta contrasenya en aquest repte.
Si esteu familiaritzat amb Git (que realment hauríeu de ser), sabríeu sobre les confirmacions, bàsicament instantànies de la vostra base de codi en diferents moments del temps. Podeu navegar a qualsevol d'aquests compromisos per veure el codi tal com estava abans de qualsevol actualització o supressió. En el nostre cas, això és genial, vol dir que podem recuperar el contingut suprimit d'aquesta manera!
Podeu veure les commits anteriors juntament amb els seus missatges mitjançant:
git log
Per anar a una confirmació específica, executeu:
i veureu els fitxers tal com estaven en aquell moment.
Extra: per tornar a l'últim commit, només cal que executeu:
Vaig utilitzar una altra opció per accelerar les coses:
Això mostrarà les diferències entre la vostra versió i la versió anterior, que també us revelarà el codi anterior.
Finalment, vaig obtenir la bandera a la 4a commit base64 codificada: Q0lUezVkODFmNzc0M2Y0YmMyYWJ9
flag
CIT{5d81f7743f4bc2ab}

Com he analitzat el vostre JSON

chal
Ara bé!
Tenim aquesta pàgina
main page
Per resumir les coses, actua com una base de dades, però obté dades dels fitxers json! I controlem aquest nom de fitxer (aquí ve a la ment un recorregut de camí ✨)
Vaig provar * i vaig obtenir el següent:
data
L'URL semblava: /select?record=*&container=employees
Vaig comprovar la font de la pàgina però no vaig trobar res útil, ni el recorregut del camí va funcionar, hi havia algun filtratge al backend
Una de les coses que li agrada a un atacant és un Error! Els errors poden revelar informació sobre el backend i, si la depuració està activada, fins i tot poden filtrar el codi font.
Afegiu això a les vostres notes: intenteu trencar coses i desencadenar errors.
Després de mirar una mica, vaig eliminar el segon paràmetre (contenidor) i vaig obtenir el meu bonic TypeError!
Error
Passant-ho, em vaig sortir amb un codi sucós
leaked Code
leaked Code
El codi és senzill: pren la vostra consulta container i la passa a la funció clean_container_name(). Aquesta funció extreu la part abans de l'extensió del fitxer i elimina qualsevol ../. El valor retornat es passa directament a la funció os.path.join() i aquest camí s'utilitza per llegir un fitxer.
Per exemple, si heu passat ../secrets.txt, es filtrarà a secrets i el camí final serà containers/secrets
Ara aquí... vas detectar la vulnerabilitat? el codi bàsicament elimina ../, però no ho fa de manera recursiva. Què passa si poseu ../ en un altre ../ perquè sigui ....//, de manera que quan s'elimini ../ el resultat final serà ../
Versió més senzilla: suposem que es filtra Mush → Passo MuMushsh → s'elimina Mush → el resultat és Mush
Això és tot! Ara passa ....//secrets.txt i... Consulta no vàlida
Per què és això? recordeu el os.path.splitext(n)[0], això només obté la primera part abans de l'extensió i es converteix en containers/../secretssecrets
Podeu gestionar-ho de dues maneres:
  • 1 - Fes servir la mateixa tècnica que acabem d'utilitzar i passa un ../ abans de l'extensió, de manera que quan es filtra, acabes correctament: ....//secrets.../txt../secrets.txt
  • 2 - L'altra manera és només codificar l'URL .: ....//secrets%2Etxt
flag
I obtens la teva bandera (amb la mateixa contrasenya que hem trobat anteriorment, sabràs el seu ús a la propera sessió)
CIT{235da65aa6444e27}

Mantenir-se al dia amb les credencials

chal
Aquest repte, juntament amb el següent, tenia les taxes de resolució més baixes (Això em va fer suposar que implicaria alguna tècnica complicada o avançada i vaig perdre molt de temps repensant-ho)
La configuració era un formulari d'inici de sessió senzill, i tenint en compte que el repte es titulava "Mantenir-se al dia amb les credencials", vaig provar d'utilitzar les credencials que havia trobat anteriorment: 9f3IC3uj9^zZ. Van treballar, i jo estava connectat... però no hi havia cap bandera.
Mentre inspeccionava la sol·licitud d'inici de sessió a Burp Suite, em vaig adonar d'alguna cosa estranya:
weird login
En lloc d'utilitzar una sol·licitud POST típica, el formulari va enviar una sol·licitud GET amb les credencials de la cadena de consulta d'URL. Al principi ho vaig descartar, pensant que potser el desenvolupador acabava d'implementar l'inici de sessió d'aquesta manera.
Més tard, vaig trobar un camí interessant: /admin.php. Quan vaig intentar accedir-hi, em van redirigir immediatament a la pàgina d'inici de sessió, així que vaig suposar que l'accés estava restringit. Vaig començar a provar diverses tècniques, inclòs el contraban de sol·licituds HTTP, tot basant-me en el supòsit que el repte havia de ser difícil a causa del seu baix nombre de solucions.
Resulta que... la solució va ser estúpidament senzilla: Només vaig haver de canviar la sol·licitud d'inici de sessió de GET a POST, i em van redirigir a /admin.php, on vaig trobar la bandera.
No estic segur de si aquest repte era provar pràctiques de codificació segura o simplement trobar-me una mica 🙂, però de qualsevol manera:
CIT{7bf610e96ade83db}

I ara amb l'últim repte: aquest és bo

Senyor Chatbot

chal
En visitar l'URL, et demana el teu nom:
name
M'han redirigit a una pàgina de xat:
chat
No hi ha moltes funcionalitats, vaig inspeccionar la font de la pàgina, tenia l'script següent
És només un script senzill que fa que el bot doni algunes respostes, però el més interessant... reflecteix el meu nom! SSTI? Anem a provar-ho
Vaig passar {{7*7}} i vaig recuperar 7*7, així que estava filtrant. S'han provat diverses càrregues útils, però totes han fallat.
A les vostres galetes, se us dóna un testimoni de sessió, concretament un testimoni de sessió de Flask. És similar a un JWT (JSON Web Token), però té algunes diferències clau.
Podeu descodificar-lo fàcilment amb Flask-Unsign
Tens el teu valor name i admin establerts a 0. Encàrrec massiu?
He enviat una altra sol·licitud amb admin establert a 1. Aquesta vegada he rebut una fitxa més llarga
He pogut establir correctament admin a 1. He intentat tornar a accedir a la pàgina però no hi ha diferències.
Observem un altre valor afegit quan vam explotar l'assignació massiva: uid, que té el que sembla un valor codificat en base64.
Després de la descodificació
decoded
Té el nom que vaig passar i alguns bytes: mushroomb'^\xf2\xc3 ... \xd7\x05'. Vaig provar de descodificar-ho amb hexadecimal però no em va donar res. Al costat positiu tenim una reflexió! el meu name hi és
Afegiu això a les vostres notes: les reflexions són bones!
La reflexió ajuda a identificar els punts d'injecció, on flueixen les dades controlades per l'usuari, que és fonamental per explotar coses com SQLi, injecció d'ordres o injecció de plantilles.
Per provar que he passat {{7*7}} a name i he definit admin a 1
reflected!
Bingo! És vulnerable, tinc 49. Aquesta és la nostra manera d'entrar!
Vaig utilitzar {{''.__class__.__mro__[1].__subclasses__()}} a name i vaig obtenir un testimoni enorme
reflected!
descodificant-lo
reflected!
A continuació, vaig utilitzar {{''.__class__.__mro__[1].__subclasses__()[399]('secrets.txt').read()}}
flag
I aquesta és la nostra bandera!
CIT{18a7fbedb4f3548f}

Finalment, aquest escrit s'ha acabat, va trigar +4 hores home lol. 😮‍💨
Tant de bo això us hagi estat beneficiós. No us oblideu de fer una ullada a la meva X i si teniu cap pregunta, no dubteu a posar-vos en contacte amb mi a Discord.
Ens veiem la propera 🚀! Pau.

També et pot interessar