首页
社区
课程
招聘
[原创]frida基础 闯关训练 七层关卡
2023-7-14 18:23 9017

[原创]frida基础 闯关训练 七层关卡

2023-7-14 18:23
9017

第一关:登录

问题:

打开app首先映入眼前是一个常规的登录界面,输入用户名和密码,提示Login filed.显然用户名和密码随便输入肯定是不行了。

分析:

首先我们用objection定位到他的页面位置activity,再结合反编译工具对源码进行分析。

1
2
3
4
adb shell dumpsys window | grep CurrentFocus
 
#返回
mCurrentFocus=Window{5b2914b u0 com.example.androiddemo/com.example.androiddemo.Activity.LoginActivity}

可以发现当前类的类已经找到了,objection hook这个类,再触发按钮,观察情况,打印出调用的方法,再hook之。

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
android hooking list activities 
 
#返回      
com.example.androiddemo.Activity.BaseFridaActivity
com.example.androiddemo.Activity.FridaActivity1
com.example.androiddemo.Activity.FridaActivity2
com.example.androiddemo.Activity.FridaActivity3
com.example.androiddemo.Activity.FridaActivity4
com.example.androiddemo.Activity.FridaActivity5
com.example.androiddemo.Activity.FridaActivity6
com.example.androiddemo.Activity.FridaActivity7
com.example.androiddemo.Activity.LoginActivity
com.example.androiddemo.MainActivity
 
 
android hooking watch class com.example.androiddemo.Activity.LoginActivity --dump-args --dump-backtrace --dump-return
#返回
(agent) [vv23m49gobd] Called com.example.androiddemo.Activity.LoginActivity.access$100(java.lang.Strinjava.lang.String)
(agent) [vv23m49gobd] Called com.example.androiddemo.Activity.LoginActivity.a(java.lang.String, java.lang.String)
(agent) [vv23m49gobd] Called com.example.androiddemo.Activity.LoginActivity.a([B)
(agent) [vv23m49gobd] Called com.example.androiddemo.Activity.LoginActivity.access$000(com.example.androiddemo.Activity.LoginActivity)           
 
android hooking watch class_method com.example.androiddemo.Activity.LoginActivity.a  --dump-args --dump-return
#返回:
(agent) [810lsp00gmj] Arguments com.example.androiddemo.Activity.LoginActivity.a([object Object])
(agent) [810lsp00gmj] Return Value: 82d476df642d6c882dcc438e028c6e0908af286439b7cd18975dc971387eb33a
(agent) [810lsp00gmj] Return Value: 82d476df642d6c882dcc438e028c6e0908af286439b7cd18975dc971387eb33a

通过返回值可以大胆猜测,密码经过了加密,将返回值输入的确通过了第一关,不过还需要结合源码分析下。
图片描述
发现是 HmacSHA256 加密,然后我们可以hmac在线加密输入加密对比下结果没问题,输入密码进入下一关。
图片描述

第二关:字符算法还原

问题:

界面提示点击进入下一关,肯定没那么简单,不出意外提示报错了。

分析:

这里只能结合源码分析了。
图片描述
将 R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL= 反向还原得到输入的密码,再用frida hook住b方法,则可进入到下一题。
a()b()方法的源码:

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
public static String a(byte[] bArr) throws Exception {
       StringBuilder sb = new StringBuilder();
       for (int i = 0; i <= bArr.length - 1; i += 3) {
           byte[] bArr2 = new byte[4];
           byte b = 0;
           for (int i2 = 0; i2 <= 2; i2++) {
               int i3 = i + i2;
               if (i3 <= bArr.length - 1) {
                   bArr2[i2] = (byte) (b | ((bArr[i3] & 255) >>> ((i2 * 2) + 2)));
                   b = (byte) ((((bArr[i3] & 255) << (((2 - i2) * 2) + 2)) & 255) >>> 2);
               } else {
                   bArr2[i2] = b;
                   b = 64;
               }
           }
           bArr2[3] = b;
           for (int i4 = 0; i4 <= 3; i4++) {
               if (bArr2[i4] <= 63) {
                   sb.append(table[bArr2[i4]]);
               } else {
                   sb.append('=');
               }
           }
       }
       return sb.toString();
   }
 
   public static byte[] b(String str) {
       try {
           ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
           GZIPOutputStream gZIPOutputStream = new GZIPOutputStream(byteArrayOutputStream);
           gZIPOutputStream.write(str.getBytes());
           gZIPOutputStream.finish();
           gZIPOutputStream.close();
           byte[] byteArray = byteArrayOutputStream.toByteArray();
           try {
               byteArrayOutputStream.close();
               return byteArray;
           } catch (Exception e) {
               e.printStackTrace();
               return byteArray;
           }
       } catch (Exception unused) {
           return null;
       }
   }

正规的算法还原,这里直接Hook通过了,后续在还原这个算法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var FridaActivity1 = Java.use("com.example.androiddemo.Activity.FridaActivity1");
FridaActivity1["b"].implementation = function (str) {
    console.log("FridaActivity1.b is called: str=${str}", str);
    var result = this["b"](str);
    console.log("FridaActivity1.b result=${result}", JSON.stringify(result));
    return result;
};
 
FridaActivity1["a"].implementation = function (bArr) {
    console.log("FridaActivity1.a is called: bArr=${bArr}", JSON.stringify(bArr));
    var result = this["a"](bArr);
    console.log("FridaActivity1.a result=${result}", result);
    result = 'R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL='
    return result;
};

第三关:修改方法值

图片描述
修改 静态成员变量和非静态成员变量的值 即可通过,但是给出来了2个函数,出题人的想法应该是让我们触发按钮的时候,主动调用这2个函数,来改变成员变量的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var FridaActivity2 = Java.use("com.example.androiddemo.Activity.FridaActivity2");
 
        FridaActivity2["onCheck"].implementation = function () {
 
            Java.choose("com.example.androiddemo.Activity.FridaActivity2", {
                onMatch: function (instance) {
                    instance.setStatic_bool_var();
                    instance.setBool_var();
 
                },
                onComplete: function () { }
            })
 
            this["onCheck"]();
        };

第四关:修改成员变量

观察代码:
图片描述
只要将三个成员变量的值改为true 即可通向下一关。

1
2
3
4
5
6
7
8
9
10
var FridaActivity3 = Java.use("com.example.androiddemo.Activity.FridaActivity3");
        // 设置静态成员变量的值
        FridaActivity3.static_bool_var.value = true;
        Java.choose("com.example.androiddemo.Activity.FridaActivity3",{
            onMatch:function(instance){
                instance.bool_var.value = true;
                instance._same_name_bool_var.value = true;
            },
            onComplete:function(){}
        })

第五关:修改内部类静态方法的返回值

看源码:
图片描述
将check的值全部改为 true,即可通过下一关。

1
2
3
4
5
6
7
8
9
10
11
12
var InnerClasses = Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses");
        InnerClasses["check1"].implementation = function () {
            var result = this["check1"]();
            result = true;
            return result;
        };
        InnerClasses["check2"].implementation = function () {
            var result = this["check2"]();
            result = true;
            return result;
        };
...

第六关:动态加载dex ,调用check()方法

代码:
图片描述

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
function hook_dyn_dex() {
        Java.perform(function () {
            var FridaActivity5 = Java.use("com.example.androiddemo.Activity.FridaActivity5");
            Java.choose("com.example.androiddemo.Activity.FridaActivity5", {
                onMatch: function (instance) {
                    console.log(instance.getDynamicDexCheck().$className);
                }, onComplete: function () {
                }
            });
            //hook 动态加载的dex
            Java.enumerateClassLoaders({
                onMatch: function (loader) {
                    try {
                        if (loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")) {
                            console.log(loader);
                            Java.classFactory.loader = loader;      //切换classloader
                        }
                    } catch (error) {
     
                    }
     
                }, onComplete: function () {
                }
            });
            var DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");
            console.log(DynamicCheck);
            DynamicCheck.check.implementation = function () {
                console.log("DynamicCheck.check");
                return true;
            }
        });
    }
 
 
 
}

