Starting
環境:<span>Windows</span> <span>XP</span><br><span>VC</span>++ 6<span>.0</span><br>
此方法只適用於測試或學習,無法動態執行shellcode。也就是說shellcode只能在XP上使用,因為從win7開始有了aslr
ASLR說明:https://blog.morphisec.com/aslr-what-it-is-and-what-it-isnt/
彈框測試:
<span>#<span>include</span><span><windows.h></span></span><br><span><span>int</span> <span>main</span><span>(<span>int</span> argc,<span>char</span>** argv)</span></span>{<br> MessageBox(<span >NULL</span>,<span>"You are hacked by Migraine!"</span>,<span>"Pwned"</span>,MB_OK);<br>}<br>
Alt+8調出反組譯模式可以觀察是如何實作呼叫win API的
透過參閱文章發現不能直接提取機器碼,必須用彙編在寫一遍。然後在提取字節碼
透過參考文章明白彙編執行shellcode是如何執行的
<span>//轉自安全客文章</span><br><span>#<span>include</span><span><windows.h></ span></span><br><span><span>void</span> <span>main</span><span>()</span><br></span>{<br> LoadLibrary(<span>"user32.dll"</span>);<span>//Load DLL</span><br> __asm<br> { <br> push <span>0x00656e</span>;ne< br> push <span>0x69617267</span>;grai<br> push <span>0x694d2079</span>;y Mi<br> push <span>0x62206565</span>;ed b<br> push <span>0x6b636168</span>;hack<br> push <span>0x20657261</ span>;Are<br> push <span>0x20756F59</span>;You<br> mov ebx,esp<br> push <span>0x0</span><br> push <span>0x656e6961</span>;aine<br> push <span> 0x7267694d</span>;Migr<br> mov ecx,esp<br><br><br> <span>//int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,UINT uType );</span><br> xor eax,eax<br> push eax<span>//uTyoe->0</span ><br> push ecx<span>//lpCaption->Migraine</span><br> push ebx<span>//lpText->You are hacked by Migraine</span><br> push eax<span>//hWnd->0</span><br> mov esi,<span>0x77D3ADD7</ span><span>//User32.dll->MessageBoxA</span><br> call esi<br><br><br> }<br>}<br>
- 將需要用到的字串轉成十六進制,由於是X86,一次可最多存放8個位元組
- 將字串轉換的十六進位入堆疊
- push 0x0後然後重複將所需的東西入棧,在次保存到另一個寄存器
- 然後從右到左設定win API的值(注意:從右到左)
- 最後將windows API的位址給esi
- call 將目前執行指令位址入堆疊,然後無條件轉移到由標籤指示的指令
透過OD給對應的API下斷點,可以取得位址
(註:每個系統的位址都有差異)
Examlpe:
然後使用C內嵌asm,調試提取機器碼
整個asm範圍的機器碼提取出來:
<span>"\x68\x6E\x65\x00\x00\x68\x67\x72\x61\x69\x68\x79\x20\x4D\x69\x68\x65\x65\x20\x62"</span>< br> <span>"\x68\x68\x61\x63\x6B\x68\x61\x72\x65\x20\x68\x61\x62\x63\x00\x8B\xDC\x6A\x00\x68\x63\x00\x8B\xDC\x6A\x00\x68"</span>< br> <span>"\x61\x69\x6E\x65\x68\x4D\x69\x67\x72\x8B\xCC\x33\xC0\x50\x68\x61\x69\x6E\x65\x68"</span>< br> <span>"\x4D\x69\x67\x72\x8B\xCC\x33\xC0\x50\x51\x53\x50\xBE\xEA\x07\xD5\x77\xFF\xD6"</span><br>
執行即可:
用WinExec彈個calc
<span>//WinExec address-7C86250D</span><br><span>//ExitProcess address-7C81CB12</span><br><span>#<span>include</span><span><windows.h></span></span><br><span><span>int< /span> <span>main</span><span>()</span><br></span>{<br> LoadLibrary(<span>"kernel32.dll"</span>);<br> __asm<br> {<br> push <span>0x636C6163</span>;calc<br> mov eax,esp<br> push < span>0x0</span><br> push <span>0x5</span><br> mov ebx,esp<br><br><br> push ebx<br> push eax<br> mov esi,<span>0x7C86250D</span><br> call esi<br> xor ecx,ecx<br> mov esi ,<span>0x7C81CB12</span><br> call esi<br> }<br> <span>return</span> <span>0</span>;<br>}<br>
shellcode為
<span>"\x68\x63\x61\x6C\x63\x8B\xC4\x6A\x05\x8B\xDC\x53\x50\xBE\x0D\x25\ x86\x7C"</span><br><span>"\xFF\xD6\x33\xC9\xBE\x12\xCB\x81\x7C\xFF\xD6"</span><br>
注意:如果你不知道calc變成十六進位怎麼整,彙編整一個就好