-
-
[原创] 杭电hgame2021 week1 writeup
-
发表于: 2021-5-27 12:52 14565
-
http请求头,按照每一步提示增加项
f12在调试器中查看project.js,搜索1999
http请求走私
和宝藏走私者一样的考点
主要加密流程如上,写出正向代码,然后对着逆
签到题,就是一个异或
简单的python字节码,对照官方文档写出源码,然后逆
这几道pwn题都非常有意思,虽然考的都是栈溢出、格式化字符串,但是都有一些有趣的细节
签到题,输入的是数字,要和一个字符串比较,相等就返回shell
通过调试发现字符串参与比较的其实是它的内存地址
那么我们直接输入这个地址就get shell了
week1压轴题,截至目前只有七解
保护全开
首先是要读源码,然后可以发现一个泄露点和一个溢出点和一处格式化字符串漏洞点
其中泄露点虽然不能溢出,但是可以由于printf的\x00才截断的性质,泄露出libc基址,然后调试的时候我们还发现,除了[rbp-0x8]处是canary的值,在栈中还残留着之前函数的canary值,由于canary在一次运行中都一样,所以我们也可以得到canary的值
溢出点就是栈溢出覆盖返回地址,ret2libc
这里的格式化字符串漏洞是个坑点,虽然存在,但经过反复调试发现触发它的条件永远不可能满足,浪费了我好多时间
泄露点+溢出点就可以打通了
然后还是要读源码,得到触发各个漏洞点的条件,也就是第几天要做固定的事
总体流程就是:
首先输入的世界线变化率要与初始世界线变化率的差值小于0.000001,这样我们就满足了 know_true
然后第一天要去神社寻找ibn5100,这样可以触发栈溢出漏洞
第二天和第五天要试试电话烤箱,这样就能够dmail回到第一天
随便挑选一天让桶子入侵SERN,在输入命令那里就是泄露点
所以就是,第一遍泄露出libc,dmail回到第一天,然后第二遍泄露canary,再dmail回到第一天,然后栈溢出ret2libc
要注意的几处细节是,系统环境为ubuntu20.04,其它版本调试时在栈上的libc的偏移会不同(刚开始一直没意识到,最后才反应过来我docker上是ubuntu18,起初怎么打都打不通,浪费了大半天时间),还有就是最后用libc的gadget时,要多一个ret,提高一下栈,使栈对齐
exp如下
保护全关
这道题的考点是atoi函数的漏洞,seccomp的过滤,栈溢出
由于atoi函数的漏洞,当我们输入-1时,既满足了小于15的条件,又让后面申请到的空间达到了0xffffffff,然后栈溢出到shellcode
刚开始因为看到保护全关,以为直接往bss段写system(sh)就行,打了几遍打不通才看到最开始的init函数有seccomp函数过滤,只允许使用write,read,open,那我们利用这三个函数写shellcode把flag内容读出来就行
开启了pie和NX
有栈溢出和格式化字符串漏洞
由于低3位不变的特性,我们栈溢出覆盖返回地址的最低字节就可以使其重复溢出
fmt泄露程序基址和libc基址
最后用onegadget打通
有一点坑人的就是,不知道为什么payload用flat拼接时会多增加了一个字节,所以我就不用flat直接拼接了
前面按流程走,卡人的点在base64解码后的处理,由于flag格式为hgame{},所以可以看出}的位置错了,所以要用栅栏密码,这里还会卡人的点在栅栏之后还要逆序才能是正确的格式,最后凯撒密码解密
xor加密,密钥为16位,且为循环加密,有一个专门的工具可以解出密钥,xortool,xortool得出的密钥有两位字符错误,手动替换后解密多试几次
quipqiup在线网站词频分析就可以得出flag
依次base64,base32,base16
图片藏压缩包,第一层用爆破,第二层用明文攻击,第三层用伪加密,最后得出的编码是html编码
流量分析找到http,然后dump出图片
解压缩第一个文档,里面有个password.xml就是第二个文档的密码,第二个文档有隐藏字符,是个snow加密
GET
/
HTTP
/
1.1
Host: thief.
0727.site
GET
/
secret HTTP
/
1.1
Host:thief.
0727.site
client
-
ip:
127.0
.
0.1
foo:
GET
/
HTTP
/
1.1
Host: thief.
0727.site
GET
/
secret HTTP
/
1.1
Host:thief.
0727.site
client
-
ip:
127.0
.
0.1
foo:
import
requests
import
json
from
bs4
import
BeautifulSoup
from
sympy
import
*
numArr
=
[
"0"
,
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
,
"-"
,
"+"
]
def
scan(str1):
newStr
=
""
for
x
in
range
(
0
,
len
(str1)):
if
str1[x]
in
numArr:
newStr
+
=
str1[x]
return
newStr
def
getQ(session
=
"session=eyJzb2x2aW5nIjoxfQ.YBfJbQ.L2PH1NyDzVTQcjiJjLR5lqeU4cw"
):
headers
=
{
"Cookie"
:session}
res
=
requests.get(url
=
"http://r4u.top:5000/api/getQuestion"
,headers
=
headers)
return
json.loads(res.text)
#q = getQ()
def
anaylaze(q):
q
=
q[
'question'
]
soup
=
BeautifulSoup(q,
"lxml"
)
xiaxian
=
soup.msubsup.mo.next_sibling
shangxian
=
soup.msubsup.mo.next_sibling.next_sibling
a
=
soup.math.mn
a
=
a.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element
b
=
soup.math.mn.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element
fuhao
=
soup.math.mn.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element
return
[
int
(scan(
str
(xiaxian))),
int
(scan(
str
(shangxian))),
int
(scan(
str
(a))),scan(
str
(fuhao)),
int
(scan(
str
(b)))]
#print(anaylaze(q))
def
calc(arr):
print
(arr)
x
=
symbols(
'x'
)
if
arr[
3
]
=
=
"+"
:
answer
=
integrate(arr[
2
]
*
x
+
arr[
4
], (x, arr[
0
], arr[
1
]))
else
:
answer
=
integrate(arr[
2
]
*
x
-
arr[
4
], (x, arr[
0
], arr[
1
]))
return
(
round
(answer,
2
))
#answer = calc(anaylaze(q))
def
submit(answer,cookie
=
"session=eyJzb2x2aW5nIjoxfQ.YBfJbQ.L2PH1NyDzVTQcjiJjLR5lqeU4cw"
):
data
=
'{"answer":'
+
str
(answer)
+
'}'
print
(data)
headers
=
{
"Cookie"
:cookie,
"Content-Type"
:
"application/json;charset=UTF-8"
}
res
=
requests.post(url
=
"http://r4u.top:5000/api/verify"
,data
=
data,headers
=
headers)
print
(res.text)
newCookie
=
res.headers[
'Set-Cookie'
]
print
(newCookie)
return
newCookie
#submit(answer)
def
run(cookie):
q
=
getQ(cookie)
answer
=
calc(anaylaze(q))
cookie
=
submit(answer,cookie)
run(cookie)
run(
"session=eyJzb2x2aW5nIjozfQ.YBfbuQ.R7aqFFYJmRgJ7FITfhRqfCKPNCg"
)
import
requests
import
json
from
bs4
import
BeautifulSoup
from
sympy
import
*
numArr
=
[
"0"
,
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
,
"-"
,
"+"
]
def
scan(str1):
newStr
=
""
for
x
in
range
(
0
,
len
(str1)):
if
str1[x]
in
numArr:
newStr
+
=
str1[x]
return
newStr
def
getQ(session
=
"session=eyJzb2x2aW5nIjoxfQ.YBfJbQ.L2PH1NyDzVTQcjiJjLR5lqeU4cw"
):
headers
=
{
"Cookie"
:session}
res
=
requests.get(url
=
"http://r4u.top:5000/api/getQuestion"
,headers
=
headers)
return
json.loads(res.text)
#q = getQ()
def
anaylaze(q):
q
=
q[
'question'
]
soup
=
BeautifulSoup(q,
"lxml"
)
xiaxian
=
soup.msubsup.mo.next_sibling
shangxian
=
soup.msubsup.mo.next_sibling.next_sibling
a
=
soup.math.mn
a
=
a.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element
b
=
soup.math.mn.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element
fuhao
=
soup.math.mn.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element.next_element
return
[
int
(scan(
str
(xiaxian))),
int
(scan(
str
(shangxian))),
int
(scan(
str
(a))),scan(
str
(fuhao)),
int
(scan(
str
(b)))]
#print(anaylaze(q))
def
calc(arr):
print
(arr)
x
=
symbols(
'x'
)
if
arr[
3
]
=
=
"+"
:
answer
=
integrate(arr[
2
]
*
x
+
arr[
4
], (x, arr[
0
], arr[
1
]))
else
:
answer
=
integrate(arr[
2
]
*
x
-
arr[
4
], (x, arr[
0
], arr[
1
]))
return
(
round
(answer,
2
))
#answer = calc(anaylaze(q))
def
submit(answer,cookie
=
"session=eyJzb2x2aW5nIjoxfQ.YBfJbQ.L2PH1NyDzVTQcjiJjLR5lqeU4cw"
):
data
=
'{"answer":'
+
str
(answer)
+
'}'
print
(data)
headers
=
{
"Cookie"
:cookie,
"Content-Type"
:
"application/json;charset=UTF-8"
}
res
=
requests.post(url
=
"http://r4u.top:5000/api/verify"
,data
=
data,headers
=
headers)
print
(res.text)
newCookie
=
res.headers[
'Set-Cookie'
]
print
(newCookie)
return
newCookie
#submit(answer)
def
run(cookie):
q
=
getQ(cookie)
answer
=
calc(anaylaze(q))
cookie
=
submit(answer,cookie)
run(cookie)
run(
"session=eyJzb2x2aW5nIjozfQ.YBfbuQ.R7aqFFYJmRgJ7FITfhRqfCKPNCg"
)
v6l
=
[
0x9E3779B9
,
0x3C6EF372
,
0xDAA66D2B
,
0x78DDE6E4
,
0x1715609D
,
0xB54CDA56
,
0x5384540F
]
v7l
=
[
0x278DDE6E
,
0xF1BBCDC
,
0x36A99B4A
,
0x1E3779B9
,
0x5C55827
,
0x2D533695
,
0x14E11503
]
key
=
[
1
,
2
,
3
,
4
]
flag
=
[
0xE74EB323
,
0xB7A72836
,
0x59CA6FE2
,
0x967CC5C1
,
0xE7802674
,
0x3D2D54E6
,
0x8A9D0356
,
0x99DCC39C
,
0x7026D8ED
,
0x6A33FDAD
,
0xF496550A
,
0x5C9C6F9E
,
0x1BE5D04C
,
0x6723AE17
,
0x5270A5C2
,
0xAC42130A
,
0x84BE67B2
,
0x705CC779
,
0x5C513D98
,
0xFB36DA2D
,
0x22179645
,
0x5CE3529D
,
0xD189E1FB
,
0xE85BD489
,
0x73C8D11F
,
0x54B5C196
,
0xB67CB490
,
0x2117E4CA
,
0x9DE3F994
,
0x2F5AA1AA
,
0xA7E801FD
,
0xC30D6EAB
,
0x1BADDC9C
,
0x3453B04A
,
0x92A406F9
]
''' 正向加密代码
flag = b'hgame{aaaaaaaaaaaaaaaaaaaaaaaaaaaa}'
flag = list(flag)
v5 = flag[34]
for i in range(7):
for j in range(34):
v5 = flag[j] + ((((v5 >> 5) ^ (4 * flag[j + 1])) + ((16 * v5) ^ (flag[j + 1] >> 3))) ^ ((key[ (j ^ v7l[i] ) & 3 ] ^ v5) + (flag[j + 1] ^ v6l[i])))
v5 &= 0xffffffff
flag[j] = v5
v5 = flag[34] + (((key[(34 ^ v7l[i]) & 3] ^ v5) + (flag[0] ^ v6l[i])) ^ (((4 * flag[0]) ^ (v5 >> 5)) + (((16 * v5) ^ (flag[0] >> 3))&0xffffffff)))
v5 &= 0xffffffff
flag[34] = v5
'''
for
x
in
range
(
7
):
i
=
6
-
x
v5
=
flag[
34
]
flag[
34
]
=
v5
-
((((key[(
34
^ v7l[i]) &
3
] ^ flag[
33
])
+
(flag[
0
] ^ v6l[i])) ^ (((
4
*
flag[
0
]) ^ (flag[
33
] >>
5
))
+
((
16
*
flag[
33
]) ^ (flag[
0
] >>
3
))))&
0xffffffff
)
flag[
34
]&
=
0xffffffff
for
y
in
range
(
34
):
j
=
33
-
y
v5
=
flag[j]
flag[j]
=
v5
-
(((((flag[j
-
1
] >>
5
) ^ (
4
*
flag[j
+
1
]))
+
((
16
*
flag[j
-
1
]) ^ (flag[j
+
1
] >>
3
))) ^ ((key[ (j ^ v7l[i] ) &
3
] ^ flag[j
-
1
])
+
(flag[j
+
1
] ^ v6l[i])))&
0xffffffff
)
flag[j]&
=
0xffffffff
if
(j
=
=
0
):
flag[j]
=
v5
-
(((((flag[
34
] >>
5
) ^ (
4
*
flag[j
+
1
]))
+
((
16
*
flag[
34
]) ^ (flag[j
+
1
] >>
3
))) ^ ((key[ (j ^ v7l[i] ) &
3
] ^ flag[
34
])
+
(flag[j
+
1
] ^ v6l[i])))&
0xffffffff
)
flag[j]&
=
0xffffffff
print
(bytes(flag))
v6l
=
[
0x9E3779B9
,
0x3C6EF372
,
0xDAA66D2B
,
0x78DDE6E4
,
0x1715609D
,
0xB54CDA56
,
0x5384540F
]
v7l
=
[
0x278DDE6E
,
0xF1BBCDC
,
0x36A99B4A
,
0x1E3779B9
,
0x5C55827
,
0x2D533695
,
0x14E11503
]
key
=
[
1
,
2
,
3
,
4
]
flag
=
[
0xE74EB323
,
0xB7A72836
,
0x59CA6FE2
,
0x967CC5C1
,
0xE7802674
,
0x3D2D54E6
,
0x8A9D0356
,
0x99DCC39C
,
0x7026D8ED
,
0x6A33FDAD
,
0xF496550A
,
0x5C9C6F9E
,
0x1BE5D04C
,
0x6723AE17
,
0x5270A5C2
,
0xAC42130A
,
0x84BE67B2
,
0x705CC779
,
0x5C513D98
,
0xFB36DA2D
,
0x22179645
,
0x5CE3529D
,
0xD189E1FB
,
0xE85BD489
,
0x73C8D11F
,
0x54B5C196
,
0xB67CB490
,
0x2117E4CA
,
0x9DE3F994
,
0x2F5AA1AA
,
0xA7E801FD
,
0xC30D6EAB
,
0x1BADDC9C
,
0x3453B04A
,
0x92A406F9
]
''' 正向加密代码
flag = b'hgame{aaaaaaaaaaaaaaaaaaaaaaaaaaaa}'
flag = list(flag)
v5 = flag[34]
for i in range(7):
for j in range(34):
v5 = flag[j] + ((((v5 >> 5) ^ (4 * flag[j + 1])) + ((16 * v5) ^ (flag[j + 1] >> 3))) ^ ((key[ (j ^ v7l[i] ) & 3 ] ^ v5) + (flag[j + 1] ^ v6l[i])))
v5 &= 0xffffffff
flag[j] = v5
v5 = flag[34] + (((key[(34 ^ v7l[i]) & 3] ^ v5) + (flag[0] ^ v6l[i])) ^ (((4 * flag[0]) ^ (v5 >> 5)) + (((16 * v5) ^ (flag[0] >> 3))&0xffffffff)))
v5 &= 0xffffffff
flag[34] = v5
'''
for
x
in
range
(
7
):
i
=
6
-
x
v5
=
flag[
34
]
flag[
34
]
=
v5
-
((((key[(
34
^ v7l[i]) &
3
] ^ flag[
33
])
+
(flag[
0
] ^ v6l[i])) ^ (((
4
*
flag[
0
]) ^ (flag[
33
] >>
5
))
+
((
16
*
flag[
33
]) ^ (flag[
0
] >>
3
))))&
0xffffffff
)
flag[
34
]&
=
0xffffffff
for
y
in
range
(
34
):
j
=
33
-
y
v5
=
flag[j]
flag[j]
=
v5
-
(((((flag[j
-
1
] >>
5
) ^ (
4
*
flag[j
+
1
]))
+
((
16
*
flag[j
-
1
]) ^ (flag[j
+
1
] >>
3
))) ^ ((key[ (j ^ v7l[i] ) &
3
] ^ flag[j
-
1
])
+
(flag[j
+
1
] ^ v6l[i])))&
0xffffffff
)
flag[j]&
=
0xffffffff
if
(j
=
=
0
):
flag[j]
=
v5
-
(((((flag[
34
] >>
5
) ^ (
4
*
flag[j
+
1
]))
+
((
16
*
flag[
34
]) ^ (flag[j
+
1
] >>
3
))) ^ ((key[ (j ^ v7l[i] ) &
3
] ^ flag[
34
])
+
(flag[j
+
1
] ^ v6l[i])))&
0xffffffff
)
flag[j]&
=
0xffffffff
print
(bytes(flag))
raw_flag
=
''
cipher
=
list
((raw_flag[
6
:
-
1
]))
length
=
len
(cipher)
for
i
in
range
(length
/
/
2
):
cipher[
2
*
i],cipher[
2
*
i
+
1
]
=
cipher[
2
*
i
+
1
],cipher[
2
*
i]
res
=
[]
for
i
in
range
(length):
res.append(
ord
(cipher[i])^i)
res
=
bytes(res).
hex
()
res
=
b
'30466633346f59213b4139794520572b45514d61583151576638643a'
raw_flag
=
''
cipher
=
list
((raw_flag[
6
:
-
1
]))
length
=
len
(cipher)
for
i
in
range
(length
/
/
2
):
cipher[
2
*
i],cipher[
2
*
i
+
1
]
=
cipher[
2
*
i
+
1
],cipher[
2
*
i]
res
=
[]
for
i
in
range
(length):
res.append(
ord
(cipher[i])^i)
res
=
bytes(res).
hex
()
res
=
b
'30466633346f59213b4139794520572b45514d61583151576638643a'