第七关:修改类的方法

代码:
图片描述

将调用的三个class的方法改成true,即可通关。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var Frida6Class0 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class0");
Frida6Class0["check"].implementation = function () {
    var result = this["check"]();
    result = true;
    return result;
};
var Frida6Class1 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class1");
Frida6Class1["check"].implementation = function () {
    var result = this["check"]();
    result = true;
    return result;
};
var Frida6Class2 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class2");
Frida6Class2["check"].implementation = function () {
    var result = this["check"]();
    result = true;
    return result;
};

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2023-7-17 18:19 被kanxue编辑 ,原因: 将百度网盘附件转本地
上传的附件:
收藏
点赞2
打赏
分享
最新回复 (11)
雪    币: 1058
活跃值: (570)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
TrumpWY 2023-7-14 22:29
2
0
很棒,值得新手学习!
雪    币: 19349
活跃值: (28971)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-7-14 23:37
3
1
感谢分享
雪    币: 21817
活跃值: (3607)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
huangyalei 2023-7-14 23:59
4
0
谢谢,apk能提供吗?
雪    币: 3113
活跃值: (4526)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
西贝巴巴 2023-7-15 08:29
5
1
huangyalei 谢谢,apk能提供吗?
链接:https://pan.baidu.com/s/1zTZ5p5-dtdHxQea4FYaRPw 
提取码:a5ho 
--来自百度网盘超级会员V1的分享
雪    币: 8900
活跃值: (3344)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
chengdrgon 2023-7-15 11:37
6
0
感谢分享
雪    币: 109
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
萌木盖 2023-7-18 18:13
7
1

