这是一个很好的问题,你很幸运——radare2 提供了几种方法来实现这一点。让我们来看看更基本和更直接的选项。
配置
首先,确保运行最新的radare2。在撰写本文时,这是 v4.3.1。radare 社区建议从源代码构建radare2。在 Linux 系统上,就像克隆存储库并执行以下命令一样简单:
$ cd radare2
$ ./sys/install.sh
注意:通过从包存储库安装radare2,您可能会因为旧版本而错过关键功能。
现在这部分已经过去了,我们可以继续寻找解决方案。
准备测试程序
对于以下示例,我编写了两个程序来演示我从一个程序动态传递到另一个程序的数据如何反映在其输出中。
中继器是一个接收用户输入并将其打印到控制台的程序。
资料来源: repeater.c
#include <stdio.h>
int main() {
char user_input[100];
fgets (user_input, 100, stdin);
printf ("[+] Received from STDIN: %s\n", user_input);
return 0;
}
exp是一个将字符串打印到控制台的程序。
资料来源: exp.c
#include <stdio.h>
int main() {
// print string, hex values, and the current UNIX time
printf ("Hello, \x41\x42\xaf\xd7, %u", (unsigned)time(NULL));
return 0;
}
为了演示所需的行为,我们可以像这样使用这些程序:
$ ./exp | ./repeater
[+] Received from STDIN: Hello, AB��, 1583565405
$ ./exp | ./repeater
[+] Received from STDIN: Hello, AB��, 1583565418
方法0:rarun2配置文件
在radare2 中,当它与调试对象交互时,rarun2 是您的首选工具。
该程序用作运行具有不同环境、参数、权限、目录和覆盖的默认文件描述符的程序的启动器。
来源: man rarun2
虽然非常复杂且功能丰富,但我们将重点关注其中一项基本功能,即与 STDIO 交互。
从您的问题来看,您显然熟悉 rarun2 配置文件的概念。当我使用 rarun2 将漏洞利用的输出传递给调试对象时,我使用的配置文件看起来有点像这样:
$ cat profile.rr2
#!/usr/bin/rarun2
stdin=!./exp
这个 rarun2 配置文件将执行./exp
程序并将程序的输出设置为调试对象的标准输入。
然后,我们就可以在不离开radare2 shell的情况下,一次又一次地快速执行radare2中的程序。
首先,创建一个 rarun 配置文件,如上所示。然后,在radare2 中打开调试对象并使用以下-r
标志加载此配置文件:
在调试模式下加载程序并用于dc
执行它:
$ r2 -r profile.rr2 -d repeater
Process with PID 86588 started...
= attach 86588 86588
[0x7f89ba9b8100]> dc
[+] Received from STDIN: Hello, AB��, 1583567900
如您所见,您进入了调试模式,并且程序成功执行并输出了exp
程序。您可以通过使用doo (as well as
ood`)继续执行该程序,该程序将“使用 args 在调试模式下重新打开”。
[0x7f316b76c100]> doo
Process with PID 86657 started...
= attach 86657 86657
[0x7f2aecada100]> dc
[+] Received from STDIN: Hello, AB��, 1583568042
[0x7f2aec99ace6]> doo
Process with PID 86660 started...
= attach 86660 86660
[0x7ff100166100]> dc
[+] Received from STDIN: Hello, AB��, 1583568056
[0x7f0efc9e4ce6]> doo
Process with PID 86673 started...
= attach 86673 86673
[0x7f676d6b2100]> # Define Breakpoint at main
[0x7f676d6b2100]> db main
[0x7f676d6b2100]> dc
hit breakpoint at: 5652649de159
[0x5652649de159]> dc
[+] Received from STDIN: Hello, AB��, 1583568059
方法一:rarun2规则
幸运的是,您可以跳过 rarun2 文件的创建,只需告诉radare2 应该从哪里获取标准输入。这可以通过使用-R
后跟 rarun 键和值的标志轻松完成。
$ r2 -R stdin=\!./exp -d repeater
Process with PID 87508 started...
= attach 87508 87508
[0x7f87588c0100]> dc
[+] Received from STDIN: Hello, AB��, 1583568818
这是一次性拍摄,doo
在radare2 会话中再次使用将不会再次使用相同的标准输入。但是,您可以利用该dor
命令并做一些技巧;)
[0x7f8758780ce6]> dor?
| dor [rarun2] Comma separated list of k=v rarun2 profile options (e dbg.profile)
[0x7f8758780ce6]> dor stdin=!./exp
[0x7f8758780ce6]> doo
Process with PID 87594 started...
= attach 87594 87594
[0x7f8758780ce6]> dc
[+] Received from STDIN: Hello, AB��, 1583568991
[0x7fdb45f3ece6]> # And this of course can be done with a single line
[0x7fdb45f3ece6]> dor stdin=!./exp; doo; dc
Process with PID 87627 started...
= attach 87627 87627
[+] Received from STDIN: Hello, AB��, 1583569028
方法∞
还有其他方法可以执行此类设置。由于时间太长,我会很快把它们记下来。这里有一些想法:
使用反引号:r2 -R "stdin=\"`python -c print(1234)`\"" -d repeater
甚至r2 -R "stdin=\"`python -c 'print(1234)'`\"" -d repeater
使用其他终端的 tty 重定向 STDIN。您可以通过执行./exp > dev/pts/X
其中 x 是 tty 编号来简单地将数据传递给tty。
使用popen
于写入的过程中,或将输出重定向到的/ proc // FD / 0
使用外部 shell 脚本自动执行您遇到的繁琐任务