log2timelineの使い方

この記事は1年半前から下書きのままになっていたものです。

log2timelineとは

タイムライン解析というファイルシステムのタイムスタンプ情報を元に、時系列順に痕跡を解析していく手法がある。
log2timelineはそのためのフレームワークである。PlasoというPythonベースのエンジンが使われている。

Home · log2timeline/plaso Wiki · GitHub

使い方

入力フォーマットの一覧

$ log2timeline -f list

出力フォーマットの一覧

$ log2timeline -o list

指定できるタイムゾーンの一覧

$ log2timeline -z list

timelineを見る

log2timelineを実行する前に、The Sleuth Kitのmmlsでパーティションの開始位置を探して、イメージをmountする必要がある。

$ mmls test.dd

mmlsの結果を見て、offsetに1セクタのサイズ*パーティションの開始位置を指定する。

$ mount -o ro,noexec,show_sys_files,loop,offset=<アドレス> test.dd /mnt/hoge

-zでタイムゾーンを -fで入力フォーマットとパスを、-wで出力ファイルを指定する。ここではcsvにした。

$ log2timeline -z <タイムゾーン> -f <入力フォーマット> /mnt/hoge -w timeline.csv

作成されたcsvファイルをEXCELとかnumbersで開くと、サイズが大きくて開くのに時間がかかるので、見たい期間がある程度絞れているなら、wオプションを付けずにlog2timelineを実行してから、l2t_process -b で期間を指定し csv ファイルにするとよい。

$ log2timeline-sift -z <タイムゾーン> -p <パーティション> -i <イメージ>
$ cd /cases/timeline-output-folder/ #sans siftの場合
$ l2t_process -b <イメージ>_bodyfile.txt 12-01-2012..12-31-2012 > <イメージ>_bodyfile.csv

Unicorn、usercornを使ってみる

Unicornとは

この記事での Unicorn は、エミュレータの方であり、決してRackサーバの方ではない。
Unicornは軽量でマルチプラットフォーム、マルチアーキテクチャな CPU emulator frameworkである。

UnicornはNguyen Anh Quynh氏が中心となって開発されているが、彼は disassembly/disassembler frameworkであるCapstone、 assembler frameworkであるKeystoneの開発も行っており、すごい!

また、似たものとしてQEMUが思い浮かぶが、UnicornQEMUをベースに開発されていて、QEMUより優れている点として、frameworkであること、flexibleであること、dynamic instrumententionをサポートしていること、thread-safeであること、いろんな言語によるbindingsがあること、軽量であること、セキュアであることが挙げられている。

Unicorn & QEMU – Unicorn – The ultimate CPU emulator

Unicornのインストール

基本的に/docs/COMPILE.mdの通りにやればうまくいく。

ただ、macにインストールする場合、Homebrewで入るものは古く、GitHub上のmasterは違うものになっているので、手でインストールするほうが無難。特にHomebrewでは入らないbindingをインストールするとき、手抜きで本体だけHomebrewでいれてbindingだけを手でインストールしても動かないので注意。これでハマった...

各言語によるbindingのインストール方法は/bindings/各言語/にあるREADMEを参照。
例えばPythonだと/bindings/python/README.TXTをみればいい。

動かしてみる

Python bindingを使って動かしてみる。

コード

#!/usr/bin/env python2
# coding: UTF-8

from unicorn import *
from unicorn.x86_const import *
import sys

# memory address where emulation starts
ADDRESS = 0x1000000

# initialize unicorn emulator
mu = Uc(UC_ARCH_X86, UC_MODE_32)
# map 4MB for this emulation
mu.mem_map(ADDRESS, 4 * 1024 * 1024)

binary = ''
if len(sys.argv) == 2:
    with open(sys.argv[1], 'rb') as f:
        binary = f.read()
else:
    binary = b"\x41\x4a" # INC ecx; DEC edx


mu.mem_write(ADDRESS, binary)

