如何将汇编程序正确转换为shellcode?
How to convert an assembler program to shellcode correctly?
我在 nasm (x64) 中编写了一个程序,它应该执行 /bin/bash
,并且工作正常。然后我 运行 带有 objdump -D
的程序,我写下了这样的机器代码:\xbb\x68\x53\x48\xbb\x2f\x62\x69\x6e\x2f\x62\x61\x73\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05
。然后我 运行 这个和 ./shell $(python -c 'print "\xbb\x68\x53\x48\xbb\x2f\x62\x69\x6e\x2f\x62\x61\x73\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"')
我得到了一个非法指令。但是汇编程序运行良好!有人可以帮忙吗?
shell.c:
int main(int argc, char **argv) {
int (*func)();
func = (int (*)()) argv[1];
(int)(*func)();
}
bash.asm:
section .text
global start
start:
mov rbx, 0x68
push rbx
mov rbx, 0x7361622f6e69622f
push rbx
mov rdi, rsp
push rax
push rdi
mov rsi, rsp
mov al, 59
syscall
objdump:
./bash: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 <start>:
401000: bb 68 00 00 00 mov [=12=]x68,%ebx
401005: 53 push %rbx
401006: 48 bb 2f 62 69 6e 2f movabs [=12=]x7361622f6e69622f,%rbx
40100d: 62 61 73
401010: 53 push %rbx
401011: 48 89 e7 mov %rsp,%rdi
401014: 50 push %rax
401015: 57 push %rdi
401016: 48 89 e6 mov %rsp,%rsi
401019: b0 3b mov [=12=]x3b,%al
40101b: 0f 05 syscall
您在此处省略了零字节:
\xbb\x68\x53\x48\xbb\x2f\x62\x69\x6e\x2f\x62\x61\x73\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05
相对于
401000: bb 68 00 00 00 mov [=11=]x68,%ebx
零字节是指令的一部分,不能跳过。所以你必须包括它们。
但是,问题是零字节会终止参数字符串,因此必须避免。作为 shellcode 设计者,您有责任以某种方式构造它,使其不包含可能不会出现的字节值。在许多情况下,这意味着没有零字节,因为 shellcode 是作为 C 字符串注入的,但其他值在其他情况下也可能有问题。
我在 nasm (x64) 中编写了一个程序,它应该执行 /bin/bash
,并且工作正常。然后我 运行 带有 objdump -D
的程序,我写下了这样的机器代码:\xbb\x68\x53\x48\xbb\x2f\x62\x69\x6e\x2f\x62\x61\x73\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05
。然后我 运行 这个和 ./shell $(python -c 'print "\xbb\x68\x53\x48\xbb\x2f\x62\x69\x6e\x2f\x62\x61\x73\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"')
我得到了一个非法指令。但是汇编程序运行良好!有人可以帮忙吗?
shell.c:
int main(int argc, char **argv) {
int (*func)();
func = (int (*)()) argv[1];
(int)(*func)();
}
bash.asm:
section .text
global start
start:
mov rbx, 0x68
push rbx
mov rbx, 0x7361622f6e69622f
push rbx
mov rdi, rsp
push rax
push rdi
mov rsi, rsp
mov al, 59
syscall
objdump:
./bash: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 <start>:
401000: bb 68 00 00 00 mov [=12=]x68,%ebx
401005: 53 push %rbx
401006: 48 bb 2f 62 69 6e 2f movabs [=12=]x7361622f6e69622f,%rbx
40100d: 62 61 73
401010: 53 push %rbx
401011: 48 89 e7 mov %rsp,%rdi
401014: 50 push %rax
401015: 57 push %rdi
401016: 48 89 e6 mov %rsp,%rsi
401019: b0 3b mov [=12=]x3b,%al
40101b: 0f 05 syscall
您在此处省略了零字节:
\xbb\x68\x53\x48\xbb\x2f\x62\x69\x6e\x2f\x62\x61\x73\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05
相对于
401000: bb 68 00 00 00 mov [=11=]x68,%ebx
零字节是指令的一部分,不能跳过。所以你必须包括它们。
但是,问题是零字节会终止参数字符串,因此必须避免。作为 shellcode 设计者,您有责任以某种方式构造它,使其不包含可能不会出现的字节值。在许多情况下,这意味着没有零字节,因为 shellcode 是作为 C 字符串注入的,但其他值在其他情况下也可能有问题。