使用外壳代码调用x86本地函数

人气:70 发布:2023-01-03 标签: c assembly code-injection shellcode

问题描述

我想使用将流重定向到本地函数,然后使用外壳代码返回到原始函数。 我定义了两个简单的函数,并使用objump来获取它们的汇编代码:

// unsigned char *g_code = "x55x48x89xe5xb8x2ax00x00x00x5dxc3";
int g() {
    return 42;
}

// unsigned char *f_code_original = "x55x48x89xe5x48x83xecx10xb8x00x00x00x00xe8x00x00x00x00x89x45xfcxb8x2ax00x00x00xc9xc3";
int f() {
    int x = g();
    return 42;
}

在另一个文件中,我有一个要在f:

的两条指令之间调用的函数
void redirect() {
    FILE *out = fopen("redirect.txt", "w");
    fprintf(out, "REDIRECT WORKED");
    fclose(out);
}

为此,我使用以下代码,用-fPIC-FNO-STACK-PROTECTOR-Z EXECSTACK编译:

void f_func() {
    unsigned char *f_code_original = "x55x48x89xe5x48x83xecx10xb8x00x00x00x00xe8x00x00x00x00x89x45xfcxb8x2ax00x00x00xc9xc3";
    unsigned char f_code_modified[] = "x55x48x89xe5x48x83xecx10xb8x00x00x00x00xe8xfbxfexffxffxb8x00x00x00x00xe8x00x00x00x00x89x45xfcx8bx45xfcxc9xc3";

    int value = 0;

    int (*f)() = (int (*)())f_code_modified;
    value = f();

    printf("%d
", value);
}

如果我使用f的原始代码(因为我是从objump获得的),它就可以工作。 我想修改它以调用我的重定向函数,然后继续当前的执行。

汇编代码(针对f_code_Modify):

0:  55                      push   ebp
1:  48                      dec    eax
2:  89 e5                   mov    ebp,esp
4:  48                      dec    eax
5:  83 ec 10                sub    esp,0x10
8:  b8 00 00 00 00          mov    eax,0x0       <==
d:  e8 fb fe ff ff          call   0xffffff0d    <==
12: b8 00 00 00 00          mov    eax,0x0
17: e8 00 00 00 00          call   0x1c
1c: 89 45 fc                mov    DWORD PTR [ebp-0x4],eax
1f: 8b 45 fc                mov    eax,DWORD PTR [ebp-0x4]
22: c9                      leave
23: c3                      ret 
如果我直接从Main(int x=g();reDirect();Return 42;)进行调用,这看起来类似于,但我认为d:e8处的调用指令。。。。。。。是相对于当前指令指针的。

如果我这样运行程序,它会给出分段错误。

问题:有没有办法在运行时找到当前指令指针,然后将外壳代码编写为xe8x??x??调用重定向函数?我需要修改什么?我已经尝试使用-fPIC并获取重定向地址(使用&;),但不起作用。

推荐答案

在Peter Cordes注释之后,您可以将目标函数的绝对地址嵌入外壳代码中。

要查找函数地址redirect(),我使用的是nm,因此命令为:

% nm <binary> | grep redirect

输出:080484bb T redirect

所以,我重写了您的外壳代码进行修改,增加了redirect()函数地址:

test_shellcode:

push ebp
dec eax
mov ebp,esp
dec eax
sub esp,0x10
mov eax,0x080484bb    ; redirect() function address
call eax
mov dword [ebp-0x4],eax
mov eax,dword [ebp-0x4]
leave
ret

test_shellcode2:

push ebp
dec eax
mov ebp,esp
dec eax
sub esp,0x10
mov eax,0x80484bb    ; redirect() function address
call eax
mov eax,0x0
call 0x1c
mov dword [ebp-0x4],eax
mov eax,dword [ebp-0x4]
leave
ret

在这里,我修改了您的代码:

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

void redirect() {
    FILE *out = fopen("redirect.txt", "w");
    fprintf(out, "REDIRECT WORKED");
    fclose(out);
}

void f_func() {
//    unsigned char *f_code_original = "x55x48x89xe5x48x83xecx10xb8x00x00x00x00xe8x00x00x00x00x89x45xfcxb8x2ax00x00x00xc9xc3";
//    unsigned char f_code_modified[] = "x55x48x89xe5x48x83xecx10xb8x00x00x00x00xe8xbbx84x04x08xb8x00x00x00x00xe8x00x00x00x00x89x45xfcx8bx45xfcxc9xc3";

// Here shellcode, I wrote :

    unsigned char *test_shellcode = "x55x48x89xe5x48x83xecx10xb8xbbx84x04x08xffxd0x89x45xfcx8bx45xfcxc9xc3";

//    unsigned char *test_shellcode2 = "x55x48x89xe5x48x83xecx10xb8xbbx84x04x08xffxd0xb8x00x00x00x00xe8xa3x7fxfbxf7x89x45xfcx8bx45xfcxc9xc3";

    int value = 0;

    int (*f)() = (int (*)())test_shellcode;
    value = f();

    printf("%d
", value);
}

int main(int argc, char **argv) {
    f_func();
}

-fPIC -fno-stack-protector -z execstack编译,所以是工作。例如,我正在使用test_shellcode:

% ls -l
total 16
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:40 shell
-rw-rw-r-- 1 febri febri 1075 Jan  1 08:39 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% ./shell
0
% ls -l  
total 20
-rw-rw-r-- 1 febri febri   15 Jan  1 08:41 redirect.txt
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:40 shell
-rw-rw-r-- 1 febri febri 1075 Jan  1 08:39 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% cat redirect.txt
REDIRECT WORKED

但是,如果我使用test_shellcode2,我会得到Segmentation fault,但它是Work:

% ls -l
total 16
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:46 shell
-rw-rw-r-- 1 febri febri 1076 Jan  1 08:46 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% ./shell
[1]    7465 segmentation fault (core dumped)  ./shell
% ls -l
total 20
-rw-rw-r-- 1 febri febri   15 Jan  1 08:46 redirect.txt
-rwxrwxr-x 1 febri febri 7548 Jan  1 08:46 shell
-rw-rw-r-- 1 febri febri 1076 Jan  1 08:46 shell.c
drwxrwxr-x 2 febri febri 4096 Jan  1 08:16 shellcode
% cat redirect.txt
REDIRECT WORKED                                                                                                                                                  % 

18