Writeup memo Pretty Raw (Forensics150) [SharifCTF 7]

SharifCTF 7の Pretty Raw (Forensics150) のWriteupメモ

http://ctf.sharif.edu/ctf7/

  • 問題文

Pretty Raw

What is this file?

http://ctf.sharif.edu/ctf7/api/download/17

  • ファイルを確認
$ file pretty_raw
pretty_raw: data
$ strings pretty_raw
---------------------------
IHDR
PLTELiq
1yy>
(略)
)+0IDBVG?KMQSajO{
IDATx
8/Sd
(略)
\70S
0r\o
IEND
---------------------------

IHDRとかIDATとかIENDとかあるのでPNGファイルが隠れているものと想定。

  • binwalkで確認。
$ binwalk pretty_raw

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
116254        0x1C61E         PNG image, 1434 x 1060, 8-bit colormap, non-interlaced
  • foremostでファイルを抜き出し。
$ foremost pretty_raw
Processing: pretty_raw
|*|

output ディレクトリにファイルが生成される。

$ find output/
output/
output/audit.txt
output/png
output/png/00000227.png

PNGファイル抜き出し。

  • ファイルを見てみる。

f:id:sh1njp:20161219025251p:plain

flag.pngをexiftoolで見た結果の画像ファイル?

1570×74ピクセルのflag.pngというのがflagらしい。横長い画像。

foremostで出てきたPNGファイルがflagというわけではない。

f:id:sh1njp:20161219023728p:plain

下の方のノイジーなのが、PNGファイルで、上の方は黒(00)が多い。 何かしら前半のデータから、画像を生成するものと想定する。

  • hexdumpで眺める。
$ hexdump -v pretty_raw
0000000 0000 0000 0000 0000 0000 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
0000030 0000 0000 0000 0000 0000 0000 0000 0000
0000040 0000 0000 0000 0000 0000 0000 0000 0000
(略)
0002570 0000 0000 0000 0000 0000 0000 061b 1e1e
0002580 1e1e 141e 0000 0000 0000 0000 0000 0000
0002590 0000 0000 0000 0000 0000 1d08 1e06 1e1e
00025a0 1e1e 1e1e 1e1e 1e1e 0001 0000 0000 0000
00025b0 0000 0000 0000 0000 0000 0700 0302 1e09
(略)

なんとなく画像に見えてきたので(?)、PNGファイルのあった 116254 より前を切り出し。

$ dd if=pretty_raw count=116253 bs=1 of=pretty_raw_first.bin
116253+0 レコード入力
116253+0 レコード出力
116253 bytes (116 kB, 114 KiB) copied, 0.217263 s, 535 kB/s
  • 文字数をカウント

hexdumpの出力結果のアドレス部・空白・改行を除いてカウント。

hexdump -v pretty_raw_first.bin | cut -c8- | tr -d '\n' | tr -d ' ' | wc
      0       1  232508

⇒ 232508文字

  • 最初に抜き出したPNGファイルの情報のflag.pngの縦の「74」で割り算してみる
$ python
>>> 232508/74
3142
>>> 3142/2
1571
>>>

3140×74 (1570×2×74)となりそう。2文字=1ピクセルの画像。

  • 3140行毎に改行入れたテキストの出力
hexdump -v pretty_raw_first.bin | cut -c8- | tr -d '\n' | tr -d ' ' | nkf -f3140-0 > flag.txt

テキストエディタで、flag.txt を見てみる。

f:id:sh1njp:20161219023746p:plain

(長い)

  • ImageMagickでテキスト(flag.txt)を画像(flag.png)に画像にしてみる。
$ convert -pointsize 2 label:@flag.txt flag.png

ImageMagickの/etc/ImageMagick-6/policy.xmlで一時的に@を許可して実行しています。

$ cat -n /etc/ImageMagick-6/policy.xml
----------------------------------------------------------------------
    68    <!-- policy domain="path" rights="none" pattern="@*" />
----------------------------------------------------------------------

f:id:sh1njp:20161219023736p:plain

  • flag

SharifCTF{100ae53903cbb68ab523c8e858034988}

Writeup memo Memory Analysis (Forensics100) [SECCON 2016 Online CTF]

SECCON 2016 Online CTF の Forensics100点の「Memory Analysis」のWriteupメモ score-quals.seccon.jp

*問題文

Memory Analysis
Find the website that the fake svchost is accessing.
You can get the flag if you access the website!!
memoryanalysis.zip (http://files.quals.seccon.jp/memoryanalysis.zip)

The challenge files are huge, please download it first.

Hint1: http://www.volatilityfoundation.org/
Hint2: Check the hosts file 

password: fjliejflsjiejlsiejee33cnc

メモリ解析をやりましょうという問題。

  • メモリダンプのイメージ情報を出力
volatility.exe imageinfo -f forensic_100.raw
-----------------------------------------------------------------------------------------------------------
Volatility Foundation Volatility Framework 2.5
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : WinXPSP2x86, WinXPSP3x86 (Instantiated with WinXPSP2x86)
                     AS Layer1 : IA32PagedMemoryPae (Kernel AS)
                     AS Layer2 : FileAddressSpace (D:\hogehoge\memoryanalysis\forensic_100.raw)
                      PAE type : PAE
                           DTB : 0x34c000L
                          KDBG : 0x80545ce0L
          Number of Processors : 1
     Image Type (Service Pack) : 3
                KPCR for CPU 0 : 0xffdff000L
             KUSER_SHARED_DATA : 0xffdf0000L
           Image date and time : 2016-12-06 05:28:47 UTC+0000
     Image local date and time : 2016-12-06 14:28:47 +0900
-----------------------------------------------------------------------------------------------------------

⇒ 「WinXPSP2x86」or 「WinXPSP3x86」らしい。

  • ヒントにあるhostsファイルの格納位置を調査
volatility.exe --profile=WinXPSP3x86 -f forensic_100.raw filescan
-----------------------------------------------------------------------------------------------------------
(略)
0x000000000217b748      1      0 R--rw- \Device\HarddiskVolume1\WINDOWS\system32\drivers\etc\hosts
(略)
-----------------------------------------------------------------------------------------------------------
  • ファイルを指定して出力
volatility.exe --profile=WinXPSP3x86 -f   forensic_100.raw dumpfiles -Q 0x000000000217b748 --name -D .\
-----------------------------------------------------------------------------------------------------------
=> file.None.0x819a3008.hosts.dat
-----------------------------------------------------------------------------------------------------------
  • hostsファイルの中身を確認
type file.None.0x819a3008.hosts.dat
-----------------------------------------------------------------------------------------------------------
(略)
127.0.0.1       localhost
153.127.200.178 crattack.tistory.com
-----------------------------------------------------------------------------------------------------------
  • IEのヒストリでそれらしいサイトを確認
volatility.exe -f forensic_100.raw --profile=WinXPSP2x86 iehistory 
-----------------------------------------------------------------------------------------------------------
(略)
Process: 380 IEXPLORE.EXE
Cache type "URL " at 0x76be00
Record length: 0x180
Location: http://crattack.tistory.com/entry/Data-Science-import-pandas-as-pd
Last modified: 2016-12-06 03:39:11 UTC+0000
Last accessed: 2016-12-06 05:28:40 UTC+0000
File Offset: 0x180, Data Offset: 0xac, Data Length: 0xd0
File: Data-Science-import-pandas-as-pd[1]
Data: HTTP/1.1 200 OK

Content-Type: application/octet-stream
Content-Length: 42
ETag: "584632df-2a"

~U:system
(略)
-----------------------------------------------------------------------------------------------------------
  • 上記URLをIP指定でアクセス
curl -H "Host:crattack.tistory.com" "http://153.127.200.178/entry/Data-Science-import-pandas-as-pd"
-----------------------------------------------------------------------------------------------------------
SECCON{_h3110_w3_h4ve_fun_w4rg4m3_}
-----------------------------------------------------------------------------------------------------------

タイムライン整理していろいろ眺めるともっと面白い何かもあるのかも。

サービス監視用スクリプト(bash,やっつけ)

やっつけなので注意☆

基本的な考え方

  • 監視スクリプト本体 : check-XXXX.sh
  • 監視対象のリストファイル : list-XXX.txt
  • 監視スクリプトから利用されるコマンドファイル : cmd-XXXX.txt
  • 動作ディレクトリ : /usr/local/tools/monitor
  • ログ保存ディレクトリ : /usr/local/tools/monitor/logs
  • テンポラリファイル : /tmp/XXXX-ng.txt

想定環境

CentOS6系

check ping

check-ping.sh

#!/bin/bash
#
# check ping script. 
# ver 0.1 2016/05/28
#
export LANG=C
CHECK=ping
DIR=/usr/local/tools/monitor
LOG=/usr/local/tools/monitor/logs/${CHECL}.log
LIST=/usr/local/tools/monitor/list-${CHECK}.txt
TEMP=/tmp/ping-ng.txt
MAIL_TO=user1@sXX.hogehoge.local

cat ${LIST}| while read DEST
  do
    ping -c 2 -w 2 ${DEST} > /dev/null
    if [ $? == 0 ] ;
    then
      echo `date +%F' '%X` "${DEST} ${CHECK} : OK" >> ${LOG}
    else
      echo `date +%F' '%X` "${DEST} ${CHECK} : NG" >  ${TEMP}
      cat ${TEMP}                         >> ${LOG}
      cat ${TEMP} | mail -s "alert [${DEST}] ${CHECK} NG!" ${MAIL_TO}
    fi
  done

list-ping.txt

192.168.1.1
192.168.1.2
192.168.1.3

check web

check-web.sh

#!/bin/bash
#
# check web script.
# ver 0.1 2016/05/28
export LANG=C
CHECK=web
#PORT=80
DIR=/usr/local/tools/monitor
LOG=${DIR}/logs/${CHECK}.log
LIST=${DIR}/list-${CHECK}.txt
REMOTE_CMD=${DIR}/cmd-${CHECK}.txt
TEMP=/tmp/${CHECK}-ng.txt

MAIL_TO=user1@sXX.hogehoge.local

cat ${LIST}| while read DEST
  do
    SITE=`echo ${DEST}| awk -F"/" '{print $3}'`
    curl -f ${DEST} > /dev/null 2>&1
    if [ $? == 0 ] ;
    then
      echo `date +%F' '%X` "${DEST} ${CHECK} : OK" >> ${LOG}
    else
      echo `date +%F' '%X` "${DEST} ${CHECK} : NG" >  ${TEMP}
      cat ${TEMP}                                  >> ${LOG}
      cat ${TEMP} | mail -s "alert [${SITE}] ${CHECK} NG!" ${MAIL_TO}
    fi
  done

list-web.txt

http://www1.sXX.hogehoge.local/
http://www2.sXX.hogehoge.local/

check smtp

check-smtp.sh

#!/bin/bash +x

# check smtp script.
# ver 0.1 2016/05/28
export LANG=C
CHECK=smtp
PORT=25
DIR=/usr/local/tools/monitor
LOG=${DIR}/logs/${CHECK}.log
LIST=${DIR}/list-${CHECK}.txt
REMOTE_CMD=${DIR}/cmd-${CHECK}.txt
TEMP=/tmp/${CHECK}-ng.txt
RESULT="221 2.0.0 Bye"

MAIL_TO=user1@sXX.hogehoge.local

cat ${LIST}| while read DEST
  do
    cat ${REMOTE_CMD} | nc ${DEST} ${PORT} | tail -1 | grep "${RESULT}" > /dev/null 2>&1
    if [ $? == 0 ] ;
    then
      echo `date +%F' '%X` "${DEST} ${CHECK} : OK" >> ${LOG}
    else
      echo `date +%F' '%X` "${DEST} ${CHECK} : NG" >  ${TEMP}
      cat ${TEMP}                                  >> ${LOG}
      cat ${TEMP} | mail -s "alert [${DEST}] ${CHECK} NG!" ${MAIL_TO}
    fi
  done

list-smtp.txt

192.168.1.3

cmd-smtp.txt

ehlo test
quit

2016年06月 Hardening Project 2016 / Hardening 100 Value x Value 参加した。

2016年06月某日。とあるチームで参加。

内容は下記。

wasforum.jp

特徴

 与えられた競技環境である、ECサイトと関連するシステムを守り切り、売り上げの最大化を目指す。

 採点について、今回の大会では下記のようなパラメータにて各チームが評価された。

・見込み販売力 (Sales Potential)
・技術点 (Technical Merit)
・顧客点 (Customer Impression)
・対応点 (Incident Response)
・経済点 (Market Creation)
・協調点 (Information Sharing)

 

各チームのスコア(結果)は、下記より参照できる。

wasforum.jp

ルール上ではまり易い点

 前日に配布された資料の十分な読み込みが必要。

 競技後の評価や不慮の事故や調査等で運営者から利用されるアカウントのについては、下記のようなルールがある。

 ・該当アカウントでのログオン可能にしておくこと

 ・該当アカウントでのsshを許可しておくこと (※)

 ・該当アカウントの sudo の設定値を変更しないこと。

 ・パスワードを変えないこと(sshのキーでログインしているっぽいので関係ないかも。)

 ※ sshを許可しておくこと = 最終的に競技環境のどこかしらから運営者がsshでログオンするため、その経路をFirewall等で止めてしまうとNG。

 外部向けのFirewallの設定では、競技環境のDMZのサーバがすべて1:1のStaticNATで外部に公開されている。一般的に考えると、公開サイトは、NAT公開されてて良いとは思うが、dbやlogを管理するサーバ、proxyなどは、NAT公開が必須ではないし、外部への不要な通信(例えば、C&Cサイトへアクセスしてしまうなど)を排除すべく外部へのNAT公開や、IPマスカレードでの外向けアクセスを停止する方が本来は正しいとは思う。

仮想基盤特有の留意点

 競技者達は、StarBED内に構築された、仮想のネットワーク環境、仮想マシンで競技します。それらは、各チーム毎にそれぞれに比較的フェアな条件で構築されており、それなりのスペックの仮想マシンが動作している。しかしながら、ディスク構成としては、チーム内の仮想化マシン間でシェアしているため、特定の仮想マシンのIO負荷が上がってしまうと、同じディスク(同じRAID Group)に属している別の仮想マシンのIOに影響が出てしまう。

 例えば、webサーバでディスクにランダムアクセスが集中しているような場合に、同じRAID Groupにある、dbサーバのIOパフォーマンスが出ないといったことが発生する。

同一RAID GROUP内の仮想マシン達でIO負荷が集中するような処理をcronで回す場合には、処理時間をずらすなどの考慮が必要となるのかもしれない。

運用監視

 サイトの監視を行い、改ざんされたり、サイトが停止していたりすることを把握する必要がある。サービス監視、プロセス監視などが必要となる。

 8時間という限られた時間である点と、発生するインシデントが頻繁に襲ってくるような競技の特性があるため、サポート端末(Windows)のブラウザより、F5でのサイト監視が最も有効な説有。tail -f とかで 各サービスのログを監視しておけば、それでもわかるのかも。

もしかしたら、ChromeのAuto Refresh プラグインを動かして監視とかがいいのかも。

chrome.google.com

 尚、競技用に作成したが、それほど役に立たなかった監視ツールを一応置いておく。

sh1njp.hatenablog.com

dnsが死んだ場合には、postfixの設定次第で、メールの送信ができないケースもあると思われるため注意が必要。/etc/postfix/main.cf の設定で、MTAに向ける設定がIP指定か、ホスト指定か、それともMXで動くのかなどにより監視サーバのメールの設定周りにも注意が必要。

改ざん検知

aideを使った。CentOS6.x でrpmで入れられてサクッと動かせるので便利。

一般的な運用とは異なり、頻繁にチェックが必要となると思われる。チームでは30分単位で動作。

8時間という競技上、改ざんを本当に確認すべきか、さっさとバックアップからコンテンツを戻す方が早いのかが結構悩ましいところではある。

各サーバからメールで通知する場合、DNSが死ぬと役に立たないケースがあるので、postfixの設定なども気を付けた方が良い。

pcap のノード毎振り分け

環境

virtualbox / ubuntu1604LTS / mem 4GB / 2cores
tshark version 2以降

前提

/NFS/work/pcap 配下にpcapファイルがたくさんある
ipv6非対応

RAMDISK作成

sudo vi /etc/fstab
tmpfs /ramdisk tmpfs rw,size=1G,x-gvfs-show 0 0

NFS上のpcapファイルを各ノード(Endpoint)で別ファイルに分割

(テンポラリとしてRAMDISK利用)

touch ~/bin/capbynode.sh
chmod +x ~/bin/capbynode.sh
vi ~/bin/capbynode.sh
#!/bin/bash

# ./capbynode.sh
# for tshark ver2

INPUTDIR=/NFS/work/pcap
OUTDIR=/NFS/work/pcap/nodes
RAMDISK=/ramdisk
LIST_PCAP=${RAMDISK}/list_pcap.txt
LIST_ENDPOINTS=${RAMDISK}/list_endpoints.txt

# output pcap file list
ls -1tr ${INPUTDIR}/*.pcap > ${LIST_PCAP}

cat ${LIST_PCAP} | while read FILE_PCAP
  do

  # clear RAMDISK pcap file
  rm -f ${RAMDISK}/*pcap

  # copy from INPUTDIR to RAMDISK
  echo "---- FILE_PCAP = ${FILE_PCAP} ----"
  cp -v ${FILE_PCAP} ${RAMDISK}/
  cd ${RAMDISK}
  INPUT_FILE=`ls -1tr *pcap | tail -1`

  # output endpoints
  echo "`date -R` : output endpoints start FILE=${INPUT_FILE}"
  tshark -r ${INPUT_FILE} -q -z endpoints,ipv4 | grep ^[0-9] | awk '{print $1}' > ${LIST_ENDPOINTS}
  echo "`date -R` : output endpoints complete FILE=${INPUT_FILE}"
  echo "${LIST_ENDPOINTS} : `cat ${LIST_ENDPOINTS} | wc -l` lines"

  cat ${LIST_ENDPOINTS} | while read IPADDR
    do
    echo "`date -R` : input_file = ${INPUTFILE} ,ipaddr = ${IPADDR} ###"
    tcpdump -r ${INPUT_FILE} -w ${OUTDIR}/${INPUT_FILE}_${IPADDR}.pcap host ${IPADDR} > /dev/null 2>&1
    done

  done

NFS上の各ノード毎のpcapファイルから任意のアドレスのpcapをマージ

touch ~/bin/merge-nodes.sh
chmod +x ~/bin/merge-nodes.sh
vi ~/bin/merge-nodes.sh
#!/bin/bash
# mergecap by nodes
# merge-nodes.sh [ip-address]

INPUTDIR="/NFS/work/pcap/nodes"
IPADDR=$1
INFILES=`ls -1tr ${INPUTDIR}/*_${IPADDR}.pcap | tr -s '\n' ' '`

mergecap -w ./merge_${IPADDR}.pcap ${INFILES}