使用空字符将字符串插入内存

信息安全 攻击 开发
2021-09-12 13:33:02

我正在尝试实现 return-to-libc,
这是代码

void func(const char *str) {
    char buf[4];
    strcpy(buf,str);
    printf("you entered [%s]\n",buf);
}

int main(int argc, char *argv[]) {
    if(argc != 2) {
        printf("Need an argument\n");
        return 0;
    }
    func(argv[1]);
    return 0;
}

现在的问题是,system我的电脑给我的函数地址是 6 个十六进制数字而不是 8 个十六进制数字(这意味着前面的两位数字为零),但是我使用 strcpy 复制字符串,从而终止复制字符串一旦遇到空字符。

任何想法如何复制我传递的整个字符串,包括空字符?
或者任何你觉得能帮助我的东西,都值得赞赏。

3个回答
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void func(const char *str) {
    char buf[4];
    strcpy(buf,str);
    printf("you entered [%s]\n",buf);
}

int main(int argc, char *argv[]) {
    if(argc != 2) {
        printf("Need an argument\n");
        return 0;
    }
    func(argv[1]);
    return 0;
}

我使用以下命令编译了您的代码。

gcc blah.c -o blah

裂开gdb

[ayrx@localhost ~]$ gdb -q blah 
Reading symbols from /home/ayrx/blah...(no debugging symbols found)...done.
(gdb) run AAAAAAAAAAAAAAAABBBB
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/fedora/blah AAAAAAAAAAAAAAAABBBB
you entered [AAAAAAAAAAAAAAAABBBB]

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()

这是来自 的寄存器转储gdb

(gdb) info registers
eax            0x23 35
ecx            0x7fffffde   2147483614 
edx            0x0  0
ebx            0x4e735000   1316179968
esp            0xbffff160   0xbffff160
ebp            0x41414141   0x41414141 
esi            0x0  0
edi            0x0  0
eip            0x42424242   0x42424242
eflags         0x10286  [ PF SF IF RF ]
cs             0x73         115
ss             0x7b         123
ds             0x7b         123
es             0x7b         123
fs             0x0          0
gs             0x33         51

如您所见,寄存器已被我输入eip的最后 4 秒覆盖。B

最后一步是覆盖eip寄存器以指向您的 shellcode 的位置。由于您的缓冲区很小,您将不得不找到一些其他内存位置来存储 shellcode。覆盖eip寄存器以指向该位置,您就赢了。我会把那部分留给你。

简短回答: 直接在strcpy.


答案: 空字符是字符串的结尾strcpy而且你不能直接注入 null character 。

但是您可以使用 to shellcode encoders//来删除您的 shellcode 空字符,encryptors或者compressor您可以使用带有其他字符串终止符的其他函数。例如gets(在获取字符串终止符是,0A

system所以在这种情况下你不能直接跳转到。您可能会考虑寻找其他一些您可以跳转到的库函数,这些函数将对您有用。或者您可以将其扩展为通用的面向返回的编程攻击,并跳转到一系列代码片段。

在这种情况下,您将寻找一些(与位置相关的)代码片段,这些代码片段使您能够导出地址system并跳转到它。您可能会寻找一个执行and指令并用于and 0xcc 0x33获取0x00或其他什么的小工具。然后,您将需要一个可以让您跳转到派生地址的小工具。