Auditing Closed-Source Applications Using reverse engineering in a security context Speech Outline: 1.Different Approaches to auditing binaries 2.How to.

Slides:



Advertisements
Similar presentations
Buffer Overflows Nick Feamster CS 6262 Spring 2009 (credit to Vitaly S. from UT for slides)
Advertisements

1 Lecture 3: MIPS Instruction Set Today’s topic:  More MIPS instructions  Procedure call/return Reminder: Assignment 1 is on the class web-page (due.
INSTRUCTION SET ARCHITECTURES
Exploring Security Vulnerabilities by Exploiting Buffer Overflow using the MIPS ISA Andrew T. Phillips Jack S. E. Tan Department of Computer Science University.
1 Lecture 4: Procedure Calls Today’s topics:  Procedure calls  Large constants  The compilation process Reminder: Assignment 1 is due on Thursday.
Lecture 9. Lecture 9: Outline Strings [Kochan, chap. 10] –Character Arrays/ Character Strings –Initializing Character Strings. The null string. –Escape.
What is a pointer? First of all, it is a variable, just like other variables you studied So it has type, storage etc. Difference: it can only store the.
Fall EE 333 Lillevik 333f06-l4 University of Portland School of Engineering Computer Organization Lecture 4 Assembly language programming ALU and.
Elementary Data Structures: Part 2: Strings, 2D Arrays, Graphs
1 Nested Procedures Procedures that don't call others are called leaf procedures, procedures that call others are called nested procedures. Problems may.
ECE 353 Introduction to Microprocessor Systems Michael G. Morrow, P.E. Week 6.
Utilizing the GDB debugger to analyze programs Background and application.
Binghamton University CS-220 Spring 2015 Binghamton University CS-220 Spring 2015 Object Code.
Auditing Closed-Source Software Using reverse engineering in a security context © 2001 by HalVar Flake Speech Outline (I): Introduction to the topic: Different.
© 2001 Halvar Flake Auditing binaries for security vulnerabilities Speech outline (I) Legal considerations concerning reverse engineering Introduction.
Buffer Overflow Exploits CS-480b Dick Steflik. What is a buffer overflow? Memory global static heap malloc( ), new Stack non-static local variabled value.
Teaching Buffer Overflow Ken Williams NC A&T State University.
Chapter 8 Characters and Strings Acknowledgment The notes are adapted from those provided by Deitel & Associates, Inc. and Pearson Education Inc.
Assembly תרגול 8 פונקציות והתקפת buffer.. Procedures (Functions) A procedure call involves passing both data and control from one part of the code to.
Static Analysis for Security Amir Bazine Per Rehnberg.
University of Washington CSE 351 : The Hardware/Software Interface Section 5 Structs as parameters, buffer overflows, and lab 3.
A survey of Buffer overflow exploitation on HTC touch mobile phone Advanced Defense Lab CSIE NCU Chih-Wen Ou.
Security Exploiting Overflows. Introduction r See the following link for more info: operating-systems-and-applications-in-
CAP6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2011.
Fall 2008CS 334: Computer SecuritySlide #1 Smashing The Stack A detailed look at buffer overflows as described in Smashing the Stack for Fun and Profit.
Chapter 6 Buffer Overflow. Buffer Overflow occurs when the program overwrites data outside the bounds of allocated memory It was one of the first exploited.
Computer Security and Penetration Testing
BLENDED ATTACKS EXPLOITS, VULNERABILITIES AND BUFFER-OVERFLOW TECHNIQUES IN COMPUTER VIRUSES By: Eric Chien and Peter Szor Presented by: Jesus Morales.
Programmer's view on Computer Architecture by Istvan Haller.
Drawing pictures from code CanSecWest 2002 Halvar Flake Reverse Engineer Blackhat Consulting Graph-Based Binary Analysis.
Compiler Construction
Computer Science Detecting Memory Access Errors via Illegal Write Monitoring Ongoing Research by Emre Can Sezer.
Mitigation of Buffer Overflow Attacks
CNIT 127: Exploit Development Ch 4: Introduction to Format String Bugs.
© 2001 Halvar Flake Auditing binaries for security vulnerabilities Speech outline (I) Legal considerations concerning reverse engineering Introduction.
Overflow Examples 01/13/2012. ACKNOWLEDGEMENTS These slides where compiled from the Malware and Software Vulnerabilities class taught by Dr Cliff Zou.
Smashing the Stack Overview The Stack Region Buffer Overflow
Buffer Overflow. Introduction On many C implementations, it is possible to corrupt the execution stack by writing past the end of an array. Known as smash.
Buffer Overflow Proofing of Code Binaries By Ramya Reguramalingam Graduate Student, Computer Science Advisor: Dr. Gopal Gupta.
CMSC 150 PROGRAM EXECUTION CS 150: Wed 1 Feb 2012.
Buffer Overflow Group 7Group 8 Nathaniel CrowellDerek Edwards Punna ChalasaniAxel Abellard Steven Studniarz.
CSC141- Introduction to Computer programming Teacher: AHMED MUMTAZ MUSTEHSAN Lecture – 21 Thanks for Lecture Slides:
Reminder Bomb lab is due tomorrow! Attack lab is released tomorrow!!
Sairajiv Burugapalli. This chapter covers three main categories of classic software vulnerability: Buffer overflows Integer vulnerabilities Format string.
Information Security - 2. A Stack Frame. Pushed to stack on function CALL The return address is copied to the CPU Instruction Pointer when the function.
Arrays. Outline 1.(Introduction) Arrays An array is a contiguous block of list of data in memory. Each element of the list must be the same type and use.
Introduction to Intel IA-32 and IA-64 Instruction Set Architectures.
CAP6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2014.
Software Security. Bugs Most software has bugs Some bugs cause security vulnerabilities Incorrect processing of security related data Incorrect processing.
Principles of Programming - NI Chapter 10: Character & String : In this chapter, you’ll learn about; Fundamentals of Strings and Characters The difference.
Some of the utilities associated with the development of programs. These program development tools allow users to write and construct programs that the.
Shellcode COSC 480 Presentation Alison Buben.
Mitigation against Buffer Overflow Attacks
Protecting Memory What is there to protect in memory?
Strings CSCI 112: Programming in C.
K. K. Mookhey Network Intelligence India Pvt. Ltd.
Protecting Memory What is there to protect in memory?
A bit of C programming Lecture 3 Uli Raich.
Protecting Memory What is there to protect in memory?
System Programming and administration
Recitation: Attack Lab
Strings, Line-by-line I/O, Functions, Call-by-Reference, Call-by-Value
CS 465 Buffer Overflow Slides by Kent Seamons and Tim van der Horst
Object Oriented Programming COP3330 / CGS5409
Lecture 4: MIPS Instruction Set
CAP6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2015.
Lecture 4: Instruction Set Design/Pipelining
CAP6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2016.
CAP6135: Malware and Software Vulnerability Analysis Buffer Overflow : Example of Using GDB to Check Stack Memory Cliff Zou Spring 2013.
Format String Vulnerability
Presentation transcript:

Auditing Closed-Source Applications Using reverse engineering in a security context Speech Outline: 1.Different Approaches to auditing binaries 2.How to spot common programming mistakes in the binary 3.Writing a small script that automates the task of searching for suspicious coding constructs 4.Example of using this script to find a buffer overflow in a major web server application. © HalVar Flake

White Hat vs Black Hat auditing White Hat Auditing: Black Hat Auditing All code has to be audited Continues after a vulnerability has been found Has to be repeated upon every upgrade Trying to find a single vulnerable condition through which the security of an application can be compromised Only audits suspicious parts of the code Only one vulnerable condition is needed Will only be repeated if all old problems have been fixed. Trying to ensure application security by auditing every line of code in a given application, hopefully fixing all problems and leaving the program in a secure and stable condition © HalVar Flake

Closed-Source Auditing Approaches 1. Stress Testing with Junk Input Long strings of data are more or less randomly generated and sent to the application, usually trying to overflow every single string that gets parsed by a certain protocol. Pros: Stress testing tools are re-usable for a given protocol Will work automatically with little to no supervision Do not require specialized personnel to use Cons: The analyzed protocol needs to be known in advance Complex problems involving several conditions at once will be missed Undocumented options and backdoors will be missed © HalVar Flake

Closed-Source Auditing Approaches 2. Manual Reverse Engineering A reverse engineer carefully reads the disassembly of the program, tediously re- constructing the program flow and spotting programming errors. This was the approach Joey__ demonstrated at BlackHat Singapore. Pros: Even the most complex issues can be spotted Cons: The process involved is incredibly time-consuming A highly skilled and specialized auditor is needed The danger is inherent that an auditor will burn out and thus miss obvious problems © HalVar Flake

Closed-Source Auditing Approaches 3. Looking at suspicious code constructs A reverse engineer audits calls to functions wich are know to be the source of common programming errors. He looks through these calls and decides which ones to read more closely. Pros: Reasonable depth: Even relatively complex issues can be uncovered In comparison to a complete manual audit, this approach saves quite a bit of time The process of looking for suspicious constructs can be automated to a certain degree Cons: Not all problems will be uncovered Needs highly specialized auditor If nothing is found, the auditor is back to approach Nr. 2 © HalVar Flake

The right tool for the task: IDA Pro by Ilfak Guilfanov Can disassemble x86, SPARC, MIPS and much more... Includes a powerful scripting language Can recognize statically linked library calls Features a powerful plug-in interface © HalVar Flake

Dynamically linked library calls: Diagram of program flow Application Code Dynamic Linkage Table Executable Image strcpy ( ) - Code sprintf ( ) - Code strcat ( ) - Code... Dynamic Library © HalVar Flake

Statically linked library calls : Diagram of program flow Application Code strcpy( ) - Code Executable Image strcat( ) - Code.... © HalVar Flake

Assembly recap: Passing arguments A simple example void *memcpy(void *dest, void *src, size_t n); Assembly representation: push4 moveax, unkn_40D278 pusheax leaeax, [ebp+var_458] pusheax call_memcpy © HalVar Flake

Dangerous Programming Constructs The classical strcpy/strcat This call targets a stack buffer The source is variable, not a static string © HalVar Flake

Dangerous Programming Constructs Criteria for suspicious strcpy/strcat calls: Does the call target a stack or heap buffer of fixed size ? Is the source buffer dynamic and not a fixed string ? The classical strcpy/strcat © HalVar Flake

Dangerous Programming Constructs sprintf( ) targeting fixed buffers Expanded strings are not static and not fixed in length © HalVar Flake Format string containing „%s“ Target buffer is a stack buffer

Dangerous Programming Constructs sprintf( ) targeting fixed buffers Criteria for suspicious sprintf( ) calls: Does the call target a stack or heap buffer of fixed size ? Does the format string contain a „%s“ ? Is the expanded string of non-fixed length ? © HalVar Flake

Dangerous Programming Constructs *scanf( ) parsing untrusted input Format string contains „%s“ Data is parsed into stack buffers © HalVar Flake

Dangerous Programming Constructs *scanf( ) parsing untrusted input Criteria for suspicious *scanf( ) calls: Does the format string contain a „%s“ ? Does the call parse a string into a fixed buffer ? © HalVar Flake

Dangerous Programming Constructs strncat/strncpy failing to null-terminate Copying data into a stack buffer again... © HalVar Flake If the source is larger than n (4000 bytes), no NULL will be appended

Dangerous Programming Constructs strncat/strncpy failing to null-terminate The target buffer is only n bytes long

Dangerous Programming Constructs strncat/strncpy failing to null-terminate Criteria for suspicious strncat/strncpy( ) calls: Is the length n the same size as or bigger than the targeted buffer ? Is the source buffer dynamic and not a fixed string ? Does the call target a stack or heap buffer of fixed size ? © HalVar Flake

Dangerous Programming Constructs format-string vulnerabilities Argument deficiency Format string is a dynamic variable © HalVar Flake

Dangerous Programming Constructs format-string vulnerabilities Criteria for suspicious *printf-calls Does the call suffer from an argument deficiency ? Is the format string dynamic instead of a static string ? © HalVar Flake

Dangerous Programming Constructs Cast-screwups void func(char *dnslabel) { char buffer[256]; char *indx = dnslabel; int count; count = *indx; buffer[0] = '\x00'; while (count != 0 && (count + strlen (buffer)) < sizeof (buffer) - 1) { strncat (buffer, indx, count); indx += count; count = *indx; } © HalVar Flake

Dangerous Programming Constructs Cast-screwups Criteria for suspicious size_t utilization Does the function copy memory with a size_t as length ? Is the size_t a dynamic value instead of a hardwired one ? Is the size_t subtracted from immediately before the call ? Is the size_t at any point written after it has been sign- extended with the movsx-mnemonic ? © HalVar Flake

Automating the boring parts: Hands on: A simple sprintf( ) analyzing script Things to check for when analyzing a sprintf()-call: Does the sprintf( ) target a static buffer ? Does the format string contain an „%s“ ? Does the call suffer from an argument deficiency ? If so, is the format string static or dynamic ? © HalVar Flake

Automating the boring parts: Hands on: A simple sprintf( ) analyzing script static GetStackCorr(lpCall) { while((GetMnem(lpCall) != "add")&&(GetOpnd(lpCall, 0) != "esp")) lpCall = Rfirst(lpCall); return(xtol(GetOpnd(lpCall, 1))); } Trace the code further until an „add esp, somevalue“ is found Convert the somevalue to a number and return it © HalVar Flake

Automating the boring parts: Hands on: A simple sprintf( ) analyzing script static GetBinString(eaString) { auto strTemp, chr; strTemp = ""; chr = Byte(eaString); while((chr != 0)&&(chr != 0xFF)) { strTemp = form("%s%c", strTemp, chr); eaString = eaString + 1; chr = Byte(eaString); } return(strTemp); } Zero the stringGet a byte Until either a NULL or a 0xFF is found, append one byte at a time to the string, then return the string. © HalVar Flake

Automating the boring parts: Hands on: A simple sprintf( ) analyzing script Steps to take to retrieve argument n of a call: 1.Locate the n-th push before the function call 2.If an immediate offset is pushed, return this value 3.If a register was pushed, trace back until the instruction is found which loaded the register and return the value it was loaded with © HalVar Flake

staticGetArg(lpCall, n) { autoTempReg; while(n > 0) { lpCall = RfirstB(lpCall); if(GetMnem(lpCall) == "push") n = n-1; } if(GetOpType(lpCall, 0) == 1) { TempReg = GetOpnd(lpCall, 0); lpCall = RfirstB(lpCall); while(GetOpnd(lpCall, 0) != TempReg) lpCall = RfirstB(lpCall); return(GetOpnd(lpCall, 1)); } else return(GetOpnd(lpCall, 0)); } Trace back until the n-th push is found Is the pushed operand a register ? Find where the register was last accessed and return the value which was pushed... © HalVar Flake

staticAuditSprintf(lpCall) { autofString, fStrAddr, buffTarget; buffTarget = GetArg(lpCall, 1); fString = GetArg(lpCall, 2); if(strstr(fString, "offset") != -1) fString = substr(fString, 7, -1); fStrAddr = LocByName(fString); fString = BinStrGet(fStrAddr); if(GetStackCorr(lpCall) < 12) if(strlen(fString) < 2) Message("%lx --> Format String Problem ?\n", lpCall); if(strstr(fString, "%s") != -1) if(strstr(buffTarget, "var_") != -1) Message("%lx --> Overflow problem ? \"%s\"\n", lpCall, fString); } Clean up the arguments Check for argument deficiency Check for a dynamic format string Scan the format string for „%s“ Check if the target is a stack variable © HalVar Flake

static main() { autoFuncAddr, xref; FuncAddr = AskAddr(-1, "Enter address:"); xref = Rfirst(FuncAddr); while(xref != -1) { if(GetMnem(xref) == "call") AuditSprintf(xref); xref = Rnext(FuncAddr, xref); } xref = DfirstB(FuncAddr); while(xref != -1) { if(GetMnem(xref) == "call") AuditSprintf(xref); xref = DnextB(FuncAddr, xref); } Ask auditor to enter the address of the sprintf( ) Call the auditing function once for each call to sprintf( ) Repeat for all indirect calls © HalVar Flake

Hands on: Seeing the script in action Running it against iWS 4.1 SHTML.DLL We feed our script the number 0x The result: This looks as if we can supply a very long string here... © HalVar Flake

Hands on: Seeing the script in action Running it against iWS 4.1 SHTML.DLL The suspicious call the target buffer push and the corresponding register load. © HalVar Flake

Hands on: Seeing the script in action Running it against iWS 4.1 SHTML.DLL... and a target buffer of only 256 bytes... © HalVar Flake

Happy End Why doesn‘t the webserver respond any more ? © HalVar Flake