app渗透测试请求包加密如何进行自动化测试


嘟嘟牛在线案例

抓包

  • 电脑usb真机连接手机界面如下

电脑usb真机连接

  • 随便输入点击登录

随便输入点击登录

  • 可能返回2,这里使用postern 和Charles 抓包。配置好postern代理

postern 和Charles

  • 打开Charles进行抓包

Charles进行抓包

POST /api/user/login HTTP/1.1
If-Modified-Since: Sat, 11 Feb 2023 08:24:10 GMT
Content-Type: application/json; charset=utf-8
User-Agent: Dalvik/2.1.0 (Linux; U; Android 10; Pixel Build/QP1A.191005.007.A3)
Host: api.dodovip.com
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 248

{"Encrypt":"NIszaqFPos1vd0pFqKlB42Np5itPxaNH\/\/FDsRnlBfgL4lcVxjXii\/UNcdXYMk0EFbT8S8sTz7fW\n5ElmCRHm1SJQF76FKmSR9iSVviBXFx+vvRhLM14Q3LH+UIUx2DmyebXLy7V5vYDpFb5iABBQIvTu\nvGJ3s8vC3PVQwH6M+1oELCAimzf0qYiBzKfzU0Id4Rxf\/FUJ+OJM5LbrL+rRwTMGBmTms2de\n"}


响应包如下:
HTTP/1.1 200 OK
Date: Sat, 11 Feb 2023 08:26:40 GMT
Content-Type: application/json;charset=utf-8
Transfer-Encoding: chunked
Server: Nginx
Content-Encoding: gzip
Connection: keep-alive

2v+DC2gq7Rs2vBLjHBwgrO0gyauGMTE6

使用工具查看是否是安卓控件开发的

  • app 界面控件的查看 使用 uiautomatorviewer.bat是否是安卓开发的

uiautomatorviewer是否是安卓开发的

搜索请求包特征使用frida确定经过函数

  • 我们使用jadx反编译一下看看

jadx反编译

  • 包名是com.dodonew.online 来搜索请求包的特征搜索字符串 “Encrypt

含有Encrypt字符串

代码截图

  • 搜索出有两个,确定到底是哪个使用frida来hook判断确定

frida hook判断

  • com.dodonew.online.http.JsonRequest 的这个方法是走的

确定加密流程1

确定加密流程2

  • com.dodonew.online.http.JsonRequest paraMap 这个登陆是不走的

确定不走这个流程

跟踪分析流程和加密算法

  • 就看第一个了代码如下
  public void addRequestMap(Map<String, String> addMap, int a) {
String time = System.currentTimeMillis() + "";
if (addMap == null) {
addMap = new HashMap<>();
}
addMap.put("timeStamp", time);
String code = RequestUtil.paraMap(addMap, Config.BASE_APPEND, "sign");
String encrypt = RequestUtil.encodeDesMap(code, this.desKey, this.desIV); //key 65102933  iv  32028092
JSONObject obj = new JSONObject();
try {
obj.put("Encrypt", encrypt);
this.mRequestBody = obj + "";
} catch (JSONException e) {
e.printStackTrace();
}
}

public static final String BASE_DES_IV = "32028092";  //字符串
public static final String BASE_DES_KEY = "65102933" //字符串

this.enCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
this.deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
  
  • 重点就是RequestUtil.encodeDesMap
  Java.perform(function () { //java层的hook代码

var jsonRequest= Java.use("com.dodonew.online.http.RequestUtil");

console.log("test");
jsonRequest.encodeDesMap.overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation=function (data,key,iv){

console.log(data);

return this.encodeDesMap(data,key,iv);
}


});
  

重点流程截图

  • 现在sgin是不知道怎么来的看看 sign值如下

sign加密流程

  • String checkCode = Utils.md5(builder.toString()).toUpperCase(); addMap.put("sign", checkCode);

编写firda hook代码

