Tfittex vulnerabbiltajiet fl-UC Browser

Tfittex vulnerabbiltajiet fl-UC Browser

Introduzzjoni

Fl-aħħar ta’ Marzu aħna rrappurtati, li skoprew ħila moħbija li jgħabbu u jmexxu kodiċi mhux verifikat fl-UC Browser. Illum se nħarsu fid-dettall lejn kif dan it-tniżżil iseħħ u kif il-hackers jistgħu jużawha għall-iskopijiet tagħhom stess.

Xi żmien ilu, UC Browser ġie reklamat u mqassam b'mod aggressiv ħafna: ġie installat fuq it-tagħmir tal-utenti bl-użu ta 'malware, imqassam minn diversi siti taħt l-iskuża ta' fajls tal-vidjo (jiġifieri, l-utenti ħasbu li kienu qed iniżżlu, pereżempju, vidjo porn, iżda minflok irċieva APK ma 'dan il-browser), uża banners tal-biża' b'messaġġi li l-browser kien skadut, vulnerabbli, u affarijiet bħal dawn. Fil-grupp uffiċjali tal-UC Browser fuq VK hemm tema, fejn l-utenti jistgħu jilmentaw dwar reklamar inġust, hemm ħafna eżempji hemmhekk. Fl-2016 kien hemm anke reklamar bil-vidjo bir-Russu (iva, reklamar għal browser li jimblokka r-reklami).

Fiż-żmien tal-kitba, UC Browser għandu aktar minn 500 installazzjoni fuq Google Play. Dan huwa impressjonanti - Google Chrome biss għandu aktar. Fost ir-reviżjonijiet tista 'tara pjuttost ħafna ilmenti dwar ir-reklamar u redirects għal xi applikazzjonijiet fuq Google Play. Din kienet ir-raġuni għar-riċerka tagħna: iddeċidejna li naraw jekk UC Browser kienx qed jagħmel xi ħaġa ħażina. U rriżulta li jagħmel hekk!

Fil-kodiċi tal-applikazzjoni, ġiet skoperta l-abbiltà li tniżżel u tħaddem kodiċi eżekutibbli, li tmur kontra r-regoli għall-pubblikazzjoni tal-applikazzjonijiet fuq Google Play. Minbarra li jniżżel kodiċi eżekutibbli, UC Browser jagħmel dan b'mod mhux sikur, li jista 'jintuża biex iniedi attakk MitM. Ejja naraw jekk nistgħux inwettqu attakk bħal dan.

Dak kollu miktub hawn taħt huwa rilevanti għall-verżjoni tal-UC Browser li kienet disponibbli fuq Google Play fiż-żmien tal-istudju:

package: com.UCMobile.intl
versionName: 12.10.8.1172
versionCode: 10598
sha1 APK-файла: f5edb2243413c777172f6362876041eb0c3a928c

Vettur tal-attakk

Fil-manifest tal-UC Browser tista' ssib servizz b'isem li jispjega lilu nnifsu com.uc.deployment.UpgradeDeployService.

    <service android_exported="false" android_name="com.uc.deployment.UpgradeDeployService" android_process=":deploy" />

Meta jibda dan is-servizz, il-browser jagħmel talba POST lil puds.ucweb.com/upgrade/index.xhtml, li tista’ tidher fit-traffiku ftit tal-ħin wara l-bidu. Bi tweġiba, huwa jista 'jirċievi kmand biex tniżżel xi aġġornament jew modulu ġdid. Matul l-analiżi, is-server ma tax tali kmandi, iżda aħna ndunajna li meta nippruvaw niftħu PDF fil-browser, jagħmel it-tieni talba fl-indirizz speċifikat hawn fuq, u wara tniżżel il-librerija nattiva. Biex twettaq l-attakk, iddeċidejna li nużaw din il-karatteristika ta 'UC Browser: il-kapaċità li tiftaħ PDF permezz ta' librerija nattiva, li mhix fl-APK u li tniżżel mill-Internet jekk meħtieġ. Ta 'min jinnota li, teoretikament, UC Browser jista' jiġi sfurzat tniżżel xi ħaġa mingħajr interazzjoni tal-utent - jekk tipprovdi rispons iffurmat tajjeb għal talba li titwettaq wara li jitnieda l-browser. Iżda biex nagħmlu dan, għandna bżonn nistudjaw il-protokoll ta 'interazzjoni mas-server f'aktar dettall, għalhekk iddeċidejna li jkun aktar faċli li teditja r-rispons interċettat u tissostitwixxi l-librerija biex taħdem ma' PDF.

Għalhekk, meta utent irid jiftaħ PDF direttament fil-browser, it-talbiet li ġejjin jistgħu jidhru fit-traffiku:

Tfittex vulnerabbiltajiet fl-UC Browser

L-ewwel hemm talba POST biex puds.ucweb.com/upgrade/index.xhtml, allura
Jitniżżel arkivju b'librerija biex tara PDF u formati tal-uffiċċju. Huwa loġiku li wieħed jassumi li l-ewwel talba tittrasmetti informazzjoni dwar is-sistema (mill-inqas l-arkitettura biex tipprovdi l-librerija meħtieġa), u bi tweġiba għaliha l-browser jirċievi xi informazzjoni dwar il-librerija li jeħtieġ li titniżżel: l-indirizz u, possibilment , xi haga ohra. Il-problema hija li din it-talba hija encrypted.

Framment talba

Framment tweġiba

Tfittex vulnerabbiltajiet fl-UC Browser

Tfittex vulnerabbiltajiet fl-UC Browser

Il-librerija nnifisha hija ppakkjata f'ZIP u mhix encrypted.

Tfittex vulnerabbiltajiet fl-UC Browser

Fittex għall-kodiċi tad-deċifrar tat-traffiku

