Google CTF 2018に参加するも1問も解けず。。
“shell we play a game?”がもう少しで解けそうだったけど、解けなかった。
ただ、android マルウェアに対するアプローチを学べたと思うので、メモ。
(flagを取れてないのでwrite upではない。)
問題:フラグを取得するために1,000,000回ゲームに勝ってね。添付ファイルにapk付き。
apkファイルを7zipでばらす。
ばらした中から、classes.dexをdex2jarでjarに変換。
$ ./d2j-dex2jar.sh classes.dex
dex2jar classes.dex -> ./classes-dex2jar.jar
jd-gui-windows-1.4.0に生成したjarを読ますとデコンパイルできる。
(ubuntuにjd-guiがinstallできず、windowsに切替たのは内緒)
以下は一部抜粋。progurdがかかっており、解読しにくかった。
void m() { Object localObject1 = N._(new Object[] { Integer.valueOf(0), N.a, Integer.valueOf(0) }); Object localObject2 = N._(new Object[] { Integer.valueOf(1), N.b, this.q, Integer.valueOf(1) }); N._(new Object[] { Integer.valueOf(0), N.c, localObject1, Integer.valueOf(2), localObject2 }); localObject1 = (byte[])N._(new Object[] { Integer.valueOf(0), N.d, localObject1, this.r }); ((TextView)findViewById(2131165269)).setText(new String((byte[])localObject1)); o(); } void n() { int i = 0; while (i < 3) { int j = 0; while (j < 3) { this.l[j][i].a(a.a.a, 25); j += 1; } i += 1; } k(); this.o += 1; Object localObject = N._(new Object[] { Integer.valueOf(2), N.e, Integer.valueOf(2) }); N._(new Object[] { Integer.valueOf(2), N.f, localObject, this.q }); this.q = ((byte[])N._(new Object[] { Integer.valueOf(2), N.g, localObject })); if (this.o == 1000000) { m(); return; } ((TextView)findViewById(2131165269)).setText(String.format("%d / %d", new Object[] { Integer.valueOf(this.o), Integer.valueOf(1000000) })); }
if (this.o == 1000000)をif (this.o == 1)にすれば、1度ゲームに勝つだけでフラグが生成される(ハズ)
apkファイルを再コンパイル可能なsmaliファイルに変換する。
$ java -jar ./apktool.jar d ./app.apk
生成されたsmaliファイルを確認。以下は一部抜粋。
.method n()V .locals 10 const v9, 0xF4240 const/4 v8, 0x1 const/4 v7, 0x3 const/4 v1, 0x0 const/4 v6, 0x2 move v2, v1
0xF4240(10進数の1000000)を0x1に変更して再コンパイル。
$ java -jar apktool_2.3.3.jar b ./app -o ./onegai.apk
apkファイルは署名が無いと、installできないため、署名を作成して、適用する。
$ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -validity 10000 $ jarsigner -verbose -tsa http://timestamp.digicert.com -keystore ./my-release-key.keystore ./onegai.apk alias_name
最後に確認を実施する。
$ jarsigner -verify -verbose ./onegai.apk
以上で再コンパイル完了。
androidで実行してみる。
ゲームをクリアした後に表示されるであろう、flagが文字化けしている・・
この後smaliをいじるもflagはでなかった。。