第五关-动态加载dex(你标题中的第六关)的另一种方法

Java.perform(function() {
    var CheckInterface = Java.use("com.example.androiddemo.Dynamic.CheckInterface");
    var RegisterClass = Java.registerClass({
                name: "com.dta.test.frida.activity.RegisterClass",
                implements : [CheckInterface],
                methods: {
                    check: {
                        returnType: "boolean",
                        argumentTypes:[],
                        implementation: function(){
                            return true
                        }
                    }
                }
            });
    Java.choose("com.example.androiddemo.Activity.FridaActivity5", {
        onMatch: function (instance) {
            instance.DynamicDexCheck.value = RegisterClass.$new();
        }, onComplete: function () {
        }
    });

});


雪    币: 3087
活跃值: (3747)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
青眼白龙 2023-7-18 22:20
8
0
感谢分享
雪    币: 6
活跃值: (239)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wantwill 2023-7-26 09:01
9
0
链接:https://pan.baidu.com/s/1zTZ5p5-dtdHxQea4FYaRPw  失效了
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
wx_吉拉德 2023-8-23 16:42
10
0
第四关:修改成员变量 
same_name_bool_var 反编译出来是这个。但是frida 设置参数的时候为何是
_same_name_bool_var  多了一个下划线才生效
雪    币: 225
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ICEtomato113 2023-9-1 17:19
11
0
第四关:修改成员变量 
根据思路解体,导致程序返回上一关之后就失效了,得重新hook 另外多个下划线不太明白
雪    币: 22
活跃值: (90)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
SPeakedness 2024-2-21 15:48
12
0
wx_吉拉德 第四关:修改成员变量 same_name_bool_var 反编译出来是这个。但是frida 设置参数的时候为何是 _same_name_bool_var 多了一个下划线才生效
是因为same_name_bool_var字段名与same_name_bool_var函数名相同,所以需要在前面加个下划线
游客
登录 | 注册 方可回帖
返回