Ejja nippruvaw niddeċifraw ir-rispons tas-server. Ejja nħarsu lejn il-kodiċi tal-klassi com.uc.deployment.UpgradeDeployService: mill-metodu onStart Command mur għand com.uc.deployment.bx, u minnha sa com.uc.browser.core.dcfe:

    public final void e(l arg9) {
int v4_5;
String v3_1;
byte[] v3;
byte[] v1 = null;
if(arg9 == null) {
v3 = v1;
}
else {
v3_1 = arg9.iGX.ipR;
StringBuilder v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]product:");
v4.append(arg9.iGX.ipR);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]version:");
v4.append(arg9.iGX.iEn);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]upgrade_type:");
v4.append(arg9.iGX.mMode);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]force_flag:");
v4.append(arg9.iGX.iEo);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]silent_mode:");
v4.append(arg9.iGX.iDQ);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]silent_type:");
v4.append(arg9.iGX.iEr);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]silent_state:");
v4.append(arg9.iGX.iEp);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]silent_file:");
v4.append(arg9.iGX.iEq);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apk_md5:");
v4.append(arg9.iGX.iEl);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]download_type:");
v4.append(arg9.mDownloadType);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]download_group:");
v4.append(arg9.mDownloadGroup);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]download_path:");
v4.append(arg9.iGH);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_child_version:");
v4.append(arg9.iGX.iEx);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_series:");
v4.append(arg9.iGX.iEw);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_cpu_arch:");
v4.append(arg9.iGX.iEt);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_cpu_vfp3:");
v4.append(arg9.iGX.iEv);
v4 = new StringBuilder("[");
v4.append(v3_1);
v4.append("]apollo_cpu_vfp:");
v4.append(arg9.iGX.iEu);
ArrayList v3_2 = arg9.iGX.iEz;
if(v3_2 != null && v3_2.size() != 0) {
Iterator v3_3 = v3_2.iterator();
while(v3_3.hasNext()) {
Object v4_1 = v3_3.next();
StringBuilder v5 = new StringBuilder("[");
v5.append(((au)v4_1).getName());
v5.append("]component_name:");
v5.append(((au)v4_1).getName());
v5 = new StringBuilder("[");
v5.append(((au)v4_1).getName());
v5.append("]component_ver_name:");
v5.append(((au)v4_1).aDA());
v5 = new StringBuilder("[");
v5.append(((au)v4_1).getName());
v5.append("]component_ver_code:");
v5.append(((au)v4_1).gBl);
v5 = new StringBuilder("[");
v5.append(((au)v4_1).getName());
v5.append("]component_req_type:");
v5.append(((au)v4_1).gBq);
}
}
j v3_4 = new j();
m.b(v3_4);
h v4_2 = new h();
m.b(v4_2);
ay v5_1 = new ay();
v3_4.hS("");
v3_4.setImsi("");
v3_4.hV("");
v5_1.bPQ = v3_4;
v5_1.bPP = v4_2;
v5_1.yr(arg9.iGX.ipR);
v5_1.gBF = arg9.iGX.mMode;
v5_1.gBI = arg9.iGX.iEz;
v3_2 = v5_1.gAr;
c.aBh();
v3_2.add(g.fs("os_ver", c.getRomInfo()));
v3_2.add(g.fs("processor_arch", com.uc.b.a.a.c.getCpuArch()));
v3_2.add(g.fs("cpu_arch", com.uc.b.a.a.c.Pb()));
String v4_3 = com.uc.b.a.a.c.Pd();
v3_2.add(g.fs("cpu_vfp", v4_3));
v3_2.add(g.fs("net_type", String.valueOf(com.uc.base.system.a.Jo())));
v3_2.add(g.fs("fromhost", arg9.iGX.iEm));
v3_2.add(g.fs("plugin_ver", arg9.iGX.iEn));
v3_2.add(g.fs("target_lang", arg9.iGX.iEs));
v3_2.add(g.fs("vitamio_cpu_arch", arg9.iGX.iEt));
v3_2.add(g.fs("vitamio_vfp", arg9.iGX.iEu));
v3_2.add(g.fs("vitamio_vfp3", arg9.iGX.iEv));
v3_2.add(g.fs("plugin_child_ver", arg9.iGX.iEx));
v3_2.add(g.fs("ver_series", arg9.iGX.iEw));
v3_2.add(g.fs("child_ver", r.aVw()));
v3_2.add(g.fs("cur_ver_md5", arg9.iGX.iEl));
v3_2.add(g.fs("cur_ver_signature", SystemHelper.getUCMSignature()));
v3_2.add(g.fs("upgrade_log", i.bjt()));
v3_2.add(g.fs("silent_install", String.valueOf(arg9.iGX.iDQ)));
v3_2.add(g.fs("silent_state", String.valueOf(arg9.iGX.iEp)));
v3_2.add(g.fs("silent_file", arg9.iGX.iEq));
v3_2.add(g.fs("silent_type", String.valueOf(arg9.iGX.iEr)));
v3_2.add(g.fs("cpu_archit", com.uc.b.a.a.c.Pc()));
v3_2.add(g.fs("cpu_set", SystemHelper.getCpuInstruction()));
boolean v4_4 = v4_3 == null || !v4_3.contains("neon") ? false : true;
v3_2.add(g.fs("neon", String.valueOf(v4_4)));
v3_2.add(g.fs("cpu_cores", String.valueOf(com.uc.b.a.a.c.Jl())));
v3_2.add(g.fs("ram_1", String.valueOf(com.uc.b.a.a.h.Po())));
v3_2.add(g.fs("totalram", String.valueOf(com.uc.b.a.a.h.OL())));
c.aBh();
v3_2.add(g.fs("rom_1", c.getRomInfo()));
v4_5 = e.getScreenWidth();
int v6 = e.getScreenHeight();
StringBuilder v7 = new StringBuilder();
v7.append(v4_5);
v7.append("*");
v7.append(v6);
v3_2.add(g.fs("ss", v7.toString()));
v3_2.add(g.fs("api_level", String.valueOf(Build$VERSION.SDK_INT)));
v3_2.add(g.fs("uc_apk_list", SystemHelper.getUCMobileApks()));
Iterator v4_6 = arg9.iGX.iEA.entrySet().iterator();
while(v4_6.hasNext()) {
Object v6_1 = v4_6.next();
v3_2.add(g.fs(((Map$Entry)v6_1).getKey(), ((Map$Entry)v6_1).getValue()));
}
v3 = v5_1.toByteArray();
}
if(v3 == null) {
this.iGY.iGI.a(arg9, "up_encode", "yes", "fail");
return;
}
v4_5 = this.iGY.iGw ? 0x1F : 0;
if(v3 == null) {
}
else {
v3 = g.i(v4_5, v3);
if(v3 == null) {
}
else {
v1 = new byte[v3.length + 16];
byte[] v6_2 = new byte[16];
Arrays.fill(v6_2, 0);
v6_2[0] = 0x5F;
v6_2[1] = 0;
v6_2[2] = ((byte)v4_5);
v6_2[3] = -50;
System.arraycopy(v6_2, 0, v1, 0, 16);
System.arraycopy(v3, 0, v1, 16, v3.length);
}
}
if(v1 == null) {
this.iGY.iGI.a(arg9, "up_encrypt", "yes", "fail");
return;
}
if(TextUtils.isEmpty(this.iGY.mUpgradeUrl)) {
this.iGY.iGI.a(arg9, "up_url", "yes", "fail");
return;
}
StringBuilder v0 = new StringBuilder("[");
v0.append(arg9.iGX.ipR);
v0.append("]url:");
v0.append(this.iGY.mUpgradeUrl);
com.uc.browser.core.d.c.i v0_1 = this.iGY.iGI;
v3_1 = this.iGY.mUpgradeUrl;
com.uc.base.net.e v0_2 = new com.uc.base.net.e(new com.uc.browser.core.d.c.i$a(v0_1, arg9));
v3_1 = v3_1.contains("?") ? v3_1 + "&dataver=pb" : v3_1 + "?dataver=pb";
n v3_5 = v0_2.uc(v3_1);
m.b(v3_5, false);
v3_5.setMethod("POST");
v3_5.setBodyProvider(v1);
v0_2.b(v3_5);
this.iGY.iGI.a(arg9, "up_null", "yes", "success");
this.iGY.iGI.b(arg9);
}

Naraw il-formazzjoni ta’ talba POST hawn. Aħna nagħtu attenzjoni għall-ħolqien ta 'firxa ta' 16 bytes u l-mili tagħha: 0x5F, 0, 0x1F, -50 (=0xCE). Jikkoinċidi ma' dak li rajna fit-talba ta' hawn fuq.

Fl-istess klassi tista 'tara klassi nested li għandha metodu ieħor interessanti:

        public final void a(l arg10, byte[] arg11) {
f v0 = this.iGQ;
StringBuilder v1 = new StringBuilder("[");
v1.append(arg10.iGX.ipR);
v1.append("]:UpgradeSuccess");
byte[] v1_1 = null;
if(arg11 == null) {
}
else if(arg11.length < 16) {
}
else {
if(arg11[0] != 0x60 && arg11[3] != 0xFFFFFFD0) {
goto label_57;
}
int v3 = 1;
int v5 = arg11[1] == 1 ? 1 : 0;
if(arg11[2] != 1 && arg11[2] != 11) {
if(arg11[2] == 0x1F) {
}
else {
v3 = 0;
}
}
byte[] v7 = new byte[arg11.length - 16];
System.arraycopy(arg11, 16, v7, 0, v7.length);
if(v3 != 0) {
v7 = g.j(arg11[2], v7);
}
if(v7 == null) {
goto label_57;
}
if(v5 != 0) {
v1_1 = g.P(v7);
goto label_57;
}
v1_1 = v7;
}
label_57:
if(v1_1 == null) {
v0.iGY.iGI.a(arg10, "up_decrypt", "yes", "fail");
return;
}
q v11 = g.b(arg10, v1_1);
if(v11 == null) {
v0.iGY.iGI.a(arg10, "up_decode", "yes", "fail");
return;
}
if(v0.iGY.iGt) {
v0.d(arg10);
}
if(v0.iGY.iGo != null) {
v0.iGY.iGo.a(0, ((o)v11));
}
if(v0.iGY.iGs) {
v0.iGY.a(((o)v11));
v0.iGY.iGI.a(v11, "up_silent", "yes", "success");
v0.iGY.iGI.a(v11);
return;
}
v0.iGY.iGI.a(v11, "up_silent", "no", "success");
}
}

