C 中 0x00001292 导致堆栈帧溢出

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

我正在关注一本有关黑客攻击的书,目前正在研究缓冲区溢出。我的

silly_password.c
程序采用命令行参数,该参数溢出到函数的返回地址中。我已经能够用任意值填充返回地址。例如,
./silly_password.c AAAAAAAAAAAAAAAAAAAAAAA
0x41414141
填充返回地址,因为
0x41
是字母 A 的 ASCII 编码。

我想用

0x00001292
填充返回地址,因为这是我想要恶意执行的程序中特定指令的地址。调用
gdb -q --args silly_password $(perl -e 'print "\x92\x12" x 20;')
有效地用
0x12921292
填充堆栈中的寄存器,这接近我想要的值
0x00001292

─── Variables ───────────────────────────────────────────────────────────────────────────────
arg password = 0x7fffffffe0b7 "\222\022\222\022\222\022\222\022\222\022\222\022\222\022\222\022\222\022\222\022\222…
loc password_buffer = "\222\022\222\022\222\022\222\022\222\022\222\022\222\022\222\022", auth_flag = 0
─────────────────────────────────────────────────────────────────────────────────────────────
>>> x/32xw $sp
0x7fffffffdb60: 0x00000000  0x00000000  0xffffe0b7  0x00007fff
0x7fffffffdb70: 0x00000000  0x00000000  0x00000000  0x00000000
0x7fffffffdb80: 0x12921292  0x12921292  0x12921292  0x12921292
0x7fffffffdb90: 0x12921292  0x12921292  0x12921292  0x12921292
0x7fffffffdba0: 0x12921292  0x12921292  0xf7ffda00  0x00000002
0x7fffffffdbb0: 0x00000002  0x00000000  0xf7c23a90  0x00007fff
0x7fffffffdbc0: 0xffffdcb0  0x00007fff  0x5555523a  0x00005555
0x7fffffffdbd0: 0x55554040  0x00000002  0xffffdcc8  0x00007fff

我们看到密码缓冲区实际上已经溢出。但是,如果我尝试添加必要的零,请运行 gdb

gdb -q --args silly_password $(perl -e 'print "\x92\x12\x00\x00" x 20;')

我的堆栈如下所示:

─── Variables ───────────────────────────────────────────────────────────────────────────────
arg password = 0x7fffffffda9f "\222\022": -110 '\222'
loc password_buffer = "\222\022", '\000' <repeats 13 times>, auth_flag = 0
─────────────────────────────────────────────────────────────────────────────────────────────
>>> x/32xw $sp
0x7fffffffbc40: 0x00000000  0x00000000  0xffffda9f  0x00007fff
0x7fffffffbc50: 0x00000000  0x00000000  0x00000000  0x00000000
0x7fffffffbc60: 0x00001292  0x00000000  0x00000000  0x00000000
0x7fffffffbc70: 0xffffbc90  0x00007fff  0x5555528e  0x00005555
0x7fffffffbc80: 0xffffbda8  0x00007fff  0xf7ffdab0  0x00000322
0x7fffffffbc90: 0x00000322  0x00000000  0xf7c23a90  0x00007fff
0x7fffffffbca0: 0xffffbd90  0x00007fff  0x5555523a  0x00005555
0x7fffffffbcb0: 0x55554040  0x00000322  0xffffbda8  0x00007fff

现在一点也不溢出了!

为什么我的第一个命令(仅带有

\x92\x12
的命令)有效地产生溢出,而后者却没有?我怎样才能产生第一个堆栈中所示的溢出,但用正确的值
0x00001292
填充寄存器?

供参考,代码的相关部分是:


int check_authentication(char *password) {
    char password_buffer[16];
    volatile int auth_flag = 0;
    strcpy(password_buffer, password);
    if(strcmp(password_buffer, "brillig") == 0)
        auth_flag = 1;
    if(strcmp(password_buffer, "outgrabe") == 0)
        auth_flag = 1;
    return auth_flag; # THIS IS THE LINE BREAK OF THE STACKS SHOWED ABOVE
}
c memory stack buffer-overflow
1个回答
0
投票

您绝对想要

0x00001292
。这不是一个有效的地址。看起来这就是您想要的值,但这只是因为您正在(静态)查看位置独立可执行文件(PIE),它没有固定的基址,并且将由操作系统随机定位在内存中。看起来二进制文件本身有基地址
0x0
或者
.text
0x1000
开始,但这只是一个偏移量。另请参阅:为什么我的 ELF 二进制文件中 LOAD 段的 VirtAddr 显示为 0x0000000000000000?

您有两个选择:

  1. 将您的程序重新编译为非 PIE。您可以通过将

    -no-pie -fno-pie
    添加到 GCC 命令行来完成此操作。然后,验证新地址是否没有以前那么低。期待类似
    0x401292
    或任何高于
    0x10000
    的东西。

  2. 继续使用已有的 PIE 程序,但先在 GDB 下启动它并查看内存映射:

    gdb -q silly_password
    (gdb) start AAAAAAAA...
    ...
    (gdb) info inferior
      Num  Description       Executable
    * 1    process 11107     ./silly_password
    
    (gdb) !cat /proc/11107/maps
    555555554000-555555558000 r--p 00000000 103:05 1443328 ./silly_password <=== base
    555555558000-55555556b000 r-xp 00004000 103:05 1443328 ./silly_password <=== .text
    55555556b000-555555574000 r--p 00017000 103:05 1443328 ./silly_password
    555555575000-555555576000 r--p 00020000 103:05 1443328 ./silly_password
    555555576000-555555577000 rw-p 00021000 103:05 1443328 ./silly_password
    ...
    

取底数(在上面的示例中为

0x555555554000
)并将其与您拥有的偏移量相加:
0x555555554000 + 0x1292 == 0x555555555292
。这就是你想要的地址。

我会推荐第一个选项,因为它处理起来要简单得多。使用第二个选项,如果您在没有 GDB 的情况下运行程序,操作系统每次都会将其映射到随机地址。如果您不希望地址不断更改,则必须在本地禁用 ASLR。您可以使用

setarch $(uname -m) -R /bin/bash
或其他方式启动一个新 shell(只需谷歌“如何禁用 ASLR”)。

© www.soinside.com 2019 - 2024. All rights reserved.