我正在努力学习如何撰写shellcode
。在四处搜寻之后,我为自己的世界编写了自己的shellcode
。我认为逻辑是正确的,但不知何故,当我用shellcode
编译包装器时,它总是给我“非法指令”。
有人可以帮我查一下这段代码的错误:
.section .data
.section .text
.globl _start
jmp dummy
_start:
# write(1, message, 13)
mov $4, %al # system call 4 is write
mov $1, %bl # file handle 1 is stdout
popl %ecx
mov $12, %dl # number of bytes to write
int $0x80 # invoke operating system code
# exit(0)
xor %eax, %eax
mov $1, %al # system call 1 is exit
xor %ebx, %ebx # we want return code 0
int $0x80 # invoke operating system code
dummy:
call _start
.string "Hello, World"
file format elf32-i386
Disassembly of section .text:
00000000 <_start-0x2>:
0: eb 11 jmp 13 <dummy>
00000002 <_start>:
2: b0 04 mov $0x4,%al
4: b3 01 mov $0x1,%bl
6: 59 pop %ecx
7: b2 0c mov $0xc,%dl
9: cd 80 int $0x80
b: 31 c0 xor %eax,%eax
d: b0 01 mov $0x1,%al
f: 31 db xor %ebx,%ebx
11: cd 80 int $0x80
00000013 <dummy>:
13: e8 fc ff ff ff call 14 <dummy+0x1>
18: 48 dec %eax
19: 65 gs
1a: 6c insb (%dx),%es:(%edi)
1b: 6c insb (%dx),%es:(%edi)
1c: 6f outsl %ds:(%esi),(%dx)
1d: 2c 20 sub $0x20,%al
1f: 57 push %edi
20: 6f outsl %ds:(%esi),(%dx)
21: 72 6c jb 8f <dummy+0x7c>
23: 64 fs
...
char code[] = "\xeb\x11"
"\xb0\x04"
"\xb3\x01"
"\x59"
"\xb2\x0c"
"\xcd\x80"
"\x31\xc0"
"\xb0\x01"
"\x31\xdb"
"\xcd\x80"
"\xe8\xfc\xff\xff\xff"
"\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64";
void main() {
int (*func)();
func = (int(*)()) code;
(int) (*func)();
}
答案 0 :(得分:1)
您的代码存在一些问题。
首先,您只需设置所有参数寄存器的低字节(即al
,bl
和dl
)。您需要设置完整的32位。当你执行现在的方式时,剩下的24位中剩下的任何东西都会被传递给内核。
此外,在您的C代码中,call
不正确:
"\xe8\xfc\xff\xff\xff"
这实际上是call $+1
,这是调用指令的第二个字节,这就是你获取非法指令的原因。
我不确定你是如何到达code
变量中的字节的,但是你需要重新组装。
使用gcc -m32
在Fedora 17上使用gcc 4.7.2进行测试。 (对不起,我只使用英特尔语法)
char code[] __attribute__((section(".text"))) =
"\xeb\x17" // jmp $+19
"\xB8\x04\x00\x00\x00" // mov eax, 4 ; (sys_write)
"\x31\xDB" // xor ebx, ebx
"\x43" // inc ebx
"\x59" // pop ecx ; (addr of string pushed by call below)
"\x31\xD2" // xor edx, edx
"\xb2\x0c" // mov dl, 0Ch ; (length of string)
"\xcd\x80" // int 80h
"\x31\xc0" // xor eax, eax
"\xb0\x01" // mov al, 1 ; (sys_exit)
"\x31\xdb" // xor ebx, ebx
"\xcd\x80" // int 80h
"\xe8\xe4\xff\xff\xff" // call $-23
"\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x00"; // "Hello, World"
void main() {
int (*func)();
func = (int(*)()) code;
(int) (*func)();
}
请注意,有一些方法可以使代码更小,但这当然是留给读者的练习。
如果您要使用这样的手动调整组件,请准备好调试,调试和调试。 Learn how to use GDB现在,或者你将永远无助。在程序集的开头设置断点(b code
)并逐步执行它。你很快就会发现出了什么问题。