This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
laboratoare:laborator-10 [2015/12/16 15:48] razvan.deaconescu [[3p] 2. First flag] |
laboratoare:laborator-10 [2016/01/09 13:39] (current) razvan.deaconescu [[3p] BONUS Graceful exit] |
||
---|---|---|---|
Line 38: | Line 38: | ||
Dacă într-o aplicație se descoperă un buffer overflow, nu înseamnă (neapărat) că acest lucru este o vulnerabilitate. Dacă un atacator nu poate **controla** buffer-ul respectiv, atunci rămâne doar un bug în cadrul aplicației respective. | Dacă într-o aplicație se descoperă un buffer overflow, nu înseamnă (neapărat) că acest lucru este o vulnerabilitate. Dacă un atacator nu poate **controla** buffer-ul respectiv, atunci rămâne doar un bug în cadrul aplicației respective. | ||
</note> | </note> | ||
+ | |||
===== Setup ===== | ===== Setup ===== | ||
- | Recomandăm să faceți următorul setup după ce porniți ''cmd.exe'': | + | Pentru a putea rula ''python'', ''gdb'' și ''objdump'' de oriunde (în cadrul acelei console) recomandăm să faceți următorul setup în ''Command Prompt'':<code> |
- | + | set PATH=%PATH%;"C:\Program Files (x86)\SASM\MinGW\bin";"C:\Python27" | |
- | ''set PATH=%PATH%;"C:\Program Files (x86)\SASM\MinGW\bin";"C:\Python27"'' | + | </code> |
- | În felul acesta, veți putea rula ''python'', ''gdb'' și ''objdump'' de oriunde (în cadrul acelui terminal). | ||
===== Exerciții ===== | ===== Exerciții ===== | ||
- | În cadrul acestui laborator, vom folosi arhiva {{:laboratoare:lab-10-tasks.zip|asociată laboratorului}}. | + | În cadrul acestui laborator, vom folosi [[http://elf.cs.pub.ro/asm/res/laboratoare/lab-10-tasks.zip|arhiva de sarcini a laboratorului]]. |
<note tip> | <note tip> | ||
Line 54: | Line 54: | ||
<note> | <note> | ||
- | Puteți folosi orice fel de consolă vi se pare adecvat. | + | Puteți folosi orice fel de consolă vi se pare adecvată. |
</note> | </note> | ||
+ | |||
==== [2p] Tutorial: Găsire offset și suprascrierea adresei de retur ==== | ==== [2p] Tutorial: Găsire offset și suprascrierea adresei de retur ==== | ||
+ | |||
+ | Accesați subdirectorul ''tutorial/'' din [[http://elf.cs.pub.ro/asm/res/laboratoare/lab-10-tasks.zip|arhiva de sarcini a laboratorului]]. | ||
Inspectați sursa ''tutorial.asm'' și rulați comanda ''build_tutorial''. | Inspectați sursa ''tutorial.asm'' și rulați comanda ''build_tutorial''. | ||
Line 72: | Line 75: | ||
(gdb) disas | (gdb) disas | ||
[...] | [...] | ||
- | (gdb) read_input | + | (gdb) b read_input |
[...] | [...] | ||
(gdb) b *0x4013ba | (gdb) b *0x4013ba | ||
Line 84: | Line 87: | ||
</note> | </note> | ||
- | Introduceți drept input o secvență lungă de 'A'-uri. | + | Introduceți drept input o secvență lungă (circa 50) de caractere ''A''. |
<code> | <code> | ||
Line 130: | Line 133: | ||
Actualizați în fișierul ''tutorial_payload.py'' variabila ''offset'' la offset-ul necesar pentru suprascrierea adresei de retur. În cazul nostru este vorba de valoarea ''32''. | Actualizați în fișierul ''tutorial_payload.py'' variabila ''offset'' la offset-ul necesar pentru suprascrierea adresei de retur. În cazul nostru este vorba de valoarea ''32''. | ||
- | Generati un ''payload'' folosind comanda<code> | + | Generati un ''payload'' (in afara GDB-ului) folosind comanda<code> |
python tutorial_payload.py | python tutorial_payload.py | ||
</code> | </code> | ||
Line 168: | Line 171: | ||
python tutorial_payload.py | python tutorial_payload.py | ||
</code> | </code> | ||
- | Comanda generează un payload în fișierul ''payload''. | ||
- | <code> | + | Comanda generează un payload în fișierul ''payload''.<code> |
.\tutorial.exe < payload | .\tutorial.exe < payload | ||
What is your name? | What is your name? | ||
Line 177: | Line 179: | ||
Programul afișează cele două mesaje, așa cum ne așteptam, și apoi crash-uiește. Vom vedea în exercițiile următoare de ce programul a crash-uit. | Programul afișează cele două mesaje, așa cum ne așteptam, și apoi crash-uiește. Vom vedea în exercițiile următoare de ce programul a crash-uit. | ||
+ | |||
==== [2p] 1. Recon ==== | ==== [2p] 1. Recon ==== | ||
- | Identificați vulnerabilitatea din program; încercați să-l faceți să crape. Inspectați sursa ''gen_payload.py'' și urmăriți comentariile marcate cu ''TODO''. | + | Accesați subdirectorul ''shellcode'' din [[http://elf.cs.pub.ro/asm/res/laboratoare/lab-10-tasks.zip|arhiva de sarcini a laboratorului]]. |
- | Generați un payload folosind comanda<code> | + | Identificați vulnerabilitatea de tip buffer overflow din programul ''shellcode.asm''. Faceți programul să crape suprascriind prin buffer overflow o adresă de retur corespunzătoare. |
- | python gen_payload.py | + | |
- | </code> | + | |
- | Determinați offsetul unde ar trebui să se găsească adresa de retur a funcției vulnerabile. | + | Pentru a face overflow, cel mai bine este să generați un fișier de tip ''payload'' pe care să îl trimiteți ca intrare programului. Pentru a genera fișierul de tip payload, recomandăm folosirea scriptului Python ''gen_payload.py'' și urmăriți comentariile marcate cu ''TODO''. |
+ | |||
+ | Determinați offsetul unde ar trebui să se găsească adresa de retur a funcției vulnerabile și completați corespunzător în fișierul ''gen_payload.py''. | ||
<note tip> | <note tip> | ||
Inspectați codul funcției ''vuln'' și aflați care este offset-ul de la adresa buffer-ului folosit de funcția ''gets()'' până la locul de pe stivă unde este reținută adresa de retur a funcției ''vuln''. | Inspectați codul funcției ''vuln'' și aflați care este offset-ul de la adresa buffer-ului folosit de funcția ''gets()'' până la locul de pe stivă unde este reținută adresa de retur a funcției ''vuln''. | ||
</note> | </note> | ||
+ | |||
+ | Generați un payload în consola de Windows (adică nu în consola GDB) folosind comanda<code> | ||
+ | python gen_payload.py | ||
+ | </code> | ||
+ | Comanda generează payload-ul în fișierul ''payload''. Transmiteți acest payload programului în linia de comandă<code> | ||
+ | .\shellcode.exe < payload | ||
+ | </code> | ||
+ | Dacă ați completat corespunzător offset-ul în cadrul scriptului Python, atunci rularea programului va rezulta într-un crash. | ||
==== [3p] 2. First flag ==== | ==== [3p] 2. First flag ==== | ||
Line 197: | Line 208: | ||
<note tip> | <note tip> | ||
Modificați ''gen_payload.py'' în mod corespunzător. Va trebui să actualizați corespunzător variabila ''offset'', să determinați adresa funcției ''flag1'' și să adăugați valoarea cu care să suprascrieți adresa de retur la sfârșitul payload-ului. Valoarea folosită pentru suprascriere este chiar adresa funcției ''flag1''. | Modificați ''gen_payload.py'' în mod corespunzător. Va trebui să actualizați corespunzător variabila ''offset'', să determinați adresa funcției ''flag1'' și să adăugați valoarea cu care să suprascrieți adresa de retur la sfârșitul payload-ului. Valoarea folosită pentru suprascriere este chiar adresa funcției ''flag1''. | ||
+ | </note> | ||
- | Funcția ''dw'' trece o valoare pe 4 bytes într-un șir de octeți în format little endian. Puteți urmări modul în care este folosită funcția ''dw'' în fișierul ''tutorial_payload.py'' din cadrul tutorialului de mai devreme. | + | <note tip> |
+ | Pentru a adăuga adresa funcției ''flag1'' la sfârșitul payload-ului va trebui să convertiți acea adresă dintr-o valoarea întreagă (pe 4 octeți) într-un șir de octeți. Pentru aceasta folosiți-vă de funcția ''dw'' care exact acest lucru îl face: trece o valoare pe 4 octeți într-un șir de octeți în format little endian. Puteți urmări modul în care este folosită funcția ''dw'' în fișierul ''tutorial_payload.py'' din cadrul tutorialului de mai devreme. | ||
</note> | </note> | ||
Line 255: | Line 268: | ||
</code> În acest moment veți face jump la adresa stocată în vârful stivei adică acolo unde programul așteaptă adresa de retur. Dacă totul e în regulă, veți face jump în funcția ''flag1''. | </code> În acest moment veți face jump la adresa stocată în vârful stivei adică acolo unde programul așteaptă adresa de retur. Dacă totul e în regulă, veți face jump în funcția ''flag1''. | ||
</note> | </note> | ||
+ | |||
+ | <note important> | ||
+ | Dacă ați completat corect payload-ul, la transmiterea payload-ului către programul ''shellcode.exe'' veți avea afișat mesajul dat de variabila ''honeypot'' din fișierul ''shellcode.asm'', anume //You shouldn't be here!//. | ||
+ | </note> | ||
+ | |||
==== [3p] 3. Second flag ==== | ==== [3p] 3. Second flag ==== | ||
+ | |||
Modificați sursa ''gen_payload.py'' astfel încât să genereze un payload care să aducă programul să apeleze funcția ''flag2''. | Modificați sursa ''gen_payload.py'' astfel încât să genereze un payload care să aducă programul să apeleze funcția ''flag2''. | ||
- | <note> | + | <note tip> |
- | **Hints**: Câte argumente are funcția? | + | Câte argumente are funcția? |
Pentru ce valori ale argumentelor ajunge funcția să treacă testele? | Pentru ce valori ale argumentelor ajunge funcția să treacă testele? | ||
Cum trebuie să arate bufferul de intrare astfel încât atunci când se ajunge în funcție parametrii să se găsească pe pozițiile corespunzătoare pe stivă? | Cum trebuie să arate bufferul de intrare astfel încât atunci când se ajunge în funcție parametrii să se găsească pe pozițiile corespunzătoare pe stivă? | ||
Line 266: | Line 285: | ||
Scrieți modificările necesare în ''gen_payload.py'' și generați un nou payload. | Scrieți modificările necesare în ''gen_payload.py'' și generați un nou payload. | ||
- | ==== [3p] BONUS Graceful exits ==== | + | <note important> |
- | Ați observat că deși se execută codul dorit de noi, programul în continuare crapă. De ce? Corectați acest lucru. Generați noi payload-uri prin care după ce se execută codul dorit, programul să se termine cu succes. | + | Dacă ați completat corect payload-ul, la transmiterea payload-ului către programul ''shellcode.exe'' veți avea afișat mesajul dat de variabila ''great'' din fișierul ''shellcode.asm'', anume //Mad skills, yo!//. |
+ | </note> | ||
+ | ==== [3p] BONUS Graceful exit ==== | ||
+ | |||
+ | Ați observat că, pentru payload-ul anterior, în care apelați funcția ''flag2()'' deși se execută codul dorit de noi, programul în continuare crapă. De ce? Corectați acest lucru. Generați noi payload-uri prin care după ce se execută codul dorit, programul să se termine cu succes. | ||
+ | |||
+ | ===== Soluții ===== | ||
+ | |||
+ | [[http://elf.cs.pub.ro/asm/res/laboratoare/lab-10-sol.zip|Soluții de referință pentru exercițiile de laborator]] |