执行缓冲区溢出攻击时EIP不会被覆盖

问题描述 投票:0回答:1

我在 youtube 上观看此视频:https://www.youtube.com/watch?v=1S0aBV-Waeo 我试图执行视频中显示的相同步骤,但我似乎无法覆盖生态工业园区。我不知道是否是因为这些年来 gdb 发生了变化,或者是否还有其他原因。当我尝试溢出时得到的结果如下

Program received signal SIGSEGV, Segmentation fault.
0x080491ac in main (
    argc=<error reading variable: Cannot access memory at address 0x41414141>, 
    argv=<error reading variable: Cannot access memory at address 0x41414145>)
    at example.c:9
9   }

无论我的输入有多大,我似乎都无法覆盖 eip。代码与视频中所示相同,但缓冲区大小较小。

#include <stdio.h>
#include <string.h>

int main(int argc, char** argv){
    char buffer[10];
    strcpy(buffer, argv[1]);

    return 0;
}

第一次在 gdb 中运行我的程序时,我也会被问到以下问题

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.archlinux.org>
Enable debuginfod for this session? (y or [n]) 

这是gdb中的寄存器信息

(gdb) info reg
eax            0x0                 0
ecx            0xffffd6b2          -10574
edx            0xffffd396          -11370
ebx            0x804bff4           134529012
esp            0xffffd390          0xffffd390
ebp            0xffffd3a8          0xffffd3a8
esi            0xffffd480          -11136
edi            0xf7ffcb60          -134231200
eip            0x80491a3           0x80491a3 <main+61>
eflags         0x286               [ PF SF IF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb) x/20x $esp
0xffffd390: 0xffffffff  0x4141d3d4  0x41414141  0x41414141
0xffffd3a0: 0xffff0041  0xf7e1fe2c  0x00000000  0xf7c20af9
0xffffd3b0: 0x00000000  0x00000000  0x080482e7  0xf7c20af9
0xffffd3c0: 0x00000002  0xffffd474  0xffffd480  0xffffd3e0
0xffffd3d0: 0xf7e1fe2c  0x0804907d  0x00000002  0xffffd474

我正在使用以下标志进行编译

gcc -o example2 -fno-stack-protector -no-pie -m32 -g -z execstack example2.c -w

gdb上的整个交互

(gdb) disassemble main
Dump of assembler code for function main:
   0x080497d5 <+0>: lea    0x4(%esp),%ecx
   0x080497d9 <+4>: and    $0xfffffff0,%esp
   0x080497dc <+7>: push   -0x4(%ecx)
   0x080497df <+10>:    push   %ebp
   0x080497e0 <+11>:    mov    %esp,%ebp
   0x080497e2 <+13>:    push   %ebx
   0x080497e3 <+14>:    push   %ecx
   0x080497e4 <+15>:    sub    $0x10,%esp
   0x080497e7 <+18>:    call   0x804981c <__x86.get_pc_thunk.ax>
   0x080497ec <+23>:    add    $0x9a808,%eax
   0x080497f1 <+28>:    mov    %ecx,%edx
   0x080497f3 <+30>:    mov    0x4(%edx),%edx
   0x080497f6 <+33>:    add    $0x4,%edx
   0x080497f9 <+36>:    mov    (%edx),%edx
   0x080497fb <+38>:    sub    $0x8,%esp
   0x080497fe <+41>:    push   %edx
   0x080497ff <+42>:    lea    -0x12(%ebp),%edx
   0x08049802 <+45>:    push   %edx
   0x08049803 <+46>:    mov    %eax,%ebx
   0x08049805 <+48>:    call   0x8049020
   0x0804980a <+53>:    add    $0x10,%esp
   0x0804980d <+56>:    mov    $0x0,%eax
--Type <RET> for more, q to quit, c to continue without paging--
   0x08049812 <+61>:    lea    -0x8(%ebp),%esp
   0x08049815 <+64>:    pop    %ecx
   0x08049816 <+65>:    pop    %ebx
   0x08049817 <+66>:    pop    %ebp
   0x08049818 <+67>:    lea    -0x4(%ecx),%esp
   0x0804981b <+70>:    ret
End of assembler dump.
(gdb) break *0x08049805
Breakpoint 1 at 0x8049805: file example.c, line 6.
(gdb) break *0x08049812
Breakpoint 2 at 0x8049812: file example.c, line 9.
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAA
Starting program: /home/r3/buffer-overflows/bo in memory example/example AAAAAAAAAAAAAAAAAAAAAAAAA

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.archlinux.org>
Enable debuginfod for this session? (y or [n]) 
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.