Il-metodu jirċievi firxa ta 'bytes bħala input u jiċċekkja li l-byte żero huwa 0x60 jew it-tielet byte huwa 0xD0, u t-tieni byte huwa 1, 11 jew 0x1F. Inħarsu lejn ir-rispons mis-server: il-byte żero huwa 0x60, it-tieni huwa 0x1F, it-tielet huwa 0x60. Ħsejjes bħal dak li għandna bżonn. Ġġudikati mill-linji ("up_decrypt", per eżempju), hawn għandu jissejjaħ metodu li jiddekofra r-rispons tas-server.
Ejja ngħaddu għall-metodu gj. Innota li l-ewwel argument huwa l-byte fl-offset 2 (jiġifieri 0x1F fil-każ tagħna), u t-tieni huwa r-rispons tas-server mingħajr
l-ewwel 16-il byte.

     public static byte[] j(int arg1, byte[] arg2) {
if(arg1 == 1) {
arg2 = c.c(arg2, c.adu);
}
else if(arg1 == 11) {
arg2 = m.aF(arg2);
}
else if(arg1 != 0x1F) {
}
else {
arg2 = EncryptHelper.decrypt(arg2);
}
return arg2;
}

Ovvjament, hawn aħna nagħżlu algoritmu ta 'decryption, u l-istess byte li huwa tagħna
każ ugwali għal 0x1F, jindika waħda minn tliet għażliet possibbli.

Aħna nkomplu nanalizzaw il-kodiċi. Wara ftit qabżiet insibu ruħna f'metodu b'isem li jispjega lilhom infushom decryptBytesByKey.

Hawnhekk żewġ bytes oħra huma separati mir-rispons tagħna, u string tinkiseb minnhom. Huwa ċar li b'dan il-mod tintgħażel iċ-ċavetta għad-decrypting tal-messaġġ.

    private static byte[] decryptBytesByKey(byte[] bytes) {
byte[] v0 = null;
if(bytes != null) {
try {
if(bytes.length < EncryptHelper.PREFIX_BYTES_SIZE) {
}
else if(bytes.length == EncryptHelper.PREFIX_BYTES_SIZE) {
return v0;
}
else {
byte[] prefix = new byte[EncryptHelper.PREFIX_BYTES_SIZE];  // 2 байта
System.arraycopy(bytes, 0, prefix, 0, prefix.length);
String keyId = c.ayR().d(ByteBuffer.wrap(prefix).getShort()); // Выбор ключа
if(keyId == null) {
return v0;
}
else {
a v2 = EncryptHelper.ayL();
if(v2 == null) {
return v0;
}
else {
byte[] enrypted = new byte[bytes.length - EncryptHelper.PREFIX_BYTES_SIZE];
System.arraycopy(bytes, EncryptHelper.PREFIX_BYTES_SIZE, enrypted, 0, enrypted.length);
return v2.l(keyId, enrypted);
}
}
}
}
catch(SecException v7_1) {
EncryptHelper.handleDecryptException(((Throwable)v7_1), v7_1.getErrorCode());
return v0;
}
catch(Throwable v7) {
EncryptHelper.handleDecryptException(v7, 2);
return v0;
}
}
return v0;
}

Meta nħarsu 'l quddiem, ninnutaw li f'dan l-istadju għadna ma niksbux ċavetta, iżda biss "l-identifikatur" tagħha. Li tikseb iċ-ċavetta hija ftit aktar ikkumplikata.

Fil-metodu li jmiss, żewġ parametri oħra huma miżjuda ma 'dawk eżistenti, li jagħmlu erbgħa minnhom: in-numru maġiku 16, l-identifikatur taċ-ċavetta, id-data encrypted, u string inkomprensibbli (fil-każ tagħna, vojta).

    public final byte[] l(String keyId, byte[] encrypted) throws SecException {
return this.ayJ().staticBinarySafeDecryptNoB64(16, keyId, encrypted, "");
}

Wara serje ta 'tranżizzjonijiet naslu għall-metodu staticBinarySafeDecryptNoB64 interface com.alibaba.wireless.security.open.staticdataencrypt.IStaticDataEncryptComponent. M'hemm l-ebda klassijiet fil-kodiċi tal-applikazzjoni prinċipali li jimplimentaw din l-interface. Hemm klassi bħal din fil-fajl lib/armeabi-v7a/libsgmain.so, li fil-fatt mhuwiex .so, iżda .jar. Il-metodu li aħna interessati fih huwa implimentat kif ġej:

package com.alibaba.wireless.security.a.i;
// ...
public class a implements IStaticDataEncryptComponent {
private ISecurityGuardPlugin a;
// ...
private byte[] a(int mode, int magicInt, int xzInt, String keyId, byte[] encrypted, String magicString) {
return this.a.getRouter().doCommand(10601, new Object[]{Integer.valueOf(mode), Integer.valueOf(magicInt), Integer.valueOf(xzInt), keyId, encrypted, magicString});
}
// ...
private byte[] b(int magicInt, String keyId, byte[] encrypted, String magicString) {
return this.a(2, magicInt, 0, keyId, encrypted, magicString);
}
// ...
public byte[] staticBinarySafeDecryptNoB64(int magicInt, String keyId, byte[] encrypted, String magicString) throws SecException {
if(keyId != null && keyId.length() > 0 && magicInt >= 0 && magicInt < 19 && encrypted != null && encrypted.length > 0) {
return this.b(magicInt, keyId, encrypted, magicString);
}
throw new SecException("", 301);
}
//...
}

Hawnhekk il-lista tagħna ta 'parametri hija supplimentata b'żewġ interi oħra: 2 u 0. Ġġudikati minn
kollox, 2 tfisser decryption, bħal fil-metodu doFinal klassi tas-sistema javax.crypto.Cipher. U dan kollu jiġi trasferit għal ċertu Router bin-numru 10601 - dan jidher li huwa n-numru tal-kmand.

Wara l-katina ta 'tranżizzjonijiet li jmiss insibu klassi li timplimenta l-interface IRouterComponent u l-metodu doKmand:

package com.alibaba.wireless.security.mainplugin;
import com.alibaba.wireless.security.framework.IRouterComponent;
import com.taobao.wireless.security.adapter.JNICLibrary;
public class a implements IRouterComponent {
public a() {
super();
}
public Object doCommand(int arg2, Object[] arg3) {
return JNICLibrary.doCommandNative(arg2, arg3);
}
}

U wkoll klassi JNICLibrerija, li fiha jiġi ddikjarat il-metodu nattiv doCommandNative:

package com.taobao.wireless.security.adapter;
public class JNICLibrary {
public static native Object doCommandNative(int arg0, Object[] arg1);
}

Dan ifisser li għandna bżonn insibu metodu fil-kodiċi nattiv doCommandNative. U hawnhekk jibda l-gost.

