【问题标题】:How to send arbitary bytes to STDIN of a program in gdb?如何将任意字节发送到 gdb 中程序的 STDIN?
【发布时间】:2017-06-08 10:44:24
【问题描述】:

我正在为学生开发缓冲区溢出练习。在这种情况下,您通常必须提供任意字节作为程序的输入(返回地址)。

假设这个例子:

#import <stdio.h>
#import <string.h>

void func() {
    char buf[4];
    gets(buf);
}

int main (int argc, char** argv) {
    func();

    return 0;
}

通常我会使用 gdb 进行试验,直到找到解决方案,然后可以将其表述为

python -c 'print "A"*8+"\x08\x04\88\72"' | ./program

在开发越来越复杂的练习时,找到解决方案的难度会增加。有时通过

覆盖gdb中的返回地址
 set {int}address_of_address = new_address

有效,但 python-approach 无效。最好能在程序运行时在 gdb 中进行调试,并能够在 gdb 中输入像“\x04”这样的字节,分析效果。

有什么办法吗?

这个问题似乎相关,但用 python 方法回答:Sending arbitrary bytes to fgets from stdin

我的不止于此:-/

【问题讨论】:

  • 仅供参考,你不需要 Python,你可以使用bash:echo $'AAAAAAAA\x08\x04\88\72' | ./program
  • 这对你有用吗stackoverflow.com/q/8422259/72178
  • 是的。这很有帮助!但是有没有办法在程序已经运行时输入任意字节?
  • 是的,你可以在运行程序的同时运行它,它会停止等待输入。然后你从另一个控制台附加到它。那就是你从 2 个不同的控制台调试和输入字节。

标签: c encoding gdb reverse-engineering buffer-overflow


【解决方案1】:

调试这个并能够输入字节会很好 gdb中的“\x04”,程序运行时,分析效果

为此,您需要 2 个控制台:第一个用于在程序标准输入中输入字节,第二个用于 gdb 调试会话。

您可以先在第一个控制台中运行程序,直到它停止等待来自标准输入的字节。然后在第二个控制台中运行 gdb 并通过它的 pid 附加到一个程序。您将能够从 2 个不同的控制台同时调试和输入字节。

【讨论】:

    【解决方案2】:

    “程序运行时”是问题的一部分。另一个是能够预先设置断点,以“分析效果”。

    GDB 的默认行为是将程序作为子进程运行,因此使用相同的标准流。因此,在 GDB 的 CLI 中无法写入孩子的标准输入,因为此时它正在由 GDB 读取,而不是您的程序。

    避免 tty 变通方法(tty 命令 + stty 设置 + 读取/写入 /proc/&lt;pid&gt;/fd/{0,1})的最简单解决方案是使您的代码可测试并从 GDB 中“可调用”。然后,您就可以将字符串参数传递给您的函数,以便对其进行测试和调试。

    例如:

    #include <stdio.h>
    #include <unistd.h>
    
    void exploitme(char* str)
    {
      printf(str);
    }
    
    int main()
    {
      while (1)
      {
        char str[10];
        fgets(str, sizeof (str), stdin);
        exploitme(str);
      }
    
      return 0;
    }
    

    exploitme() 是正确包装在单个入口点中的漏洞利用案例,因此现在可以在它使用的所有内容正确初始化后调用它。然后,您可以在到达main() 断点后使用命令call 调用它(这样在main 的调用者中执行的C 运行时初始化就完成了)。

    ~/test $ gdb ./a.out                                                                                       
    (gdb) call exploitme("hello")
    You can't do that without a process to debug.
    (gdb) b main
    Breakpoint 1 at 0x4005ae: file helloworld.c, line 14.
    (gdb) r
    Starting program: /home/julio/test/a.out 
    
    Breakpoint 1, main () at helloworld.c:14
    14          fgets(str, sizeof (str), stdin);
    (gdb) call exploitme("hello")
    (gdb) call exploitme("hello\n")
    hellohello
    (gdb) call exploitme("AAAAAAAA\x08\x04\88\72\n")
    AAAAAAA�:
    (gdb) b exploitme 
    Breakpoint 2 at 0x400592: file helloworld.c, line 6.
    (gdb) call exploitme("foo")
    Breakpoint 2, exploitme (str=0x602010 "foo") at helloworld.c:6
    6         printf(str);
    The program being debugged stopped while in a function called from GDB.
    Evaluation of the expression containing the function
    (exploitme) will be abandoned.
    When the function is done executing, GDB will silently stop.
    

    请注意,您将从 GDB 的参数扩展中受益,其中包括 C 字符串求值。

    另一个(更长和更复杂的)解决方案,如前所述,是在另一个 tty 下运行您的程序,这样您就可以独立地写入 GDB 和您的程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-25
      • 1970-01-01
      • 2017-10-02
      • 2014-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      相关资源
      最近更新 更多