Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

8 Commits

Repository files navigation

Security bn0

Overview

I exploited a Format String Vulnerability in the clawdbot application to give me root priviledges, exploiting the "channeling project" discussed on the PDF given on the lessons website.. By providing a malicious format string as input, I was able to trick the printf function into writing an arbitrary value (the address of a backdoor function) to an arbitrary memory location (a global function pointer).

Finding the vulnerability

  • Firstly it was pretty evident by looking at the clawdbot.c code that the main function uses sprintf to format a message buffer with user input and then calls "printf(message);". Because the first argument to printf is user-controlled and lacks a static format specifier (like "%s"), it is vulnerable.I also saw the function "void all_your_base_are_belong_to_us()", which is like the "thank_you" functions we saw that give us root access.
  • To find the buffer's position on the stack, I used the technique from the paper. I ran: clawdbot 'AAAABBBB.%08x.%08x.%08x.%08x.%08x.%08x'.The output returned 41414141 (hex for AAAA) as the 4th value. This confirmed a stack offset of 4
  • To verify control, I used the $ qualifier: clawdbot 'AAAA%4$x'. This successfully printed "Prompt received: AAAA41414141!", proving I could directly address my input.

Write-What-Where

To get control of the execution flow, I needed to identify what to write and where to write it.

  • What: As i said in the .c file i found that "thank_you" function that spawns a root shell. I found its address using ```bash bot@9454b82fc4e6:/sbin$ nm clawdbot | grep "all_your" 08049c6d T all_your_base_are_belong_to_us

- WHere: I identified a global function pointer named process that is called immediately after the vulnerable printf - unfortunately didnt have time to think something else so i used process() :)
```bash
bot@9454b82fc4e6:/sbin$ nm clawdbot | grep "process"
0804e044 D process

Exploiting with the payload

  • To achieve arbitrary code execution, I constructed a payload in Python that utilizes the Short Write technique from the paper to overwrite the process function pointer.
  • To overwrite the 4-byte process pointer, I had to provide two target addresses at the beginning of my payload: the base address of the pointer and the base address plus two bytes. I used struct.pack() to "pack" these into raw bytes that the CPU can read from the stack. Because my target value for the high bits 0x0804 is smaller than the low bits 09c6d, I placed the address for the high bits first in the buffer to ensure the printf counter only increases.
  • I used the %hn specifier, which writes the total number of characters printf has printed so far into a memory address. I treated printf as having an internal counter that I could manipulate using %u. The program's source code shows that a static prefix "Prompt received: " (17 characters) is printed before our input even begins. Combined with the 8 bytes of raw addresses I placed at the start of the buffer, the internal counter starts at 25 (17 + 8)
  • To write the high bits 0804, I subtracted the current counter from the target: 2052 - 25 = 2027. By adding %2027u to the payload, the counter hits 2052, and %4$hn writes that value to the first address.
  • To reach the low bits 0x9c6d (40045), I added more padding: 40045 - 2052 = 37993. Adding %37993u brings the counter to 40045, and %5$hn writes it to the second address.

Finally

The final exploit.py script automates this logic, using Direct Parameter Access ($) to jump straight to the addresses at stack offsets 4 and 5

Successful invocation

Demo

About

Found and exploited a format-string vulnerability in a dockerized service to gain arbitrary memory read/write and spawn a root shell via an automated Python exploit.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages