Android Hacking Event 2017 AES-Decrypt Writeup
はじめに
Android問に強くなる全然更新してないなと思ったので久々にやります。ちなみに途中までは自力しましたがわかんなくなったのでWriteupは見てます。
AES-Decrypt
とりあえずapkファイルがあるので実行してみる
+NvwsZ48j3vyDlaMu6LrjnNn8/OAnexGL
T9WoXhrsQHgY3NLr8SwBbw==
という文字列がある、試しにDecryptボタンを押すと
Key=AF03BC291F82
という文字列が現れる
まぁ本題は2個目を復号したのが答えだろうと予想する。なのでとりあえず中身を見てみる
javaの解析
MainActivity.java
package challenge.teamsik.aesdecryption; import android.content.Context; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.*; public class MainActivity extends AppCompatActivity { public MainActivity() { } public native String decryptAES(Context context); protected void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(0x7f04001b); mContext = this; ((Button)findViewById(0x7f0b005e)).setOnClickListener(new android.view.View.OnClickListener() { public void onClick(View view) { view = decryptAES(MainActivity.mContext); ((TextView)findViewById(0x7f0b0061)).setText(view); Toast.makeText(MainActivity.mContext, "Decryption Successfull!", 1).show(); } final MainActivity this$0; { this$0 = MainActivity.this; super(); } }); } public static final String TAG = "CHALLENGE"; public static Context mContext; static { System.loadLibrary("native-lib"); } }
ソースコードを見て察した。これNDK問題だなと....
libnativeにdecryptAESという関数がありそこでdecryptしている。
libnativeの解析
radare2を使う
$ r2 lib/armeabi-v7a/libnative-lib.so -- Set color to your screen with 'e scr.color=true' [0x0000347c]> aaa [x] Analyze all flags starting with sym. and entry0 (aa) [ ] [Value from 0x00000000 to 0x00011144 aav: 0x00000000-0x00011144 in 0x0-0x11144 aav: 0x00000000-0x00011144 in 0x123d0-0x1300c aav: 0x00000000-0x00011144 in 0x1300c-0x17f35 Value from 0x0001300c to 0x00017f35 aav: 0x0001300c-0x00017f35 in 0x0-0x11144 aav: 0x0001300c-0x00017f35 in 0x123d0-0x1300c aav: 0x0001300c-0x00017f35 in 0x1300c-0x17f35 [x] Analyze len bytes of instructions for references (aar) [x] Analyze function calls (aac) [x] Use -AA or aaaa to perform additional experimental analysis. [x] Constructing a function name for fcn.* and sym.func.* functions (aan) [0x0000347c]> afl .... 0x00003518 10 1068 sym.Java_challenge_teamsik_aesdecryption_MainActivity_decryptAES ....
やはりdecryptAES関数を発見。中身を見てみる
[0x0000347c]> s sym.Java_challenge_teamsik_aesdecryption_MainActivity_decryptAES [0x00003518]> pdf ... 0x00003906 00f0a7f8 bl sub.EVP_CIPHER_CTX_new_a58 ...
とりあえずなんか怪しいのが見つかる。CIPHERとかあるししかもEVPだしOpensslのやつっぽい。
と思って調べたらOpenSSL EVP 関数を見つけた。予想は当たっていたようだ。
後は文字列調べるかなと思って調べた結果がこちら
[0x00003518]> iz vaddr=0x0000f788 paddr=0x0000f788 ordinal=000 sz=10 len=9 section=.rodata type=ascii string=CHALLENGE vaddr=0x0000f792 paddr=0x0000f792 ordinal=001 sz=6 len=5 section=.rodata type=ascii string=0x%2x vaddr=0x0000f798 paddr=0x0000f798 ordinal=002 sz=18 len=17 section=.rodata type=ascii string=Invalid key used! vaddr=0x0000f7aa paddr=0x0000f7aa ordinal=003 sz=21 len=20 section=.rodata type=ascii string=Initalizing OpenSSL: vaddr=0x0000f7bf paddr=0x0000f7bf ordinal=004 sz=45 len=44 section=.rodata type=ascii string=0fk8j09RWT8+bKFQ0BdwRVjM+PuM5GeauUORaOtuP5A= vaddr=0x0000f7ec paddr=0x0000f7ec ordinal=005 sz=65 len=64 section=.rodata type=ascii string=0fk8j09RWT8+bKFQ0BdwRTwVQHvav+HIQH3zWg0UtCw8RCtgr772N3KAfKdWMKZN vaddr=0x0000f82d paddr=0x0000f82d ordinal=006 sz=45 len=44 section=.rodata type=ascii string=0fk8j09RWT8+bKFQ0BdwRWYaE95rIj008XoTqeq1YJU= vaddr=0x0000f85a paddr=0x0000f85a ordinal=007 sz=45 len=44 section=.rodata type=ascii string=0fk8j09RWT8+bKFQ0BdwRVw0J6O9tU1N3bUR4SpMgIE= vaddr=0x0000f887 paddr=0x0000f887 ordinal=008 sz=45 len=44 section=.rodata type=ascii string=pJolsMEG1ZjA39Z0RdSfbtgf/6QqiXXgLDYZWMRIpno= vaddr=0x0000f8b4 paddr=0x0000f8b4 ordinal=009 sz=65 len=64 section=.rodata type=ascii string=5XN3JZ0qQnZOlVT+FvZutMspEknw0l2ylINvmahr58xEQL4+3GEWnF/ojZ8OwwdZ vaddr=0x0000f8f5 paddr=0x0000f8f5 ordinal=010 sz=65 len=64 section=.rodata type=ascii string=5XN3JZ0qQnZOlVT+FvZutEVENxTKdhobEn9okV2h5Bj8PXPBkbRrEEDjxknjA16H vaddr=0x0000f936 paddr=0x0000f936 ordinal=011 sz=65 len=64 section=.rodata type=ascii string=u9o2dJItY/yt633wMhsDP2BaKb9kHJm/HZtwOe4L1ADV+U+aiHgpGhZ7EEaEcHq9 vaddr=0x0000f977 paddr=0x0000f977 ordinal=012 sz=45 len=44 section=.rodata type=ascii string=ZrnY4AKdp5ByAoHREWtYv+NamtJA/p0Swvc6D6u7qx0= vaddr=0x0000f9a4 paddr=0x0000f9a4 ordinal=013 sz=45 len=44 section=.rodata type=ascii string=P2m808wtZdzcP9ouyfWvjoGLm2jZi0D4uK5YnjsP+B4= vaddr=0x0000f9d1 paddr=0x0000f9d1 ordinal=014 sz=65 len=64 section=.rodata type=ascii string=5jW+2fK2AEWXkb5wmwjbau9My2QuA9MhMDQP06c9e+pCDbCx7kdtJ6ZJQSkeJdWk vaddr=0x0000fa12 paddr=0x0000fa12 ordinal=015 sz=25 len=24 section=.rodata type=ascii string=YqXS6chhZJr0JwhXiBTwSA== vaddr=0x0000fa2b paddr=0x0000fa2b ordinal=016 sz=45 len=44 section=.rodata type=ascii string=l23Klp6+80bbLX8Aor0Aitb5I2paF+dxz8UpAQylJKI= vaddr=0x0000fa58 paddr=0x0000fa58 ordinal=017 sz=25 len=24 section=.rodata type=ascii string=HUO0GJiv0BJHQu49yAOsvg== vaddr=0x0000fa71 paddr=0x0000fa71 ordinal=018 sz=89 len=88 section=.rodata type=ascii string=me/LE9SHGipWIAdMwewSpNxMcbHu7koanAld8nvXh4Nkf7Mn9o/GPj6dCB95B00SaEw4OTn6MBdjKnFBmMEmQw== vaddr=0x0000faca paddr=0x0000faca ordinal=019 sz=25 len=24 section=.rodata type=ascii string=9H7sv0baQSW+dJcuy1kTcg== vaddr=0x0000fae3 paddr=0x0000fae3 ordinal=020 sz=45 len=44 section=.rodata type=ascii string=djcVuQzrYzzvIBzv6qwU78XoK9b9Axx6rzOipkBNI9M= vaddr=0x0000fb10 paddr=0x0000fb10 ordinal=021 sz=25 len=24 section=.rodata type=ascii string=Tc6oeVRcAP5Ed1yKFb1y4Q== vaddr=0x0000fb29 paddr=0x0000fb29 ordinal=022 sz=25 len=24 section=.rodata type=ascii string=k70Em+XsW/0rwt6FiPz5cw== vaddr=0x0000fb42 paddr=0x0000fb42 ordinal=023 sz=25 len=24 section=.rodata type=ascii string=1mwCw3AgNVhGG+gPBXu7gQ== vaddr=0x0000fb5b paddr=0x0000fb5b ordinal=024 sz=25 len=24 section=.rodata type=ascii string=j3PbP1T7rSkj3zq+hkGqLA== vaddr=0x0000fb74 paddr=0x0000fb74 ordinal=025 sz=25 len=24 section=.rodata type=ascii string=FwB0AaNtkiZqymRhe2dV/g== vaddr=0x0000fb8d paddr=0x0000fb8d ordinal=026 sz=89 len=88 section=.rodata type=ascii string=me/LE9SHGipWIAdMwewSpOgpB/hPmqJ505Coc0q+diYVOvgpUNs3r6VIZHETDSh3zKheQnLGhBEuPlgw/wRtxA== vaddr=0x0000fbe6 paddr=0x0000fbe6 ordinal=027 sz=25 len=24 section=.rodata type=ascii string=26Ai/jguFtNz4eK3Rfcuxg== vaddr=0x0000fbff paddr=0x0000fbff ordinal=028 sz=45 len=44 section=.rodata type=ascii string=1ZIXfbbppzkz4tclxQA3BtcRorc3mMLTivhI3S9tjUM= vaddr=0x0000fc2c paddr=0x0000fc2c ordinal=029 sz=89 len=88 section=.rodata type=ascii string=+jrIt+CNy/la9PHTLuZUjvkays5GIPScMVpJpyV+nul+WkiY6pmTRD0v/pCtowvxt6mEAwXZXU4Zr9dx90s3Kw== vaddr=0x0000fc85 paddr=0x0000fc85 ordinal=030 sz=25 len=24 section=.rodata type=ascii string=jHDAGbW9MO5AA/jXIj4VRA== vaddr=0x0000fc9e paddr=0x0000fc9e ordinal=031 sz=45 len=44 section=.rodata type=ascii string=udv/kxBBdbg3PItkFW6Kms/ko9FHaJzGIagOHSAJsC0= vaddr=0x0000fccb paddr=0x0000fccb ordinal=032 sz=25 len=24 section=.rodata type=ascii string=pV1HOig44OVVCUGk57OhuQ== vaddr=0x0000fce4 paddr=0x0000fce4 ordinal=033 sz=45 len=44 section=.rodata type=ascii string=7fIEIbf6NxVvrVFmlEAdYLUSriDuoGdtLbvZWBjJ3LI= vaddr=0x0000fd11 paddr=0x0000fd11 ordinal=034 sz=22 len=21 section=.rodata type=ascii string=You used a wrong key! vaddr=0x0000fd28 paddr=0x0000fd28 ordinal=035 sz=45 len=44 section=.rodata type=ascii string=+NvwsZ48j3vyDIaMu6LrjnNn8/OAnexGUXn3POeavI8= vaddr=0x0000fd5d paddr=0x0000fd5d ordinal=036 sz=5 len=4 section=.rodata type=ascii string=gI'f
base64が多いのが怪しいけどこれだけではわからない。アセンブラを読めばいいのだが諦めてWriteupを見た
動的解析
Fridaというものを使う。Fridaの使い方は多分別の日に記事にするよ。
AESの256の鍵の長さは32バイト、ivの長さは16バイトであることから動的解析を行いメモリ内の32バイトの値と16バイトの値を取る
そのコードはwriteup先と一緒なので割愛、keyとivが2組出てくるのでそれでデコードを行う。最後のsolverは書いたのでそれだけ載せます
solver
from Crypto.Cipher import AES import hashlib import base64 def get_decrypt_data(cipher_data_base64): cipher_data = base64.b64decode(cipher_data_base64) secret_key = base64.b64decode("AMKyAMuv7U4Us1KTVjb2AGV8QGy7jynAoU+77LatjlQ=") iv = base64.b64decode("mT92BqeIHGdJJ2YGjenYqg==") crypto = AES.new(secret_key, AES.MODE_CBC, iv) raw_data_base64_16byte = crypto.decrypt(cipher_data) #raw_data_base64 = raw_data_base64_16byte.split("_")[0] #raw_data = base64.b64decode(raw_data_base64) return raw_data_base64_16byte print get_decrypt_data("T9WoXhrsQHgY3NLr8SwBbw==")
AHE17{Frida!}
おわり
なかなか学びを得た問題。Fridaってものをしれたのはでかい