首发于: https://www.0x557.cn/bbs/viewtopic.php?id=551
经过测试发现,好像只有WS_FTP 5.05以上的才支持XCRC/XSHA1/XMD5这些命令, 这个漏洞还是比较简单的,直接发送XCRC [long string] 就可以触发。 以iFtpSvc.exe 5.05为例:
.text:0041E5CF loc_41E5CF: ; CODE XREF: sub_41DB09+AB7j .text:0041E5CF push offset aXcrc ; "XCRC" .text:0041E5D4 mov ecx, [ebp+arg_0] .text:0041E5D7 push ecx ; char * .text:0041E5D8 call __strcmpi .text:0041E5DD add esp, 8 .text:0041E5E0 test eax, eax .text:0041E5E2 jnz short loc_41E628 .text:0041E5E4 mov edx, [ebp+arg_4] .text:0041E5E7 movsx eax, byte ptr [edx+4] .text:0041E5EB cmp eax, 20h ; 比较XCRC后面是否是空格 .text:0041E5EE jz short loc_41E5FB .text:0041E5F0 mov ecx, [ebp+arg_4] .text:0041E5F3 movsx edx, byte ptr [ecx+4] .text:0041E5F7 test edx, edx .text:0041E5F9 jnz short loc_41E628 .text:0041E5FB .text:0041E5FB loc_41E5FB: ; CODE XREF: sub_41DB09+AE5j .text:0041E5FB mov eax, [ebp+var_4] .text:0041E5FE mov ecx, [eax+1B4h] .text:0041E604 mov edx, [ebp+var_4] .text:0041E607 mov eax, [edx+1B4h] .text:0041E60D mov edx, [eax] .text:0041E60F call dword ptr [edx+14h] ; 00441960 .text:0041E612 and eax, 40h .text:0041E615 test eax, eax .text:0041E617 jnz short loc_41E628 .text:0041E619 push 1 .text:0041E61B mov ecx, [ebp+var_4] .text:0041E61E call sub_42EEE5 ;进入真正的处理流程
.text:0042EEE5 sub_42EEE5 proc near ; CODE XREF: sub_41DB09+B15p .text:0042EEE5 ; sub_41DB09+B6Ep ... .text:0042EEE5 .text:0042EEE5 var_34F4 = dword ptr -34F4h .text:0042EEE5 var_34F0 = dword ptr -34F0h .text:0042EEE5 var_24F0 = dword ptr -24F0h .text:0042EEE5 var_24EC = dword ptr -24ECh .text:0042EEE5 NumberOfBytesRead= dword ptr -24E8h .text:0042EEE5 hObject = dword ptr -24E4h .text:0042EEE5 var_24E0 = dword ptr -24E0h .text:0042EEE5 var_24DC = dword ptr -24DCh .text:0042EEE5 var_24D8 = dword ptr -24D8h .text:0042EEE5 var_24D4 = dword ptr -24D4h .text:0042EEE5 var_24D0 = dword ptr -24D0h .text:0042EEE5 var_24CC = dword ptr -24CCh .text:0042EEE5 lDistanceToMove = dword ptr -24C8h .text:0042EEE5 DistanceToMoveHigh= dword ptr -24C4h .text:0042EEE5 nNumberOfBytesToRead= dword ptr -24C0h .text:0042EEE5 Buffer = byte ptr -24BCh .text:0042EEE5 var_14BC = dword ptr -14BCh .text:0042EEE5 var_14B8 = dword ptr -14B8h .text:0042EEE5 String2 = byte ptr -14B4h .text:0042EEE5 var_14B0 = dword ptr -14B0h .text:0042EEE5 var_12B4 = dword ptr -12B4h .text:0042EEE5 var_12B0 = dword ptr -12B0h .text:0042EEE5 var_12AC = dword ptr -12ACh .text:0042EEE5 var_12A8 = dword ptr -12A8h .text:0042EEE5 var_12A4 = dword ptr -12A4h .text:0042EEE5 FileName = byte ptr -12A0h .text:0042EEE5 var_2A0 = byte ptr -2A0h .text:0042EEE5 var_A0 = dword ptr -0A0h .text:0042EEE5 var_9C = dword ptr -9Ch .text:0042EEE5 var_4 = dword ptr -4 .text:0042EEE5 arg_0 = dword ptr 8
.......略
.text:0042EFF5 loc_42EFF5: ; CODE XREF: sub_42EEE5+FFj .text:0042EFF5 mov eax, [ebp+var_A0] .text:0042EFFB push eax ; char * .text:0042EFFC call _strlen .text:0042F001 add esp, 4 .text:0042F004 mov [ebp+var_12B0], eax 如果发送的命令如下: XCRC[空格][参数] 这里eax指向[参数]内容, 并且调用strlen计算长度,并且把长度保存在一个局部变量中。
.text:0042F04C loc_42F04C: ; CODE XREF: sub_42EEE5+156j .text:0042F04C mov edx, [ebp+var_12B0] .text:0042F052 push edx ; size_t .text:0042F053 mov eax, [ebp+var_A0] .text:0042F059 push eax ; char * .text:0042F05A lea ecx, [ebp+var_2A0] .text:0042F060 push ecx ; char * .text:0042F061 call _strncpy
从局部变量中取刚才strlen计算的长度,并且作为第三个参数传递给strncpy函数。 [ebp+var_A0] 指向刚才的[参数]数据 [ebp+var_2A0] 栈上面的缓冲区 其实类似于 strncpy(dest, src, strlen(src))的操作。
安装Hotfix以后,多了如下检测:
.text:0042F04C loc_42F04C: ; CODE XREF: sub_42EEE5+156j .text:0042F04C cmp [ebp+var_12B0], 1FFh .text:0042F056 jbe short loc_42F062 .text:0042F058 mov [ebp+var_12B0], 1FFh
判断长度是否大于0x1ff, 否则就把拷贝长度设置为0x1ff。
|