-
-
[原创]格式化字符串漏洞入门
-
发表于:
2017-4-14 22:01
12166
-
寒假在家的时候总结了一下格式化字符串漏洞,主要是在http://blogs.microsoft.co.il/applisec/2006/12/04/buffer-overflow-overrun-examples/上看到了利用格式化字符串漏洞改变程序执行流程的一个非常棒的例子,加上读了《C和C++安全编码》,所以就写一篇这个玩意的入门知识。
试验工具:ollydbg、VC++6.0
实验环境:windows2000虚拟机
1.%x查看栈内容
执行printf时第四个%x没有提供对应的参数,因此会显示本应该是参数所在位置的栈内容。通过更多的%x甚至可以重建大部分的栈内存。
2.%s查看指定地址内容
执行printf。
1,2,3是提供3个参数。利用%x步进,将%s的参数对应到77E61044,因此可以输出77E61044开始的字符串直到遇到截断符。0x0012FF58为format字符串起始地址,前四个字节即我们想要查看的内存地址77E61044。
3.缓冲区溢出
作为向字符数组中写入数据的格式化输出函数,sprintf会假定存在任意长度的缓冲区。此处将字符数组user作为由用户构造的输入,其中出现了非常规字符%497d,是此次实验成功的关键。\x39\x4a\x42\x00是shellcode的起始地址,用来覆盖返回地址。\x90…\x33…\xD0…\x90为此次的弹框的shellcode。
第一次调用sprintf(buffer,"ERR Wrong command:%.400s",user);时写入数据的目的地址为0x0012FB2C,格式化字符串为"ERR Wrong command:%.400s",%.400s对应的参数为起始地址为0x00424A30的字符串,即用户输入的字符数组user。对地址0x00424A30数据窗口跟随后可以看见该字符数组的内容。
对地址0x0012FB2C查看ASCII数据,可见此时buffer中的字符串为"ERR Wrong command:%497d\x39\x4a\x42\x00",其后的数据由于0x00而被截断。
执行sprintf(outbuf, buffer);时buffer中格式化字符串为"ERR Wrong command:%497d\x39\x4a\x42\x00",根据格式化字符串,sprintf会读取一个参数以%497d的格式写入outbuf,由于未提供该参数,会自动将栈地址0x0012FAE0中的值视为该参数,即0x12FF80(十进制1245056)。需要写入outbuf的总字符串长度为19+497=516,而outbuf长度为512,因此会导致栈溢出,使得函数返回执行sprintf后outbuf中的内容。
outbuf起始地址为0x0012FD2C,19字节的字符串"ERR Wrong command:"后为497字节的整型数字1245056,因此从0x0012FF30开始为\x39\x4a\x42\x00。下图可见成功将返回地址覆写为shellcode起始地址0x00424A39。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-2-27 10:27
被houjingyi编辑
,原因: 重新上传图片