# emulate code in infinite time & unlimited instructions
mu.emu_start(ADDRESS, ADDRESS + len(binary))

r_eax = mu.reg_read(UC_X86_REG_EAX)
r_ebx = mu.reg_read(UC_X86_REG_EBX)
r_ecx = mu.reg_read(UC_X86_REG_ECX)
r_edx = mu.reg_read(UC_X86_REG_EDX)
r_ebp = mu.reg_read(UC_X86_REG_EBP)
r_esp = mu.reg_read(UC_X86_REG_ESP)
r_edi = mu.reg_read(UC_X86_REG_EDI)
r_esi = mu.reg_read(UC_X86_REG_ESI)
r_eip = mu.reg_read(UC_X86_REG_EIP)
r_eflags = mu.reg_read(UC_X86_REG_EFLAGS)

print(">>> EAX = 0x%x" % r_eax)
print(">>> EBX = 0x%x" % r_ebx)
print(">>> ECX = 0x%x" % r_ecx)
print(">>> EDX = 0x%x" % r_edx)
print(">>> EBP = 0x%x" % r_ebp)
print(">>> ESP = 0x%x" % r_esp)
print(">>> EDI = 0x%x" % r_edi)
print(">>> ESI = 0x%x" % r_esi)
print(">>> EIP = 0x%x" % r_eip)
print(">>> EFLAGS = 0x%x" % r_eflags)

実行結果

$ python nishizumi.py 
>>> EAX = 0x0
>>> EBX = 0x0
>>> ECX = 0x1
>>> EDX = 0xffffffff
>>> EBP = 0x0
>>> ESP = 0x0
>>> EDI = 0x0
>>> ESI = 0x0
>>> EIP = 0x1000002
>>> EFLAGS = 0x94

INC ecx; DEC edxを実行した。正しくレジスタが加減されているのが分かる。

Unicornとusercorn

Unicornを試したところで、やはりPEやELF等のバイナリを実行したくなる。
しかし、Unicornはframeworkであり、ツールではないので、ヘッダーをパースして、メモリ上に配置したり、スタックを初期化したりといったことまではできない。

unicorn emulate binary · Issue #227 · unicorn-engine/unicorn · GitHub


そこでusercornを使う。usercornは、Unicornを使った User-space system emulatorでバイナリを実行できる。

GitHub - lunixbochs/usercorn: dynamic binary analysis via platform emulation

usercornのインストール

CapstoneとUnicornを入れて、go getする。

go get -u github.com/lunixbochs/usercorn/go/cmd/usercorn

動かしてみる

サンプルファイルを動かしてみる。

$ usercorn bins/x86_64.linux.elf
hello with printf: world
args (1):
  0 @0x607ffa37 = "bins/x86_64.linux.elf"
test: hi
ceil(1.0) = 1, ceil(1.1) = 2
strcmp: -1, 1, 0
file test 1: success

file test 2: success

$ usercorn bins/mipsel.linux.elf
hello with printf: world
args (1):
  0 @0x607ffa3d = "bins/mipsel.linux.elf"
test: hi
memcmp("aa", "aa") == 0
memcmp("aa", "bb") == -1
memcmp("bb", "aa") == 1
strcmp: -1, 1, 0
file test 1: success

file test 2: success

感想

unicorn、usercornを用いてなにか便利ツールを作っていきたい。

急にCSSがくずれた話

大分前に作ったchrome拡張のCSSがくずれていた。

favurl - Chrome Web Store

確認してみたらpreタグに対しての word-wrap: break-word; が効いていなかった。
html - How do I wrap text in a pre tag? - Stack Overflowによると、CSS3ではwhite-space: pre-wrapと書くのがいいらしく、そう書き換えたら直った。

pre {
    white-space: pre-wrap;       /* CSS 3 */
    white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
    white-space: -pre-wrap;      /* Opera 4-6 */
    white-space: -o-pre-wrap;    /* Opera 7 */
    word-wrap: break-word;       /* Internet Explorer 5.5+ */
}

