Exploitování – tvorba shellkódu 2. část

Pokračování článku o vytváření shellkódu v assembleru. Bude následovat ještě jeden díl.

Hledání dalších funkcí

Jelikož budeme hledat větší množství funkcí, uděláme si vlastní proceduru která nám najde funkce z určitého seznamu a uloží je na další seznam. Bude vypadat takto: (komentáře hovoří za vše)

 

Procedura která nám najde adresy exportovaných funkcí je vytvořena. Takže jí musíme nachystat potřebné údaje a pak ji zavolat:

 

Našli jsme adresy jednotlivých funkcí a uložili jsme je na místo původních názvů. Názvy totiž už nebudeme potřebovat, když známe adresy, a ušetříme tak místo, čas i velikos exploitu.
Dále víme že budeme vytvářet exploit co pracuje se sítí, takže potřebujeme knihovnu WinSock.

 

Všimněte si že při druhém volání procedury hledej_fce nenastavovali registr edi. Odkazuje totiž hned za poslední nalezenou adresu funkce z kernellu. Můžeme klidně zapisovat za ně.

Vytvoření rour

Abychom mohli přesměrovat příkazovou řádku na nějakou IP:port, budeme potřebovat vytvořit tzv. Pipe neboli rouru. Konkrétně budeme potřebovat tyto roury 2. Do první budeme zapisovat my co dostaneme ze socketu a číst z ní bude proces příkazové řádky. Do druhé bude zapisovat příkazová řádka svůj výstup který z ní následně přečteme a zašleme přes socket.
Registr edi nám odkazuje někam mezi názvy funkcí které jsme hledali v kernellu. Před ním jsou v paměti uložené adresy funkcí, které jsme si našli. A jelikož zbytek názvů funkcí a taktéž kód který následuje za nimi už byl vykonán a nebude potřeba být volán znova, můžeme jej klidně přepsat a použít jej třeba jako buffer. Mohli bychom si sice vytvořit buffer kdekoliv jinde, např. voláním funkce GlobalAlloc, ale pak bychom museli někam ukládat jeho adresu a tím bychom přišli o registr. Když si přepíšeme kód, ušetříme místo v paměti, nějaký čas, ale hlavně jeden registr který nám odkazuje na buffer.
Vzhledem k registru edi si tedy rozvrhneme paměť takto:
• Před edi máme adresy funkcí
• Od edi do edi+20h si budeme ukládat proměnné které potřebujeme pro další běh programu
• Od edi+20h výš budeme používat jako buffer pro různé účely

 

Spuštění příkazové řádky

Pro spuštění příkazové řádky použijeme funkci CreateProcess. Pro ni ale potřebujeme parametr StartupInfo, který získáme funkcí GetStartupInfoA. Spouštěná aplikace bude mít tato data stejná, pouze upravíme některé parametry. Zároveň spouštěnému procesu přiřadíme roury.

 

Zde by nebylo na škodu si opět přidat breakpoint a zkusit si prográmek debuggnout, zda nám správně spustí příkazovou řádku. To zjistíme podle návratové hodnoty uložené v eax, která je nenulová při úspěšném provedené funkce. Ověřit si funkčnost můžeme také přes Task manager ve kterém by se měla nově objevit spuštěná příkazová řádka.

Související články:
Exploitování – tvorba shellkódu 1. část
Exploitování – tvorba shellkódu 3. část