抓包,反抓包,反反抓包


前言

當年還在學校的時候,就接觸到了抓包,當時還在貼吧寫了一篇小白文來誤導小白(不是。但當時的自己還沒接觸到逆向,竟然對抓包沒有提起興趣,說到底又是太年輕,不懂事。時至今日,才發現它是安全人員必須要掌握的基本技能,面試安全崗位也多多少會問到與抓包相關的知識。抓包(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
		}

	})
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM