APP抓不到包也许是NO_PROXY在作怪 – 作者:JustForHE

0x1 开始

有一天交流时抛出一个问题,有没有遇到过apk在网络交互过程中,burpsuite和fiddler等抓包工具,无法抓取数据包,是否知道原因,以及如何解决? 今天就把这坑给填了

0x2 示例1

OKHttp3是一个当前主流的网络请求的开源框架,我们就用这个框架来进行说明 首先我们构建一个简单的demo

package com.example.fridatest;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.view.View;
import android.widget.Toast;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.net.Proxy;
import java.util.Objects;

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

this.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onClick(View v) {
new Thread(new Runnable(){
@Override
public void run() {
Looper.prepare();
OkHttpClient okHttpClient = new OkHttpClient.Builder().
build();
Request request = new Request.Builder()
.url("http://www.baidu.com/?id=1")
.build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
String ss= Objects.requireNonNull(response.body()).string();
System.out.println(ss);
Toast.makeText(MainActivity.this,ss,Toast.LENGTH_SHORT).show();

} catch (IOException e) {
e.printStackTrace();
}
Looper.loop();
}
}).start();
}
});

}

}

apk功能很简单,提供一个按钮,点击后访问url(http://www.baidu.com/?id=1),弹窗显示Response。

运行app,并点击按钮后可见下图

1600170017.png!small

可以看到请求发出,并被抓包工具记录

0x3 示例2

我们给示例1修改下,添加上no_proxy

package com.example.fridatest;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.view.View;
import android.widget.Toast;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.net.Proxy;
import java.util.Objects;

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

this.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onClick(View v) {
new Thread(new Runnable(){
@Override
public void run() {
Looper.prepare();
OkHttpClient okHttpClient = new OkHttpClient.Builder().
proxy(Proxy.NO_PROXY).//添加proxy属性
build();
Request request = new Request.Builder()
.url("http://www.baidu.com/?id=1")
.build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
String ss= Objects.requireNonNull(response.body()).string();
System.out.println(ss);
Toast.makeText(MainActivity.this,ss,Toast.LENGTH_SHORT).show();

} catch (IOException e) {
e.printStackTrace();
}
Looper.loop();
}
}).start();
}
});

}

}

同样运行apk,查看结果此时的结果显示,请求成功,但抓包工具没改请求记录,说明数据未经过代理。

1600170083.png!small

0x4 绕过

我们尝试用frida hook掉proxy函数

我们先找到proxy函数的位置,通过android Studio可以轻松实现

okhttp-3.14.0.jar!\okhttp3\OkHttpClient.class:461

1600170123.png!small

从类结构来看,可以看到这个方法处于OkHttpClient这个类的一个叫Builder的内部类中

1600170127.png!small

利用同样的方式,我们也查看了Java.net.Proxy这个类的结构(proxy方法中需要传入这个参数)

1600170140.png!small

然后可看到NO_PROXY这个参数实际上的内容如下

1600170147.png!small

鉴于以上内容,我们需要hookOkHttpClient的Builder内部类的proxy方法。将参数修改成null即可。 最终的脚本如下

console.log("[*] Starting script");
Java.perform(function () {
var ss = Java.use("okhttp3.OkHttpClient$Builder");

ss.proxy.implementation = function (x) {
console.log(x.type())
console.log(x.address())
console.log(x)
//以上打印的是java.net.proxy中附带的方法。具体看查看源码
return this.proxy(null)
}
});
console.log("end");

最终运行结果如下,成功让代理获取到数据

1600169972.png!small

来源:freebuf.com 2020-09-15 20:03:05 by: JustForHE

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论