【攻防世界】Mobile系列之app2
点击登录后,显示”Waiting fot you!”
反编译打开该app,定位程序入口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 COPY @SuppressLint({"ShowToast"}) public class MainActivity extends Activity implements View .OnClickListener { private Button a; private Handler b = null ; private EditText c; private EditText d; public void onCreate (Bundle bundle) { super .onCreate(bundle); setContentView(R.layout.activity_main); this .a = (Button) findViewById(R.id.button1); this .a.setOnClickListener(this ); this .c = (EditText) findViewById(R.id.editText1); this .d = (EditText) findViewById(R.id.editText2); SharedPreferences.Editor edit = getSharedPreferences("test" , 0 ).edit(); edit.putLong("ili" , System.currentTimeMillis()); edit.commit(); Log.d("hashcode" , SignatureTool.getSignature(this ) + "" ); } public boolean onCreateOptionsMenu (Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true ; } public boolean onOptionsItemSelected (MenuItem menuItem) { if (menuItem.getItemId() == R.id.action_settings) { return true ; } return super .onOptionsItemSelected(menuItem); } public void onClick (View view) { switch (view.getId()) { case R.id.button1 : if (this .c.getText().length() == 0 || this .d.getText().length() == 0 ) { Toast.makeText(this , "不能为空" , 1 ).show(); return ; } String obj = this .c.getText().toString(); String obj2 = this .d.getText().toString(); Log.e("test" , obj + " test2 = " + obj2); Intent intent = new Intent(this , SecondActivity.class); intent.putExtra("ili" , obj); intent.putExtra("lil" , obj2); startActivity(intent); return ; default : return ; } } }
这里**Intent intent = new Intent(this, SecondActivity.class);**调用了SecondActivity类,我们继续跟踪
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 COPY public class SecondActivity extends a { private BroadcastReceiver c = new BroadcastReceiver() { public void onReceive (Context context, Intent intent) { Toast.makeText(context, "myReceiver receive" , 0 ).show(); if (context.getPackageName().equals(intent.getAction())) { } } }; @Override public void onCreate (Bundle bundle) { super .onCreate(bundle); setContentView(R.layout.activity_main2); Intent intent = getIntent(); String stringExtra = intent.getStringExtra("ili" ); String stringExtra2 = intent.getStringExtra("lil" ); if (Encryto.doRawData(this , stringExtra + stringExtra2).equals("VEIzd/V2UPYNdn/bxH3Xig==" )) { intent.setAction("android.test.action.MoniterInstallService" ); intent.setClass(this , MoniterInstallService.class); intent.putExtra("company" , "tencent" ); intent.putExtra("name" , "hacker" ); intent.putExtra("age" , 18 ); startActivity(intent); startService(intent); } SharedPreferences.Editor edit = getSharedPreferences("test" , 0 ).edit(); edit.putString("ilil" , stringExtra); edit.putString("lili" , stringExtra2); edit.commit(); } public boolean onCreateOptionsMenu (Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true ; } public boolean onOptionsItemSelected (MenuItem menuItem) { if (menuItem.getItemId() == R.id.action_settings) { return true ; } return super .onOptionsItemSelected(menuItem); } }
这里注意到这行代码**Encryto.doRawData(this, stringExtra + stringExtra2).equals(“VEIzd/V2UPYNdn/bxH3Xig==”)**将输入的两个字符串拼接然后使用Encryto.doRawData()对其进行处理后与”VEIzd/V2UPYNdn/bxH3Xig==”作对比
我们继续跟踪Encryto.doRawData(),这是一个native层的so文件,我们使用IDA打开该文件定位到doRawData函数
伪代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 COPY int __cdecl doRawData(int a1, int a2, int a3, int a4) { char *v4; // esi int result; // eax char *v6; // esi size_t v7; // eax int v8; // [esp+0h] [ebp-2Ch] int (__cdecl *v9)(int, char *, size_t); // [esp+0h] [ebp-2Ch] char v10[20]; // [esp+4h] [ebp-28h] BYREF unsigned int v11; // [esp+18h] [ebp-14h] v11 = __readgsdword(0x14u); if ( checkSignature(a1, a2, a3) == 1 ) { strcpy(v10, "thisisatestkey=="); v4 = (char *)(*(int (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 676))(a1, a4, 0); v8 = AES_128_ECB_PKCS5Padding_Encrypt(v4, (int)v10); (*(void (__cdecl **)(int, int, char *))(*(_DWORD *)a1 + 680))(a1, a4, v4); result = (*(int (__cdecl **)(int, int))(*(_DWORD *)a1 + 668))(a1, v8); } else { v6 = UNSIGNATURE[0]; v9 = *(int (__cdecl **)(int, char *, size_t))(*(_DWORD *)a1 + 652); v7 = strlen(UNSIGNATURE[0]); result = v9(a1, v6, v7); } return result; }
上面那一段程序是一个AES加密算法,使用CBC模式,密钥为”thisisatestkey==”,如果想要获取明文的账号和密码,只需要对其进行AES解密操作获取明文。
1 2 3 4 5 6 7 COPY import base64from Crypto.Cipher import AESkey = 'thisisatestkey==' aes = AES.new(key,AES.MOOD_ECB) text = base64.b64decode('VEIzd/V2UPYNdn/bxH3Xig==' ) print (aes.decrypt(test))
得出如下结果
再次对反编译后的代码进行分析,在FileDataActivity中发现新的字符串
然后对字符串”9YuQ2dk8CSaCe7DTAmaqAA==”进行解密
1 2 3 4 5 6 7 COPY import base64 from Crypto.Cipher import AES key = '9YuQ2dk8CSaCe7DTAmaqAA==' aes = AES.new(key,AES.MOOD_ECB) text = base64.b64decode('VEIzd/V2UPYNdn/bxH3Xig==') print(aes.decrypt(test))
得到Cas3_0f_A_CAK3