PA193 - Secure coding principles and practices LABS: Language level vulnerabilities: Buffer overflow, type overflow, strings Petr Švenda svenda@fi.muni.cz 2 | PA193 - Buffer overflow, string vulnerabilities // Note: GCC and MSVC uses different memory alignment // Try "12345678DevilEvecosia" as a password for gcc build // Try "1234567812345678Devil I am. Ha Ha" as a password for MSVC debug build void demoBufferOverflowData() { int unused_variable = 30; #define NORMAL_USER 'n' #define ADMIN_USER 'a' int userRights = NORMAL_USER; #define USER_INPUT_MAX_LENGTH 8 char userName[USER_INPUT_MAX_LENGTH]; char passwd[USER_INPUT_MAX_LENGTH]; // print some info about variables printf("%-20s: %p\n", "userName", userName); printf("%-20s: %p\n", "passwd", passwd); printf("%-20s: %p\n", "unused_variable", &unused_variable); printf("%-20s: %p\n", "userRights", &userRights); printf("\n"); // Get user name memset(userName, 1, USER_INPUT_MAX_LENGTH); memset(passwd, 2, USER_INPUT_MAX_LENGTH); printf("login as: "); fflush(stdout); gets(userName); // Get password printf("%s@vulnerable.machine.com: ", userName); fflush(stdout); gets(passwd); // Check user rights (set to NORMAL_USER and not changed in code) if (userRights == NORMAL_USER) { printf("\nWelcome, normal user '%s', your rights are limited.\n\n", userName); fflush(stdout); } if (userRights == ADMIN_USER) { printf("\nWelcome, all mighty admin user '%s'!\n", userName); fflush(stdout); } // How to FIX: //memset(userName, 0, USER_INPUT_MAX_LENGTH); //fgets(userName, USER_INPUT_MAX_LENGTH - 1, stdin); //memset(passwd, 0, USER_INPUT_MAX_LENGTH); //fgets(passwd, USER_INPUT_MAX_LENGTH - 1, stdin); } Setup • Create new Visual Studio 2013 Project – File->New->Project->VisualC++->Win32 Console app – Turn off ‘Precompiled header’ and ‘SDL checks’ • Copy content of BufferOverflow.cpp from IS instead of generated main file • Try to compile (disable warning on gets() function) – #define _CRT_SECURE_NO_WARNINGS • Insert breakpoint (begin of demoBufferOverflowData()) – F9 • Run program in debug mode – F5 • Execute next step of program – F10 • Display memory (must be in debugging session), Debug → Windows → Memory 3 PA193 | LABS | BufferOverflow Úvo d do C, void demoBufferOverflowData() { int unused_variable = 30; #define NORMAL_USER 'n' #define ADMIN_USER 'a' int userRights = NORMAL_USER; #define USER_INPUT_MAX_LENGTH 8 char userName[USER_INPUT_MAX_LENGTH]; char passwd[USER_INPUT_MAX_LENGTH]; // print some info about variables printf("%-20s: %p\n", "userName", userName); printf("%-20s: %p\n", "passwd", passwd); printf("%-20s: %p\n", "unused_variable", &unused_variable); printf("%-20s: %p\n", "userRights", &userRights); printf("\n"); // Get user name printf("login as: "); gets(userName); // Get password printf("%s@vulnerable.machine.com: ", userName); gets(passwd); // Check user rights (set to NORMAL_USER and not changed in code) if (userRights == NORMAL_USER) { printf("\nWelcome, normal user '%s', your rights are limited.\n\n", userName); } if (userRights == ADMIN_USER) { printf("\nWelcome, all mighty admin user '%s'!\n", userName); } } Reading username and password (no length checking) Print information about current user rights Array with fixed length (will be overwritten) Variable containing current access rights Help output of address of local variables stored on the stack | PA193 - Buffer overflow, string vulnerabilities Data in memory passwd userName userRights unused_variable | PA193 - Buffer overflow, string vulnerabilities Running without malicious input passwd userName | PA193 - Buffer overflow, string vulnerabilities Running with malicious input – userName insert ‘evil’ into userName | PA193 - Buffer overflow, string vulnerabilities Running with malicious input - passwd • Too long password overflow userName and userRights Insert ‘1234567812345678Devil I am. Ha Ha’ into passwd Úvo d do C, Running with attacker input - result Questions (debug mode) • How are userName, password and userRights positioned in memory? • How you will find memory location (address) of userRights variable? • How many bytes you need to write into userName variable to change userRights ? • Can you get admin rights by changing userName only? 10 PA193 | LABS | BufferOverflow Questions (debug mode) • Why is program throwing debugger exception when finishing function demoBufferOverflowData()? • How program was able to detect memory corruption? • Why 0xcc bytes are here? How you can type 0xcc into terminal? • Can you get admin rights without raising runtime exception (memory around userName variable corrupted) when leaving demoBufferOverflowData()? • Where you can find return address? • What should be the return address value? – Try R-Click -> Go to Disassembly 11 PA193 | LABS | BufferOverflow Questions (release mode) • Release mode, /GS on – What is memory layout with respect to debug mode? – Can you still execute buffer overflow and change userRights? – What is the value of canary word? • Release mode, /GS off – What is the influence of /GS disabled? – What is the impact on addresses of variables? – Can you be admin in Release? Why? 12 PA193 | LABS | BufferOverflow Lab – compiler protections • GCC (e.g., QT Creator) & MSVC (Visual Studio) – list of compiler flags, release mode • Compile program with/without compiler protection – bufferoverflowdemo.cpp::demoBufferOverflowData() • download from IS materials – return pointer smash behavior (crash, exception) • Disassembly display of resulting binary – instruction-wise mode in IDE (Visual Studio), OllyDbg – existence of canary word (function with/without GS buffer) • Display address of variable, function..., • run program multiple times – memory randomization (ASLR) 13 PA193 | LABS | BufferOverflow Compiler flags • Locate all flags discussed during lecture • Visual Studio Projects Settings • Observe memory layout for stack frame with and without the flag – what is changing? – what is missing? 14 PA193 | LABS | BufferOverflow Compiler settings for /DEP and /ASLR 15 PA1 93 | LAB S | Deeper look into disassembly 16 PA1 93 | LAB S | Deeper look into disassembly (cont.) 17 PA193 | LABS | BufferOverflow BinScope Binary Analyzer • Download Microsoft SDL’s Binscope – https://www.microsoft.com/en-us/download/details.aspx?id=11910 • Run BinScope Binary Analyzer (cmd or GUI) – binscope.exe – binscope.exe /o results.xml targetApp.exe • Run on the binaries produced with different compiler settings – /GS... 18 PA193 | LABS | BufferOverflow Lab – exploiting exercises • Protostar image (http://exploit-exercises.com) – pre-prepared virtual machine – http://exploit-exercises.com/protostar (task description) • Important: site now not available, use this link: – https://web.archive.org/web/20140922114755/http://exploit- exercises.com/protostar – Or protostar.zip in IS • Login credentials: user / user; root / godmode • Challenges stored in /opt/protostar/bin/ directory – stack0-7 • Run it, supply malformed input leading to crash • Think about how to fix the source code 19 PA193 | LABS | BufferOverflow Protostar virtual image with exercises 20 PA1 93 | LAB S | Lab - Homework • Finish exploit exercises (Protostar, stack0-4) – submit txt file with inputs causing corruption • Fix problems from these exercises (stack0-4) – submit corrected code that will not contain vulnerable constructions (save functions, proper arguments checking...) • Bonus (+3 points): – Finish exploit exercise (Protostar, stack5-7) • Upload your solution to IS repository – (homework vaults) • Deadline: one week (22.10.2015 23:59 / 27.10.2015 23:59 depending on your seminar group) 21 PA193 | LABS | BufferOverflow 22 PA193 | LABS | BufferOverflow