<?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>SAGES:: Blog &#187; Krzysztof Cabaj</title>
	<atom:link href="http://blog.sages.com.pl/author/kcabaj/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sages.com.pl</link>
	<description>Blog konsultantów firmy Sages - artykuły o technologiach Java EE i pokrewnych</description>
	<lastBuildDate>Mon, 13 Jun 2011 15:50:18 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Błąd Buffer Overflow&#8230; w szczegółach</title>
		<link>http://blog.sages.com.pl/2010/07/blad-buffer-overflow-w-szczegolach/</link>
		<comments>http://blog.sages.com.pl/2010/07/blad-buffer-overflow-w-szczegolach/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 12:52:58 +0000</pubDate>
		<dc:creator>Krzysztof Cabaj</dc:creator>
				<category><![CDATA[Problemy i rozwiązania]]></category>
		<category><![CDATA[bezpieczeństwo]]></category>
		<category><![CDATA[buffer overflow]]></category>

		<guid isPermaLink="false">http://blog.sages.com.pl/?p=68</guid>
		<description><![CDATA[Chyba każda osoba interesująca się sieciami komputerowymi i ich bezpieczeństwem zetknęła się z atakiem typu „Buffer overflow”. Idea działania większości też jest znana, jednak kojarzy się z jakimiś niesamowitymi sztuczkami. W tym artykule chcę przybliżyć jak w szczegółach wygląda podatny kod oraz jak trzeba spreparować specjalny ciąg wejściowy aby doprowadzić to ataku.
Rozpatrzmy prostą funkcję zaprezentowaną [...]]]></description>
			<content:encoded><![CDATA[<p>Chyba każda osoba interesująca się sieciami komputerowymi i ich bezpieczeństwem zetknęła się z atakiem typu „Buffer overflow”. Idea działania większości też jest znana, jednak kojarzy się z jakimiś niesamowitymi sztuczkami. W tym artykule chcę przybliżyć jak w szczegółach wygląda podatny kod oraz jak trzeba spreparować specjalny ciąg wejściowy aby doprowadzić to ataku.<span id="more-68"></span></p>
<p>Rozpatrzmy prostą funkcję zaprezentowaną poniżej:</p>
<pre>void VulnFunc(char *ptr)
{
  char buffer[32];
  int i;

  for(i=0;(*ptr)!='&amp;';i++)
    buffer[i]=*(ptr++);

  //dalsze instrukcje działające na buforze, nie zmieniające jego
  //zawartości, przykładowo liczące wartość skrótu MD5 z zawartości
  //bufora, nieistotne jeśli chodzi o atak buffer overflow
}
</pre>
<p>Możemy łatwo wyobrazić sobie i podać zadanie tej funkcji, która pobiera pewne dane, kopiuje je do bufora oraz wykonuje z jego pomocą pewne operacje. Łatwo możemy wskazać widoczny od razu błąd: dane kopiujemy do bufora bez sprawdzania czy go nie przepełnimy. Warunkiem zakończenia kopiowania jest natrafienie na znak &amp;. Właśnie taki błąd, o ile możemy podać dowolne dane wejściowe może zostać wykorzystany.</p>
<p>Nim przejdziemy do preparowania odpowiedniego ciągu znaków będących exploitem obejrzyjmy stos podczas normalnego wywołania funkcji, zaprezentowany na rysunku nr 1.</p>
<div id="attachment_77" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.sages.com.pl/wp-content/uploads/2010/07/rys1.png"><img class="size-medium wp-image-77" title="Stos podczas normalnego wywołania funkcji" src="http://blog.sages.com.pl/wp-content/uploads/2010/07/rys1-300x107.png" alt="Stos podczas normalnego wywołania funkcji" width="300" height="107" /></a><p class="wp-caption-text">Stos podczas normalnego wywołania funkcji</p></div>
<p><!-- 		@page { size: 21cm 29.7cm; margin: 2cm } 		P { margin-bottom: 0.21cm } -->W lewej części rysunku przedstawiona jest zawartość pamięci wykorzystywanej na stos. Wyróżnione na czerwono obszary to zmienna i oraz bufor, z przepisaną zawartością, w tym przypadku tekstem „Ala”. Wyróżniony na niebiesko fragment to wskaźnik ptr przekazywany jako parametr. Wszystkie te informacje można skonfrontować z zawartością zmiennych podczas wykonania programu zaprezentowanych po prawej stronie rysunku.</p>
<p>Wróćmy na chwilę do wyróżnionego na niebiesko adresu, będącego parametrem. W takim przypadku nasze zainteresowanie powinny dotyczyć 32 bitowy adres znajdujący się bezpośrednio przed nim. Adres ten, jest adresem powrotu z funkcji. Jeśli uda nam się go zmienić, w momencie powrotu z funkcji … wykonamy inny kod, nieprzewidziany przez programistę.</p>
<p>Aby prześledzić taki przypadek rozpatrzmy sytuację, kiedy do funkcji zostanie podany ciąg znaków postaci (liczby hexadecymalne):</p>
<p><code><br />
0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x83,0xec,0x80,0xbe,<br />
0xe6,0x10,0x41,0x00,0x68,0x41,0x6c,0x61,0x00,0x8b,0xdc,0x6a,0x40,0x53,<br />
0x53,0x33,0xc0,0x50,0xff,0xd6,0xff,0x15,0xe6,0x6c,0x41,0x00,0x68,<br />
0xfd,0x12,0x00,0x26</code></p>
<p><!-- 		@page { size: 21cm 29.7cm; margin: 2cm } 		P { margin-bottom: 0.21cm } -->… i podobnie jak w poprzednim wywołaniu funkcji prześledźmy zawartość stosu.</p>
<div id="attachment_78" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.sages.com.pl/wp-content/uploads/2010/07/rys2.png"><img class="size-medium wp-image-78" title="Stos przy próbie ataku" src="http://blog.sages.com.pl/wp-content/uploads/2010/07/rys2-300x102.png" alt="Stos przy próbie ataku" width="300" height="102" /></a><p class="wp-caption-text">Stos przy próbie ataku</p></div>
<p><!-- 		@page { size: 21cm 29.7cm; margin: 2cm } 		P { margin-bottom: 0.21cm } -->Na zaprezentowanym rysunku możemy zaobserwować, że do bufora zostało przepisane dużo więcej danych niż poprzednio. Dokładnie 44 bajty (wartość hexadecymalna 2c w obszarze pamięci zmiennej i). Wartość ta jest większa niż zadeklarowany na 32 bajty bufor. Jednak co najważniejsze, czy &#8211; powinniśmy powiedzieć &#8211; najgroźniejsze, został nadpisany adres powrotu z funkcji (fragment wyróżniony na niebiesko), gdzie teraz znajdują się instrukcje które zostaną wykonane przez program. Pamiętając iż zmienne na maszynach z procesorem Intel są przechowywane „od końca” możemy odkodować adres powrotu. Skok nastąpi do instrukcji znajdującej się pod adresem 0&#215;0012fd68. Jeśli przyjrzymy się dokładnie obszarowi pamięci stosu, możemy zauważyć, że skoczymy w zaprezentowany na rysunku obszar pamięci. Dokładniej wykonanie nowego kodu zaczniemy od instrukcji o kodzie 0&#215;90. Dalej możemy zaobserwować jeszcze kilka instrukcji o tym samym kodzie. Taka sekwencja jest często spotykana w exploitach. Kod 0&#215;90 ma instrukcja NOP – no operation. Instrukcja która nic nie robi, ale ma długość jednego bajta. Taka sekwencją zwana poduszeczką NOP ( jest przydatna, jeśli okazało by się, iż nie trafimy dokładnie w początek kodu exploita). Dalszą analizę tego kodu zostawmy na później … i zobaczmy co się stanie jak wykonamy ten kod. Wyniki przedstawia rysunek.</p>
<div id="attachment_79" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.sages.com.pl/wp-content/uploads/2010/07/rys3.png"><img class="size-medium wp-image-79" title="Wykonanie kodu" src="http://blog.sages.com.pl/wp-content/uploads/2010/07/rys3-300x154.png" alt="Wykonanie kodu" width="300" height="154" /></a><p class="wp-caption-text">Wykonanie kodu</p></div>
<h3>Co robi kod na stosie … trochę assemblera</h3>
<p>Znaczenie instrukcji o kodzie 0&#215;90 zostało już wyjaśnione wcześniej, teraz przyjrzyjmy się reszcie kodu.<br />
. . .</p>
<table>
<tbody>
<tr>
<td>0&#215;90</td>
<td>nop</td>
</tr>
<tr>
<td>0&#215;83,0xec, 0&#215;80,</td>
<td>sub esp,0&#215;80//zrobienie miejsca na stosie</td>
</tr>
<tr>
<td>0xbe,0xe6, 0&#215;10, 0&#215;41, 0&#215;00</td>
<td>mov esi, &lt;adres&gt;</td>
</tr>
<tr>
<td>0&#215;68,0&#215;41, 0&#215;6c, 0&#215;61, 0&#215;00</td>
<td>push &lt;dane&gt;</td>
</tr>
<tr>
<td>0&#215;8b,0xdc</td>
<td>mov ebx,esp</td>
</tr>
<tr>
<td>0&#215;6a,0&#215;40</td>
<td>push 0&#215;40</td>
</tr>
<tr>
<td>0&#215;53</td>
<td>push ebx</td>
</tr>
<tr>
<td>0&#215;53</td>
<td>push ebx</td>
</tr>
<tr>
<td>0&#215;33,0xc0</td>
<td>xor eax, eax</td>
</tr>
<tr>
<td>0&#215;50</td>
<td>push eax</td>
</tr>
<tr>
<td>0xff,0xd6</td>
<td>call esi</td>
</tr>
<tr>
<td>0xff,0&#215;15, 0xe6, 0&#215;6c, 0&#215;41, 0&#215;00</td>
<td>call &lt;adres&gt;</td>
</tr>
<tr>
<td>0&#215;68,0xfd, 0&#215;12,0&#215;00</td>
<td>adres nadpisujacy adres powrotu</td>
</tr>
<tr>
<td>0&#215;26</td>
<td>znak &amp;</td>
</tr>
</tbody>
</table>
<p>Co robi ten kod? Pierwsza instrukcja odejmuje 128 od rejestru esp – stack pointer, robiąc miejsce na stosie dla dalszego kodu. W dalszej części przypisujemy do rejestru esi adres funkcji MessageBox. Później odkładamy 5 wartości na stos, najpierw pewne dane, które już wcześniej widzieliśmy na stosie (co dokładnie … zostawiam czytelnikowi do zgadnięcia). Nim odłożymy kolejne 4 wartości zapamiętujemy zawartość rejestru esp w rejestrze ebx. Adres ten odpowiada początkowi stosu, czyli aktualnie danym załadowanym na stos przed chwila. W dalszej części odkładamy na stos liczbę 0&#215;40, dwa razy wskaźnik wskazujący na pewne dane znajdujące się na stosie oraz wartość 0. Potem dokonujemy wywołania funkcji MessageBoxA. Co robiliśmy wcześniej na stosie? – odkładaliśmy parametry – handle do okna (0 – NULL, czyli okno bez powiązania z innym oknem), dalej dwa razy wskaźnik na zawartość okna i jego tytuł (czy już wiadomo jakie dane były wkładane na stos? <img src='http://blog.sages.com.pl/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) i na końcu typ okna, w naszym przypadku okno informacyjne. Na uwagę zasługuje jeszcze ostatnia wartość – 0&#215;26 czyli w reprezentacji ASCII znak &amp; &#8211; warunek stopu pętli kopiującej dane do bufora.</p>
<p>Oczywiście zaprezentowany w tym przykładzie kod nie robi nic groźnego, jedynie wyświetla okienko. Jednak mając więcej miejsca na stosie można spreparować naprawdę groźną funkcję. Ale to już temat na kolejny wpis … <img src='http://blog.sages.com.pl/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3>Kilka wyjaśnień</h3>
<p>Wykorzystywane w przykładowym kodzie exploita adresy zostały wcześniej odkryte poprzez analizę kodu działającego programu za pomocą debuggera. Architektura systemu Windows (no może z wyjątkiem Visty i dalszych) powoduje, że w tym samym środowisku  (te same zainstalowane programy) wykonujący się program zawsze będzie posiadał te same adresy funkcji oraz stosu. Dzięki temu w środowisku testowym można je poznać … i wykorzystywać do ataku na inne identyczne lub podobne (patrz poduszeczkę NOP) systemy. Analogicznie ma się sprawa z adresem wykorzystywanej funkcji MessageBoxA.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sages.com.pl/2010/07/blad-buffer-overflow-w-szczegolach/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Atak wstrzyknięcia na stronach bez pól tekstowych</title>
		<link>http://blog.sages.com.pl/2010/03/atak-wstrzykniecia-na-stronach-bez-pol-tekstowych/</link>
		<comments>http://blog.sages.com.pl/2010/03/atak-wstrzykniecia-na-stronach-bez-pol-tekstowych/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 13:36:13 +0000</pubDate>
		<dc:creator>Krzysztof Cabaj</dc:creator>
				<category><![CDATA[Problemy i rozwiązania]]></category>
		<category><![CDATA[bezpieczeństwo]]></category>
		<category><![CDATA[injection flaw]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[WebScarab]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://blog.sages.com.pl/?p=30</guid>
		<description><![CDATA[Artykuł ten jest pierwszym z serii wpisów poświęconych zagadnieniom bezpieczeństwa aplikacji Webowych. W niniejszym artykule zostanie omówiona możliwość wykorzystania podatności typu injection na stronach bez pól tekstowych oraz wykorzystanie narzędzia WebScarab do przeprowadzenia takiego ataku.
Wykorzystanie podatności wstrzyknięcia (ang. Injection Flaw) jest częstą przyczyną włamań do aplikacji internetowych. Problemy związane z bezpieczeństwem aplikacji dotyczące wstrzyknięcia niepoprawnych [...]]]></description>
			<content:encoded><![CDATA[<p>Artykuł ten jest pierwszym z serii wpisów poświęconych zagadnieniom bezpieczeństwa aplikacji Webowych. W niniejszym artykule zostanie omówiona możliwość wykorzystania podatności typu injection na stronach bez pól tekstowych oraz wykorzystanie narzędzia WebScarab do przeprowadzenia takiego ataku.</p>
<p>Wykorzystanie <a href="http://www.owasp.org/index.php/Injection_Flaws">podatności wstrzyknięcia (ang. Injection Flaw)</a> jest częstą przyczyną włamań do aplikacji internetowych. Problemy związane z bezpieczeństwem aplikacji dotyczące wstrzyknięcia niepoprawnych danych na stronach z polami testowymi są powszechne (w szczególności ataki typu <a href="http://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29">Cross Site Scripting, XSS</a>). Jednak możliwość wykorzystania podatności wstrzyknięcia na stronach bez pól tekstowych nie jest już tak oczywista.</p>
<p><span id="more-30"></span></p>
<h3>Injection Flaw</h3>
<p>Rozpatrzmy prostą funkcjonalność aplikacji obsługującej sklep internetowy, służącą do przedstawienia statusu złożonych zamówień. Przykładowy wygląd takiej aplikacji przedstawiony jest na rysunku 1.<br />
<a href="http://blog.sages.com.pl/wp-content/uploads/2010/03/aplikacja.jpg"><img src="http://blog.sages.com.pl/wp-content/uploads/2010/03/aplikacja-300x213.jpg" alt="" title="Aplikacja przykładowa" width="300" height="213" class="aligncenter size-medium wp-image-31" /></a></p>
<p>Jak można przypuszczać, informacja uzyskana od użytkownika, związana z wyborem interesującego statusu przesyłki służy do sparametryzowania zapytania SQL do bazy danych. Z dużym prawdopodobieństwem można założyć, że wykorzystane zapytanie SQL będzie zbliżone do zapytania w następującej postaci:</p>
<p><code>SELECT id, towar, adres FROM zamowienia WHERE klient_id = ...<br />
          and status = ...</code></p>
<p>Jeśli założy się, że programista aplikacji kleił ręcznie zapytanie oraz nie zapewnił walidacji dostarczanych danych, łatwo można się domyśleć jaki tekst trzeba umieścić w zapytaniu aby uzyskać informację o wszystkich zamówieniach.</p>
<p>Rozważyć można sytuację, kiedy zamiast spodziewanego identyfikatora statusu podstawiony zostanie fragment zapytania SQL postaci:</p>
<p><code>4 or 1=1</code></p>
<p>W takim przypadku warunek w zapytaniu będzie zawsze prawdziwy, co w efekcie spowoduje wyszukanie wszystkich rekordów z tabeli.</p>
<p>Ponieważ aplikacja wysyła dane użytkownika za pomocą metody GET, w wysyłanym URLu możemy zaobserwować wszystkie parametry. Wystarczy, że w odpowiednim miejscu zostanie wklejony spreparowany fragment danych a cały URL ponownie wysłany. Na rysunku 2 można zaobserwować wynik wykonania za pomocą zwykłej przeglądarki takiego złośliwego zapytania.<br />
<a href="http://blog.sages.com.pl/wp-content/uploads/2010/03/aplikacja-atak.jpg"><img src="http://blog.sages.com.pl/wp-content/uploads/2010/03/aplikacja-atak-300x208.jpg" alt="" title="Atak na aplikację przykładową" width="300" height="208" class="aligncenter size-medium wp-image-33" /></a></p>
<p>Jak można było się spodziewać, w wyniku tego zapytania została ujawniona cała zawartość tabeli. W tym przypadku poznano wszystkich adresatów do których sklep wysłał paczki. Jednak jeśli byłby to system bankowy i &#8220;dziurawa&#8221; funkcjonalność dotyczyłaby kodów jednorazowych &#8211; ujawnione zostałyby adresy, pod które zostały one wysłane. Jeśli w tablicy znajdowały by się adresy mailowe, to ich poznanie mogło by posłużyć do wysyłania SPAMu lub wiadomości związanych z <a href="http://pl.wikipedia.org/wiki/Phishing">phishingiem</a>. Taki atak byłby o tyle groźny, że dotyczył rzeczywistych klientów danej organizacji.</p>
<p>W omawianym powyżej przykładzie aplikacja wykorzystywała do komunikacje metodę GET, więc atak można przeprowadzić nawet za pomocą przeglądarki. Jednak wykorzystanie metody POST, chociaż ukrywa część informacji przed zwykłym użytkownikiem oraz umożliwia szyfrowanie przesyłanych danych w przypadku protokołu HTTPS, nie jest zabezpieczeniem (patrz paradygmat <a href="http://pl.wikipedia.org/wiki/Security_through_obscurity">security by obscurity</a>). W takim przypadku pomocne może być narzędzie <a href="http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project">WebScarab</a>. WebScarab jest specjalnym rodzajem serwera proxy. Każde żądanie przechodzące przez niego jest przechwytywane i może zostać dowolnie zmodyfikowane. Program ten jest często wykorzystywany przy testach bezpieczeństwa aplikacji webowych. </p>
<h3>Jak przeprowadzić atak wykorzystując program WebScarab</h3>
<p>Pierwszym krokiem jest ustawienie proxy w używanej przeglądarce na adres wykorzystywany przez program WebScarab (standardowo nasłuchuje na porcie 8008). Następnym krokiem jest wejście na stronę, której ewentualne podatności chcemy sprawdzić. Podczas wywołania zapytania zostanie ono przechwycone i zaprezentowane użytkownikowi. W tym miejscu można dokonać dowolnych modyfikacji nagłówków a także danych przesyłanych za pomocą metody POST. Przykład takiej modyfikacji dobrze znanym fragmentem zapytania SQL zaprezentowany jest na rysunku 3.<br />
<a href="http://blog.sages.com.pl/wp-content/uploads/2010/03/webscarab-atak.jpg"><img src="http://blog.sages.com.pl/wp-content/uploads/2010/03/webscarab-atak-300x242.jpg" alt="" title="Atak za pomocą WebScarab" width="300" height="242" class="aligncenter size-medium wp-image-34" /></a></p>
<p>Efekt przeprowadzonych działań widoczny jest na rysunku 4.<br />
<a href="http://blog.sages.com.pl/wp-content/uploads/2010/03/aplikacja-atak-post.jpg"><img src="http://blog.sages.com.pl/wp-content/uploads/2010/03/aplikacja-atak-post-300x217.jpg" alt="" title="WebScarab - rezultat" width="300" height="217" class="aligncenter size-medium wp-image-35" /></a></p>
<p>Zgodnie z oczekiwaniami po zatwierdzeniu zmiany dokonanej w programie WebScarab uzyskany zostaje dostęp do wszystkich danych znajdujących się w tabeli.</p>
<h3>Podsumowanie</h3>
<p>Jak można zabezpieczyć się przed tego typu atakiem</p>
<ul>
<li>Nie kleić ręcznie zapytań, zamiast tego skorzystać ze specjalnych funkcji lub obiektów służących do tego (ale nie zawsze się da, np. zapytanie XPath). Dla przykładu, w JDBC mamy do dospozycji PreparedStatement:
<pre>
. . .
PreparedStatement ps;
c = ds.getConnection();
ps = c.prepareStatement("SELECT id, towar, adres FROM zamowienia
   WHERE klient_id = ? and status = ?");
ps.setString(1, klient_id);
ps.setString(2, status);
ps.execute();
. . .
</pre>
</li>
<li>Nie ufać w żadne dane wysłane od klienta, zawsze dokonywać walidacji albo choćby procesu escapowania danych
<pre>
. . .

try {
   Integer val = null;
   val = val.parseInt(request.getParameter("status"));
   if (val <= 0 || val > 4)
      throw new NumberValidationException(); //własna klasa wyjątku
   . . .
} catch(NumberFormatException ex) {
   out.println("Parameter problem, try once again");
} catch(NumberValidationException ex) {
   out.println("Parameter problem, try once again");
} catch(...) ...
</pre>
</li>
]]></content:encoded>
			<wfw:commentRss>http://blog.sages.com.pl/2010/03/atak-wstrzykniecia-na-stronach-bez-pol-tekstowych/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

