NetBare

Project Url: MegatronKing/NetBare
Introduction: Net packets capture & injection library designed for Android
More: Author   ReportBugs   
Tags:

NetBare 是一款网络包拦截和注入框架,可以实现抓包、屏蔽包、改包等各种强大功能。NetBare 核心是基于 VPN 技术,将网络包转发到本地代理服务器,再通过虚拟网关(VirtualGateway)进行拦截分发。在设计上,虚拟网关层是完全对外开放的,开发者可以自由定义虚拟网关,也可以使用 NetBare 内部已实现的虚拟网关进行网络包的处理。

NetBare 初始化

  1. 在 Application 中绑定

    NetBare.get().attachApplication(application, BuildConfig.DEBUG)
    
  2. 创建自签证书(SSL 需要)

    val jks = JKS(context, alias, password, commonName, organization,
         organizationalUnitName, certOrganization, certOrganizationalUnitName)
    
  3. 安装自签证书(SSL 需要)

    // 判断证书是否安装
    JKS.isInstalled(context, alias)
    // 安装证书
    JKS.install(context, name, alias)
    
  4. 创建 NetBare 服务。由于 NetBare 具有危险性,所以在设计上会强制要求在通知栏提示用户服务正在运行,同时要在 Manifest 中配置 Service。

    // 继承 NetBareService 创建自己应用的 Service
    class AppService : NetBareService() {
         override fun notificationId(): Int {
             // 通知栏 ID
         }
         override fun createNotification(): Notification {
             // 创建一个 Notification
         }
    }
    
    <service android:name=".AppService"
             android:permission="android.permission.BIND_VPN_SERVICE">
             <intent-filter>
                 <action android:name="android.net.VpnService" />
                 <action android:name="com.github.megatronking.netbare.action.Start"/>
                 <action android:name="com.github.megatronking.netbare.action.Stop"/>
             </intent-filter>
    </service>
    
  5. NetBare 服务的启动和停止

    // 通过 NetBareConfig 自由配置 NetBare 服务并启动
    NetBare.get().start(NetBareConfig)
    // 停止 NetBare 服务
    NetBare.get().stop()
    

NetBareConfig 配置

NetBareConfig 需要使用 NetBareConfig.Builder 进行构造,解释下以下几个重要的配置方法。

  • setMtu 最大传输单元,必要,建议大于 2048。
  • setAddress 本地代理服务器 IP 地址,必要,建议用 A 类 IP 地址,防止冲突。
  • addRoute 设置经过 VPN 的目标 IP 包,必要,建议使用 0.0.0.0,所有 IP 全部经过 VPN。
  • dumpUid 是否 dump 网络包所属的 uid,可选,耗电方法,建议 false
  • setVirtualGatewayFactory 配置虚拟网关,可选。

NetBare 框架提供了默认的 NetBareConfig 来快速集成:

// 创建默认的 NetBareConfig,作用于所有 IP 协议
val config = NetBareConfig.defaultConfig()
// 为 Http 协议创建默认的 NetBareConfig
val config = NetBareConfig.defaultHttpConfig(jks, interceptors)

NetBare 虚拟网关

虚拟网关是对网络包进行拦截、解析、注入的核心,可以加载开发者自定义的拦截器,通过 NetBareConfig.Builder 来配置。NetBare 框架提供了两个默认的虚拟网关对象。

DefaultVirtualGateway

默认虚拟网关,可以拦截到所有协议的网络包。默认虚拟网关无法直接构造,需要通过 DefaultVirtualGatewayFactory 来进行构造。开发者可以使用 NetBareConfig.setVirtualGatewayFactory 配置默认虚拟网关工厂。

// 配置自定义拦截器
val interceptors = listOf(...)
//  创建默认虚拟网关工厂
val defaultGatewayFactory = DefaultVirtualGatewayFactory(interceptors)
// 通过 NetBareConfig.Builder 来配置 defaultGatewayFactory
...

虚拟网关拦截器,继承 Interceptor。Interceptor 使用工厂模式,由 InterceptorFactory 来构造。

class TestIntercepter : Interceptor {

    @Throws(IOException::class)
    override fun intercept(chain: RequestChain, buffer: ByteBuffer) {
        // 对请求包进行自定义处理
        ...
        // 将请求发射出去,交给下个拦截器或者发给服务器
        chain.process(buffer)
    }

    @Throws(IOException::class)
    override fun intercept(chain: ResponseChain, buffer: ByteBuffer) {
        // 对响应包进行处理
        ...
        // 将响应发射出去,交给下个拦截器或者发给客户端
        chain.process(buffer)
    }

    override fun onRequestFinished(request: Request) {
        // 请求包已全部发送完成
    }

    override fun onResponseFinished(response: Response) {
        // 响应包已全部发送完成
    }
}

HttpVirtualGateway

Http 协议虚拟网关,可以拦截到所有 Http 协议的网络包。Http 协议虚拟网关也无法直接构造,需要通过 HttpVirtualGatewayFactory 来进行构造。创建 HttpVirtualGatewayFactory 实例需要前面的 JKS 以及拦截器 HttpInterceptor。

