<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    通過某音Cronet模塊學習Quic協議

    一顆小胡椒2022-03-12 16:03:33

    記錄下學習Quic協議的過程,測試工程是在之前發的帖子中提到的測試app:

    某視頻app(V15.7)及web分析記錄|bbs.pediy.com

    某視頻app(V15.7-V18.4)的學習記錄|bbs.pediy.com

    軟硬件環境:

    某音android (應用寶渠道)

    IDA 7.5

    Frida 14.2.2

    Gda

    JEB

    jadx-gui

    unidbg

    Wireshark

    LineageOs 17.1 (android 10)

    小米8

    了解到Quic也是從某音開始的,之前看過某音相關帖子提到Quic,說用Cronet就是走Quic協議,現在看感覺有概念問題,Cronet是協議棧組件,

    支持http,ftp 等很多種協議的,Quic也支持,用Cronet并不表示會走Quic協議。

    使用某音libsscronet.so訪問相同鏈接,是否開quic協議的返回數據對比,如下面2張調試截圖:

    開quic后mNegotiatedProtocol是 http/2+quic/43;

    關quic后是 h2。

    最開始看到quic時候一臉懵,查了些資料:

    Cronet網絡協議選擇之HTTP2與QUIC的競速_嗶哩嗶哩_bilibili

    QUIC探索(二):編譯第一個QUIC工程 - 簡書 (jianshu.com)

    [翻譯]QUIC 與 HTTP/3:太過龐大而致失敗?-- 論導致 QUIC 失敗的因素-外文翻譯-看雪論壇-安全社區|安全招聘|bbs.pediy.com

    實戰 | QUIC 協議助力騰訊業務提速 30% (qq.com)

    實戰 | QUIC 協議在螞蟻集團落地 (qq.com)

    受前面提到的一個某音帖子影響,以為手機上協議在傳輸層都是走quic的,直接截了下某音數據包,做了下常用操作(刷視頻,點贊,關注等),但是沒發現有quic相關的數據包,仍然還是TLS1.2的,這樣搞得完全不知道怎么回事。

    后來想到直接用測試app調用libsscronet.so連本地服務器看看,考慮到quic強制要求走加密的,這里要使用https連接(連本地服務器,需要屏蔽掉java層和native層的ssl證書校驗,so層的這個論壇有帖子說過了,java層的要是服務器是正式證書也不需要修改):

    UrlRequest.Builder requestBuilder = cronetEngine.newUrlRequestBuilder(        "https://10.0.117.217/about", new MyUrlRequestCallback(), executor);
    

    結果發現還是TLS1.2的,就說還是走的TCP:

     

    這里提下指紋JA3:

    tls.handshake.ja3_full:771,64250-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,2570-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-10794-21,2570-29-23-24,0[JA3: ca6385bf726b3d5f2b4db30186da0fec] 這個JA3,其實就是md5(ja3_full)。
    

    逗號隔開5個部分,分別對應如下:

    771: Version: TLS 1.2 (0x0303)64250-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53:
    

    2570-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-10794-21:

    2570-29-23-24:Supported Groups (4 groups)    Supported Group: Reserved (GREASE) (0x0a0a)    Supported Group: x25519 (0x001d)    Supported Group: secp256r1 (0x0017)Supported Group: secp384r1 (0x0018)
    

    這里最后一部分是0:

    猜測對應Extension: padding

    后來看到下面這張圖:

    想到會不會是因為沒走TLS1.3的緣故,打算本地用TLS1.3請求aweme.snssdk.com看看有什么返回,Node請求option要設置如下,需要v14.18.2以上版本:

    secureOptions: m_constants.SSL_OP_NO_TLSv1 | m_constants.SSL_OP_NO_TLSv1_1 | m_constants.SSL_OP_NO_TLSv1_2

    這樣看起來就是TLSv1.3的協議了,但是也沒看到有quic相關的信息。

    后來看一個資料提到youtube(https://www.youtube.com)已經支持quic訪問了,測試了下:

    確實有頭部字段Alt-Svc,下面文章有提到

    https://blog.csdn.net/wangyiyungw/article/details/81746901

    這種訪問QUIC服務的奇怪方式,要求終端事先知道訪問一個特定網站所用的協議及服務的端口。這樣是非常不靈活的,因而它主要用于缺乏適當的協議協商機制的情況下,用于QUIC協議的實驗階段。不久前,有一個稱為 替代服務(Alternative Services) 的HTTP機制標準化了,其標準規范文檔為 RFC7838。

    這種機制允許對一個HTTP資源的訪問,被重定向到另外的一個網絡位置,甚至是以一種不同的協議配置來訪問。具體而言,這種機制為HTTP新增了一個頭部字段Alt-Svc,HTTP服務器可以通過這個頭部字段,告知客戶端服務器被重定向到的服務的信息,包括協議,端口號等。

    通過手機瀏覽器訪問youtube,截包也能看到有quic相關協議:

    不過這里發現有的是GQUIC,查了下資料:

    gGUIC 與 iQUIC

    由 Google 創建并以 QUIC 的名稱提交給 IETF 的協議與隨后在 IETF 中創建的 QUIC 完全不同(盡管名稱相同)。最初的 Google QUIC(也稱為 gQUIC)嚴格來說是通過加密 UDP 發送 HTTP/2 幀的協議,而 IETF 創建的 QUIC 是通用傳輸協議,也就是說 HTTP 以外的其他協議(如 SMTP、DNS、SSH、Telnet、NTP)也可以使用它。

    重要的是要注意并記住其差異。自 2012 年以來,Google 在其服務及 Chrome 中使用的 QUIC 版本(直到 2019 年 2 月)為 Google QUIC。隨著時間的推移,它正在逐漸變得類似于 IETF QUIC(也稱為 iQUIC)。

    知道可以使用qui協議訪問youbube后,就想在測試app中使用cronet來訪問,需要設置enableQuic為true,及調用addQuicHint添加quic使用的域名:

    public CronetEngineBuilderImpl(Context context) {     this.mApplicationContext = context.getApplicationContext();     enableQuic(true);             //這里可以設置打開Quic     enableHttp2(true);     enableBrotli(false);
    

    addQuicHint("m.youtube.com",443,443);   //這里如果不設置,就會走tlsv1.3協議,設置后才會走QUIC協議。

    某音中途有個版本升到QuicVersion:c9f35932 2021-09-15,后來又降到了QuicVersion:68cae75d 2021-08-12,最新19.5版本的quic也還是這個版本。

    這里也能通過:

    cronetEngine.startNetLogToFile("/data/local/tmp/cronet_log.json",true);

    輸出日志,然后使用下面地址可以分析這個日志:https://netlog-viewer.appspot.com/#events

    這個其實也可以用在某音里面截包:

    Java.choose("org.chromium.CronetClient", {                           onMatch: function (instance) {                                                 instance.getCronetEngine().startNetLogToFile("/data/local/tmp/cronet_log.json", true);                    },       onComplete: function () { }});
    

    到這里后,已經能夠調用libsscronet.so走quic協議了,就想回過頭來繼續訪問某音協議,從頭分析了下數據,在某音啟動時候發現了quic數據包:

    看到了這個域名api5-core-c-lf.amemv.com。

    這里提一下,Quic是帶競速模式的,同時也會發送tcp鏈接,如遇網絡或服務器不支持quic/udp,客戶端標記quic為broken,后面會嘗試重試quic,一旦再次成功采用quic并把broken標記取消:

    后來發現了這個url,正好跟前面發現的域名一致的:

    https://api5-core-c-lf.amemv.com/top/v1?Action=ApplyUploadInner&Region=CN&SpaceName=aweme&UseQuic=false&Version=

    這里還有個字段UseQuic=false,更加說明這個協議涉及到的相關功能會用到quic(后來發現是視頻上傳相關的),雖然這個url請求本身不一定會走quic,但是這個域名跟之前截到的quic數據包中的一致,可以拿來測試。

    使用app測試訪問這個域名,也能正常走quic協議。

    到這里后,就要繼續看看這個協議格式及Cronet模塊中的quic請求流程了,

    調試時候斷在sendto能看到quic數據包:

    這里碰到了知識盲區,發現sendto調用的時候沒有設置目標地址參數,一下懵了,這怎么知道數據發哪里去的,也嘗試斷在sendmsg,發現不是,查資料后發現:

    UDP也可以有connect連接

    若sendto()函數和sendmsg()函數向已連接的進程中發送消息,則忽略參數dest_addr、addrlen和msg結構體中用于傳遞地址的成員。此時若參數dest_addr和addrlen不為NULL,則可能會返回錯誤EISCONN或0;

    連接套接字是需要一定開銷的,比如需要查找路由表信息。

    所以,UDP 客戶端程序通過 connect 可以獲得一定的性能提升。

    斷在connect后,發現了目標IP和端口:

    調試分析流程過程中,發現要是有個本地服務器會更方便,看網上有提到node支持quic,打算用node.js架設一個支持quic的服務器。

    直接下了個V16+的,結果發現不支持,后來查了下提交log,發現有次提交,去掉了這個quic支持:

    quic: remove experimental quic by jasnell · Pull Request #37067 · nodejs/node (github.com)

    需要拿15.X的代碼編譯,帶上experimental_quic

    git clone https://github.com/nodejs/node

    git checkout c4cab1f408

    在本地架好TCP UDP服務器后測試,也驗證了開啟quic請求url確實會同時發送tcp和udp的請求:

    在調試協議過程中,發現走不通,翻了下代碼,找到ngtcp2相關,查了下

    ngtcp2/ngtcp2: ngtcp2 project is an effort to implement IETF QUIC protocol (github.com)

    ngtcp2項目是實現IETF QUIC的協議,那跟某音這個還不同,協議幀最小數據長度也不一致,實際用這個測試需要基于某音版本修改。

    現在這個quic還沒統一,很多資料不是gquic的,就算是也可能是不同版本的。

    頭部格式目前就有幾種:

    enum PacketHeaderFormat : uint8_t {

      IETF_QUIC_LONG_HEADER_PACKET,

      IETF_QUIC_SHORT_HEADER_PACKET,

      GOOGLE_QUIC_PACKET,

    };

    想著還是直接用google版本的,把quiche拖下來了:

    https://chromium.googlesource.com/chromium/src;

    https://quiche.googlesource.com/quiche。

     

    這里面的協議就是跟某音quic協議一致的了,這里提下Pulic Flags的bit3:

    0x08: Bit3被置上就表示header中包含8字節的connection id 這個標志位在所有的包中都應該被設置

    google代碼中的注釋:

    // All versions of Google QUIC up to and including Q043 set
        // FLAGS_DEMULTIPLEXING_BIT to one on all client-to-server packets. Q044
        // and Q045 were never default-enabled in production. All subsequent
        // versions of Google QUIC (starting with Q046) require FLAGS_FIXED_BIT to
        // be set to one on all packets. All versions of IETF QUIC (since
        // draft-ietf-quic-transport-17 which was earlier than the first IETF QUIC
        // version that was deployed in production by any implementation) also
        // require FLAGS_FIXED_BIT to be set to one on all packets. If a packet
        // has the FLAGS_LONG_HEADER bit set to one, it could be a first flight
        // from an unknown future version that allows the other two bits to be set
        // to zero. Based on this, packets that have all three of those bits set
        // to zero are known to be invalid.
    

    看資料說google去掉了win上的編譯支持,就打算改下,希望能用VS編譯,方便調試,后來越改感覺工作量越多,放棄了,搜索發現了lsquic,還是c實現的,拿代碼下來編譯了個版本(基本按照文檔走,需要先編譯boringssl,perl,go都需要安裝,perl裝好后要手動加入環境變量,之前就卡這里了): 

    litespeedtech/lsquic: LiteSpeed QUIC and HTTP/3 Library (github.com)

    lsquic文檔:

    Tutorial — lsquic 3.0.4 documentation

    開啟自帶的測試程序中的服務器后,app上發起連接,服務器正常收到了請求,要記得設置證書啟動,不然處理CHLO Frame數據會異常:

    http_server.exe -r ./ -s 10.0.117.217:443 -c 10.0.117.217,file.crt,private.pem

    再鏈接發現有交互數據了:

    但是隨后就被客戶端斷了,發現是證書校驗錯誤,我這個測試證書是自己生成的:

    之前已經是修改了證書校驗的(java層和so的都修改了),能夠連接我本地的https服務器,但是連quic服務器不行,就算設置enablePublicKeyPinningBypassForLocalTrustAnchors 屬性也不行,說明走quic時候還有一個校驗,根據字符串找到下面地方:

    在google代碼中也找到對應的:

    根據代碼找到修改點:

    這個時候服務器沒收到客戶端因為校驗斷開的包了,截包發現認證也過了,不會像之前那樣斷開了:

    到這里后,基本上有了完整的調試環境,后面需要分析quic協議算法就可以很方便的帶源碼調試了。

    目前看起來某音并沒有大規模使用quic,從測試url看是上傳視頻可能會用到,但是我的測試環境也沒發現走quic,最近的幾個版本看見有協議中增加了下面信息:

    current_network_quality_info={"http_rtt":27,"tcp_rtt":15,"quic_rtt":15,"downstream_throughput_kbps":1600,"net_effective_connection_type":7,"video_download_speed":3311,"quic_receive_loss_rate":-1,"quic_send_loss_rate":-1}
    

    看起來是quic相關的,不知道是不是在收集用戶環境信息,評估用戶網絡環境,然后再決定是否部署quic。

    就算后面一些功能http協議都轉向quic,那也有很多切入點:

    1、對于走Cronet的,那還是可以在JAVA層對應jni函數及Cronet回調函數拿到請求數據。

    2、Cronet最終還是走native層的,在so層收發數據對應函數也可以拿到數據。

    3、用上面提到的cronetEngine.startNetLogToFile直接寫網絡日志(這個實際測試發現不全,還不確定是不是參數設置問題)。

    4、直接在quic實現部分的收發函數拿數據。

    5、了解quic協議過程后,還可以把各個通訊層級加密key記錄下來,直接解析udp截包數據。

    6、可以像上面測試那樣,搭建本地quic服務器,把請求轉到本地服務器來。

    httpsquic
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    記錄下學習Quic協議的過程
    奇安信威脅情報中心:本周高級威脅情報解讀(2021.11.04~11.11)
    WinRM 作為 Windows 操作系統的一部分,是一項允許管理員在系統上遠程執行管理任務的服務。
    Firebird是一個跨平臺的關系數據庫系統,目前能夠運行在Windows、linux和各種Unix操作系統上,提供了大部分SQL-99標準的功能。它既能作為多用戶環境下的數據庫服務器運行,也提供嵌入式數據庫的實現。
    https://www.winfe.net一、簡介WinFE (Windows Forensic Envir
    默認情況下,按時間倒序排列,首先顯示最新的文檔。Lucene查詢語法Kibana查詢語言基于Lucene查詢語法。這就意味著,會匹配到"Quick brown fox",而不會匹配"quick fox brown"。查詢解析器將不再基于空格進行分割。多個搜索項必須由明確的布爾運算符分隔。注意,布爾運算符不區分大小寫。在Lucene中,response:200 extension:php 等價于 response:200 and extension:php。這將匹配response字段值匹配200并且extenion字段值匹配php的文檔。默認情況下,and 比 or 具有更高優先級。
    2020年9月,Quick Heal披露了一起針對印度國防軍和武裝部隊陸軍人員的竊密行動并將其命名為Operation SideCopy。
    AES會話密鑰在每次木馬與C2通信時隨機產生,用于加密二者之間的通信信息。網絡通信部分有個sendMsg函數,其作用是發送加密數據。七總 結利用deimosc2工具進行C&C通信,攻擊者可以將通信內容加密從而規避傳統明文流量設備的檢測,但是基于人工智能、流行為特征和TLS限定域指紋檢測的加密威脅智能檢測系統能夠檢測此類加密通信行為。
    一個好用的RPC框架
    2023-06-05 09:41:11
    前言之前挖SRC時亦或者做題時,不想去分析對應的算法,很多時候就需要用hook,或者RPC調用對應的加密函數,發現一個很好用的RPC框架sekiro。訪問端口:http://ip:5612/,第一次打開會讓你注冊賬戶,第一個注冊賬戶默認將會成為管理員。然后去分組頁面創建一個分組,我這里用test1,方便監控:按照手冊里面的要求,安裝證書,不然后面可能會因為瀏覽器的安全策略而碰上奇奇怪怪的問題。對于一些CSP的問題,官方文檔也提供了解決辦法。
    QUIC(Quick UDP Internet Connections, 快速UDP網絡連接)是基于UDP的協議, 利用了UDP的速度和效率, 同時整合TCP, TLS和HTTP/2的優點并加以優化. 用一張圖可以清晰的表示他們之間的關系.
    一顆小胡椒
    暫無描述
      亚洲 欧美 自拍 唯美 另类