brokenpasscode Writeup

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}となる