Jump to content

0x01脆弱性はじめに

dolibarr erp crm=15.0.3は、評価注入に対して脆弱です。デフォルトでは、任意の管理者をdolibarrのインストールページに追加でき、正常に追加された場合、悪意のあるコードをデータベースに挿入してから、評価によって実行できます。

CVE番号:CVE-2022-2633

脆弱性の説明:dolibarr edit.phpには、リモートコマンド実行の脆弱性があります。攻撃者が論理的な脆弱性を通じて管理者を作成した後、バックグラウンドの脆弱性を介してサーバーの権限を取得できます。

影響を受けるバージョン:=15.0.3

0x02脆弱性分析

1.環境構造

ソースコードダウンロードアドレス:3https://github.com/dolibarr/dolibarr/archive/refs/tags/15.0.3.zip

それをWebディレクトリに解凍して直接アクセスする〜/htdocs/

image-20221112215135292

次に、インストールするようにconf/conf.phpを構成します

2。管理者ユーザーを登録

これは実際には論理的な脆弱性です。システムをインストールした後、ロックしませんが、ユーザーがドキュメントディレクトリに手動で追加する必要があるため、管理者アカウントを追加するためにいつでも入力できます。

たとえば、ここにAAAユーザーを追加します

image-20221112224440198

背景を正常に入力できます

image-20221112224514801

3.BackEnd RCE

バックグラウンドRCEの最後のポイントは、htdocs/core/lib/functions.lib.phpのdol_eval()関数にあります

しかし、ここにはWAFがあり、危険な機能のほとんどは禁止されています

//PHP execまたはPHPファイル機能の使用をブロックします

$ forbiddenphpstrings=array( '$$');

$ FORBIDDENPHPSTRINGS=ARRAY_MERGE($ FORBIDDENPHPSTRINGS、ARRAY( '_ 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', 'fpassthru', 'require', 'include', 'mkdir', 'rmdir', 'symlink', 'touch', 'unlink', 'umask'));

$ forbiddenphpfunctions=array_merge($ forbiddenphpfunctions、array( 'function'、 'call_user_func'));

$ forbiddenphpregex='global \ s+\ $ | \ b('。prode( '|'、$ forbiddenphpfunctions)。 ')\ 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 and $ mycall-mythod(

} while($ oldstringtoclean!=$ s);

if(strpos($ s、 '__forbiddenstring__')!==false){

dol_syslog( 'bad string syntax to Evaluate3:'。$ s、log_warning);

if($ returnValue){

'bad string構文を返して、'を評価します。$ s;

} それ以外{

dol_syslog( 'bad string syntax to Evaluate:'。$ s);

戻る '';

}

}

//$ s.'br \ n 'を印刷します。

if($ returnValue){

if($ hiderrors){

return @eval( 'return'。$ s。 ';');

} それ以外{

return eval( 'return'。$ s。 ';');

}

} それ以外{

if($ hiderrors){

@eval($ s);

} それ以外{

eval($ s);

}

}

ここでは、dol_eval()の呼び出しを探し、上記のverifcond()が呼び出されます

そして、ここにスプライシングがあり、これについては後で説明します。

関数verifcond($ stroevaluate)

{

グローバル$ユーザー、$ conf、$ langs;

グローバル$ leftmenu;

グローバル$ rights; //dol_eval関数にエクスポートします

//$ strtoevaluate.'br \ n ';

$ rights=true;

if(ISSET($ sttoevaluate)$ stroevaluate!==''){

$ str='if(!('。$ sttoevaluate。 '))$ rights=false;';

dol_eval($ str、0、1、 '2');

}

$ rightsを返します。

}

次に、Verifcond関数のグローバルパラメーター制御可能な呼び出しを探します。 menubase.class.phpのmenuload()関数にポイントがあります。

image-20221112232201159

Verifcondコードは制御可能ですが、データベースのクエリ結果から取得されることがわかります。

パームと有効化に注意してください。どちらも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)。 ''、 'all')

したがって、「.main_db_prefix」に挿入ステートメントを見つけることができる場合。メニューでは、パームを制御し、フィールドとエンティティとmenu_handlerを有効にして、条件を満たすことができます。エンティティは$ conf-entityから来ていることに注意してください

$ sql='Select 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.Leftmenu、M.Position';

$ sql。='from' .main_db_prefix.'menu as m ';

$ sql。='ここで、m.entity in(0、'。$ conf-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()関数、そのような点があります。

image-20221113000249851

次に、パラメーターが制御可能かどうかを確認する必要があります。ここの値はメンバー属性として設定されますが、エンティティは$ conf-entityであり、上記のSQLクエリもこれであるため、条件を直接満たします。

image-20221113001946769

次に、menuload関数を実行するときにmenu_handlerが自動的に入力されることがわかりました。

image-20221113002330295

したがって、両方の条件が解決された場所。残りは、パーマとイネーブルが制御されているかどうかを確認することです。クラス内のメンバー変数を割り当てる場所はないため、グローバルに検索する必要があります。

メニュー/edit.phpでパーマとイネーブルを直接制御できることがわかります

image-20221113002856865

デバッグ後、MenuIDは一意である必要があることがわかりました。そうしないと、競合し、データベースに書き込むことができません。ここでのタイプは1に設定する必要があります。そうしないと、エラーが報告されます。

1049983-20221114122937786-1858356172.png

次に、WAFをバイパスしてevalを実行する方法を研究します。ここで、著者のアプローチは、PHP:変数関数の特性を使用することです

//file_put_contents

$ a=base64_decode( 'zmlszv9wdxrfy29udgvudhm=');

//shellcode

$ a( '。1234.php'、base64_decode( 'pd9wahagcghwaw5mbygpoz8+cg=='));

Verifcond関数を見る

これが文字列のスプライシングです。 evalが実行されているため、ブラケットを閉じて次のコードをコメントすることができます。

関数verifcond($ stroevaluate)

{

グローバル$ユーザー、$ conf、$ langs;

グローバル$ leftmenu;

グローバル$ rights; //dol_eval関数にエクスポートします

//$ strtoevaluate.'br \ n ';

$ rights=true;

if(ISSET($ sttoevaluate)$ stroevaluate!==''){

$ str='if(!('。$ sttoevaluate。 '))$ rights=false;';

dol_eval($ str、0、1、 '2');

}

$ rightsを返します。

}

これはそのようなペイロードです(無害なペイロード

1==1)

次に、有効なパラメーターを配置してデータベースに保存すると、最終的にパッケージは次のとおりです。

image-20221113004416906

データベースに正常に保存されます

image-20221113004508666

デバッグしてVerifcondを入力します

image-20221113004645570

Verifcond、悪意のあるコンストラクトステッチバイパスでフォローアップ、Dol_Evalを入力します

image-20221113004826342

コード実行に正常に

image-20221113004918701

成功したけいれん

image-20221113005123697

脆弱性コールスタック

image-20221113004952924

0x03脆弱性の概要

ここでのこのRCEの脆弱性の原則は、実際には二次注射に似ています。まず、悪意のあるコードがデータベースに保存され、次にデータベースからデータを抽出するときに悪意のあるコードがトリガーされます。ここでもWAFがバイパスされ、PHP機能——変数関数を使用します

脆弱性修正

ここでは、著者の脆弱性に対する修正は、Verifcond関数を強化することです

ここで、文字列のスプライシングがキャンセルされ、dol_evalの4番目のパラメーターは「1」です

image-20221113010538177

これは、次の判断になります。ここでのコメントを見てください。ここのルールは、RCEを防ぐように設計されています。

image-20221113011151428

1つは、DOL_EVAL関数の強化です。ここで、ForbiddenPhpFunctionsはVerifcond関数を追加します。これはVerifcondの実行を直接禁止しますが、このHHHの意味がわかりません

image-20221113010132703

著者:Huamang

元のテキスト接続から転載:https://blog.huamang.xyz/post/cve-2022-40871/

0 Comments

Recommended Comments

There are no comments to display.

Guest
Add a comment...