急に古い書き方が使えなくなったことによって、反映されないCSSが出てきたという話だった。

おもしろ事案だった。

セキュリティ・キャンプ・フォーラム2016で発表してきた

セキュリティ・キャンプ・フォーラムとは

セキュリティ・キャンプの卒業生の同窓会的なイベントです。

「セキュリティ・キャンプフォーラム2016」開催のご案内:IPA 独立行政法人 情報処理推進機構

経緯

今年からセキュリティ・キャンプ・フォーラムにセキュリティ・キャンプアワードというものが併催されることとなり、一次審査を突破するとセキュリティ・キャンプ・フォーラムで発表することになりました。

セキュリティ・キャンプアワード 2016

最初はキャンプの卒業生こわいしアワードとか無理ゲーと思ってたのですが、アワードの締め切り3日前くらいに対象が昨年の卒業生だけであるというのを知り、交通費もらえるしダメ元で応募しとくかと思い応募してみたら、めでたく発表することになりました。

発表

開発中のバイナリエディタ biwxを用いたバイナリ解析について発表してきました。

speakerdeck.com

tkmru/biwx: binary editor for Pythonista.

一発芸てきなあまり中身のないスライドになってしまいましたが、アワードで開発技術賞をいただけました。

感想

カップル講演を見て精神的にダメージを受けたり、ああいう感じのところでしゃべるの初めてだったりしたので、うまく話せるか不安でしたが、それなりにうまく話せて安心しました。

聴衆のスーツ率が異様に高く、完全にスライドのノリを間違えたなと思ってましたが、まあまあ笑いを取れてよかったなと思っています。

次はもっとまともな高度なネタで発表できるように精進していこうと思います。

Rubyでparse.com経由でPush通知をする

parse.comとは

MBaaS(Mobile Backend as a Service)の一種で、簡単にAndroidIOSにPush通知できるサービス。

https://www.parse.com/

RubyでPush通知を送る

gem

Rubyからはparse-ruby-clientというgemを使うことで楽に使える。しかし、ドキュメントが分かりにくく、使うのに苦労した。
adelevie/parse-ruby-client · GitHub

Gemfile

parse-ruby-clientのmasterブランチにはリリース版に含まれていない変更が多数あるので、Gemfileに以下のように書く必要がある。(12/28時点)

gem 'parse-ruby-client', git: 'https://github.com/adelevie/parse-ruby-client.git'

コード

client = Parse.create :application_id => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                      :api_key        => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', # REST API key
                      :quiet          => false  # quietはオプションでデファルトでfalse

push = client.push('Hello')
push.where = {} # 全デバイスに送る

result = push.save['result'] # {"result"=>true}

Parse.createで認証を通し、client.pushで送るデータをセットし、push.saveで実際に各端末に通知を投げている。
また、上のコードでは文字列を各端末に送信しているが、JSONを送ることもできる。client.pushの引数をハッシュにすればよい。

json = {'test'=>'hello'}
push = client.push(json)

Androidで文字列を送信した際は自動で通知画面が生成されるが、JSONを送信したときは通知されないので自分で通知を生成する必要がある。iOSは未確認。

pysandboxの話

Python Advent Calendar 2015の15日目担当の たけまる(@tkmru)です。
今日はSECCON 2015 九州大会で見かけたpysandboxの話をしようと思います。

pysandboxとは

Pythonで作られたsandboxのひとつで、2010年から2013年まで開発が行われていましたが、設計上の問題によりこれ以上発展させることはできないと分かり開発が停止したという歴史をもっています。
GitHub - vstinner/pysandbox: WARNING: pysandbox is BROKEN BY DESIGN, please move to a new sandboxing solution (run python in a sandbox, not the opposite!)

設計の問題とは

pysandboxはCPythonインタプリタ名前空間を制限することで、安全にPythonコードを実行できるsandboxを作ろうと開発されていました。
しかし、CPythonにsandboxをescapeするのに使える関数が多く、sandboxを実装するのに適していないという問題に作者は気付きました。

