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

程序有两个native方法:

public native int IsCorrect(String arg1)

public native int processObjectArrayFromNative(String arg1)

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;
3 temp_chars_ptr = *p_chars;
4 v46 = &v8;
5 v51 = 101;
6 v8 = 926246501;
7 v52 = 53;
8 v45 = 55;
9 v9 = 102;
10 v10 = 51;
11 v11 = 102;
12 v12 = 101;
13 v13 = 51;
14 v44 = 99;
15 v14 = 99;
16 v15 = 102;
17 v16 = 54;
18 v17 = 48;
19 v18 = 51;
20 v19 = 99;
21 v20 = 48;
22 v21 = 51;
23 v22 = 56;
24 v23 = 57;
25 v24 = 48;
26 v25 = 101;
27 v26 = 101;
28 v27 = 53;
29 v28 = 56;
30 v29 = 56;
31 v30 = 56;
32 v31 = 55;
33 v32 = 56;
34 v33 = 99;
35 v34 = 48;
36 v35 = 101;
37 v36 = 99;
38 v50_2 = v50;
39 v38 = 53;
40 v5 = j_strcmp(temp_chars_ptr, &v8);

processObjectArrayFromNative方法返回值:0或者0x57cbbd2

Java_com_example_ctf2_MainActivity_IsCorrect方法内也进行了字符串比较,

通过脚本我们可以获取到进行比较的字符串:

 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):
36 x+=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):
75 y+=chr(locals()['v'+str(i)])
76 print(y)
77 print(len(y))
78
79
80 '''
81 ef57f3fe3cf603c03890ee588878c0ec
82 32
83 ef57f3fe3cf603c03890ee588878c0ec
84 32
85 '''

ef57f3fe3cf603c03890ee588878c0ec

运行adb命令输入到编辑框

adb shell input text ef57f3fe3cf603c03890ee588878c0ec

当然也可以静态获取:

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脚本:

  1 import frida, sys
2
3
4 def on_message(message, data):
5 if message['type'] == 'send':
6 print("[*] {0}".format(message['payload']))
7 else:
8 print(message)
9
10
11 jscode = """
12 setImmediate(function () {
13 Java.perform(function () {
14 console.log("start");
15 //so层hook
16 //导出函数
17 //var exports = Module.enumerateExportsSync("libadnjni.so");
18 //for(var i=0;i<exports.length;i++){
19 // send("name:"+exports[i].name+" address:"+exports[i].address);
20 // }
21 var str = Java.use("java.lang.String");
22 //遍历模块找基址
23 // Process.enumerateModules({
24 // onMatch: function (exp) {
25 // if (exp.name == 'libadnjni.so') {
26 // send('enumerateModules find');
27 // send(exp.name + "|" + exp.base + "|" + exp.size + "|" + exp.path);
28 // send(exp);
29 // return 'stop';
30 // }
31 // },
32 // onComplete: function () {
33 // send('enumerateModules stop');
34 // }
35 // });
36
37 //通过模块名直接查找基址
38 var soAddr = Module.findBaseAddress("libadnjni.so");
39 send("soAddr:" + soAddr);
40
41 var parray=0x48c+1;
42 var pcorrect=0x74c+1;
43 // hook导出函数 通过函数名
44
45 //Module.findExportByName 找到的函数地址无效
46 // var farray=Module.findExportByName("libadnjni.so", "Java_com_example_ctf2_MainActivity_processObjectArrayFromNative")
47 // send("findExportByName farray() by Module.findExportByName:" +farray);
48 var farray=new NativePointer(soAddr).add(parray);
49 //NativePointer 简写ptr
50 send("findExportByName farray() by ptr:" +farray );
51
52 Interceptor.attach(farray, {
53 onEnter: function (args) {
54 var s = Java.cast(args[2], str);
55 send("array() jstring:" + s );
56 },
57 onLeave: function (retval) {
58 send("array() return:" + retval);
59 }
60 });
61
62 // hook导出函数 通过函数名
63 // var fcorrect=Module.findExportByName("libadnjni.so", "Java_com_example_ctf2_MainActivity_IsCorrect");
64 // send("findExportByName correct() by Module.findExportByName:" +fcorrect );
65 var fcorrect=new NativePointer(soAddr).add(pcorrect);
66 send("findExportByName correct() by ptr:" +fcorrect );
67 Interceptor.attach(fcorrect, {
68 onEnter: function (args) {
69 var s = Java.cast(args[2], str);
70 send("fcorrect() jstring:" + s );
71 },
72 onLeave: function (retval) {
73 send("fcorrect() return:" + retval);
74 }
75 });
76
77 });
78 });
79 """
80 # print(jscode)
81
82 # 启动时hook
83 # devices=frida.get_usb_device()
84 # pid=devices.spawn(['com.example.goal'])
85 # session=devices.attach(pid)
86 # devices.resume(pid) #创建完脚本, 恢复进程运行
87 # script=session.create_script(jscode)
88
89 # 命令行frida -U -f com.example.goal --no-pause -l <hook.js>
90
91 # 运行中hook
92 process = frida.get_usb_device().attach('com.example.ctf2')
93 script = process.create_script(jscode)
94 script.on('message', on_message)
95 print('[*] Running test')
96 script.load()
97 sys.stdin.read()
98
99 # ef57f3fe3cf603c03890ee588878c0ec
100
101 '''
102 [*] Running test
103 start
104 [*] soAddr:0xcd562000
105 [*] findExportByName farray() by ptr:0xcd56248d
106 [*] findExportByName correct() by ptr:0xcd56274d
107 [*] array() jstring:Serial Number
108 [*] array() return:0x0
109 [*] fcorrect() jstring:Serial Number
110 [*] fcorrect() return:0x0
111
112
113 [*] array() jstring:ef57f3fe3cf603c03890ee588878c0ec
114 [*] array() return:0x57cbbd2
115 [*] fcorrect() jstring:ef57f3fe3cf603c03890ee588878c0ec
116 [*] fcorrect() return:0x1
117 '''

