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]] | ||