攻防世界|攻防世界 reverse android-app-100

android-app-100suctf-2016
jeb启动,找到点击事件:
验证流程:
输入作为参数 --> processObjectArrayFromNative 得到一返回值(ret_a) --> IsCorrect 返回0,失败;返回1,成功 --> 输出"Sharif_CTF("+md5(str(d+ret_a)+” “+”)“(.d = 0x1BEBE)
可以发现flag的获取关键在于processObjectArrayFromNative 的返回值。

1 public void onClick(View arg8) { 2new String(" "); 3String v0 = this.a.b.getText().toString(); 4Log.v("EditText", this.a.b.getText().toString()); 5new String(""); 6int v1 = this.a.processObjectArrayFromNative(v0); 7int v2 = this.a.IsCorrect(v0); 8v0 = String.valueOf(this.a.d + v1) + " "; 9try { 10MessageDigest v1_1 = MessageDigest.getInstance("MD5"); 11v1_1.update(v0.getBytes()); 12byte[] v1_2 = v1_1.digest(); 13StringBuffer v3 = new StringBuffer(); 14int v0_2; 15for(v0_2 = 0; v0_2 < v1_2.length; ++v0_2) { 16v3.append(Integer.toString((v1_2[v0_2] & 0xFF) + 0x100, 16).substring(1)); 17} 18 19if(v2 == 1 && this.a.e != "unknown") { 20this.a.c.setText("Sharif_CTF(" + v3.toString() + ")"); 21} 22 23if(v2 == 1 && this.a.e == "unknown") { 24this.a.c.setText("Just keep Trying :-)"); 25} 26 27if(v2 == 0) { 28this.a.c.setText("Just keep Trying :-)"); 29} 30 31return; 32} 33catch(NoSuchAlgorithmException v0_1) { 34v0_1.printStackTrace(); 35return; 36} 37}

程序有两个native方法:
public native int IsCorrect(String arg1)
public native int processObjectArrayFromNative(String arg1)
【攻防世界|攻防世界 reverse android-app-100】
IDA启动,
发现有混淆,但我们还是能发现这两个native方法中调用了strcmp方法
Java_com_example_ctf2_MainActivity_processObjectArrayFromNative:
1 ptr_chars = (env_2->functions->GetStringUTFChars)(env_2, jstring_2, 0); 2*p_chars = ptr_chars; 3temp_chars_ptr = *p_chars; 4v46 = &v8; 5v51 = 101; 6v8 = 926246501; 7v52 = 53; 8v45 = 55; 9v9 = 102; 10v10 = 51; 11v11 = 102; 12v12 = 101; 13v13 = 51; 14v44 = 99; 15v14 = 99; 16v15 = 102; 17v16 = 54; 18v17 = 48; 19v18 = 51; 20v19 = 99; 21v20 = 48; 22v21 = 51; 23v22 = 56; 24v23 = 57; 25v24 = 48; 26v25 = 101; 27v26 = 101; 28v27 = 53; 29v28 = 56; 30v29 = 56; 31v30 = 56; 32v31 = 55; 33v32 = 56; 34v33 = 99; 35v34 = 48; 36v35 = 101; 37v36 = 99; 38v50_2 = v50; 39v38 = 53; 40v5 = j_strcmp(temp_chars_ptr, &v8);

processObjectArrayFromNative方法返回值:0或者0x57cbbd2
攻防世界|攻防世界 reverse android-app-100
文章图片





Java_com_example_ctf2_MainActivity_IsCorrect方法内也进行了字符串比较,
通过脚本我们可以获取到进行比较的字符串:
攻防世界|攻防世界 reverse android-app-100
文章图片
攻防世界|攻防世界 reverse android-app-100
文章图片
1 v51 = 'e'; 2 v8 = '75fe'[::-1]; 3 v52 = '5'; 4 v45 = '7'; 5 v9 = 'f'; 6 v10 = '3'; 7 v11 = 'f'; 8 v12 = 'e'; 9 v13 = '3'; 10 v44 = 'c'; 11 v14 = 'c'; 12 v15 = 'f'; 13 v16 = '6'; 14 v17 = '0'; 15 v18 = '3'; 16 v19 = 'c'; 17 v20 = '0'; 18 v21 = '3'; 19 v22 = '8'; 20 v23 = '9'; 21 v24 = '0'; 22 v25 = 'e'; 23 v26 = 'e'; 24 v27 = '5'; 25 v28 = '8'; 26 v29 = '8'; 27 v30 = '8'; 28 v31 = '7'; 29 v32 = '8'; 30 v33 = 'c'; 31 v34 = '0'; 32 v35 = 'e'; 33 v36 = 'c'; 34 x='' 35 for i in range(8,37): 36x+=locals()['v'+str(i)] 37 print(x) 38 print(len(x)) 39 40 v12 = 101; 41 v13 = 102; 42 v14 = 53; 43 v15 = 55; 44 v16 = 102; 45 v17 = 51; 46 v18 = 102; 47 v19 = 101; 48 v20 = 51; 49 v21 = 99; 50 v22 = 102; 51 v23 = 54; 52 v24 = 48; 53 v25 = 51; 54 v26 = 99; 55 v27 = 48; 56 v28 = 51; 57 v29 = 56; 58 v30 = 57; 59 v31 = 48; 60 v32 = 101; 61 v33 = 101; 62 v34 = 53; 63 v35 = 56; 64 v36 = 56; 65 v37 = 56; 66 v38 = 55; 67 v39 = 56; 68 v40 = 99; 69 v41 = 48; 70 v42 = 101; 71 v43 = 99; 72 73 y='' 74 for i in range(12,44): 75y+=chr(locals()['v'+str(i)]) 76 print(y) 77 print(len(y)) 78 79 80 ''' 81 ef57f3fe3cf603c03890ee588878c0ec 82 32 83 ef57f3fe3cf603c03890ee588878c0ec 84 32 85 '''

View Code ef57f3fe3cf603c03890ee588878c0ec
运行adb命令输入到编辑框
adb shell input text ef57f3fe3cf603c03890ee588878c0ec
攻防世界|攻防世界 reverse android-app-100
文章图片

当然也可以静态获取:
1 ret_a=0x57CBBD2 2 d=0x1BEBE 3 d=str(d+ret_a)+' ' 4 print(d) 5 import hashlib 6 m=hashlib.md5(d.encode()).hexdigest() 7 print('Sharif_CTF('+m+')')

Sharif_CTF(833489ef285e6fa80690099efc5d9c9d)

(一开始还原算法时得到的结果不对,又写了个frida脚本验证,返回值没问题,后来才发现要md5的字符串忘了加空格 0.0)
frida脚本:
攻防世界|攻防世界 reverse android-app-100
文章图片
攻防世界|攻防世界 reverse android-app-100
文章图片
1 import frida, sys 2 3 4 def on_message(message, data): 5if message['type'] == 'send': 6print("[*] {0}".format(message['payload'])) 7else: 8print(message) 9 10 11 jscode = """ 12 setImmediate(function () { 13Java.perform(function () { 14console.log("start"); 15//so层hook 16//导出函数 17//var exports = Module.enumerateExportsSync("libadnjni.so"); 18//for(var i=0; i
View Code
转载于:https://www.cnblogs.com/DirWang/p/11579448.html

    推荐阅读