使用 shellcode 调用 x86 本地函数
Calling x86 local function using shellcode
我想使用将流重定向到本地函数,然后使用 shellcode returning 到原始函数。
我定义了两个简单的函数并使用 objdump 获取它们的汇编代码:
// unsigned char *g_code = "\x55\x48\x89\xe5\xb8\x2a\x00\x00\x00\x5d\xc3";
int g() {
return 42;
}
// unsigned char *f_code_original = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
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 = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
unsigned char f_code_modified[] = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\xfb\xfe\xff\xff\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";
int value = 0;
int (*f)() = (int (*)())f_code_modified;
value = f();
printf("%d\n", value);
}
如果我使用 f 的原始代码(因为我是从 objdump 获得的)它就可以工作。
我想修改它以调用我的重定向功能,然后恢复当前执行。
汇编代码(针对f_code_modified):
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 处的调用指令 .. .. .. .. 是相对于当前指令指针的。
如果我 运行 这样的程序,它会给出分段错误。
问题:有没有办法在运行时找到当前指令指针,然后将shellcode写成\xe8\x??\x??\x??\x??调用函数重定向?我需要修改什么?我已经尝试使用 -fPIC 并获取重定向地址(使用 &),但它不起作用。
根据 Peter Cordes 的评论,您可以将目标函数的绝对地址嵌入到 shellcode 中。
要查找函数地址redirect()
,我使用的是nm
,所以命令是:
% nm <binary> | grep redirect
输出:080484bb T redirect
所以,我重写你的shellcode来修改,添加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 = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
// unsigned char f_code_modified[] = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\xbb\x84\x04\x08\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";
// Here shellcode, I wrote :
unsigned char *test_shellcode = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\xbb\x84\x04\x08\xff\xd0\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";
// unsigned char *test_shellcode2 = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\xbb\x84\x04\x08\xff\xd0\xb8\x00\x00\x00\x00\xe8\xa3\x7f\xfb\xf7\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";
int value = 0;
int (*f)() = (int (*)())test_shellcode;
value = f();
printf("%d\n", 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
,但这是有效的:
% 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 %
我想使用将流重定向到本地函数,然后使用 shellcode returning 到原始函数。
我定义了两个简单的函数并使用 objdump 获取它们的汇编代码:
// unsigned char *g_code = "\x55\x48\x89\xe5\xb8\x2a\x00\x00\x00\x5d\xc3";
int g() {
return 42;
}
// unsigned char *f_code_original = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
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 = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
unsigned char f_code_modified[] = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\xfb\xfe\xff\xff\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";
int value = 0;
int (*f)() = (int (*)())f_code_modified;
value = f();
printf("%d\n", value);
}
如果我使用 f 的原始代码(因为我是从 objdump 获得的)它就可以工作。 我想修改它以调用我的重定向功能,然后恢复当前执行。
汇编代码(针对f_code_modified):
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 处的调用指令 .. .. .. .. 是相对于当前指令指针的。
如果我 运行 这样的程序,它会给出分段错误。
问题:有没有办法在运行时找到当前指令指针,然后将shellcode写成\xe8\x??\x??\x??\x??调用函数重定向?我需要修改什么?我已经尝试使用 -fPIC 并获取重定向地址(使用 &),但它不起作用。
根据 Peter Cordes 的评论,您可以将目标函数的绝对地址嵌入到 shellcode 中。
要查找函数地址redirect()
,我使用的是nm
,所以命令是:
% nm <binary> | grep redirect
输出:080484bb T redirect
所以,我重写你的shellcode来修改,添加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 = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\xb8\x2a\x00\x00\x00\xc9\xc3";
// unsigned char f_code_modified[] = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\x00\x00\x00\x00\xe8\xbb\x84\x04\x08\xb8\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";
// Here shellcode, I wrote :
unsigned char *test_shellcode = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\xbb\x84\x04\x08\xff\xd0\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";
// unsigned char *test_shellcode2 = "\x55\x48\x89\xe5\x48\x83\xec\x10\xb8\xbb\x84\x04\x08\xff\xd0\xb8\x00\x00\x00\x00\xe8\xa3\x7f\xfb\xf7\x89\x45\xfc\x8b\x45\xfc\xc9\xc3";
int value = 0;
int (*f)() = (int (*)())test_shellcode;
value = f();
printf("%d\n", 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
,但这是有效的:
% 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 %