codezen.fr code hacking, zen coding

2May/12Off

PlaidCTF 2012 – Pwnables 300 – Chest Writeup

Posted by aXs

Robots are running secret service that aims to mill down diamonds into fairy dust, and use it to take over our world! Help us please!
23.22.1.14:1282

In this challenge we have a telnet interface to a nice chest that can store an item, remove an item or view the list of stored items.

Welcome to the Adventurers' storage room!
If you don't yet have a personal chest, you can use this one: XXXXFJ4bO1
Which chest to you wish to access? [XXXXFJ4bO1]:
Using chest XXXXFJ4bO1

What do you want to do?

[1] View items
[2] Store an item
[3] Take an item
[4] Leave
[5] Destroy the chest
> Choose an option:

After disassembling the binary, we see that there is a format string vulnerability in the "View items" function.

  do
  {
    v0 = sub_8048C7B(dword_804AC90, &v2, 499, 0);
    dprintf(fd, (const char *)&v2);
  }

The name of the item is used as format to dprintf. So easy right ? Not so fast...

There is a function that filter heavily user input based on a whitelist:

  n = strspn(src, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&-+ ");

The percent character is of course not whitelisted so we cannot send a format string.

To exploit this vulnerability, we need to combine it with another design conception error: when you connect to the service, you can input the name of the chest you want to open.

The error is that if you connect simultaneously 2 clients, ask both clients to open the same chest and use the destroy chest function in one client, the other client will malfunction in a very interesting way.

Rember this read loop for viewing the items ?

  do
  {
    v0 = sub_8048C7B(dword_804AC90, &v2, 499, 0);
    dprintf(fd, (const char *)&v2);
  }
...
int __cdecl sub_8048C7B(int fd, void *a2, int a3, char a4)
{
  char v4; // al@3
  char v5; // al@7
  void *buf; // [sp+28h] [bp-10h]@1
  ssize_t v8; // [sp+2Ch] [bp-Ch]@2

  buf = a2;
  do
  {
    v5