android逆向奇技淫巧五:x音fiddler抓包分析協議字段


  android逆向奇技淫巧第二篇介紹了通過method profiling追蹤找到了點贊的方法,於時就用jadx打開,找到了onclick的代碼: com.ss.android.ugc.aweme.feed.quick.presenter.cb類下面的onclick方法:混淆非常嚴重,只能看懂java語法,至於代碼的業務意義大部分是不好理解的;單從部分未混淆的方法和變量名看,點擊后會先判斷是否登陸,如果沒登陸就彈出登陸界面;如果登陸了就show各種toast;具體是哪行代碼向服務器發送數據了?靜態分析完全看不出來!

public final void onClick(View view) {
            String string;
            boolean z = false;
            if (!PatchProxy.proxy(new Object[]{view}, this, f171628a, false, 251117).isSupported) {
                ClickAgent.onClick(view);
                cb.this.f172363h.a("VIDEO_CANCEL_REPORT_SKIP_BEHAVIOR", cb.this.f172358c.getAid());
                int b2 = m.b();
                if (b2 == 0) {
                    z = !AccountProxyService.userService().isLogin();
                } else if (b2 > 0 && !AccountProxyService.userService().isLogin() && !cb.this.l && cb.this.f172358c.getUserDigg() == 0 && bh.b() >= b2) {
                    z = true;
                }
                if (z) {
                    new z().a(cb.this.f172359d).a(cb.this.f172361f).b(cb.this.f172358c.getAid()).f(cb.this.f172358c).c("click_like").c(!bh.d() ? 1 : 0).d(1).e();
                    if (!bh.d()) {
                        bh.c();
                    }
                    String str = "";
                    if (TextUtils.equals(cb.this.f172359d, e.c.f229429a)) {
                        string = str;
                    } else {
                        string = cb.this.m.getString(C4212R.string.f4m);
                    }
                    if (cb.this.f172358c != null) {
                        str = cb.this.f172358c.getAid();
                    }
                    if (a.h().isTeenModeON()) {
                        AccountProxyService.showLogin((Activity) cb.this.m, cb.this.f172359d, "click_like", av.a().a("login_title", string).a("group_id", str).a("log_pb", ae.k(str)).f262690b, null);
                        return;
                    }
                    AccountProxyService.showLogin((Activity) cb.this.m, cb.this.f172359d, "click_like", av.a().a("login_title", string).a("group_id", str).a("log_pb", ae.k(str)).f262690b, new cd(this, view));
                } else if (com.ss.android.ugc.aweme.login.utils.a.a(cb.this.f172358c) && cb.this.f172358c.getUserDigg() == 0) {
                    DmtToast.makeNegativeToast(cb.this.m, com.ss.android.ugc.aweme.login.utils.a.a(cb.this.f172358c, C4212R.string.n0t)).show();
                } else if (cb.this.f172358c.isCanPlay() || cb.this.f172358c.getUserDigg() != 0) {
                    if (cb.this.f172358c.isDelete() && cb.this.f172358c.getUserDigg() == 0) {
                        DmtToast.makeNegativeToast(cb.this.m, (int) C4212R.string.n0t).show();
                    } else if (cb.this.f172358c.getVideoControl() != null && cb.this.f172358c.getVideoControl().timerStatus == 0) {
                        DmtToast.makeNeutralToast(cb.this.m, (int) C4212R.string.mza).show();
                    } else if (ac.f262626b.d(cb.this.f172358c)) {
                        DmtToast.makeNeutralToast(cb.this.m, (int) C4212R.string.h6t).show();
                    } else if (cb.this.l || !ac.f262626b.c(cb.this.f172358c) || !ac.f262626b.a(cb.this.f172358c)) {
                        ((DiggAnimationView) cb.this.G.a(C4212R.id.byb).a()).a(view);
                        if (!NetworkUtils.isNetworkAvailable(cb.this.m)) {
                            DmtToast.makeNegativeToast(cb.this.m, (int) C4212R.string.f288170d).show();
                            return;
                        }
                        cb cbVar = cb.this;
                        cbVar.a(cbVar.f172358c);
                    } else {
                        DmtToast.makeNeutralToast(cb.this.m, (int) C4212R.string.n5u).show();
                    }
                } else if (cb.this.f172358c.isImage()) {
                    DmtToast.makeNegativeToast(cb.this.m, (int) C4212R.string.evm).show();
                } else {
                    DmtToast.makeNegativeToast(cb.this.m, (int) C4212R.string.n0t).show();
                }
            }
        }

   既然靜態分析看不出,要不試試動態調試?這種想法理論上是可行的,但分析這里的點贊代碼還是困難:(1)jeb或as調試,只能調試smali代碼,無法調試java代碼  (2)java代碼就是smali反編譯而來的,所以smali也是混淆的;如果不理解代碼的業務目的,單步執行代碼有啥意義了?(3)smali代碼遠比java多,動態逐行調試耗時也很多;怎么辦了?

   計算機網絡發展到今天,已經找不到單機的app了! 客戶端安裝的app做的所有工作最終目的都是為了和服務器通信(就像打工人,每天干的所有活的最終目的都是為了掙錢、養家糊口);前面說過了,逆向破解一般都是從數據開始的。數據可以通過CE或其他軟件搜索內存,也可以先抓網絡封包,看看客戶端給服務器發送了啥,然后根據數據的字段在代碼里面找,看看這些字段的值都是怎么生成的!這里逆向android應用,所以先用fiddler抓封包!

   這個app會給服務器發送很多數據包,哪個才是點贊的數據包了?這里介紹一個小技巧:這個軟件通過發給服務器的host是aweme.snssdk.com,可以先用fiddler過濾一下,只選這個服務器;很快,就能抓到點贊的封包(個人很好奇,為啥點贊接口取名叫digg了?好奇怪的名字):

