Week 3

Format Strings

Good Faith Policy

“These courses expects a high standard of professionalism from its students with regard to how security testing is conducted. We expect all students to act in good faith at all times […]”

TL;DR Don’t be mean

https://sec.edu.au/good-faith-policy

cdecl, again

mycoolfunc(arg1, arg2, arg3);
                               | 0xFF
push arg3                      |      arg3
push arg2                      |      arg2
push arg1                      |      arg1
call mycoolfunc                |      ret_addr  <-- esp
                               | 0x00

Format Strings

Used in C library functions

  • [s,sn,v,va,...]printf
  • [s,sn,v,va,...]scanf
  • etc

printf(format, ...vargs)

 

printf("%s world!", "hello");

 

printf("👋 🌏!");

Format Specifier

%<flags><width><precision><modifier><type>

  • %s - print as string
  • %x - print as hex
  • %p - print as pointer
  • %c - print as char
  • %d - print as (signed) int
  • %u - print as (unsigned) int
  • %n - write the number of printed bytes…

%<flags><width><precision><modifier><type>

  • %d - print as (signed) int

  • %hd - print as half (signed) int

  • %hhd - print as half half (signed) int

  • %n - write as int

  • %hn - write as half int

  • %hhn - write as half half int

%<flags><width><precision><modifier><type>

 
Output maximum limit  

printf("%.3s", "abcdef");

$> "abc"
printf("%.5f", 4 * 1.0 / 3);

$> 1.33333

%<flags><width><precision><modifier><type>

 
Output minimum limit  

printf("%d", 10);

$> 10
printf("%5d", 10);

$>    10
printf("%10d", 10);

$>         10

%<flags><width><precision><modifier><type>

 
Modifiers, eh.  

  • - - Left-align the output
  • + - Prepends a plus for +ve signed-numeric types
  • - Prepends a space for +ve signed-numeric types
  • 0 - Prepends zeros
  • ' - Show thousandths separators
  • # - misc.

jks one more

%<parameter><flags><width><precision><modifier><type>

 
Allows you to specify a certain index from the vargs.
 

%<idx>$...

printf("%3$c %1$s %2$d", "string", 50, 'c')

$> c string 50

Format String Vulnerabilities

What if you don’t provide any arguments?

printf("%d %d %d %d %s")
  • Responsibility of the caller to push the relevant data
  • Program will just grab items off the stack

Read Primitive

For numbers…

  • %d will read the next item on the stack
  • %20$d will read the 20th item from the stack

For hex…

  • %p will read the next item on the stack
  • %20$p will read the 20th item from the stack

For addresses…

  • %s will read the next item (as a pointer) on the stack
  • %20$s will read the 20th item (pointer) on the stack

Demo: ./leakValues

Your C code may not reflect the correct order of function locals (bc compiler optimisations)

Demo: ./varOrder

Write Primitive

%n format specifier

Writes the number of printed bytes to the next item (pointer) on the stack

 

%7$n format specifier

Writes the number of printed bytes to the seventh item (pointer) on the stack

Alignment

Sometimes our values aren’t aligned to the 4-byte boundary. We just need to pad our values then :)

Demo: ./printfRunner

Demo: ./setValue

TL;Dr

  • If our address is on the stack, we can read and write from that address
  • If our format specifier buffer is on the stack, we can read and write from addresses in the buffer

i.e. write 0xdeadbeef into our buffer, then write into that address

  • Find our buffer region (relative the format string)
  • Pad the payload (if needed)
  • Write the 4-byte address(es)
  • Write bytes (... or %...$c)
  • Write into the address (%...$n / hn / hhn)

Write Optimisation

  • Write one 4-byte value (max = 2^32 = 4,294,967,296)
  • Write two 2-byte values (max = 2 x 2^16 = 131,072)
  • Or… write four 1-byte values (max = 4 x 2^8 = 1024)

Craft your write payload wisely!
Sometimes you don’t have alot of buffer space

Demo: ./setValueBig - better-ish

Demo: ./setValueBig - better

Where Write?

  • Variables
  • PLT / GOT (dynamic library function calls)
  • Function hooks (malloc hook, free hook, __atexit)

GOT

GOT - Global Offset Table
PLT - Process Linkage Table

  • Calls to library functions go through a redirection.
  • Entries in the GOT are unset until first called
    • They initially point to some lookup handler
      • The lookup handler replaces the uninitialised value with the correct address
  • got command - shows all of the linkable functions
  • vmmap command - shows all the memory regions
    • useful for figuring out offsets later on

Memory Protection

  • Memory Corruption
    • stack reordering
    • random padding
    • stack canaries
    • FORTIFY
    • RELRO
  • Post-corruption code execution
    • ASLR + PIE
    • NX
    • PAC
    • Hypervisor
  • PIE - Program can only contain relative jumps

    • Requires ASLR to be on
  • FORTIFY - Stop string vulnerabilities

    • Disables %n if the fmtstr is in writeable memory
  • RELRO - Relocation Read-Only

    • GOT is read-only
    • Partial - GOT appears before BSS (globals)
    • Full RELRO - rip.

General Pointer Addresses

  • 0x565 - Binary base with PIE enabled
  • 0x804 - Binary base with PIE disabled
  • 0xf7f - Library base
  • 0xff.. - Stack base

Activities

Lab 3: ./format_prac

also, wargames 2 are due tonight at 5.59pm!

Home