Offuskazzjoni tal-kodiċi tal-magna

Fil-fajl libsgmain.so (li fil-fatt huwa .jar u li fih sibna l-implimentazzjoni ta 'xi interfaces relatati mal-encryption eżatt fuq) hemm librerija nattiva waħda: libsgmainso-6.4.36.so. Niftħuh f'IDA u nġibu mazz ta 'kaxxi ta' djalogu bi żbalji. Il-problema hija li t-tabella tal-header tat-taqsima hija invalida. Dan isir apposta biex tikkomplika l-analiżi.

Tfittex vulnerabbiltajiet fl-UC Browser

Iżda mhux meħtieġ: biex tgħabbi b'mod korrett fajl ELF u tanalizzah, tabella tal-header tal-programm hija biżżejjed. Għalhekk, aħna sempliċement inħassru t-tabella tas-sezzjoni, billi niżżlu żero l-oqsma korrispondenti fl-intestatura.

Tfittex vulnerabbiltajiet fl-UC Browser

Iftaħ il-fajl f'IDA mill-ġdid.

Hemm żewġ modi kif tgħid lill-magna virtwali Java fejn tinsab eżattament fil-librerija nattiva l-implimentazzjoni ta 'metodu ddikjarat fil-kodiċi Java bħala indiġeni. L-ewwel huwa li tagħtiha isem ta 'speċi Java_package_name_ClassName_MethodName.

It-tieni huwa li tirreġistraha meta tgħabbi l-librerija (fil-funzjoni JNI_OnLoad)
bl-użu ta' sejħa ta' funzjoni ReġistruNattivi.

Fil-każ tagħna, jekk nużaw l-ewwel metodu, l-isem għandu jkun bħal dan: Java_com_taobao_wireless_security_adapter_JNICLibrary_doCommandNative.

M'hemm l-ebda funzjoni bħal din fost il-funzjonijiet esportati, li jfisser li għandek bżonn tfittex sejħa ReġistruNattivi.
Ejja mmorru għall-funzjoni JNI_OnLoad u naraw din l-istampa:

Tfittex vulnerabbiltajiet fl-UC Browser

X'qed jiġri hawn? L-ewwel daqqa t'għajn, il-bidu u t-tmiem tal-funzjoni huma tipiċi għall-arkitettura ARM. L-ewwel istruzzjoni fuq il-munzell taħżen il-kontenut tar-reġistri li l-funzjoni se tuża fit-tħaddim tagħha (f'dan il-każ, R0, R1 u R2), kif ukoll il-kontenut tar-reġistru LR, li fih l-indirizz tar-ritorn mill-funzjoni . L-aħħar istruzzjoni tirrestawra r-reġistri salvati, u l-indirizz tar-ritorn jitqiegħed immedjatament fir-reġistru tal-PC - u b'hekk jirritorna mill-funzjoni. Imma jekk tħares mill-qrib, tinduna li l-istruzzjoni ta’ qabel tal-aħħar tbiddel l-indirizz tar-ritorn maħżun fuq il-munzell. Ejja nikkalkulaw kif se jkun wara
eżekuzzjoni tal-kodiċi. Ċertu indirizz 1xB0 jitgħabba f'R130, 5 jitnaqqas minnu, imbagħad jiġi trasferit għal R0 u 0x10 jiżdied miegħu. Jirriżulta 0xB13B. Għalhekk, IDA jaħseb li l-aħħar istruzzjoni hija ritorn ta 'funzjoni normali, iżda fil-fatt sejjer għall-indirizz ikkalkulat 0xB13B.

Ta 'min ifakkar hawnhekk li l-proċessuri ARM għandhom żewġ modi u żewġ settijiet ta' struzzjonijiet: ARM u Thumb. L-inqas daqsxejn sinifikanti tal-indirizz jgħid lill-proċessur liema sett ta 'struzzjonijiet qed jintuża. Jiġifieri, l-indirizz huwa fil-fatt 0xB13A, u wieħed fl-inqas bit sinifikanti jindika l-modalità Thumb.

"Adapter" simili ġie miżjud mal-bidu ta 'kull funzjoni f'din il-librerija u
kodiċi taż-żibel. Mhux se noqogħdu aktar fuqhom fid-dettall - niftakru biss
li l-bidu reali ta 'kważi l-funzjonijiet kollha huwa ftit aktar 'il bogħod.

Peress li l-kodiċi ma jaqbiżx b'mod espliċitu għal 0xB13A, IDA nnifisha ma għarfetx li l-kodiċi kien jinsab f'dan il-post. Għall-istess raġuni, ma jirrikonoxxix il-biċċa l-kbira tal-kodiċi fil-librerija bħala kodiċi, li jagħmel l-analiżi kemmxejn diffiċli. Aħna ngħidu lill-IDA li dan huwa l-kodiċi, u dan huwa dak li jiġri:

Tfittex vulnerabbiltajiet fl-UC Browser

It-tabella tibda b'mod ċar f'0xB144. X'hemm f'sub_494C?

Tfittex vulnerabbiltajiet fl-UC Browser

Meta nsejħu din il-funzjoni fir-reġistru LR, inġibu l-indirizz tat-tabella msemmija qabel (0xB144). F'R0 - indiċi f'din it-tabella. Jiġifieri, il-valur jittieħed mit-tabella, miżjud ma 'LR u r-riżultat huwa
l-indirizz biex tmur. Ejja nippruvaw nikkalkulawha: 0xB144 + [0xB144 + 8* 4] = 0xB144 + 0x120 = 0xB264. Immorru fl-indirizz riċevuti u naraw litteralment ftit istruzzjonijiet utli u għal darb'oħra mmorru għal 0xB140:

Tfittex vulnerabbiltajiet fl-UC Browser

Issa se jkun hemm transizzjoni b'offset b'indiċi 0x20 mit-tabella.

Ġġudikati mid-daqs tat-tabella, se jkun hemm ħafna tranżizzjonijiet bħal dawn fil-kodiċi. Tqum il-mistoqsija jekk huwiex possibbli li b'xi mod dan jiġi ttrattat b'mod aktar awtomatiku, mingħajr ma jiġu kkalkulati manwalment l-indirizzi. U l-iskripts u l-abbiltà li l-kodiċi tal-garża fl-IDA jiġu għall-għajnuna tagħna:

def put_unconditional_branch(source, destination):
offset = (destination - source - 4) >> 1
if offset > 2097151 or offset < -2097152:
raise RuntimeError("Invalid offset")
if offset > 1023 or offset < -1024:
instruction1 = 0xf000 | ((offset >> 11) & 0x7ff)
instruction2 = 0xb800 | (offset & 0x7ff)
patch_word(source, instruction1)
patch_word(source + 2, instruction2)
else:
instruction = 0xe000 | (offset & 0x7ff)
patch_word(source, instruction)
ea = here()
if get_wide_word(ea) == 0xb503: #PUSH {R0,R1,LR}
ea1 = ea + 2
if get_wide_word(ea1) == 0xbf00: #NOP
ea1 += 2
if get_operand_type(ea1, 0) == 1 and get_operand_value(ea1, 0) == 0 and get_operand_type(ea1, 1) == 2:
index = get_wide_dword(get_operand_value(ea1, 1))
print "index =", hex(index)
ea1 += 2
if get_operand_type(ea1, 0) == 7:
table = get_operand_value(ea1, 0) + 4
elif get_operand_type(ea1, 1) == 2:
table = get_operand_value(ea1, 1) + 4
else:
print "Wrong operand type on", hex(ea1), "-", get_operand_type(ea1, 0), get_operand_type(ea1, 1)
table = None
if table is None:
print "Unable to find table"
else:
print "table =", hex(table)
offset = get_wide_dword(table + (index << 2))
put_unconditional_branch(ea, table + offset)
else:
print "Unknown code", get_operand_type(ea1, 0), get_operand_value(ea1, 0), get_operand_type(ea1, 1) == 2
else:
print "Unable to detect first instruction"

Poġġi l-cursor fuq il-linja 0xB26A, mexxi l-iskript u ara t-tranżizzjoni għal 0xB4B0:

Tfittex vulnerabbiltajiet fl-UC Browser

L-IDA għal darb'oħra ma għarfetx din il-qasam bħala kodiċi. Ngħinuha u naraw disinn ieħor hemmhekk:

Tfittex vulnerabbiltajiet fl-UC Browser

L-istruzzjonijiet wara BLX ma jidhirx li jagħmlu ħafna sens, huwa aktar bħal xi tip ta 'spostament. Ejja nħarsu lejn sub_4964:

Tfittex vulnerabbiltajiet fl-UC Browser

U tabilħaqq, hawnhekk tittieħed dword fl-indirizz li jinsab f'LR, miżjud ma 'dan l-indirizz, wara li jittieħed il-valur fl-indirizz li jirriżulta u jitqiegħed fuq il-munzell. Ukoll, 4 huwa miżjud ma 'LR sabiex wara li jirritornaw mill-funzjoni, dan l-istess offset jinqabeż. Wara dan il-kmand POP {R1} jieħu l-valur li jirriżulta mill-munzell. Jekk tħares lejn dak li jinsab fl-indirizz 0xB4BA + 0xEA = 0xB5A4, se tara xi ħaġa simili għal tabella tal-indirizzi:

Tfittex vulnerabbiltajiet fl-UC Browser

Biex timla dan id-disinn, ser ikollok bżonn tikseb żewġ parametri mill-kodiċi: l-offset u n-numru tar-reġistru li fih trid tpoġġi r-riżultat. Għal kull reġistru possibbli, ikollok tipprepara biċċa kodiċi minn qabel.

patches = {}
patches[0] = (0x00, 0xbf, 0x01, 0x48, 0x00, 0x68, 0x02, 0xe0)
patches[1] = (0x00, 0xbf, 0x01, 0x49, 0x09, 0x68, 0x02, 0xe0)
patches[2] = (0x00, 0xbf, 0x01, 0x4a, 0x12, 0x68, 0x02, 0xe0)
patches[3] = (0x00, 0xbf, 0x01, 0x4b, 0x1b, 0x68, 0x02, 0xe0)
patches[4] = (0x00, 0xbf, 0x01, 0x4c, 0x24, 0x68, 0x02, 0xe0)
patches[5] = (0x00, 0xbf, 0x01, 0x4d, 0x2d, 0x68, 0x02, 0xe0)
patches[8] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0x80, 0xd8, 0xf8, 0x00, 0x80, 0x01, 0xe0)
patches[9] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0x90, 0xd9, 0xf8, 0x00, 0x90, 0x01, 0xe0)
patches[10] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0xa0, 0xda, 0xf8, 0x00, 0xa0, 0x01, 0xe0)
patches[11] = (0x00, 0xbf, 0xdf, 0xf8, 0x06, 0xb0, 0xdb, 0xf8, 0x00, 0xb0, 0x01, 0xe0)
ea = here()
if (get_wide_word(ea) == 0xb082 #SUB SP, SP, #8
and get_wide_word(ea + 2) == 0xb503): #PUSH {R0,R1,LR}
if get_operand_type(ea + 4, 0) == 7:
pop = get_bytes(ea + 12, 4, 0)
if pop[1] == 'xbc':
register = -1
r = get_wide_byte(ea + 12)
for i in range(8):
if r == (1 << i):
register = i
break
if register == -1:
print "Unable to detect register"
else:
address = get_wide_dword(ea + 8) + ea + 8
for b in patches[register]:
patch_byte(ea, b)
ea += 1
if ea % 4 != 0:
ea += 2
patch_dword(ea, address)
elif pop[:3] == 'x5dxf8x04':
register = ord(pop[3]) >> 4
if register in patches:
address = get_wide_dword(ea + 8) + ea + 8
for b in patches[register]:
patch_byte(ea, b)
ea += 1
patch_dword(ea, address)
else:
print "POP instruction not found"
else:
print "Wrong operand type on +4:", get_operand_type(ea + 4, 0)
else:
print "Unable to detect first instructions"