GET https://aweme.snssdk.com/aweme/v1/commit/item/digg/?aweme_id=6956180208793718055&type=1&channel_id=-1&city=510100&activity=0&os_api=22&device_type=M973Q&ssmix=a&manifest_version_code=150501&dpi=480&uuid=865166023654745&app_name=aweme&version_name=15.5.0&ts=1620296753&cpu_support64=false&app_type=normal&appTheme=light&ac=wifi&host_abi=armeabi-v7a&update_version_code=15509900&channel=xiaomi&_rticket=1620296754623&device_platform=android&iid=2744832902828125&version_code=150500&cdid=7addad62-d097-41da-b852-e0de8b24fe75&openudid=338803367b93a120&device_id=70039083151&resolution=1080*1920&os_version=5.1.1&language=zh&device_brand=Meizu&aid=1128&minor_status=0&mcc_mnc=46000 HTTP/1.1
Accept-Encoding: gzip
x-tt-dt: AAA7NE2KX2XRH5ZIBMIIJHUGNWEXQLPT2G5U2VKAPRSBVVGBNOLZGYT36N7VMCWTDFTQBQXBW6FSC2IWBD36QSIH6MSUI2SKDMHF4T27M5MS6TL2XHUCXVFWWDJM2Y3HQZEHXQ42UCB7JUEHURQRH6Y
passport-sdk-version: 18
X-Tt-Token: 000e8f473aea647b3c44fd3b9f7482439e02da23d858b1609a77f5edbf3bcc6c774f39175ea27eed09ffb2dee02c173fcc137b53019bb3614db48a84e88879cf2cabc8a810d38b88fb1d9bc7640b02e655a186f8b1e0daf197e60067b35a68adc68ad-1.0.1
sdk-version: 2
X-SS-REQ-TICKET: 1620296754625
Cookie: passport_csrf_token_default=f4442957bc07adf1986f4df139296dd7; install_id=2744832902828125; ttreq=1$184784690dc292ea1ad4e5db65553166a5674c3e; multi_sids=95063141447%3A0e8f473aea647b3c44fd3b9f7482439e; odin_tt=fac32cc300e49d8f22a70f1cd7b92569039d7305b6fdef7f2389cb98e0f9e9493f6c8374ad33dabed24ea41c55e1834e; n_mh=B6WRe0yd-1qIuffF6ZWNO-CSGlW1Q-VhC0E79NrqYTg; sid_guard=0e8f473aea647b3c44fd3b9f7482439e%7C1620296607%7C5184000%7CMon%2C+05-Jul-2021+10%3A23%3A27+GMT; uid_tt=d06498fc7329b7187e209d0e6279e1d7; sid_tt=0e8f473aea647b3c44fd3b9f7482439e; sessionid=0e8f473aea647b3c44fd3b9f7482439e;
X-Ladon: gW1IO3ulq0eYymnbYa+7nAu2l116ADdAdmSIA1eB3Cv5BBIo
X-Khronos: 1620296754
X-Gorgon: 0404401f40051f42c987ec09aebf8038d629adf2add584933f8f
X-Tyhon: s2S+nKZ8jrepKJ2VtCulu7carp/ZLqe2gn24aHA=
X-Argus: Uictv+neuH8ZqjOjXzvEIvXCEXYEgUy3dUKWzj08JUtmGeYa4HfNfN8bp7Yga22Jbik2N2dBKezA48YN1E9A1KaBjXi2ixu5cHzAkQU9Tl4f/+a9xWuLYIZ/+PkW/YXUsmRCfszWlcMePPeyNQYEGkb5FssTkIr3EZ87TJ9NLBDJCJGA0i4PICbLnClzdfmBs+57JVi1sU2/MELCr9gO/Nka5eIJsEoGB/CIaL3gPmEbZ0sUl7sxIvKksMwj3f7tYBCriYBKmfeREuiYf1S18c7i
Host: aweme.snssdk.com
Connection: Keep-Alive
User-Agent: okhttp/3.10.0.1

 服務器返回字段:每次點贊成功后,status_code會是0;

   

 

   逆向的目的是重放,簡單理解就是自己構造數據包模擬用戶真實的點贊行為,所以這里也要搞清楚每個字段的含義,這些字段是怎么生成的,后續才能自己寫代碼實現;這里面的字段有很多,哪些字段可以直接寫死復用,哪些字段需要我們重新用算法生成了?這里繼續在app點贊,再抓一個digg數據包,然后把兩個包對比,就知道哪些字段可以寫死復用,哪些字段要動態生成了,對比如下:第一行是url,參數不同,待會單獨分析;接着是X-SS-REQ-TICKET和X-Khronos,這兩個明顯是毫秒和秒級別的時間戳,生成很簡單;還剩X-Ladon、X-GORGON、X-Tyhon、X-Argus4個字段不同。從這個4個字段的取值看,明顯不是人能讀懂的數據,這個就需要分析代碼了

   

   回過頭來再看看url的參數對比,如下:第一個不一樣的地方就是aweme_id,明顯是被點贊短視頻的id;第二個是ts、第三個是_rticket都是時間戳,所以url這里也沒啥需要額外分析代碼的,比較簡單!注意:url里面有個type字段,等於1表示點贊,等於0表示取消點贊!

    

   綜上所述:要自己寫代碼模擬實現真實的點贊行為,需要生成4個關鍵的字段:X-Ladon、X-GORGON、X-Tyhon、X-Argus;這4個字段都是怎么生成的了? 下一步就需要分析java個so層的代碼了!

 

  最后有一點疑惑:這個app為啥不學微信(在tls1.3的基礎上打造mmtls協議了)自定義通信協議了? 目前用的還是https協議,很容易被fiddler抓包的!微信的mmtls協議通信,用的就不是https協議,fidder就無法解析,保障了數據安全!

 

  該APP版本:15.5.0


免責聲明!

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



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