在断点处而不是最初在 GDB 中发送管道输入
Send piped input in GDB at breakpoint rather than initially
我研究过这个问题,我能找到的最接近的答案是这个。
gdb - debugging with piped input (not arguments)
我需要完全按照此人的要求进行操作,但是,我需要能够在已经查看我的程序的一部分后发送输入 运行。
这是我在 GDB 中查看的代码
#define SECRET1 0x44
#define SECRET2 0x55
int main(int argc, char *argv[])
{
char user_input[100];
int *secret;
int int_input;
int a, b, c, d; /* other variables, not used here.*/
/* The secret value is stored on the heap */
secret = (int *) malloc(2*sizeof(int));
/* getting the secret */
secret[0] = SECRET1; secret[1] = SECRET2;
printf("The variable secret’s address is 0x%8x (on stack)\n", &secret);
printf("The variable secret’s value is 0x%8x (on heap)\n", secret);
printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]);
printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]);
printf("Please enter a decimal integer\n");
scanf("%d", &int_input); /* getting an input from user */
printf("Please enter a string\n");
scanf("%s", user_input); /* getting a string from user */
/* Vulnerable place */
printf(user_input);
printf("\n");
/* Verify whether your attack is successful */
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
printf("The new secrets: 0x%x -- 0x%x\n", secret[0], secret[1]);
return 0;
}
我正试图对我的虚拟机执行格式化字符串攻击。为此,我需要知道存储机密的地址。该程序通过这些行的输出告诉我这一点
printf("The variable secret’s address is 0x%8x (on stack)\n", &secret);
printf("The variable secret’s value is 0x%8x (on heap)\n", secret);
printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]);
printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]);
攻击的性质要求我发送非 ASCII 十六进制值作为第二次 scanf 的输入,所以我不能简单地自己键入输入。我在这里使用 perl 完成了输入设置,
ramtest@ramtest-VirtualBox:/tmp$ perl -e 'print "5\x0a"; print "\x08\xb0\x04\x08%x.%x.%x.%x.%x.%x.%x";' > /tmp/input
然后我运行
$gdb ./vul_prog < /tmp/input
我已经找到了在内存随机化关闭的环境中工作的方法,因为我可以 运行 程序一次,查看内存地址,然后更改 perl 脚本,然后简单地 运行 再来一次。但是,随着内存随机化,我无法知道地址在我 运行 之前的位置,所以我需要能够看到程序中告诉我地址 运行 之前的部分我创建并发送我的输入。
我尝试以此处看起来最直观的方式进行操作,但我只是遇到语法错误。
Starting program: /home/ramtest/Downloads/vulprog
The variable secret’s address is 0xbfffefd8 (on stack)
The variable secret’s value is 0x 804b008 (on heap)
secret[0]’s address is 0x 804b008 (on heap)
secret[1]’s address is 0x 804b00c (on heap)
Please enter a decimal integer
1
Please enter a string
Breakpoint 2, 0x0804858f in main ()
(gdb) c > /tmp/input
A syntax error in expression, near `> /tmp/input'.
(gdb) c < /tmp/input
A syntax error in expression, near `< /tmp/input'.
是否可以在提示我输入之前在 GDB 中设置一个断点,然后以某种方式将 /tmp/input 信息作为输入发送?
如果是这样,我该怎么做?
如有任何帮助,我们将不胜感激。
只需使用run
命令。我将通过将 /bin/cat
馈送到 gdb 并中断其 main()
并重定向标准输入来进行演示:
示例:
$ gdb /bin/cat
GNU gdb (GDB) Fedora 7.12.1-47.fc25
[ ... ]
(gdb) b main
Breakpoint 1 at 0x1bc0
(gdb) run </etc/issue
Starting program: /usr/bin/cat </etc/issue
Breakpoint 1, 0x0000555555555bc0 in main ()
(gdb) c
Continuing.
\S
Kernel \r on an \m (\l)
[Inferior 1 (process 18190) exited normally]
(gdb)
您应该能够在 gdb
下启动您的程序,在 scanf 之前设置一个断点,然后 run
它使用从空文件重定向的标准输入。我不希望您的程序在那之前尝试从其标准输入中读取,因此它不会在其重定向的标准输入上看到文件结束条件。
当断点命中时你应该有你的内存地址,然后准备你的有效载荷并将它简单地附加到零长度文件,然后
c
执行,然后应该继续并尝试读取现在在其标准输入上可用的有效负载。
这种技术甚至不需要调试器的变体是使用一个命名管道,该管道预先打开用于写入,然后 运行 这个程序的标准输入从命名管道重定向管道。预期的结果是程序打印内存地址,然后在从管道读取时阻塞。此时您可以准备您的有效载荷,并将其写入管道。
我研究过这个问题,我能找到的最接近的答案是这个。 gdb - debugging with piped input (not arguments)
我需要完全按照此人的要求进行操作,但是,我需要能够在已经查看我的程序的一部分后发送输入 运行。
这是我在 GDB 中查看的代码
#define SECRET1 0x44
#define SECRET2 0x55
int main(int argc, char *argv[])
{
char user_input[100];
int *secret;
int int_input;
int a, b, c, d; /* other variables, not used here.*/
/* The secret value is stored on the heap */
secret = (int *) malloc(2*sizeof(int));
/* getting the secret */
secret[0] = SECRET1; secret[1] = SECRET2;
printf("The variable secret’s address is 0x%8x (on stack)\n", &secret);
printf("The variable secret’s value is 0x%8x (on heap)\n", secret);
printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]);
printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]);
printf("Please enter a decimal integer\n");
scanf("%d", &int_input); /* getting an input from user */
printf("Please enter a string\n");
scanf("%s", user_input); /* getting a string from user */
/* Vulnerable place */
printf(user_input);
printf("\n");
/* Verify whether your attack is successful */
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
printf("The new secrets: 0x%x -- 0x%x\n", secret[0], secret[1]);
return 0;
}
我正试图对我的虚拟机执行格式化字符串攻击。为此,我需要知道存储机密的地址。该程序通过这些行的输出告诉我这一点
printf("The variable secret’s address is 0x%8x (on stack)\n", &secret);
printf("The variable secret’s value is 0x%8x (on heap)\n", secret);
printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]);
printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]);
攻击的性质要求我发送非 ASCII 十六进制值作为第二次 scanf 的输入,所以我不能简单地自己键入输入。我在这里使用 perl 完成了输入设置,
ramtest@ramtest-VirtualBox:/tmp$ perl -e 'print "5\x0a"; print "\x08\xb0\x04\x08%x.%x.%x.%x.%x.%x.%x";' > /tmp/input
然后我运行
$gdb ./vul_prog < /tmp/input
我已经找到了在内存随机化关闭的环境中工作的方法,因为我可以 运行 程序一次,查看内存地址,然后更改 perl 脚本,然后简单地 运行 再来一次。但是,随着内存随机化,我无法知道地址在我 运行 之前的位置,所以我需要能够看到程序中告诉我地址 运行 之前的部分我创建并发送我的输入。
我尝试以此处看起来最直观的方式进行操作,但我只是遇到语法错误。
Starting program: /home/ramtest/Downloads/vulprog
The variable secret’s address is 0xbfffefd8 (on stack)
The variable secret’s value is 0x 804b008 (on heap)
secret[0]’s address is 0x 804b008 (on heap)
secret[1]’s address is 0x 804b00c (on heap)
Please enter a decimal integer
1
Please enter a string
Breakpoint 2, 0x0804858f in main ()
(gdb) c > /tmp/input
A syntax error in expression, near `> /tmp/input'.
(gdb) c < /tmp/input
A syntax error in expression, near `< /tmp/input'.
是否可以在提示我输入之前在 GDB 中设置一个断点,然后以某种方式将 /tmp/input 信息作为输入发送?
如果是这样,我该怎么做?
如有任何帮助,我们将不胜感激。
只需使用run
命令。我将通过将 /bin/cat
馈送到 gdb 并中断其 main()
并重定向标准输入来进行演示:
示例:
$ gdb /bin/cat
GNU gdb (GDB) Fedora 7.12.1-47.fc25
[ ... ]
(gdb) b main
Breakpoint 1 at 0x1bc0
(gdb) run </etc/issue
Starting program: /usr/bin/cat </etc/issue
Breakpoint 1, 0x0000555555555bc0 in main ()
(gdb) c
Continuing.
\S
Kernel \r on an \m (\l)
[Inferior 1 (process 18190) exited normally]
(gdb)
您应该能够在 gdb
下启动您的程序,在 scanf 之前设置一个断点,然后 run
它使用从空文件重定向的标准输入。我不希望您的程序在那之前尝试从其标准输入中读取,因此它不会在其重定向的标准输入上看到文件结束条件。
当断点命中时你应该有你的内存地址,然后准备你的有效载荷并将它简单地附加到零长度文件,然后
c
执行,然后应该继续并尝试读取现在在其标准输入上可用的有效负载。
这种技术甚至不需要调试器的变体是使用一个命名管道,该管道预先打开用于写入,然后 运行 这个程序的标准输入从命名管道重定向管道。预期的结果是程序打印内存地址,然后在从管道读取时阻塞。此时您可以准备您的有效载荷,并将其写入管道。