Aħna npoġġu l-cursor fil-bidu tal-istruttura li rridu nissostitwixxu - 0xB4B2 - u nħaddmu l-iskrittura:

Tfittex vulnerabbiltajiet fl-UC Browser

Minbarra l-istrutturi diġà msemmija, il-kodiċi fih ukoll dan li ġej:

Tfittex vulnerabbiltajiet fl-UC Browser

Bħal fil-każ preċedenti, wara l-istruzzjoni BLX hemm kumpens:

Tfittex vulnerabbiltajiet fl-UC Browser

Nieħdu l-offset għall-indirizz minn LR, żidha ma 'LR u mmorru hemm. 0x72044 + 0xC = 0x72050. L-iskript għal dan id-disinn huwa pjuttost sempliċi:

def put_unconditional_branch(source, destination):
offset = (destination - source - 4) >> 1
if offset > 2097151 or offset < -2097152:
raise RuntimeError("Invalid offset")
if offset > 1023 or offset < -1024:
instruction1 = 0xf000 | ((offset >> 11) & 0x7ff)
instruction2 = 0xb800 | (offset & 0x7ff)
patch_word(source, instruction1)
patch_word(source + 2, instruction2)
else:
instruction = 0xe000 | (offset & 0x7ff)
patch_word(source, instruction)
ea = here()
if get_wide_word(ea) == 0xb503: #PUSH {R0,R1,LR}
ea1 = ea + 6
if get_wide_word(ea + 2) == 0xbf00: #NOP
ea1 += 2
offset = get_wide_dword(ea1)
put_unconditional_branch(ea, (ea1 + offset) & 0xffffffff)
else:
print "Unable to detect first instruction"

Riżultat tal-eżekuzzjoni tal-iskript:

Tfittex vulnerabbiltajiet fl-UC Browser

Ladarba kollox huwa patched fil-funzjoni, inti tista 'tippunta IDA għall-bidu reali tagħha. Se tgħaqqad il-kodiċi tal-funzjoni kollu, u tista 'tiġi dekompilata bl-użu ta' HexRays.

Kordi ta' dekodifikazzjoni

Tgħallimna nittrattaw l-obfuscation tal-kodiċi tal-magni fil-librerija libsgmainso-6.4.36.so minn UC Browser u rċeviet il-kodiċi tal-funzjoni JNI_OnLoad.

int __fastcall real_JNI_OnLoad(JavaVM *vm)
{
int result; // r0
jclass clazz; // r0 MAPDST
int v4; // r0
JNIEnv *env; // r4
int v6; // [sp-40h] [bp-5Ch]
int v7; // [sp+Ch] [bp-10h]
v7 = *(_DWORD *)off_8AC00;
if ( !vm )
goto LABEL_39;
sub_7C4F4();
env = (JNIEnv *)sub_7C5B0(0);
if ( !env )
goto LABEL_39;
v4 = sub_72CCC();
sub_73634(v4);
sub_73E24(&unk_83EA6, &v6, 49);
clazz = (jclass)((int (__fastcall *)(JNIEnv *, int *))(*env)->FindClass)(env, &v6);
if ( clazz
&& (sub_9EE4(),
sub_71D68(env),
sub_E7DC(env) >= 0
&& sub_69D68(env) >= 0
&& sub_197B4(env, clazz) >= 0
&& sub_E240(env, clazz) >= 0
&& sub_B8B0(env, clazz) >= 0
&& sub_5F0F4(env, clazz) >= 0
&& sub_70640(env, clazz) >= 0
&& sub_11F3C(env) >= 0
&& sub_21C3C(env, clazz) >= 0
&& sub_2148C(env, clazz) >= 0
&& sub_210E0(env, clazz) >= 0
&& sub_41B58(env, clazz) >= 0
&& sub_27920(env, clazz) >= 0
&& sub_293E8(env, clazz) >= 0
&& sub_208F4(env, clazz) >= 0) )
{
result = (sub_B7B0(env, clazz) >> 31) | 0x10004;
}
else
{
LABEL_39:
result = -1;
}
return result;
}

Ejja nagħtu ħarsa aktar mill-qrib lejn il-linji li ġejjin:

  sub_73E24(&unk_83EA6, &v6, 49);
clazz = (jclass)((int (__fastcall *)(JNIEnv *, int *))(*env)->FindClass)(env, &v6);

Fil-funzjoni sub_73E24 l-isem tal-klassi qed jiġi decrypted b'mod ċar. Bħala parametri għal din il-funzjoni, jiġu mgħoddija pointer għal data simili għal data encrypted, ċertu buffer u numru. Ovvjament, wara li ssejjaħ il-funzjoni, se jkun hemm linja decrypted fil-buffer, peress li hija mgħoddija lill-funzjoni SibKlassi, li tieħu l-isem tal-klassi bħala t-tieni parametru. Għalhekk, in-numru huwa d-daqs tal-buffer jew it-tul tal-linja. Ejja nippruvaw niddeċifraw l-isem tal-klassi, għandu jgħidilna jekk hux sejrin fid-direzzjoni t-tajba. Ejja nagħtu ħarsa aktar mill-qrib lejn dak li jiġri fi sub_73E24.

int __fastcall sub_73E56(unsigned __int8 *in, unsigned __int8 *out, size_t size)
{
int v4; // r6
int v7; // r11
int v8; // r9
int v9; // r4
size_t v10; // r5
int v11; // r0
struc_1 v13; // [sp+0h] [bp-30h]
int v14; // [sp+1Ch] [bp-14h]
int v15; // [sp+20h] [bp-10h]
v4 = 0;
v15 = *(_DWORD *)off_8AC00;
v14 = 0;
v7 = sub_7AF78(17);
v8 = sub_7AF78(size);
if ( !v7 )
{
v9 = 0;
goto LABEL_12;
}
(*(void (__fastcall **)(int, const char *, int))(v7 + 12))(v7, "DcO/lcK+h?m3c*q@", 16);
if ( !v8 )
{
LABEL_9:
v4 = 0;
goto LABEL_10;
}
v4 = 0;
if ( !in )
{
LABEL_10:
v9 = 0;
goto LABEL_11;
}
v9 = 0;
if ( out )
{
memset(out, 0, size);
v10 = size - 1;
(*(void (__fastcall **)(int, unsigned __int8 *, size_t))(v8 + 12))(v8, in, v10);
memset(&v13, 0, 0x14u);
v13.field_4 = 3;
v13.field_10 = v7;
v13.field_14 = v8;
v11 = sub_6115C(&v13, &v14);
v9 = v11;
if ( v11 )
{
if ( *(_DWORD *)(v11 + 4) == v10 )
{
qmemcpy(out, *(const void **)v11, v10);
v4 = *(_DWORD *)(v9 + 4);
}
else
{
v4 = 0;
}
goto LABEL_11;
}
goto LABEL_9;
}
LABEL_11:
sub_7B148(v7);
LABEL_12:
if ( v8 )
sub_7B148(v8);
if ( v9 )
sub_7B148(v9);
return v4;
}

Funzjoni sub_7AF78 joħloq eżempju ta 'kontenitur għal arrays ta' byte tad-daqs speċifikat (mhux se noqogħdu fuq dawn il-kontenituri fid-dettall). Hawnhekk jinħolqu żewġ kontenituri bħal dawn: wieħed fih il-linja "DcO/lcK+h?m3c*q@" (huwa faċli li wieħed isib li din hija ċavetta), l-oħra fiha dejta kriptata. Sussegwentement, iż-żewġ oġġetti jitqiegħdu f'ċerta struttura, li tiġi mgħoddija lill-funzjoni sub_6115C. Ejja nimmarkaw ukoll qasam bil-valur 3 f'din l-istruttura.Ejja naraw x'jiġri minn din l-istruttura jmiss.

int __fastcall sub_611B4(struc_1 *a1, _DWORD *a2)
{
int v3; // lr
unsigned int v4; // r1
int v5; // r0
int v6; // r1
int result; // r0
int v8; // r0
*a2 = 820000;
if ( a1 )
{
v3 = a1->field_14;
if ( v3 )
{
v4 = a1->field_4;
if ( v4 < 0x19 )
{
switch ( v4 )
{
case 0u:
v8 = sub_6419C(a1->field_0, a1->field_10, v3);
goto LABEL_17;
case 3u:
v8 = sub_6364C(a1->field_0, a1->field_10, v3);
goto LABEL_17;
case 0x10u:
case 0x11u:
case 0x12u:
v8 = sub_612F4(
a1->field_0,
v4,
*(_QWORD *)&a1->field_8,
*(_QWORD *)&a1->field_8 >> 32,
a1->field_10,
v3,
a2);
goto LABEL_17;
case 0x14u:
v8 = sub_63A28(a1->field_0, v3);
goto LABEL_17;
case 0x15u:
sub_61A60(a1->field_0, v3, a2);
return result;
case 0x16u:
v8 = sub_62440(a1->field_14);
goto LABEL_17;
case 0x17u:
v8 = sub_6226C(a1->field_10, v3);
goto LABEL_17;
case 0x18u:
v8 = sub_63530(a1->field_14);
LABEL_17:
v6 = 0;
if ( v8 )
{
*a2 = 0;
v6 = v8;
}
return v6;
default:
LOWORD(v5) = 28032;
goto LABEL_5;
}
}
}
}
LOWORD(v5) = -27504;
LABEL_5:
HIWORD(v5) = 13;
v6 = 0;
*a2 = v5;
return v6;
}

Il-parametru tal-iswiċċ huwa qasam tal-istruttura li qabel kien assenjat il-valur 3. Ħares lejn il-każ 3: għall-funzjoni sub_6364C il-parametri huma mgħoddija mill-istruttura li ġew miżjuda hemm fil-funzjoni preċedenti, jiġifieri ċ-ċavetta u d-dejta kriptata. Jekk tħares mill-qrib lejn sub_6364C, tista 'tagħraf l-algoritmu RC4 fih.

Għandna algoritmu u ċavetta. Ejja nippruvaw niddeċifraw l-isem tal-klassi. Hawn x'ġara: com/taobao/wireless/security/adapter/JNICLibrary. Kbir! Aħna qegħdin fit-triq it-tajba.

Siġra tal-kmand

Issa rridu nsibu sfida ReġistruNattivi, li se jindikalna għall-funzjoni doCommandNative. Ejja nħarsu lejn il-funzjonijiet imsejħa minn JNI_OnLoad, u nsibuha fi sub_B7B0:

int __fastcall sub_B7F6(JNIEnv *env, jclass clazz)
{
char signature[41]; // [sp+7h] [bp-55h]
char name[16]; // [sp+30h] [bp-2Ch]
JNINativeMethod method; // [sp+40h] [bp-1Ch]
int v8; // [sp+4Ch] [bp-10h]
v8 = *(_DWORD *)off_8AC00;
decryptString((unsigned __int8 *)&unk_83ED9, (unsigned __int8 *)name, 0x10u);// doCommandNative
decryptString((unsigned __int8 *)&unk_83EEA, (unsigned __int8 *)signature, 0x29u);// (I[Ljava/lang/Object;)Ljava/lang/Object;
method.name = name;
method.signature = signature;
method.fnPtr = sub_B69C;
return ((int (__fastcall *)(JNIEnv *, jclass, JNINativeMethod *, int))(*env)->RegisterNatives)(env, clazz, &method, 1) >> 31;
}

