GEEKy Script Writer [perl and more!]
You should permit the JavaScript!!
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
リバースエンジニアリングチャレンジ 2009の感想とか
今更だが、リバースエンジニアリングチャレンジ 2009に挑戦したので感想とか書いておく。

1問目がたしか26分、2問目が33分(3位)、3問目は途中までやって時間切れ。

以下、感想とてきとーな解説。

1問目


コードからパスワードを抜き出す。
シェアウェアのパスワードクラックを思い浮かべればよい。

2問目


ブロック崩し。クリアすればパスワードが得られる。しかし、改造しないとクリアできない。
HP減算処理をNOPで潰して無敵みたいな改造を思い浮かべればよい。

3問目


7つのエンコーダによって変換されたデータを元に戻せばパスワードが得られるという問題。
6つの同封されたエンコーダを解析してデコーダを作る。

encode6


PerlスクリプトをPARで固めたものなのでzipとして解凍すれば.plファイルを取り出せる。
あとは.plファイルの$cipherの数字を逆順にすればデコーダになる。
デコードするとwaveファイルっぽいものがでてくる。
参考:http://www.kajisoku.com/archives/eid1024.html

encode5


エンコーダはWindowsの実行ファイル。
エンコーダはまず44Bのwaveヘッダを出力するが、これはただの飾りなのでデコード時には無視してよい。その後、入力1Bを下位2bitsと上位2bitsに分けランダムなゴミデータに混ぜて4Bの値を256回作り出力する。
デコーダをPerlで書くとこんな感じ。

#!/usr/local/bin/perl
use strict;
open my $fr, 'password.e0.e1.e2.e3.e4.e5' or die;
open my $fw, '>', 'password.e0.e1.e2.e3.e4' or die;
binmode $fr;
binmode $fw;
$/ = \0x2c;
<$fr>;
$/ = \1024; # 256*4
print $fw chr(((ord(substr($_,0,1)) & 0x3c) >> 2) | ((ord(substr($_,3,1)) & 0x3c) << 2))
for <$fr>;
close $fw;
close $fr;


encode4


encode5でデコードしたファイルはencode5のwaveのように特徴的なシグネチャは見られない。
enocde4のエンコーダもWindowsの実行ファイルだが、AMD64。
環境がなく実行できないのでnasmで逆アセンブルした。
参考:http://d.hatena.ne.jp/kenjiaiko/20090907/1252306069
AMD64のasmなんてちゃんと読むのは初めてだったので、たしかこのあたりからやる気がなくなってきた。

エンコーダの出力は末尾256Bが変換表になっている。出力の先頭から1Bずつ取りその値を末尾256Bから探す。当該(256Bデータ先頭を0とした)オフセット値がエンコード前の値。
単純なのでデコーダは省略。

encode3


ここで挫折した。あとで参加者のtwitterとか見てみると同じくここで挫折した人が多くてわろた。
encode3はARMのELF。ARMのasmも読んだことがなかったので諦めた。
開催期間終了後とりあえずqemuで動かしてみたが、エンコード後のデータを見てもよくわかなかったので
結局諦めて逆アセンブルしたコードを読んで解析することにした。
参考:http://d.hatena.ne.jp/kenjiaiko/20090920/1253385747
x86みたいにSPが頻繁に動かないから命令や構文の変態さを差し引いてもわりと読みやすかったと思う。
エンコードは入力を5bitsずつとって0x41を足すだけ。つまり5Bが8Bになる。賢い人はエンコード後のバイナリを見るだけで気づくと思う。(エンコード後のデータがそもそもASCIIだけって時点でbaseなんちゃら系って考えて出現する文字の範囲を調べて云々みたいな)
Perlで書いたデコーダ(1回実行しただけでちゃんと検証してないからバグあるかも)

#!/usr/local/bin/perl
use strict;
open my $fr, 'password.e0.e1.e2.e3' or die;
open my $fw, '>', 'password.e0.e1.e2' or die;
binmode $fr;
binmode $fw;
$/ = \1;
my $v = 0;
my $n = 0;
while ($_ = <$fr>) {
$v = ($v << 5) | ((ord()-0x41) & 0x1f);
$n += 5;
if ($n >= 8) {
$n -= 8;
print $fw chr(0xff & ($v >> $n));
}
}
close $fw;
close $fr;


encode2


JavaをJNI(っていうんだよね?)で呼び出すWindowsの実行ファイル。
リソースからCLASSES_PACK_GZを取り出してJavaのなんとかに含まれてるunpack200.exeでunpackするとjarファイルが出てくる。
あとはclassファイルをjadで逆コンパイルするだけ。encode6の次に簡単なんじゃないだろうか。
デコーダは紛失したからなし。

encode1


encode6.binの次にサイズがでかくて今度はどんなインタプリタだろうとか考えながらヘキサエディタで覗いてみると、0x90以降0ばっかのすっかすかのデータ。"FAT12"とか見えるし。"神LEVEL3"←わろた
オフセット0x1FEを見ると0x55AA。ここでやっと気づいた。0x50から逆アセンブルすればいい。
処理としては、入力の1Bから初期値0の入力から1B取る毎にインクリメントされる値を引くだけ。
ただし引く値は0x41を超えたら0に戻り、入力が0x20の場合は0x20をそのまま出力する。
簡単すぎるのでデコーダは省略。

encode0


まさかのppencode
PerlのスクリプトとしてPerlで実行すればパスワードが表示される。

4問目


開催期間終了後に問題ファイルを入手したけどppcらしいからやる気がおきない。

3問目まで解いたけど全体的に難しくて楽しかった。来年も開催されるならまた参加したい。

テーマ:ソフトウェア - ジャンル:コンピュータ

コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
copyright © 2005 GEEKy Script Writer [perl and more!] all rights reserved.
Powered by FC2ブログ.
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。