0x01 前言
获取xxx节点的途径多种多样,但大体有以下几种方法:
- 人工点击连接xxx节点,到网站上查询自己的IP归属
- 通过抓包获取xxx节点列表
- 根据app应用编写自动化脚本,模拟人工点击与连接获取节点信息
但是这三种方法各有利弊,对于第一种,人工分析太费时费力,但胜在节点有效性可以保证。第二种好处在于可以获得大量节点,准确性稍差,不过现在大多数应用节点信息都是加密传输的,所以效率不够高。第三种,节省了人工分析的时间,但是对于每个app都要编写脚本,优势在于可以持续性稳定的获取节点信息。
厌倦了人工分析,也不想碰运气抓到节点列表,编写脚本太麻烦。所以尝试通过获取应用节点列表以减轻工作量。最初的想法时对app进行逆向分析,直接hook获取节点的函数获得节点信息,但大多数app都进行了加固,脱壳是个问题,逆向更是个问题。然后想通过hook基本的加解密函数,打印其参数与结果,其中可能就包含了应用的节点列表,但是编写繁琐,应用也可能自己编写加解密函数,无果。
目前绝大多数app传递节点列表是使用的json格式数据,所以可以hook基础的json相关函数,就有一定的概率获取到节点列表。
0x02 frida hook
目前常用的三种解析json数据的方法,分别是Android系统自带的json解析、Google提供的Gson解析、阿里巴巴的fastjson解析。
Android系统自带的json相关包为: org.json.JSONObject
Google提供的Gson解析包为: com.google.gson.Gson
阿里巴巴的fastjson解析包为: com.alibaba.fastjson.JSON
简易脚本如下:
Java.perform(function () {
// 判断是否字串是否存在ip
function is_include_ip(str) {
var pattern = /((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/;
if(pattern.test(str)){
return true;
}
else{
return false;
}
}
// hook安卓默认json函数
var json_an_obj = Java.use('org.json.JSONObject');
json_an_obj.toString.overload().implementation = function () {
var ret= this.toString();
if(is_include_ip(ret)){
console.log('安卓默认json.toString(): '+ret)
}
return ret;
}
// hook安卓默认json构造函数
json_an_obj.$init.overload('java.lang.String').implementation = function(str){
if(is_include_ip(str)){
console.log('安卓默认json构造函数: '+str)
}
return this.$init(str);
}
// hook谷歌Gson函数
var json_gson_obj = Java.use('com.google.gson.Gson');
json_gson_obj.toString.overload().implementation = function () {
var ret= this.toString();
if(is_include_ip(ret)){
console.log('谷歌Gson.toString(): '+ret)
}
return ret;
}
// hook阿里fastjson函数
var json_fast_obj = Java.use('com.alibaba.fastjson.JSON');
json_fast_obj.parseObject.implementation = function (str) {
if(is_include_ip(str)){
console.log('阿里fastjson.toString(): '+str
}
return this.parseObject(str);
}
});
在模拟器开启frida之后,使用frida -U 进程名 -l json_hook.js
或者frida -U -f 包名 --no-pause -l json_hook.js
效果如下:
然后在网站:http://www.soshoulu.com/tools/getip.aspx 提取出ip地址即可。