U tabilħaqq, metodu nattiv bl-isem huwa rreġistrat hawn doCommandNative. Issa nafu l-indirizz tiegħu. Ejja naraw x'jagħmel.

int __fastcall doCommandNative(JNIEnv *env, jobject obj, int command, jarray args)
{
int v5; // r5
struc_2 *a5; // r6
int v9; // r1
int v11; // [sp+Ch] [bp-14h]
int v12; // [sp+10h] [bp-10h]
v5 = 0;
v12 = *(_DWORD *)off_8AC00;
v11 = 0;
a5 = (struc_2 *)malloc(0x14u);
if ( a5 )
{
a5->field_0 = 0;
a5->field_4 = 0;
a5->field_8 = 0;
a5->field_C = 0;
v9 = command % 10000 / 100;
a5->field_0 = command / 10000;
a5->field_4 = v9;
a5->field_8 = command % 100;
a5->field_C = env;
a5->field_10 = args;
v5 = sub_9D60(command / 10000, v9, command % 100, 1, (int)a5, &v11);
}
free(a5);
if ( !v5 && v11 )
sub_7CF34(env, v11, &byte_83ED7);
return v5;
}

Bl-isem tista 'raden li hawn huwa l-punt tad-dħul tal-funzjonijiet kollha li l-iżviluppaturi ddeċidew li jittrasferixxu għal-librerija nattiva. Aħna interessati fil-funzjoni numru 10601.

Tista 'tara mill-kodiċi li n-numru tal-kmand jipproduċi tliet numri: kmand/10000, kmand % 10000 / 100 и kmand % 10, jiġifieri, fil-każ tagħna, 1, 6 u 1. Dawn it-tliet numri, kif ukoll pointer għal JNIEnv u l-argumenti mgħoddija lill-funzjoni huma miżjuda ma 'struttura u mgħoddija. Bl-użu tat-tliet numri miksuba (ejja nindikawhom N1, N2 u N3), tinbena siġra tal-kmand.

Xi ħaġa bħal din:

Tfittex vulnerabbiltajiet fl-UC Browser

Is-siġra timtela b'mod dinamiku JNI_OnLoad.
Tliet numri jikkodifikaw il-mogħdija fis-siġra. Kull werqa tas-siġra fiha l-indirizz pocked tal-funzjoni korrispondenti. Iċ-ċavetta tinsab fin-node ġenitur. Is-sejba tal-post fil-kodiċi fejn il-funzjoni li neħtieġu hija miżjuda mas-siġra mhix diffiċli jekk tifhem l-istrutturi kollha użati (aħna ma niddeskrivuhomx sabiex ma nefħux artiklu diġà pjuttost kbir).

Aktar tfixkil

Irċevejna l-indirizz tal-funzjoni li għandha tiddikripta t-traffiku: 0x5F1AC. Imma għadu kmieni wisq biex nifirħu: l-iżviluppaturi tal-UC Browser ħejjew sorpriża oħra għalina.

Wara li tirċievi l-parametri mill-firxa li ġiet iffurmata fil-kodiċi Java, irridu
għall-funzjoni fl-indirizz 0x4D070. U hawn tip ieħor ta 'obfuscation tal-kodiċi jistenniena.

Aħna npoġġu żewġ indiċijiet f'R7 u R4:

Tfittex vulnerabbiltajiet fl-UC Browser

Aħna nbiddlu l-ewwel indiċi għal R11:

Tfittex vulnerabbiltajiet fl-UC Browser

Biex tikseb indirizz minn tabella, uża indiċi:

Tfittex vulnerabbiltajiet fl-UC Browser

Wara li tmur għall-ewwel indirizz, jintuża t-tieni indiċi, li jinsab f'R4. Hemm 230 element fit-tabella.

X'għandek tagħmel dwarha? Tista' tgħid lill-IDA li dan huwa swiċċ: Edit -> Oħrajn -> Speċifika l-idjoma tal-iswiċċ.

Tfittex vulnerabbiltajiet fl-UC Browser

Il-kodiċi li jirriżulta huwa terribbli. Iżda, waqt li tagħmel triqtek fil-ġungla tagħha, tista 'tinnota sejħa għal funzjoni diġà familjari għalina sub_6115C:

Tfittex vulnerabbiltajiet fl-UC Browser

Kien hemm swiċċ li fih fil-każ 3 kien hemm decryption bl-użu tal-algoritmu RC4. U f'dan il-każ, l-istruttura mgħoddija lill-funzjoni hija mimlija mill-parametri mgħoddija lil doCommandNative. Ejja niftakru dak li kellna hemm magicInt bil-valur 16. Inħarsu lejn il-każ korrispondenti - u wara diversi tranżizzjonijiet insibu l-kodiċi li bih l-algoritmu jista 'jiġi identifikat.

Tfittex vulnerabbiltajiet fl-UC Browser

Dan huwa AES!

L-algoritmu jeżisti, dak kollu li jibqa 'huwa li jinkisbu l-parametri tiegħu: mod, ċavetta u, possibilment, il-vettur tal-inizjalizzazzjoni (il-preżenza tiegħu tiddependi fuq il-mod operattiv tal-algoritmu AES). L-istruttura magħhom trid tiġi ffurmata x'imkien qabel is-sejħa tal-funzjoni sub_6115C, iżda din il-parti tal-kodiċi hija speċjalment moħbija sew, għalhekk tqum l-idea li l-kodiċi jiġi garża sabiex il-parametri kollha tal-funzjoni tad-decryption jintremew f'fajl.

Garża

Sabiex ma tiktebx il-kodiċi kollu tal-garża fil-lingwa tal-assemblaġġ manwalment, tista 'tniedi Android Studio, tikteb funzjoni hemmhekk li tirċievi l-istess parametri ta' input bħall-funzjoni tad-deċifrar tagħna u tikteb f'fajl, imbagħad kopja-pejst il-kodiċi li l-kompilatur se jiġġeneraw.

Il-ħbieb tagħna mit-tim tal-UC Browser ħadu ħsieb ukoll il-konvenjenza taż-żieda tal-kodiċi. Ejja niftakru li fil-bidu ta 'kull funzjoni għandna kodiċi taż-żibel li jista' faċilment jiġi sostitwit ma 'xi ieħor. Konvenjenti ħafna 🙂 Madankollu, fil-bidu tal-funzjoni fil-mira m'hemmx biżżejjed spazju għall-kodiċi li jiffranka l-parametri kollha f'fajl. Kelli naqsamha f'partijiet u nuża blokki taż-żibel minn funzjonijiet ġirien. B’kollox kien hemm erba’ partijiet.

L-ewwel parti:

Tfittex vulnerabbiltajiet fl-UC Browser

Fl-arkitettura ARM, l-ewwel erba 'parametri tal-funzjoni huma mgħoddija mir-reġistri R0-R3, il-bqija, jekk ikun hemm, jgħaddu mill-munzell. Ir-reġistru LR iġorr l-indirizz tar-ritorn. Dan kollu jeħtieġ li jiġi ffrankat sabiex il-funzjoni tkun tista 'taħdem wara li niddempjaw il-parametri tagħha. Għandna bżonn ukoll insalvaw ir-reġistri kollha li se nużaw fil-proċess, għalhekk nagħmlu PUSH.W {R0-R10,LR}. F'R7 nikbru l-indirizz tal-lista ta 'parametri mgħoddija lill-funzjoni permezz tal-munzell.