// 配置自定义 HttpInterceptor
val interceptors = listOf(...)
//  创建 Http 虚拟网关工厂
val httpGatewayFactory = HttpVirtualGatewayFactory(jks, interceptors)
// 通过 NetBareConfig.Builder 来配置 httpGatewayFactory
...

Http 虚拟网关拦截器,继承 HttpInterceptor。同样的 HttpInterceptor 也使用工厂模式,由 HttpInterceptorFactory 来构造。

class TestHttpIntercepter : HttpInterceptor() {

    override fun intercept(chain: HttpRequestChain, buffer: ByteBuffer) {
        // 对 Http 请求包进行自定义处理
        ...
        // 将 Http 请求发射出去,交给下个拦截器或者发给服务器
        chain.process(buffer)
    }

    override fun intercept(chain: HttpResponseChain, buffer: ByteBuffer) {
        // 对 Http 响应包进行自定义处理
        ...
        // 将 Http 响应发射出去,交给下个拦截器或者发给客户端
        chain.process(buffer)
    }

    override fun onRequestFinished(request: HttpRequest) {
        // Http 请求包已全部发送完成
    }

    override fun onResponseFinished(response: HttpResponse) {
        // Http 响应包已全部发送完成
    }

}

此外,NetBare 框架内置了 HttpIndexInterceptor 等特殊拦截器方便开发者使用。

注入器 Injector

NetBare 提供了一套通用的 injector 框架来方便开发者注入请求和响应。Injector 框架是基于虚拟网关的拦截器来运行的。目前只开发了针对 Http 协议的注入器,其它协议可以后续再扩展。

Http 协议的注入是基于 HttpInjectInterceptor 拦截器来实现的,在配置 HttpVirtualGatewayFactory 的时候,需要配置此拦截器,每一个注入器对应一个拦截器实例。而所有注入器都必须实现 HttpInjector 接口。

class TestHttpInjector : HttpInjector {

    override fun sniffRequest(request: HttpRequest): Boolean {
        // 对 request 进行判定,是否需要注入。true 表示需要注入。
        return false
    }

    override fun sniffResponse(response: HttpResponse): Boolean {
        // 对 response 进行判定,是否需要注入。true 表示需要注入。
        return false
    }

    @Throws(IOException::class)
    override fun onRequestInject(header: HttpRequestHeaderPart,
                                 callback: InjectorCallback) {
        // 当 sniffRequest 返回 true 时,会走到此方法。
        // 对请求头部进行注入,包括 method、url、headers 都可以修改
        ...
        // 将注入完成后将新的数据发射出去
        callback.onFinished(header)
    }

    @Throws(IOException::class)
    override fun onResponseInject(header: HttpResponseHeaderPart,
                                  callback: InjectorCallback) {
        // 当 sniffResponse 返回 true 时,会走到此方法。
        // 对响应头部进行注入,包括 code、message、headers 都可以修改
        ...
        // 将注入完成后将新的数据发射出去
        callback.onFinished(header)
    }

    @Throws(IOException::class)
    override fun onRequestInject(request: HttpRequest, body: HttpBody,
                                 callback: InjectorCallback) {
        // 当 sniffRequest 返回 true 时,会走到此方法。
        // 对请求体进行注入,如果请求体数据较大,会多次走到此方法。
        ...
        // 将注入完成后将新的数据发射出去
        callback.onFinished(body)
    }

    @Throws(IOException::class)
    override fun onResponseInject(response: HttpResponse, body: HttpBody,
                                  callback: InjectorCallback) {
        // 当 sniffResponse 返回 true 时,会走到此方法。
        // 对响应体进行注入,如果请求体数据较大,会多次走到此方法。
        ...
        // 将注入完成后将新的数据发射出去
        callback.onFinished(body)
    }

    override fun onRequestFinished(request: HttpRequest) {
        // Http 请求包已全部发送完成
    }

    override fun onResponseFinished(response: HttpResponse) {
        // Http 响应包已全部发送完成
    }

将注入器绑定到拦截器,并装载到虚拟网关中:

// 配置自定义 HttpInjectInterceptor
val interceptor1 = HttpInjectInterceptor.createFactory(injector1)
val interceptor2 = HttpInjectInterceptor.createFactory(injector2)
...
val interceptors = listOf(interceptor1, interceptor2 ...)
//  创建 Http 虚拟网关工厂
val httpGatewayFactory = HttpVirtualGatewayFactory(jks, interceptors)
// 通过 NetBareConfig.Builder 来配置 httpGatewayFactory
...

NetBare 范例

NetBare 的接入步骤就有些繁琐,所以提供了一个简单的 Sample 工程供大家参考。sample 中包含三个比较有趣的东西:

  • 拦截器 1:打印所有 Http 请求的 URL。
  • 注入器 1:将百度首页的 logo 图片修改成自定义的图片。
  • 注入器 2:将发朋友圈的定位地点修改到珠峰。

结语

NetBare 框架尚未完全成熟,仍然有很多工作要做,包括 ICMP、IGMP 等 IP 协议的转发等等,后续会继续完善。

基于 NetBare 实现的一款抓包+注入工具,欢迎大家下载体验:https://play.google.com/store/apps/details?id=com.guoshi.httpcanary

声明:DON'T BE EVIL!NetBare 只可用于学习和调试,禁止用于网络恶意攻击和钓鱼等非法途径

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools