Tahoo!!

自分の勉強していること(コンピュータ関連 / ネットワーク / セキュリティ / サーバ)や趣味について書いていきます

SECCON Beginners CTF 2019 作問Writeup

今年もSECON BeginnersのOB(?)として、SECCON Beginners CTF 2019の作問とレビューに参加してました。

f:id:takahoyo:20190525161439p:plain

私が作ったのは MiscのDumpで、最終的には163チームに解いてもらい、138ptsの問題でした。

問題解いてくださったみなさま、ありがとうございます。

f:id:takahoyo:20190526150414p:plain

それでは、Dumpについて解説していきたいと思います。

Writeup

まずは file コマンドを使用してファイルの種類を判別。

$ file fc23f13bcf6562e540ed81d1f47710af_dump 
fc23f13bcf6562e540ed81d1f47710af_dump: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 262144)

みんな大好きpcapファイルなので、拡張子に .pcap をつけて Wiresharkで中身を見てみましょう。

Wiresharkでpcapを解析

pcapファイルには2つのHTTPの通信が記録されている。

f:id:takahoyo:20190526172109p:plain

この2つの通信について、WiresharkFollow HTTP Stream 機能を実行してみる。 (Follow TCP Stream を使ってTCPレベルでパケットをreassembleすると、HTTPレスポンスヘッダのTransfer-Encoding: chunked を認識しないためchunkの長さを示すデータが入ってしまう)

1つ目のコネクション

GET /webshell.php?cmd=ls%20%2Dl%20%2Fhome%2Fctf4b%2Fflag HTTP/1.1
Host: 192.168.75.230
User-Agent: curl/7.54.0
Accept: */*

HTTP/1.1 200 OK
Date: Sun, 07 Apr 2019 11:55:16 GMT
Server: Apache/2.4.18 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 130
Content-Type: text/html; charset=UTF-8

<html>
<head>
<title>Web Shell</title>
</head>
<pre>
-rw-r--r-- 1 ctf4b ctf4b 767400 Apr  7 19:46 /home/ctf4b/flag
</pre>
</html>

2つ目のコネクション

GET /webshell.php?cmd=hexdump%20%2De%20%2716%2F1%20%22%2502%2E3o%20%22%20%22%5Cn%22%27%20%2Fhome%2Fctf4b%2Fflag HTTP/1.1
Host: 192.168.75.230
User-Agent: curl/7.54.0
Accept: */*

HTTP/1.1 200 OK
Date: Sun, 07 Apr 2019 11:55:27 GMT
Server: Apache/2.4.18 (Ubuntu)
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

<html>
<head>
<title>Web Shell</title>
</head>
<pre>
037 213 010 000 012 325 251 134 000 003 354 375 007 124 023 133
327 007 214 117 350 115 272 110 047 012 212 122 223 320 022 252
164 220 052 275 051 204 044 100 050 011 044 024 101 120 274 166
244 010 010 050 315 002 110 023 024 244 012 330 005 351 012 012
322 024 245 011 202 205 242 202 212 337 204 216 242 357 175 336
…

これにより以下のことが推測できる。

  • webshell.php というファイル名からWebShellを利用してコマンドを実行
  • パラメータ cmd で指定したコマンドの結果を、<pre>...</pre> に表示
  • 1つ目が ls コマンドの出力結果、2つ目が hexdump コマンドの出力結果

また、cmd パラメータはURLエンコードされていて、2つ目のHTTP通信の cmd パラメータの値をURLデコードすると以下のような文字列となる。

hexdump -e '16/1 "%02.3o " "\n"' /home/ctf4b/flag

このサイトなどを参考にすると、-e オプションで出力するフォーマットを指定していて、8進数で flag ファイルのバイナリをdumpしていることがわかる。

よって、次のような方針で問題を解く。

  • 2つ目の<pre> ... </pre> タブで囲まれた文字列を抽出
  • 8進数でdumpされたデータを変換してバイナリファイルにする

solverを書く

pcapから <pre> ... </pre> の部分を抜き出すのはWiresharkを使用しても良いが、WiresharkCUI版であるtsharkを使用すると簡単に抽出できる。

$ tshark -r fc23f13bcf6562e540ed81d1f47710af_dump.pcap -q -z follow,http,ascii,1

このコマンドをプログラム中から実行し Follow HTTP Stream の結果を加工、バイナリファイルとして保存するsolverを書く。

# -*- coding: utf-8 -*-

import sys
import subprocess
import re

# tsharkの出力結果を読み込み
command = ["tshark","-r","fc23f13bcf6562e540ed81d1f47710af_dump.pcap","-q","-z","follow,http,ascii,1"] 
raw = subprocess.run(command, stdout=subprocess.PIPE, text=True)

# 正規表現とstrip, repalace, split を使用してデータの整形
data = re.findall('<pre>((.|\s)*?)</pre>', raw.stdout)[0][0]
data = data.strip().replace("\n"," ").split(" ")

# 8進数の文字列からbyte型のデータへ変換
res = b""
for d in data:
    res += int(d,8).to_bytes(1,"little")

# 変換したデータをファイルに書き込み
with open("flag.bin","wb") as f:
    f.write(res)

出力したファイルの種類を調べる

file コマンドで出力したファイルの種類を調べる。

$ file .flag.bin
flag.bin: gzip compressed data, last modified: Sun Apr  7 10:46:34 2019, from Unix, original size 798720

tar.gz 形式のファイルなので、tar コマンドを実行して展開。

$ tar xzvf flag.bin
x ./._flag.jpg
x flag.jpg

flag.jpgにFLAG

f:id:takahoyo:20190331150520j:plain

ctf4b{hexdump_is_very_userful}

ちなみに、これは今年の4月に上野公園で撮影した桜の写真です。 あとで気づいたのですが、撮影に使用したカメラやレンズ、現像ソフトウェアの情報を消し忘れたので、exiftool 等を使うと私の撮影環境ががわかります(誰得…

おわりに

この問題は、何らかの方法で攻撃者がWebサーバ上にWebShellを設置、そのWebShellを使って外部に情報を持ち出すというシナリオを想定して作りました。 ただ、実際の攻撃の通信は暗号化や難読化されていて、パケット解析とスクリプト作成で持ち出された情報を復元するのは一筋縄では行かないかもしれません。

近年のCTFではパケットを読むような問題はほとんど出ませんが、パケット解析スキルやスクリプト作成スキルはCTF(や、ITエンジニアのお仕事)をやる上で知っておいた方が良いベーシックスキルの一つだと思います。今回の問題が参加されたみなさまのパケット解析スキルやスクリプト作成スキルの向上に少しでもお役に立てていれば幸いです。