攻防世界 reverse android-app-100的更多相关文章

  1. 攻防世界 reverse 进阶 10 Reverse Box

    攻防世界中此题信息未给全,题目来源为[TWCTF-2016:Reverse] Reverse Box 网上有很多wp是使用gdb脚本,这里找到一个本地还原关键算法,然后再爆破的 https://www ...

  2. 攻防世界 reverse evil

    这是2017 ddctf的一道逆向题, 挑战:<恶意软件分析> 赛题背景: 员工小A收到了一封邮件,带一个文档附件,小A随手打开了附件.随后IT部门发现小A的电脑发出了异常网络访问请求,进 ...

  3. 攻防世界 reverse tt3441810

    tt3441810 tinyctf-2014 附件给了一堆数据,将十六进制数据部分提取出来, flag应该隐藏在里面,(这算啥子re,) 保留可显示字符,然后去除填充字符(找规律 0.0) 处理脚本: ...

  4. 攻防世界 reverse 进阶 APK-逆向2

    APK-逆向2 Hack-you-2014 (看名以为是安卓逆向呢0.0,搞错了吧) 程序是.net写的,直接祭出神器dnSpy 1 using System; 2 using System.Diag ...

  5. 攻防世界 reverse pingpong

    pingpong  XCTF 3rd-BCTF-2017 java层代码很简单: 1 package com.geekerchina.pingpongmachine; 2 3 import andro ...

  6. 攻防世界 reverse BabyXor

    BabyXor     2019_UNCTF 查壳 脱壳 dump 脱壳后 IDA静态分析 int main_0() { void *v0; // eax int v1; // ST5C_4 char ...

  7. 攻防世界 reverse 进阶 8-The_Maya_Society Hack.lu-2017

    8.The_Maya_Society Hack.lu-2017 在linux下将时间调整为2012-12-21,运行即可得到flag. 下面进行分析 1 signed __int64 __fastca ...

  8. 攻防世界 reverse Windows_Reverse2

    Windows_Reverse2   2019_DDCTF 查壳: 寻找oep-->dump-->iat修复   便可成功脱壳 int __cdecl main(int argc, con ...

  9. 攻防世界 reverse Replace

    Replace 湖湘杯2018 查壳upx,手动脱壳,修复IAT,去掉重定向便可以运行. ida查看,流程清晰.关键函数check_E51090. int __cdecl main(int argc, ...

  10. 攻防世界 reverse 流浪者

    流浪者 int __thiscall sub_401890(CWnd *this) { struct CString *v1; // ST08_4 CWnd *v2; // eax int v3; / ...

随机推荐

  1. MATLAB字符串分解, 合并

    % 分解 % regexp s = 'ab/c/d.png' file_name = regexp(s, '/', 'split'); % 'd.png' % split fractions = sp ...

  2. Deep Learning Specialization 笔记

    1. numpy中的几种矩阵相乘: # x1: axn, x2:nxb np.dot(x1, x2): axn * nxb np.outer(x1, x2): nx1*1xn # 实质为: np.ra ...

  3. Clipboard API

    Clipboard API click copy click copy demo clickGetNewsLink(data_ref = `newsLink`) { let that = this; ...

  4. HTML <keygen> 标签(👎 已废弃)

    HTML 标签( 已废弃) 该标签在新的 Web 标准中已废弃. <!DOCTYPE html> <html> <head>  <meta charset=& ...

  5. Google Tag Manager

    Google Tag Manager SEO https://www.wappalyzer.com/technologies/tag-managers/google-tag-manager/ UTM ...

  6. React Security Best Practices All In One

    React Security Best Practices All In One Default XSS Protection with Data Binding Dangerous URLs Ren ...

  7. SwiftUI error All In One

    SwiftUI error All In One Instance member xxx cannot be used on type yyy Instance member 'game' canno ...

  8. Beacon API

    Beacon API User Tracking https://caniuse.com/#feat=beacon Question & Solution Beacon API 不会延缓网页卸 ...

  9. SameSite cookies explained

    SameSite cookies explained

  10. Flutter & QRCode App

    Flutter & QRCode App https://github.com/xgqfrms/qrcode-reader-app how to open android emulator o ...