AngstromCTF2017のAndroid問題brokenpasscodeのwriteup
Writup
いつも通りJavaのコードをみる
MainActivity.java
public void addListenerOnButton()
{
((Button)findViewById(0x7f0b0055)).setOnClickListener(new android.view.View.OnClickListener() {
public void onClick(View view)
{
int i = Integer.parseInt(((EditText)findViewById(0x7f0b0054)).getText().toString());
if(i == r)
{
Log.i("debug", (new StringBuilder()).append("If you think you've successfully recovered my passcode...enter actf{").append(i).append("} as the flag!").toString());
return;
} else
{
Log.i("debug", "lmao you messed up");
return;
}
}
final MainActivity this$0;
{
this$0 = MainActivity.this;
super();
}
}
);
}
protected void onCreate(Bundle bundle)
{
super.onCreate(bundle);
setContentView(0x7f04001a);
try
{
bundle = getPackageManager().getApplicationInfo(getPackageName(), 128);
if(((ApplicationInfo) (bundle)).metaData != null)
{
System.out.println(((ApplicationInfo) (bundle)).metaData.getInt("com.example.guest1.passcode_actf.key"));
r = ((ApplicationInfo) (bundle)).metaData.getInt("com.example.guest1.passcode_actf.key");
}
}
// Misplaced declaration of an exception variable
catch(Bundle bundle)
{
bundle.printStackTrace();
}
addListenerOnButton();
}
rがAndroidManifest.xmlにある数字だとわかる、apktoolでデコードしてみてAndroidManifest.xmlを見てみると9999999であるとわかる。だがflag送信してみると答えじゃなかった。当日はそこで諦めた。
ここからWriteupを見てみたがMETA-INFの署名情報と比較すると答えと違うことが分かる。
$ cat tmp/META-INF/MANIFEST.MF| grep Android -A 2
Created-By: Android Gradle 1.5.0
Name: res/drawable-xhdpi-v4/abc_ic_star_half_black_48dp.png
--
Name: AndroidManifest.xml
SHA1-Digest: F0T3vG9oImHgTmMPeAu0dfJ0sVk=
$ python
>>> f = open("AndroidManifest.xml","rb")
>>> data = f.read()
>>> import hashlib
>>> import base64
>>> tmp = hashlib.sha1(data).digest()
>>> tmp
'\x07\x98R\xdaT\xd4O`g\xa5L8\xac\xa6\x0f)\x82\xa3L\x86'
>>> base64.b64encode(tmp)
'B5hS2lTUT2BnpUw4rKYPKYKjTIY='
9999999を変更していけばSHA1-Digestが一緒になるであろうことを予想する
それでbase64の感じからして9999999より小さいと思われる。後はブルートフォース
import hashlib
import base64
import struct
key = "F0T3vG9oImHgTmMPeAu0dfJ0sVk="
encode = base64.b64decode(key)
f = open("./tmp/AndroidManifest.xml","rb")
content = f.read()
for i in range(1000000,9999999):
tmp = content.replace(struct.pack("i",9999999),struct.pack("i",i))
if hashlib.sha1(tmp).digest() == encode:
print(i)
$ python solve.py 8195472
flag:RCTF{8195472}となる