Breakpoint 1, 0x08049805 in main (argc=2, argv=0xffffd464) at example.c:6
6       strcpy(buffer, argv[1]);
(gdb) info reg
eax            0x80e3ff4           135151604
ecx            0xffffd330          -11472
edx            0xffffd306          -11514
ebx            0x80e3ff4           135151604
esp            0xffffd2f0          0xffffd2f0
ebp            0xffffd318          0xffffd318
esi            0x80e3ff4           135151604
edi            0x1                 1
eip            0x8049805           0x8049805 <main+48>
eflags         0x292               [ AF SF IF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb) x/20x $esp
0xffffd2f0: 0xffffd306  0xffffd6a4  0x00000000  0x080497ec
0xffffd300: 0x080ade17  0x080e7c04  0x08049030  0x080ae037
0xffffd310: 0xffffd330  0x080e3ff4  0xffffd428  0x08049ceb
0xffffd320: 0x00000021  0xffffd338  0x00067e1c  0x08049ceb
0xffffd330: 0x00000002  0xffffd464  0xffffd470  0xffffd354
(gdb) c
Continuing.

Breakpoint 2, main (
    argc=<error reading variable: Cannot access memory at address 0x41414141>, 
    argv=<error reading variable: Cannot access memory at address 0x41414145>)
    at example.c:9
9   }
(gdb) info reg
eax            0x0                 0
ecx            0xffffd6b0          -10576
edx            0xffffd312          -11502
ebx            0x80e3ff4           135151604
esp            0xffffd300          0xffffd300
ebp            0xffffd318          0xffffd318
esi            0x80e3ff4           135151604
edi            0x1                 1
eip            0x8049812           0x8049812 <main+61>
eflags         0x286               [ PF SF IF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb) x/20x $esp
0xffffd300: 0x080ade17  0x41417c04  0x41414141  0x41414141
0xffffd310: 0x41414141  0x41414141  0x41414141  0x00414141
0xffffd320: 0x00000021  0xffffd338  0x00067e1c  0x08049ceb
0xffffd330: 0x00000002  0xffffd464  0xffffd470  0xffffd354
0xffffd340: 0x080e3ff4  0x0804968d  0x00000002  0xffffd464
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x0804981b in main (
    argc=<error reading variable: Cannot access memory at address 0x41414141>, 
    argv=<error reading variable: Cannot access memory at address 0x41414145>)
    at example.c:9
9   }
(gdb) info reg
eax            0x0                 0
ecx            0x41414141          1094795585
edx            0xffffd312          -11502
ebx            0x41414141          1094795585
esp            0x4141413d          0x4141413d
ebp            0x41414141          0x41414141
esi            0x80e3ff4           135151604
edi            0x1                 1
eip            0x804981b           0x804981b <main+70>
eflags         0x10286             [ PF SF IF RF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb) x/20x $esp
0x4141413d: Cannot access memory at address 0x4141413d
(gdb) c
Continuing.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
gdb buffer-overflow machine-code eip
1个回答
0
投票

这段代码

   0x08049815 <+64>:    pop    %ecx
   0x08049816 <+65>:    pop    %ebx
   0x08049817 <+66>:    pop    %ebp
   0x08049818 <+67>:    lea    -0x4(%ecx),%esp
   0x0804981b <+70>:    ret

从堆栈上保存的位置恢复寄存器。但是,您已经覆盖了堆栈内容,因此所有寄存器现在都设置为

0x4141...
值。并且 that 导致
lea    -0x4(%ecx),%esp
指令指向
SIGSEGV
,因为
ECX
指向无法访问的内存。

正如 ssbssa 评论的那样,这是由于堆栈重新对齐而发生的(堆栈重新对齐本身需要处理 64 位对齐(较新的)AVX 等)。

如果我使用

-mpreferred-stack-boundary=2
关闭堆栈重新对齐,代码将变为:

   0x08049176 <+0>:     push   %ebp
   0x08049177 <+1>:     mov    %esp,%ebp
   0x08049179 <+3>:     sub    $0xc,%esp
   0x0804917c <+6>:     mov    0xc(%ebp),%eax
   0x0804917f <+9>:     add    $0x4,%eax
   0x08049182 <+12>:    mov    (%eax),%eax
   0x08049184 <+14>:    push   %eax
   0x08049185 <+15>:    lea    -0xa(%ebp),%eax
   0x08049188 <+18>:    push   %eax
   0x08049189 <+19>:    call   0x8049050 <strcpy@plt>
   0x0804918e <+24>:    add    $0x8,%esp
   0x08049191 <+27>:    mov    $0x0,%eax
   0x08049196 <+32>:    leave
   0x08049197 <+33>:    ret

RIP
覆盖作品:

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) x/i $pc
=> 0x41414141:  Cannot access memory at address 0x41414141
© www.soinside.com 2019 - 2024. All rights reserved.