pysandboxの作者であるVictor StinnerはThe pysandbox project is broken [LWN.net]で、以下のように述べられています。

In my opinion, the compile() vulnerabilty is the proof that it is not possible to put a sandbox in CPython. Blocking access to the open() builtin function and the file type constructor are not enough if unrelated functions can give access indirectly to the file system. Having read access on the file system is a critical vulnerability in pysandbox and modifying CPython to not print the source code line in a traceback is also not acceptable.

「私の見解では、compile()による脆弱性がCPython上にsandboxを置くのは不可能だという証拠となる。無関係な機能が、ファイルシステムに間接的にアクセス権を与えるとすると、内蔵関数 open() とファイル・タイプ コンストラクタへのアクセスをブロックするだけでは十分でない。ファイルシステムへの読み取りアクセスは pysandboxで重大な脆弱性となり、tracebackにコードを表示しないようCPythonを修正することもまた受け入れられない。」

I now agree that putting a sandbox in CPython is the wrong design. There are too many ways to escape the untrusted namespace using the various introspection features of the Python language. To guarantee the [safety] of a security product, the code should be [carefully] audited and the code to review must be as small as possible. Using pysandbox, the "code" is the whole Python core which is a really huge code base. For example, the Python and Objects directories of Python 3.4 contain more than 126,000 lines of C code.
The security of pysandbox is the security of its weakest part. A single bug is enough to escape the whole sandbox.

「私はCPythonの上にsandboxを置くのが間違った設計だというのは正しいと思う。Pythonの機能を使って名前空間をescapeする方法はとても多い。セキュリティ製品の安全性を保証するのに、コードは注意深く監査されるべきで、そのためにコードは出来る限り小さくなければならない。pysandboxの下のコードはものすごく大きいPythonのコアだ。例えば、Python3.4のコードは126,000行を超えるCのコードを含む。pysandboxのセキュリティは最弱のセキュリティとなる。ひとつのバグはsandbox全体をescapeするのに十分だ。」

compile() を使った脆弱性が発見される以前には、__builtins__.__init__、type.__bases__をつかった脆弱性が発見されていました。

また、Pythonインタプリタの外からアプローチすべきだとも述べられています。

To build a secure sandbox, the whole Python process must be put in an external sandbox. There are for example projects using Linux SECCOMP security feature to isolate the Python process.

「セキュアなsandboxを作るためには、Pythonのプロセス全体を外部のsandboxに置く必要があり、例としてLinuxのSECCOMPのPythonプロセスの扱い方が挙げられる。」とのことです。SECCOMPはlinuxカーネルの機能の1つで、どのシステムコールを実行して、どのシステムコールを実行しないかをシステムコールのフィルターとして設定できるというものです。

speakerdeck.com

このような経緯があるため、PythonのsandboxがCTFに出題されるようになったのだと思います。

おわりに

Pythonでsandboxを作るのは難しそうだという話でした。
sandboxは面白そうなので時間をつくって他のものについても調べたり作ったりしたいと思います。
アドカレ投稿遅れてすみませんでした。

CODE BLUEに行ってきた。

CODE BLUE 2015に行ってきた。
世界トップクラスの専門家による情報セキュリティ国際会議「CODE BLUE(コードブルー)」

f:id:TAKEmaru:20151028180515j:plain
f:id:TAKEmaru:20151028181232j:plain
f:id:TAKEmaru:20151031135003j:plain

ああいうカンファレンスは初めてで、スーツ率が意外と高くてビビってたけど、セキュキャンとか勉強会とかで知り合った人が結構いて助かった。

カスペルスキーの学生支援枠で参加したので、カスペルスキー大先生にはめっちゃ感謝です。

f:id:TAKEmaru:20151028122101j:plain
f:id:TAKEmaru:20151029115019j:plain

昼ごはん豪華だった。

頑張っていきたい。