hook代码

  Java.perform(function () { //java层的hook代码

var Utils= Java.use("com.dodonew.online.util.Utils");

console.log("testaa");
Utils.md5.implementation=function (data){

console.log("sign数据:"+data);
var md5=this.md5(data);
console.log(md5);
return md5;
}

var RequestUtil= Java.use("com.dodonew.online.http.RequestUtil");

console.log("test");
RequestUtil.encodeDesMap.overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation=function (data,key,iv){

console.log("要加密的数据:",data);

var encodeData= this.encodeDesMap(data,key,iv);
console.log(encodeData);
return encodeData;
}

});
  

加密流程分析

  • sign数据:equtype=ANDROID&loginImei=Androidnull&timeStamp=1676112935252&userPwd=111&username=111125563&key=sdlkjsdljf0j2fsjk de729eee7e7c53f220292712c686b94d 要加密的数据: {"equtype":"ANDROID","loginImei":"Androidnull","sign":"DE729EEE7E7C53F220292712C686B94D","timeStamp":"1676112935252","userPwd":"111","username":"111125563"} NIszaqFPos1vd0pFqKlB42Np5itPxaNH//FDsRnlBfgL4lcVxjXii/UNcdXYMk0EHdbdwRDGADPvJlZMZqsYcRLgBo9ZcfD+QFQcNIEUonlHHkJ40A/3P/7z+jmJS0Tr3kaMU/y5tVOjyDyQIAskXC+ZknputIDnDC1V23cu2PAeGn/EnUn367Pj0cdcOVWQ1k+Rg4qybOMnYUVOLvG8SA==

    总体流程是

    md5(equtype=ANDROID&loginImei=Androidnull&timeStamp=1676112935252&userPwd=111&username=111125563&key=sdlkjsdljf0j2fsjk) 至于是不是标准的md5暂不看

    然后在把数据变成json数据

加密流程截图


key是md5以后 弄成十六进制
iv 是直接十六进制
public static final String BASE_DES_IV = "32028092";  //字符串
public static final String BASE_DES_KEY = "65102933" //字符串

this.enCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
this.deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

key:c3d26dca86259782bd9186481f892ae6       Hex byte
iv:3332303238303932                          hex byte

使用工具模拟解密请求数据包

工具模拟解密加密数据

编写hook脚本在bp可以对明文进行修改

  • 既然先经过md5然后我们可以编写一个脚本让他经过bp来修改进行测试 参考脚本https://github.com/L3B1anc/simpleencrypt
  • 修改一下我们 核心代码
  
   send(string)


      var op = recv(function(value) {
    console.log("<li> js recv encryptdata content: " + value);
    string =  value;
});
op.wait();
    
  • hook.js 编写这个是重点注意 方法内修改属于值传递所以需要吧用户名和密码单独提取出来进行赋值修改 代码如截图

hook.js代码

  • frida_hook.py

frida_hook.py

  • trace.py 脚本

trace.py

实战hook修改明文

  • 启动frida server 怎么安装和启动情况博客里面的教程。先运行frida-hook.py脚本 在运行trace.py脚本
  • frida-hook.py 运行界面


  • trace.py 运行界面


  • 配置好bp代理手机点击登录

bp代理配置

hook后数据截图

软件解密

  • 这就可以测试了

bp测试

自动化对功能进行测试(frida RPC主动调用)

  • 如何进行自动化测试呢比如我用sqlmap 对用户名和密码进行测试如何进行。这时候就不用hook了我们使用rpc主动调用来测试执行。需要修改trace.py 增加python发包请求添加rpc主动调用
  • firda开启远程监听模式

frida远程监听

  • 修改后的trace.py代码截图 关键代码截图

修改后的trace.py代码截图

运行trace.py

  • 至此就可以任意进行测试了

自动化测试截图

  • 完整代码以及测试app 内部放出

完整代码以及测试app


文章作者: peiqiF4ck
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 peiqiF4ck !
  目录