声明:
免责声明:本文为个人作品,只做技术研究,只可用于正常的技术交流与学习,不可用于灰黑产业,不可从事违法犯罪行,严禁利用本文所介绍的技术恶意攻击,否则,后果自负!!!
上一篇文章 非root情况下安卓Hook Java方法,修改返回值_pyth0zn的博客-CSDN博客
我们讲解了tweakMe的使用方法,以及如何hook安卓api的方法,在实际工作中,我们经常遇到一些app的返回包和请求包都加密了的情况,如果我们要修改请求包,那么就需要把加密方法还原,然后自己构造数据包,然后加密发送给服务器,同样的拿到加密后的返回包,也需要用解密方法解密。这个过程如果加解密逻辑不复杂还好,但是如果是特别复杂的,比如什么动态key啊,那就太麻烦了,那么有没有简单的办法呢?请看下张图
OK 上面的图已经描述的很明显了。
下面我们看tweakMe代码怎么写
首先我们在 util目录下新建一个工具类 InterceptEncryptOrDecrypt
package com.android.guobao.liao.apptweak.util;
import android.util.Log;
import com.android.guobao.liao.apptweak.JavaTweakBridge;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class InterceptEncryptOrDecrypt implements Callable<String> {
private String postBody;
public void setHttpUrl(String httpUrl) {
this.httpUrl = httpUrl; }
private String httpUrl;
private void setPostBody(String postBody) {
this.postBody = postBody;
}
private String ECHO_SERVER="http://192.168.31.100:27080"; //echo server 电脑段 运行 echerServer.py
public static String doHttp(String postBody,String httpUrl) throws ExecutionException, InterruptedException {
InterceptEncryptOrDecrypt d1=new InterceptEncryptOrDecrypt();
d1.setPostBody(postBody);
d1.setHttpUrl(httpUrl);
FutureTask<String> task=new FutureTask<>(d1);
new Thread(task).start();
if (!task.isDone()) {
System.out.println("task has not finished, please wait!");
}
System.out.println( "task return: " + task.get());
return task.get();
}
@Override
public String call() throws Exception {
String rsp="";
JavaTweakBridge.writeToLogcat(Log.ERROR,"[*****]调用前原始参数 %s \n",postBody);
try {
HttpURLConnection con = null;
BufferedReader buffer = null;
StringBuffer resultBuffer = null;
URL url = new URL(ECHO_SERVER+httpUrl);
//得到连接对象
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
"192.168.31.100", 8888)); //burp端口
con = (HttpURLConnection) url.openConnection(proxy);
//设置请求类型
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
//允许写出
con.setDoOutput(true); //允许读入
con.setDoInput(true);
con.setUseCaches(false);
OutputStream os = con.getOutputStream();
os.write(postBody.getBytes());
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // 必须返回200
InputStream inputStream = con.getInputStream();
//将响应流转换成字符串
resultBuffer = new StringBuffer();
String line;
buffer = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
while ((line = buffer.readLine()) != null) {
resultBuffer.append(line);
}
rsp= resultBuffer.toString();
}
} catch (Exception e) {
JavaTweakBridge.writeToLogcat(Log.ERROR,"echo Server 报错");
e.printStackTrace();
}
JavaTweakBridge.writeToLogcat(Log.ERROR,"[*****]调用前修改后的参数 %s \n",rsp);
return rsp;
}
}
我们的类继承了Callable这个回调方法,主要就是多线程接受一个postBody,然后把他发送给EchoServer,echoServer 就是利用python自带的脚本起了一个27080的webserver,功能是原样输出请求包,同时这个请求用的是burp的代理
然后我们到拦截java加密函数的地方。调用这个InterceptEncryptOrDecrypt方法就好
解密是同样的道理、区别就是先执行一次原始函数,然后再把解密的结果发送给burp,然后return原来的函数就可以了
看下效果,可以看到从app提交的手机号,经过burp修改后,最后发送给服务器的是另外一个手机号,让app继续走加密的逻辑
burp中的修改记录
这样我们就实现了类似frida的 send 功能,ok 本文就到这