zoukankan      html  css  js  c++  java
  • 抓包,反抓包,反反抓包

    前言

    当年还在学校的时候,就接触到了抓包,当时还在贴吧写了一篇小白文来误导小白(不是。但当时的自己还没接触到逆向,竟然对抓包没有提起兴趣,说到底又是太年轻,不懂事。时至今日,才发现它是安全人员必须要掌握的基本技能,面试安全岗位也多多少会问到与抓包相关的知识。抓包(packet capture)是查看数据包发送和接收过程的手段。抓包也有很多种办法,可以在软件层面对函数进行hook,查看发送或接受的数据包,还有利用WireShark,tcpdump,Fiddler,Charles等第三方工具来抓包。本文演示如何利用Charles来对AndroidApp进行抓包,并且强行让App走代理

    工具准备

    步骤

    安装Charles后打开。依次选择菜单Proxy -> SSL Proxying Settings...

    在SSL Proxying标签下勾选Enable SSL Proxying,再点击Add按钮

    添加一条Host为*,Port为443的规则,如图:

    点击OK

    依次点击Help -> SSL Proxying -> Save Charles Root Certificate...导出根证书,另存为charles.pem

    将下载好的OpenSSL放入环境变量

    转到证书导出目录,打开命令行,执行以下命令:

    openssl x509 -subject_hash_old -in charles.pem
    

    根据输出的内容,将charles.pem重命名为b6a3624b.0,注意文件后缀是0

    然后重新挂载手机的system分区

    adb root
    adb remount
    

    将重命名后的文件推入/system/etc/security/cacerts目录中

    adb push b6a3624b.0 /system/etc/security/cacerts
    

    回到Charles,依次选择Proxy->Proxy Settings

    设置一个端口,按确定

    在手机WIFI设置页面,给连接的WIFI设置代理,代理到Charles。代理服务器主机名写电脑的主机名或者ip地址,代理服务器端口写上面在Charles中设置的端口,写完后点保存

    接下来,手机的https包都会被转到Chales中,并成功解析

    当然,有时候事情不会那么顺利。咱们抓包,那别人也会想办法防止抓包。如果抓包的时候我们知道应用明明有http请求但是在抓包工具中却抓不到包,那么应用中很有可能设置了不让请求走代理,常用的设置代码如下:

    1. URLConnection类
        public static String get(String urlStr){
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            InputStream inputStream = null;
            try {
                URL url = new URL(urlStr);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
                httpURLConnection.setRequestMethod("GET");
                inputStream = httpURLConnection.getInputStream();
                if(httpURLConnection.getResponseCode() == 200) {
                    byte[] buf = new byte[1024];
                    int len = -1;
                    while ((len = inputStream.read(buf)) != -1) {
                        byteArrayOutputStream.write(buf, 0, len);
                    }
                }
            }
            catch (Exception e){
                return e.toString();
            }
            finally {
                close(inputStream);
                close(byteArrayOutputStream);
            }
            return byteArrayOutputStream.toString();
        }
    

    注意上面的openConnection(Proxy.NO_PROXY),这就是设置请求不走代理的地方

    1. OkHttp库
        public static String get(String url)  {
            OkHttpClient.Builder client = new OkHttpClient.Builder();
    //        //方式一:
    //        client.proxy(Proxy.NO_PROXY);
    //        //方式二:
            ProxySelector proxySelector = new ProxySelector() {
                @Override
                public List<Proxy> select(URI uri) {
                    return null;
                }
    
                @Override
                public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
    
                }
            };
            client.proxySelector(proxySelector);
            Request request = new Request.Builder()
                    .url(url)
                    .build();
    
            try (Response response = client.build().newCall(request).execute()) {
                return response.body().string();
            }
            catch (Exception e){
                return e.toString();
            }
        }
    

    同样的,上面注释标出的地方也是设置请求不走代理

    针对这些我们可以利用Hook相应的方法强行让http请求走代理,这里使用frida来进行hook,代码如下:

    if(Java.available){
    	Java.perform(function(){
    		//openConnection
    		var URL = Java.use("java.net.URL")
    		var openConnection1 = URL.openConnection.overload("java.net.Proxy")
    		var openConnection2 = URL.openConnection.overload()
    		openConnection1.implementation = function(proxy){
    			console.log("openConnection() proxy = " + proxy)
    			return openConnection2.call(this)
    		}
    		//okhttp
    		var OkHttpClientBuilder = Java.use("okhttp3.OkHttpClient$Builder")
    		var proxy = OkHttpClientBuilder.proxy.overload("java.net.Proxy")
    		proxy.implementation = function(proxy){
    			console.log("proxy() prxoy = " + proxy)
    			return null
    		}
    
    		var proxySelector = OkHttpClientBuilder.proxySelector.overload("java.net.ProxySelector")
    		proxySelector.implementation = function(proxySelector){
    			console.log("proxySelector() proxySelector = " + proxySelector)
    			return null
    		}
    
    	})
    }
    
  • 相关阅读:
    数据结构笔记(第三章)
    数据结构笔记(第二章)
    Java第三阶段学习(四、缓冲流)
    Java第三阶段学习(三、字符流、转换流)
    Java第三阶段学习(二、IO流--------递归,字节流Stream)
    Java学习(异常类)
    Java学习(异常类练习题)
    Java学习(JDBC java连接数据库)
    Java学习(Map接口)
    Java学习(set接口、HashSet集合)
  • 原文地址:https://www.cnblogs.com/luoyesiqiu/p/packet_capture.html
Copyright © 2011-2022 走看看