- 1、本文档共18页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
windows平台下的格式化字符串漏洞利用技术
作者:A
本文真正的受益者应该是那些有定汇编语言基础,以及具备经典的栈溢出知识的人,这样本文才能引领读者在windows平台下编写出自己的格式化字符串漏洞利用程序。本文主要讲述各种关键的利用技术,也许在本文发布前已经有不少人写了关于格式化字符串漏洞的文章,但他们的文章一般都相对枯燥和基础。但我们也不敢说本文讲述得相当出色和全面,不过我们会尽量使其达到这种程度。
格式化字符串这类软件漏洞最初是在1999年左右发现的,但在2000年之前一直被认为是没有危害和利用价值的。格式化字符串攻击可使程序崩溃或者执行恶意代码。这个问题源于对用户输入内容未进行过滤导致的,这些输入数据都是作为某些C函数执行格式化操作时的参数,如printf()。恶意用户可以使用%s和%x等格式符,从堆栈或其它可能内存位置来输出数据。也可以使用格式符%n向任意地址写入任意数据, 配合printf()函数和其它类似功能的函数就可以向存储在栈上的地址写入被格式化的字节数。一个经典的exploit是混合这些技术,然后用恶意shellcode的地址来覆盖某一链接库函数地址或者栈上的返回地址。其中填充的一些格式化参数主要是用于控制输出的字节数,而%x主要用于从栈中弹出字节直至格式化字符串自身的起始位置。伪造的格式化字符串起始部分应该用欲执行的恶意代码地址来覆写,这个可以借助%n格式符来实现。因此你现在需要理解受此类漏洞影响的PERL 和C/C++软件,除printf()函数之外,其它函数也可能受到格式化字符串漏洞的影响,比如:
Printf()
Snprintf()
Vprintf()
Syslog()
……
格式化字符串漏洞除了可以执行恶意代码外,还可以从漏洞程序中读取某些数据,比如密码及其它重要信息。下面我们写份C代码进行分析,以帮助大家理解消化。
#include stdio.h
#include string.h
int main (int argc, char *argv[])
{
int x,y,z;
x= 10;
y= 20;
z = y -x;
print (“the result is : %d”,z); // %d using correct format so code is secure
}
#include stdio.h
#include string.h
void parser(char *string)
{
char buff[256];
memset(buff,0,sizeof(buff));
strncpy(buff,string,sizeof(buff)-1);
printf(buff); //here is format string vulnerability
}
int main (int argc, char *argv[])
{
parser(argv[1]);
return 0;
}
正如你在parser函数中看到的,程序员忘记使用%s来输出buf,以致攻击者可以使用它控制程序的执行流程,进而执行恶意shellcode。现在的问题是我们该如何来控制程序的执行流程?现在我们运行漏洞程序,然后在入口处注入一些格式化参数,运行后输入一些正常的参数,如图1所示:
图1
现在我们使用格式化参数,结果如图2所示:
图2
如上所示输出内容已被更改了,这个问题主要是printf()(格式化函数)未使用%s参数,以致%x被作为正常的格式化参数而直接读取了栈中的后4个值。不要忘记了,格式化函数中还有一个指向当前格式化参数的指针。因此我们可以利用它从指定的内存地址中读取数据,这个可以用字符串地址或者shellcode地址来替换。比如像图3中的情况:
图3
现在另一个问题是我们该如何向内存中写入数据?为了向特定的内存地址中写入数据,我们应该使用%n格式符来利用漏洞。下面我使用以下格式化参数来执行程序,如图4所示:
图4
如上所示,我们可以读取内存及其它一些可用信息。为了定位字符串的起始地址,我们可以使用5个%x和%n来实现,如图5所示:
图5
程序崩溃了……
我们调试一下此次崩溃,这里我用Immunity D
文档评论(0)