Bl-użu tal-funzjoni miftuħa ejja niftħu l-fajl /data/local/tmp/aes fil-modalità "ab".
jiġifieri għaż-żieda. F'R0 aħna tagħbija l-indirizz tal-isem tal-fajl, f'R1 - l-indirizz tal-linja li tindika l-mod. U hawn jispiċċa l-kodiċi taż-żibel, għalhekk nimxu fuq il-funzjoni li jmiss. Sabiex tkompli taħdem, aħna npoġġu fil-bidu t-tranżizzjoni għall-kodiċi reali tal-funzjoni, billi taqbeż iż-żibel, u minflok iż-żibel inżidu kontinwazzjoni tal-garża.

Tfittex vulnerabbiltajiet fl-UC Browser

Sejħa miftuħa.

L-ewwel tliet parametri tal-funzjoni aES għandhom tip int. Peress li ssejvjajna r-reġistri fil-munzell fil-bidu, nistgħu sempliċement ngħaddu l-funzjoni fwrite l-indirizzi tagħhom fuq il-munzell.

Tfittex vulnerabbiltajiet fl-UC Browser

Sussegwentement għandna tliet strutturi li fihom id-daqs tad-dejta u pointer għad-dejta għaċ-ċavetta, il-vettur tal-inizjalizzazzjoni u d-dejta kriptata.

Tfittex vulnerabbiltajiet fl-UC Browser

Fl-aħħar, agħlaq il-fajl, irrestawra r-reġistri u ttrasferixxi l-kontroll għall-funzjoni reali aES.

Aħna niġbru APK b'librerija patched, niffirmawha, intellgħuha fuq l-apparat/emulatur, u nnieduha. Naraw li d-dump tagħna qed jinħoloq, u hemm ħafna dejta qed tinkiteb. Il-browser juża encryption mhux biss għat-traffiku, u l-encryption kollha jgħaddi mill-funzjoni inkwistjoni. Iżda għal xi raġuni d-dejta meħtieġa mhix hemm, u t-talba meħtieġa mhix viżibbli fit-traffiku. Sabiex ma tistennax sakemm UC Browser jiddeignja li jagħmel it-talba meħtieġa, ejja nieħdu r-rispons kriptat mis-server li wasal qabel u erġa' waħħal l-applikazzjoni: żid id-decryption ma' onCreate tal-attività ewlenija.

    const/16 v1, 0x62
new-array v1, v1, [B
fill-array-data v1, :encrypted_data
const/16 v0, 0x1f
invoke-static {v0, v1}, Lcom/uc/browser/core/d/c/g;->j(I[B)[B
move-result-object v1
array-length v2, v1
invoke-static {v2}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
move-result-object v2
const-string v0, "ololo"
invoke-static {v0, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

Aħna niġbru, niffirmaw, ninstallaw, inniedu. Nirċievu NullPointerException minħabba li l-metodu rritorna null.

Waqt analiżi ulterjuri tal-kodiċi, ġiet skoperta funzjoni li tiddeċifra linji interessanti: "META-INF/" u ".RSA". Jidher li l-applikazzjoni qed tivverifika ċ-ċertifikat tagħha. Jew saħansitra jiġġenera ċwievet minnha. Ma rridx verament nittratta x'qed jiġri biċ-ċertifikat, għalhekk aħna niżżluh iċ-ċertifikat korrett. Ejja nimxu l-linja kriptata sabiex minflok "META-INF/" nikseb "BLABLINF/", oħloq folder b'dak l-isem fl-APK u żid iċ-ċertifikat tal-browser iskojjattlu hemmhekk.

Aħna niġbru, niffirmaw, ninstallaw, inniedu. Bingo! Għandna ċ-ċavetta!

MitM

Irċevejna ċavetta u vettur ta 'inizjalizzazzjoni ugwali għaċ-ċavetta. Ejja nippruvaw niddeċifraw ir-rispons tas-server fil-modalità CBC.

Tfittex vulnerabbiltajiet fl-UC Browser

Naraw il-URL tal-arkivju, xi ħaġa simili għal MD5, "extract_unzipsize" u numru. Aħna niċċekkjaw: l-MD5 tal-arkivju huwa l-istess, id-daqs tal-librerija mhux ippakkjata huwa l-istess. Qed nippruvaw nagħtu garża lil din il-librerija u nagħtuha lill-browser. Biex nuru li l-librerija patched tagħna tagħbija, aħna se nniedu Intenzjoni li noħolqu SMS bit-test "PWNED!" Se nissostitwixxu żewġ tweġibiet mis-server: puds.ucweb.com/upgrade/index.xhtml u biex tniżżel l-arkivju. Fl-ewwel nissostitwixxu MD5 (id-daqs ma jinbidelx wara l-ispakkjar), fit-tieni nagħtu l-arkivju bil-librerija patched.

Il-browser jipprova jniżżel l-arkivju diversi drabi, u wara jagħti żball. Apparentement xi ħaġa
hu ma jħobbx. Bħala riżultat tal-analiżi ta 'dan il-format mċajpra, irriżulta li s-server jittrasmetti wkoll id-daqs tal-arkivju:

Tfittex vulnerabbiltajiet fl-UC Browser

Huwa kodifikat f'LEB128. Wara l-garża, id-daqs tal-arkivju bil-librerija nbidel ftit, għalhekk il-browser ikkunsidra li l-arkivju ġie mniżżel b'mod mgħawweġ, u wara diversi tentattivi tefa' żball.

Aħna naġġustaw id-daqs tal-arkivju... U – rebħa! 🙂 Ir-riżultat jinsab fil-video.

https://www.youtube.com/watch?v=Nfns7uH03J8

Konsegwenzi u reazzjoni tal-iżviluppatur

Bl-istess mod, il-hackers jistgħu jużaw il-karatteristika mhux sigura tal-UC Browser biex iqassmu u jmexxu libreriji malizzjużi. Dawn il-libreriji se jaħdmu fil-kuntest tal-browser, għalhekk se jirċievu l-permessi kollha tas-sistema tiegħu. Bħala riżultat, il-kapaċità li juru twieqi tal-phishing, kif ukoll aċċess għall-fajls tax-xogħol tal-iskojjattlu Ċiniż oranġjo, inklużi logins, passwords u cookies maħżuna fid-database.

Ikkuntattjana l-iżviluppaturi tal-UC Browser u infurmajnahom dwar il-problema li sibna, ippruvajna nirrimarkaw il-vulnerabbiltà u l-periklu tagħha, iżda ma ddiskutew xejn magħna. Sadanittant, il-browser kompla juri l-karatteristika perikoluża tiegħu fil-vista. Iżda ladarba żvelajna d-dettalji tal-vulnerabbiltà, ma kienx aktar possibbli li tinjoraha bħal qabel. Is-27 ta’ Marzu kien
ġiet rilaxxata verżjoni ġdida ta' UC Browser 12.10.9.1193, li aċċessat is-server permezz ta' HTTPS: puds.ucweb.com/upgrade/index.xhtml.

Barra minn hekk, wara l-"iffissar" u sal-ħin tal-kitba ta' dan l-artikolu, jekk tipprova tiftaħ PDF f'browser irriżulta f'messaġġ ta' żball bit-test "Oops, xi ħaġa marret ħażin!" Ma saritx talba lis-server meta pprova jiftaħ PDF, iżda saret talba meta tnieda l-browser, li tagħti ħjiel dwar il-kapaċità kontinwa li tniżżel kodiċi eżekutibbli bi ksur tar-regoli tal-Google Play.

Sors: www.habr.com

Żid kumment