攻防世界 reverse android-app-100
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的更多相关文章
- 攻防世界 reverse 进阶 10 Reverse Box
攻防世界中此题信息未给全,题目来源为[TWCTF-2016:Reverse] Reverse Box 网上有很多wp是使用gdb脚本,这里找到一个本地还原关键算法,然后再爆破的 https://www ...
- 攻防世界 reverse evil
这是2017 ddctf的一道逆向题, 挑战:<恶意软件分析> 赛题背景: 员工小A收到了一封邮件,带一个文档附件,小A随手打开了附件.随后IT部门发现小A的电脑发出了异常网络访问请求,进 ...
- 攻防世界 reverse tt3441810
tt3441810 tinyctf-2014 附件给了一堆数据,将十六进制数据部分提取出来, flag应该隐藏在里面,(这算啥子re,) 保留可显示字符,然后去除填充字符(找规律 0.0) 处理脚本: ...
- 攻防世界 reverse 进阶 APK-逆向2
APK-逆向2 Hack-you-2014 (看名以为是安卓逆向呢0.0,搞错了吧) 程序是.net写的,直接祭出神器dnSpy 1 using System; 2 using System.Diag ...
- 攻防世界 reverse pingpong
pingpong XCTF 3rd-BCTF-2017 java层代码很简单: 1 package com.geekerchina.pingpongmachine; 2 3 import andro ...
- 攻防世界 reverse BabyXor
BabyXor 2019_UNCTF 查壳 脱壳 dump 脱壳后 IDA静态分析 int main_0() { void *v0; // eax int v1; // ST5C_4 char ...
- 攻防世界 reverse 进阶 8-The_Maya_Society Hack.lu-2017
8.The_Maya_Society Hack.lu-2017 在linux下将时间调整为2012-12-21,运行即可得到flag. 下面进行分析 1 signed __int64 __fastca ...
- 攻防世界 reverse Windows_Reverse2
Windows_Reverse2 2019_DDCTF 查壳: 寻找oep-->dump-->iat修复 便可成功脱壳 int __cdecl main(int argc, con ...
- 攻防世界 reverse Replace
Replace 湖湘杯2018 查壳upx,手动脱壳,修复IAT,去掉重定向便可以运行. ida查看,流程清晰.关键函数check_E51090. int __cdecl main(int argc, ...
- 攻防世界 reverse 流浪者
流浪者 int __thiscall sub_401890(CWnd *this) { struct CString *v1; // ST08_4 CWnd *v2; // eax int v3; / ...
随机推荐
- MATLAB字符串分解, 合并
% 分解 % regexp s = 'ab/c/d.png' file_name = regexp(s, '/', 'split'); % 'd.png' % split fractions = sp ...
- Deep Learning Specialization 笔记
1. numpy中的几种矩阵相乘: # x1: axn, x2:nxb np.dot(x1, x2): axn * nxb np.outer(x1, x2): nx1*1xn # 实质为: np.ra ...
- Clipboard API
Clipboard API click copy click copy demo clickGetNewsLink(data_ref = `newsLink`) { let that = this; ...
- HTML <keygen> 标签(👎 已废弃)
HTML 标签( 已废弃) 该标签在新的 Web 标准中已废弃. <!DOCTYPE html> <html> <head> <meta charset=& ...
- Google Tag Manager
Google Tag Manager SEO https://www.wappalyzer.com/technologies/tag-managers/google-tag-manager/ UTM ...
- React Security Best Practices All In One
React Security Best Practices All In One Default XSS Protection with Data Binding Dangerous URLs Ren ...
- SwiftUI error All In One
SwiftUI error All In One Instance member xxx cannot be used on type yyy Instance member 'game' canno ...
- Beacon API
Beacon API User Tracking https://caniuse.com/#feat=beacon Question & Solution Beacon API 不会延缓网页卸 ...
- SameSite cookies explained
SameSite cookies explained
- Flutter & QRCode App
Flutter & QRCode App https://github.com/xgqfrms/qrcode-reader-app how to open android emulator o ...