前言
该文章仅是为了技术交流,如有侵权,请立即联系删除!!!
该文章主要分析了某个潮流app的下单的接口的某个参数还原思路(当然此时某些大佬想到的是某个知名app,然而并不是,因为该app已经有某个知名大佬写过了,我知道是谁,但我不说,嘿嘿嘿…那篇文章我看过了,受教很多,xxx爹yyds!!!),有兴趣交流的大佬,欢迎进群交流(成都逆向天团),除了我都是大佬,个个都是高富帅,3米多高。
一、pandas是什么?
pandas是。。。。是个屁,我也不会。。。
二、开始凑篇幅
1.抓包分析需要还原的参数
安排尿壶和postern进行点击购买抓包分析
经过多次抓包重放测试 应该就是这个了。
2.定位参数加密位置
这里的话我一般有一个自己的思路,不知道准不准确,就是这里他是一个字典类型(python里面是这么叫的),然后他在java中发请求时,他会先将这些参数put到一个map里面去,然后利用frida相关的去hook这个方法加上过滤出我们需要的字段,然后,然后编不下去了,因为这个app没hook到,这里我是用了另外一个判断该字段的值存不存在的方法去hook(因为在python里面我也经常判断)。
var params = Java.use("android.text.TextUtils");
params.isEmpty.implementation = function(str){
showStack();
console.log("str:",str);
return this.isEmpty(str);
}
通过打印出的堆栈去java看看他的逻辑(该app有一层某厂的壳),然后根据堆栈一步一步的hook参看参数与结果,先从发请求的附近开始:
然后进入AsyncHttpTaskOKHttp方法,
console.log("2 arg =====================")
console.log("str:",str+"\n");
console.log("str1",str1+"\n");
var res2 = this.getHttpTask(str,str1);
console.log("res2: ",res2);
return this.getHttpTask(str,str1);
};
打印的结果为(提示一下:这里的[object object],如果需要转换的话 一般可以使用 JSON。Stringfy,或者明确是什么类型的话 可以使用Java.cast来转换,因为这里我们不需要看结果,所以我就没做处理):
由图可得,这里已经生成了 那就按照这种思路继续往下走,一直走到他生成的地方。
说时迟那时快啊 这里就是了。。。
3.so层分析
该app是通过静态加载 然后用小姐姐(IDA)打开后,在导出表中通过静态的注册的命名规则(Java_+java中该函数所在的 包名_+类名_+方法名_)来定位到该函数的位置
继续看,前面都是一些字符类型的抓换和一些不必要的交代,不如出去不要打架惹事啊,呸,跑题了,就是一下字符串的声明啊之类的。这里才是重点,是他最终对传进来的字符串的一些操作加密等,所以直插主题。
进入那个重点的函数:
因为在上面给出的第一张so代码里面有出现JNI调用Java层函数,所以这里我有重新hook了下这个重要的函数(nice_sign_v3),看看究竟传进来的是什么东西 (其实一般我都有这个习惯,不能太相信Java里面调用的native函数,容易出问题):
其中第三个参数是一个随机生成的字符,这回就彻底明朗了。
首先潦草的分析一下,然后遇到操作的地方可以通过hook来查看细节,这下面就是之前做的时候第一遍潦草的分析的手稿
现在需要处理的有以下几点:
(1)md5和sha1加密是否有过魔改;
(2)他的交换规则是什么样的;
(3)没了。
通过hook 函数j_swap_char可以得到他交换的规则(看他的源码也行,但我就不!)
得出他的第二参数是一个固定的did的值,交换的规则就是将32位的前后16位交换位置
(2)鉴定md5加密算法,同样hook:
对比了下,没问题,就懒得去看源码还原了,同理去鉴定sha1加密,然后发现没啥问题。
然后,好像确实没啥了,挺简单的,也没啥混淆,也没有魔改算法之类的等等其他我不会的东西,也就是多了几步对加密结果的操作,我就稍微总结一下整个加密路线吧:
(1)将第二个参数拿去md5(试过很多次都没变,是前面返回来的,具体是啥没研究,因为menage需求,当初就是为了拿来练手的);
(2)然后将加密结果交换以后在前面拼接第三个参数(那一串随机数)在加密结果的后面拼接一段固定的字符串再md5;
(3)然后将第二次的md5结果接着swap,同时将那个map(第一个参数)转换成字符串拿去移位操作,得出的新字符串拼接在md5的前面;
def translate_str(old_str):
new_str = ""
temp_list = []
for i in range(0, int(len(old_str) / 2)):
temp_list.append(ord(old_str[2 * i]) & 0xF0 | (ord(old_str[2 * i + 1]) & 0xF))
for i in range(len(temp_list)):
new_str += chr(temp_list[i])
return new_str
(4)然后将拼接的字符串进行sha1加密,最后取最后32位字符串,完事!
代码复现结果
搞定~
总结
没啥总结的,特此感谢Alive徐少给的app练手,还有杨总,祝你们好人一胎十个。。。