Ukukhangela ubuthathaka kwi-UC Browser

Ukukhangela ubuthathaka kwi-UC Browser

Intshayelelo

Ekupheleni kuka March thina ingxelo, ukuba bafumene isakhono esifihliweyo sokulayisha kunye nokuqhuba ikhowudi engaqinisekiswanga kwi-UC Browser. Namhlanje siza kujonga ngokweenkcukacha ukuba kwenzeka njani oku kukhutshelwa kunye nendlela abaduni abangayisebenzisa ngayo ngeenjongo zabo.

Ngexesha elidlulileyo, i-UC Browser yapapashwa kwaye yasasazwa ngamandla kakhulu: ifakwe kwizixhobo zabasebenzisi usebenzisa i-malware, isasazwa kwiindawo ezahlukeneyo phantsi kweefayile zevidiyo (oko kukuthi, abasebenzisi bacinga ukuba bayakhuphela, umzekelo, ividiyo ye-porn, kodwa endaweni yoko ifumene i-APK ngesi sikhangeli), isebenzise iibhena ezoyikisayo ezinemiyalezo yokuba isikhangeli siphelelwe lixesha, sisengozini, kunye nezinto ezilolo hlobo. Kwiqela elisemthethweni le-UC Browser kwi-VK kukho umxholo, apho abasebenzisi banokukhalaza malunga neentengiso ezingalunganga, kukho imizekelo emininzi apho. Ngo-2016 kwabakho kwakhona intengiso yevidiyo ngesiRashiya (ewe, intengiso ye-ad-blocking browser).

Ngexesha lokubhalwa, isikhangeli se-UC sinofakelo olungaphezulu kwe-500 kuDlalo lukaGoogle. Oku kuyamangalisa - nguGoogle Chrome kuphela onokungaphezulu. Phakathi kophononongo unokubona izikhalazo ezininzi malunga nentengiso kunye nokuhanjiswa kwezinye usetyenziso kuGoogle Play. Esi yayisisizathu sophando lwethu: sigqibe kwelokuba sibone ukuba i-UC Browser yenza into embi. Yaye kwathi kanti uyayenza!

Kwikhowudi yesicelo, ukukwazi ukukhuphela kunye nokusebenzisa ikhowudi ephunyeziweyo kufunyenwe, into echasene nemigaqo yokupapasha izicelo kuDlalo lukaGoogle. Ukongeza kokukhuphela ikhowudi ephunyeziweyo, iSikhangeli se-UC sikwenza oko ngendlela engakhuselekanga, enokusetyenziswa ukuqalisa uhlaselo lweMitM. Makhe sibone ukuba sinokuluhlasela kusini na.

Yonke into ebhalwe ngezantsi ifanelekile kuguqulelo lwe-UC Browser eyayikhona kuGoogle Play ngexesha lokufunda:

package: com.UCMobile.intl
versionName: 12.10.8.1172
versionCode: 10598
sha1 APK-Ρ„Π°ΠΉΠ»Π°: f5edb2243413c777172f6362876041eb0c3a928c

Vector yohlaselo

Kwi-UC Browser manifest unokufumana inkonzo enegama elizichazayo com.uc.deployment.UpgradeDeployService.

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

Xa le nkonzo iqala, isikhangeli senza isicelo se-POST puds.ucweb.com/upgrade/index.xhtml, enokubonwa kwi-traffic ixesha elithile emva kokuqala. Ukuphendula, usenokufumana umyalelo wokukhuphela uhlaziyo oluthile okanye imodyuli entsha. Ngethuba lokuhlalutya, umncedisi akazange anike imiyalelo enjalo, kodwa saqaphela ukuba xa sizama ukuvula i-PDF kwisikhangeli, yenza isicelo sesibini kwidilesi echazwe ngasentla, emva koko ikhuphe ilayibrari yasekhaya. Ukwenza uhlaselo, sigqibe kwelokuba sisebenzise eli nqaku le-UC Browser: ukukwazi ukuvula iPDF usebenzisa ithala leencwadi lemveli, elingekho kwi-APK kwaye likhuphela kwi-Intanethi ukuba kuyimfuneko. Kuyaphawuleka ukuba, ngokwethiyori, i-UC Browser inokunyanzeliswa ukuba ikhuphele into ngaphandle kokusebenzisana komsebenzisi - ukuba unikezela ngempendulo eyenziwe kakuhle kwisicelo esenziwe emva kokuba isikhangeli siqaliswe. Kodwa ukwenza oku, kufuneka sifunde iprotocol yokunxibelelana nomncedisi ngokweenkcukacha ezithe vetshe, ngoko ke siye sagqiba kwelokuba kuya kuba lula ukuhlela impendulo ebanjiweyo kwaye sithathe indawo yethala leencwadi ukuze sisebenze ngePDF.

Ke, xa umsebenzisi efuna ukuvula iPDF ngokuthe ngqo kwisikhangeli, ezi zicelo zilandelayo zinokubonwa kwitrafikhi:

Ukukhangela ubuthathaka kwi-UC Browser

Okokuqala kukho isicelo se-POST ukuya puds.ucweb.com/upgrade/index.xhtmlemva koko
Uvimba onethala leencwadi lokujonga iPDF kunye neefomathi zeofisi uyakhutshelwa. Kusengqiqweni ukucinga ukuba isicelo sokuqala sidlulisela ulwazi malunga nenkqubo (ubuncinci ulwakhiwo lokubonelela ngethala leencwadi elifunekayo), kwaye ekuphenduleni isikhangeli sifumana ulwazi malunga nethala leencwadi ekufuneka likhutshelwe: idilesi kwaye, , enye into. Ingxaki kukuba esi sicelo sinoguqulelo oluntsonkothileyo.

Cela iqhekeza

Phendula isiqwenga

Ukukhangela ubuthathaka kwi-UC Browser

Ukukhangela ubuthathaka kwi-UC Browser

Ilayibrari ngokwayo ipakishwe kwi-ZIP kwaye ayifihlwanga.

Ukukhangela ubuthathaka kwi-UC Browser

Khangela ikhowudi yoguqulelo lwetrafikhi

Makhe sizame ukucacisa impendulo yomncedisi. Makhe sijonge ikhowudi yeklasi com.uc.deployment.UpgradeDeployService: ukusuka kwindlela onStartCommand Yiya e com.uc.deployment.bx, kwaye ukusuka kuyo ukuya 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);
}

Sibona ukuqulunqwa kwesicelo se-POST apha. Sinikela ingqalelo ekudalweni kwe-16 bytes kunye nokuzaliswa kwayo: 0x5F, 0, 0x1F, -50 (=0xCE). Ingqamana nale nto siyibonileyo kwesi sicelo singentla.

Kwiklasi enye unokubona iklasi enendlwane enenye indlela enomdla:

        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");
}
}

Indlela ithatha uluhlu lwee-byte njengegalelo kwaye ijonga ukuba i-byte engu-0x60 okanye i-byte yesithathu ngu-0xD0, kwaye i-byte yesibini ngu-1, 11 okanye 0x1F. Sibheka impendulo evela kumncedisi: i-byte ye-zero ngu-0x60, okwesibini ngu-0x1F, okwesithathu ngu-0x60. Ivakala ngathi yile nto siyidingayo. Ukuqwalasela imigca ("up_decrypt", umzekelo), indlela kufuneka ibizwe apha eya kuqhawula impendulo yomncedisi.
Masiqhubele phambili kwindlela gj. Qaphela ukuba ingxabano yokuqala yi-byte kwi-offset 2 (okt 0x1F kwimeko yethu), kwaye okwesibini yimpendulo yomncedisi ngaphandle
yokuqala 16 bytes.

     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;
}

Ngokucacileyo, apha sikhetha i-algorithm ye-decryption, kunye ne-byte efanayo kweyethu
icala elilingana no-0x1F, lichaza enye yeendlela ezintathu ezinokukhethwa.

Siyaqhubeka sihlalutya ikhowudi. Emva kokutsiba kancinane sizifumana sikwindlela enegama elizichazayo decryptBytesByKey.

Apha ii-byte ezimbini ezingaphezulu zihlukaniswe kwimpendulo yethu, kwaye intambo ifunyenwe kubo. Kucacile ukuba ngale ndlela iqhosha lokufihla umyalezo likhethiwe.

    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;
}

Ukujonga phambili, siqaphela ukuba okwangoku asikafumani isitshixo, kodwa kuphela "isazisi" saso. Ukufumana isitshixo kunzima ngakumbi.

Kwindlela elandelayo, iiparameters ezimbini zongezwa kwizinto ezikhoyo, zenza ezine zazo: inombolo yomlingo 16, isihlonzi esibalulekileyo, idatha efihliweyo, kunye nomtya ongaqondakaliyo (kwimeko yethu, engenanto).

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

Emva koluhlu lweenguqu sifika kwindlela i-staticBinarySafeDecryptNoB64 ujongano com.alibaba.wireless.security.open.staticdataencrypt.IStaticDataEncryptComponent. Akukho ziklasi kwikhowudi yesicelo engundoqo eyenza olu jongano. Kukho udidi olunjalo kwifayile lib/armeabi-v7a/libsgmain.so, engeyiyo ngokwenene a .so, kodwa a .jar. Indlela esinomdla ngayo iphunyezwa ngolu hlobo lulandelayo:

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);
}
//...
}

Apha uluhlu lwethu lweeparamitha ludityaniswe ngee-integer ezimbini ezingakumbi: 2 kunye no-0. Ngokujonga
yonke into, i-2 ithetha ukuchithwa, njengakwindlela doFinal iklasi yenkqubo javax.crypto.Cipher. Kwaye konke oku kudluliselwa kwi-Router ethile kunye nenombolo 10601 - oku ngokucacileyo inombolo yomyalelo.

Emva kwekhonkco elilandelayo leenguqu sifumana iklasi eyenza ujongano IRouterComponent kunye nendlela doCommand:

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);
}
}

Kwaye kwakhona iklasi Ithala leencwadi le-JNIC, apho indlela yemveli ibhengezwe khona doCommandNative:

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

Oku kuthetha ukuba kufuneka sifumane indlela kwikhowudi yemveli doCommandNative. Kwaye kulapho ulonwabo luqala khona.

Ukunyanzeliswa kwekhowudi yomatshini

Kwifayile libsgmain.so (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π° самом Π΄Π΅Π»Π΅ .jar ΠΈ Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΌΡ‹ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ нашли Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… интСрфСйсов, связанных с ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ) Π΅ΡΡ‚ΡŒ ΠΎΠ΄Π½Π° нативная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°: libsgmainso-6.4.36.so. Siyivula kwi-IDA kwaye sifumane iqela leebhokisi zengxoxo ezineempazamo. Ingxaki kukuba itheyibhile yeheader yecandelo ayisebenzi. Oku kwenziwa ngenjongo ukwenza nzima uhlalutyo.

Ukukhangela ubuthathaka kwi-UC Browser

Kodwa ayidingeki: ukulayisha ngokuchanekileyo ifayile yeELF kwaye uyihlalutye, itafile yeheader yeprogram yanele. Ke ngoko, sisusa ngokulula itafile yecandelo, sikhuphela ngaphandle iindawo ezihambelanayo kwiheda.

Ukukhangela ubuthathaka kwi-UC Browser

Vula ifayile kwi-IDA kwakhona.

Kukho iindlela ezimbini zokuxelela umatshini weJava onenyani apho kanye kwithala leencwadi lemveli ukuphunyezwa kwendlela echazwe kwikhowudi yeJava njengemveli ibekwe. Eyokuqala kukuyinika igama lohlobo Java_package_name_ClassName_MethodName.

Okwesibini kukubhalisa xa ulayisha ithala leencwadi (kwintsebenzo JNI_Onload)
usebenzisa ifowuni yokusebenza Abemi bomthonyama.

Kwimeko yethu, ukuba sisebenzisa indlela yokuqala, igama kufuneka libe ngolu hlobo: Java_com_taobao_wireless_security_adapter_JNICLibrary_doCommandNative.

Akukho msebenzi onjalo phakathi kwemisebenzi ethunyelwa ngaphandle, okuthetha ukuba kufuneka ujonge umnxeba Abemi bomthonyama.
Masiye kumcimbi JNI_Onload kwaye sibona lo mfanekiso:

Ukukhangela ubuthathaka kwi-UC Browser

Kwenzeka ntoni apha? Ukuqala nje kokubona, ukuqala kunye nokuphela komsebenzi kuqhelekileyo kuyilo lwe-ARM. Umyalelo wokuqala kwi-stack ugcina imixholo yeerejista ukuba umsebenzi uya kusebenzisa ekusebenzeni kwayo (kule meko, i-R0, i-R1 kunye ne-R2), kunye nemixholo yerejista ye-LR, equlethe idilesi yokubuyisela evela kumsebenzi. . Umyalelo wokugqibela ubuyisela iirejista ezigciniweyo, kwaye idilesi yokubuyisela ifakwe ngokukhawuleza kwirejista yePC - ngaloo ndlela ibuya emsebenzini. Kodwa ukuba ujongisisa, uya kuqaphela ukuba umyalelo wokugqibela utshintsha idilesi yokubuyisela egcinwe kwi-stack. Masibale ukuba kuya kuba njani emva koko
ukwenziwa kwekhowudi. Idilesi ethile i-1xB0 ilayishwe kwi-R130, i-5 ikhutshwe kuyo, emva koko idluliselwe kwi-R0 kwaye i-0x10 yongezwa kuyo. Kuvela i-0xB13B. Ngaloo ndlela, i-IDA icinga ukuba umyalelo wokugqibela yimbuyekezo yomsebenzi oqhelekileyo, kodwa eneneni uya kwidilesi ebaliweyo 0xB13B.

Kufanelekile ukukhumbula apha ukuba abaqhubekeki be-ARM baneendlela ezimbini kunye neseti ezimbini zemiyalelo: i-ARM kunye neThupha. Eyona nto incinci ibalulekileyo yedilesi ixelela umqhubekekisi ukuba yeyiphi iseti yomyalelo esetyenziswayo. Oko kukuthi, idilesi eneneni ngu-0xB13A, kwaye enye kweyona incinci ibalulekileyo ibonisa imo yeThupha.

"I-adaptha" efanayo yongezwe ekuqaleni komsebenzi ngamnye kweli thala leencwadi kunye
ikhowudi yenkunkuma. Asiyi kuhlala kuzo ngokweenkcukacha ngakumbi - siyakhumbula nje
ukuba isiqalo sokwenyani phantse yonke imisebenzi ikude kancinane.

Kuba ikhowudi ayitsibe ngokucacileyo kwi-0xB13A, i-IDA ngokwayo ayizange iqonde ukuba ikhowudi ibikule ndawo. Ngesizathu esifanayo, ayiqapheli uninzi lwekhowudi kwithala leencwadi njengekhowudi, nto leyo eyenza uhlalutyo lube nzima. Sixelela i-IDA ukuba le yikhowudi, kwaye yile yenzekayo:

Ukukhangela ubuthathaka kwi-UC Browser

Itafile iqala ngokucacileyo kwi-0xB144. Yintoni ekwi-sub_494C?

Ukukhangela ubuthathaka kwi-UC Browser

Xa ubiza lo msebenzi kwirejista ye-LR, sifumana idilesi yetafile ekhankanywe ngaphambili (0xB144). Kwi-R0 - isalathisi kule theyibhile. Oko kukuthi, ixabiso lithatyathwe kwitafile, yongezwa kwi-LR kwaye umphumo uthi
idilesi yokuya kuyo. Makhe sizame ukuyibala: 0xB144 + [0xB144 + 8* 4] = 0xB144 + 0x120 = 0xB264. Siya kwidilesi efunyenweyo kwaye sibone ngokwenyani imiyalelo embalwa eluncedo kwaye kwakhona uye ku-0xB140:

Ukukhangela ubuthathaka kwi-UC Browser

Ngoku kuya kubakho utshintsho kwi-offset kunye nesalathisi 0x20 ukusuka kwitafile.

Ukuqwalasela ubungakanani betafile, kuya kubakho utshintsho oluninzi olunjalo kwikhowudi. Umbuzo uvela ukuba ngaba kunokwenzeka ngandlela-thile ukujongana nale nto ngokuzenzekelayo, ngaphandle kokubala ngesandla iidilesi. Kwaye imibhalo kunye nokukwazi ukupakisha ikhowudi kwi-IDA iza kuncedo lwethu:

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"

Beka ikhesa kumgca we-0xB26A, sebenzisa iskripthi kwaye ubone utshintsho kwi-0xB4B0:

Ukukhangela ubuthathaka kwi-UC Browser

I-IDA kwakhona ayizange iqaphele le ndawo njengekhowudi. Siyamnceda kwaye sibone enye uyilo apho:

Ukukhangela ubuthathaka kwi-UC Browser

Imiyalelo emva kwe-BLX ayibonakali isengqiqweni, ifana nolunye uhlobo lokufuduswa. Makhe sijonge kwi-sub_4964:

Ukukhangela ubuthathaka kwi-UC Browser

Kwaye ngokwenene, apha i-dword ithathwa kwidilesi elele kwi-LR, yongezwa kule dilesi, emva koko ixabiso kwidilesi yesiphumo lithathwa kwaye libekwe kwisitaki. Kwakhona, u-4 wongezwa kwi-LR ukwenzela ukuba emva kokubuya emsebenzini, le offset efanayo iyatsitywa. Emva koko umyalelo wePOP {R1} uthatha ixabiso lesiphumo kwisitaki. Ukuba ujonga into ekhoyo kwidilesi 0xB4BA + 0xEA = 0xB5A4, uya kubona into efana netafile yedilesi:

Ukukhangela ubuthathaka kwi-UC Browser

Ukupakisha olu yilo, kuya kufuneka ufumane iiparitha ezimbini kwikhowudi: i-offset kunye nenombolo yerejista ofuna ukubeka kuyo umphumo. Kwirejista nganye enokwenzeka, kuya kufuneka ulungiselele isiqwenga sekhowudi kwangaphambili.

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"

Sibeka ikhesa ekuqaleni kwesakhiwo esifuna ukusitshintsha - 0xB4B2 - kwaye siqhube iskripthi:

Ukukhangela ubuthathaka kwi-UC Browser

Ukongeza kwizakhiwo esele zikhankanyiwe, ikhowudi ikwaqulethe oku kulandelayo:

Ukukhangela ubuthathaka kwi-UC Browser

Njengakwimeko yangaphambili, emva komyalelo we-BLX kukho i-offset:

Ukukhangela ubuthathaka kwi-UC Browser

Sithatha i-offset kwidilesi esuka kwi-LR, yongeza kwi-LR kwaye uye apho. 0x72044 + 0xC = 0x72050. Umbhalo wolu yilo ulula kakhulu:

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"

Isiphumo sokwenziwa kwescript:

Ukukhangela ubuthathaka kwi-UC Browser

Nje ukuba yonke into ikhutshiwe kumsebenzi, ungakhomba i-IDA ekuqaleni kwayo. Iza kudibanisa yonke ikhowudi yomsebenzi, kwaye inokuchithwa kusetyenziswa i-HexRays.

Uluhlu lweekhowudi

Sifunde ukujongana ne-obfuscation yekhowudi yomatshini kwithala leencwadi libsgmainso-6.4.36.so ukusuka kwiBrowser ye-UC kwaye ifumene ikhowudi yomsebenzi 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;
}

Masijonge ngakumbi le migca ilandelayo:

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

Kumsebenzi ngaphantsi_73E24 igama leklasi licinywa ngokucacileyo. Njengeeparamitha kulo msebenzi, isalathi kwidatha efana nedatha efihliweyo, isikhuseli esithile kunye nenani ziyagqithiswa. Ngokucacileyo, emva kokubiza umsebenzi, kuya kubakho umgca ofihliweyo kwi-buffer, kuba igqithiselwe kumsebenzi. Fumana iClass, ethatha igama leklasi njenge parameter yesibini. Ngoko ke, inani libukhulu besikhuseli okanye ubude bomgca. Masizame ukucacisa igama leklasi, kufuneka lisixelele ukuba sihamba ngendlela elungileyo. Makhe sijonge ngakumbi okwenzekayo ngaphantsi_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;
}

Umsebenzi ngaphantsi_7AF78 yenza umzekelo wesikhongozeli se-byte arrays yobukhulu obuchaziweyo (asiyi kuhlala kwezi zikhongozeli ngokweenkcukacha). Apha izitya ezimbini ezinjalo zenziwe: enye iqulethe umgca "DcO/lcK+h?m3c*q@" (Kulula ukuqikelela ukuba esi sisitshixo), enye iqulethe idatha efihliweyo. Emva koko, zombini izinto zifakwe kwisakhiwo esithile, esidluliselwa kumsebenzi ngaphantsi_6115C. Masiphawule indawo enexabiso 3 kolu lwakhiwo.Makhe sibone ukuba kwenzeka ntoni kwesi sakhiwo ngokulandelayo.

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;
}

Iparamitha yokutshintsha yintsimi yesakhiwo eyayinikwe ngaphambili ixabiso le-3. Jonga kwimeko yesi-3: kumsebenzi ngaphantsi_6364C iiparamitha zigqithiswa kwisakhiwo esongezwa apho kumsebenzi wangaphambili, oko kukuthi isitshixo kunye nedatha efihliweyo. Ukuba ujongisisa ngaphantsi_6364C, unokwazi ukubona i-algorithm ye-RC4 kuyo.

Sine-algorithm kunye nesitshixo. Makhe sizame ukucacisa igama leklasi. Nantsi into eyenzekayo: com/taobao/wireless/security/adapter/JNICLibrary. Kakhulu! Sisendleleni elungileyo.

Umthi womyalelo

Ngoku kufuneka sifumane umngeni Abemi bomthonyama, eya kusikhomba kumsebenzi doCommandNative. Makhe sijonge imisebenzi ebizwa ukusuka JNI_Onload, kwaye siyifumana kuyo ngaphantsi_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;
}

Kwaye eneneni, indlela yemveli enegama ibhalisiwe apha doCommandNative. Ngoku siyayazi idilesi yakhe. Makhe sibone ukuba wenza ntoni.

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;
}

Ngegama ungaqikelela ukuba nantsi indawo yokungena yayo yonke imisebenzi abaphuhlisi abagqibe ekubeni bayigqithisele kwithala leencwadi lemveli. Sinomdla kwinombolo yomsebenzi 10601.

Ungabona kwikhowudi ukuba inombolo yomyalelo ivelisa amanani amathathu: umyalelo/10000, umyalelo % 10000 / 100 ΠΈ umyalelo % 10, oko kukuthi, kwimeko yethu, 1, 6 kunye no-1. La manani mathathu, kunye nesalathi JNIEnv kwaye iingxoxo ezigqithiselwe kumsebenzi zongezwa kwisakhiwo kwaye zigqithiselwe. Kusetyenziswa amanani amathathu afunyenweyo (masiwachaze u-N1, N2 kunye no-N3), umthi womyalelo wakhiwe.

Into efana nale:

Ukukhangela ubuthathaka kwi-UC Browser

Umthi uzaliswe ngamandla JNI_Onload.
Amanani amathathu afaka ikhowudi yendlela emthini. Igqabi ngalinye lomthi liqulethe idilesi epokiweyo yomsebenzi ohambelanayo. Isitshixo sikwinodi yomzali. Ukufumana indawo kwikhowudi apho umsebenzi esiwudingayo wongezwa emthini akukho nzima ukuba uyaziqonda zonke izakhiwo ezisetyenzisiweyo (asizichazi ukuze singabhubhisi inqaku esele lilikhulu).

I-obfuscation engakumbi

Sifumene idilesi yomsebenzi ekufuneka iguqule ukuntsonkotha kwetrafikhi: 0x5F1AC. Kodwa kuselithuba ukuba sivuye: abaphuhlisi be-UC Browser basilungiselele enye into emangalisayo.

Emva kokufumana iiparamitha ukusuka kuluhlu olwenziwe kwikhowudi yeJava, sifumana
kumsebenzi kwidilesi 0x4D070. Kwaye nantsi olunye uhlobo lwekhowudi obfuscation isilindile.

Sibeka ii-indices ezimbini kwi-R7 kunye ne-R4:

Ukukhangela ubuthathaka kwi-UC Browser

Sitshintsha isalathisi sokuqala siye kwi-R11:

Ukukhangela ubuthathaka kwi-UC Browser

Ukufumana idilesi kwitafile, sebenzisa isalathisi:

Ukukhangela ubuthathaka kwi-UC Browser

Emva kokuya kwidilesi yokuqala, kusetyenziswa isalathiso sesibini, esikwi-R4. Kukho izinto ezingama-230 kwitheyibhile.

Yintoni onokuyenza ngayo? Ungaxelela i-IDA ukuba olu lutshintsho: Hlela -> Okunye -> Cacisa iswitshi isithethi.

Ukukhangela ubuthathaka kwi-UC Browser

Ikhowudi yesiphumo iyoyikeka. Kodwa, ukwenza indlela yakho kwihlathi layo, unokuqaphela umnxeba kumsebenzi osele uqhelekile kuthi ngaphantsi_6115C:

Ukukhangela ubuthathaka kwi-UC Browser

Kwakukho utshintsho apho kwimeko ye-3 kwakukho ukuchithwa kwe-decryption usebenzisa i-algorithm ye-RC4. Kwaye kule meko, isakhiwo esigqithiselwe kumsebenzi sizaliswe kwiiparamitha ezidluliselwe kuyo doCommandNative. Masikhumbule into esasinayo apho magicInt ngexabiso 16. Sijonge kwimeko ehambelanayo - kwaye emva kweenguqu ezininzi sifumana ikhowudi apho i-algorithm inokuchongwa ngayo.

Ukukhangela ubuthathaka kwi-UC Browser

Le yi-AES!

I-algorithm ikhona, konke okuseleyo kukufumana iiparitha zayo: imowudi, isitshixo kwaye, mhlawumbi, i-vector yokuqalisa (ubukho bayo buxhomekeke kwindlela yokusebenza ye-algorithm ye-AES). Ulwakhiwo kunye nabo kufuneka lwenziwe kwindawo ethile phambi komnxeba wokusebenza ngaphantsi_6115C, kodwa le ndawo yekhowudi ibonakaliswe kakuhle, ngoko ke uluvo luvela ukupeyisha ikhowudi ukuze zonke iiparameters zomsebenzi wokuguqulelwa kwekhowudi zilahlwe kwifayile.

Ubamba

Ukuze ungabhali yonke ikhowudi yesiqwenga ngolwimi lwendibano ngesandla, unokuphehlelela i-Android Studio, bhala umsebenzi apho ofumana iiparamitha zegalelo ezifanayo njengomsebenzi wethu wokuguqulela uguqulelo oluntsonkothileyo kwaye ubhale kwifayile, emva koko ukope-uncamathisele ikhowudi umqambi aya kuthi. velisa.

Abahlobo bethu kwiqela le-UC Browser nabo bakukhathalele ukongezwa kwekhowudi. Masikhumbule ukuba ekuqaleni komsebenzi ngamnye sinekhowudi yenkunkuma enokutshintshwa ngokulula kunye nayo nayiphi na enye. Ilungele kakhulu πŸ™‚ Nangona kunjalo, ekuqaleni komsebenzi ojoliswe kuyo akukho ndawo eyaneleyo yekhowudi egcina zonke iiparameters kwifayile. Kwafuneka ndilahlule libe ngamacandelo ndize ndisebenzise imiqobo yenkunkuma evela kwimisebenzi eselumelwaneni. Kwakukho iinxalenye ezine xa zizonke.

Inxalenye yokuqala:

Ukukhangela ubuthathaka kwi-UC Browser

Kuyilo lwe-ARM, iiparamitha ezine zokuqala zigqithiswa kwiirejista ze-R0-R3, ezinye, ukuba zikhona, zigqithiswa kwi-stack. Irejista ye-LR inedilesi yokubuya. Konke oku kufuneka kugcinwe ukuze umsebenzi usebenze emva kokulahla iiparameters zawo. Kwakhona kufuneka sigcine zonke iirejista esiza kuzisebenzisa kwinkqubo, ngoko senza i-PUSH.W {R0-R10,LR}. Kwi-R7 sifumana idilesi yoluhlu lweeparamitha ezigqithiselwe kumsebenzi nge-stack.

Ukusebenzisa umsebenzi fopen masivule ifayile /data/local/tmp/aes kwimo ka "ab".
oko kukuthi ukongeza. Kwi-R0 silayisha idilesi yegama lefayile, kwi-R1 - idilesi yomgca ebonisa indlela. Kwaye apha ikhowudi yenkunkuma iphela, ngoko siqhubela phambili kumsebenzi olandelayo. Ukuze iqhubeke nokusebenza, sibeka ekuqaleni ukutshintshela kwikhowudi yangempela yomsebenzi, ukudlula inkunkuma, kwaye endaweni yenkunkuma songeza ukuqhubeka kwesiqwenga.

Ukukhangela ubuthathaka kwi-UC Browser

Ukufowuna fopen.

Iiparamitha ezintathu zokuqala zomsebenzi AES babe nodidi int. Ekubeni sigcine iirejista kwisitaki ekuqaleni, sinokudlula ngokulula umsebenzi bhala iidilesi zabo kwistakhi.

Ukukhangela ubuthathaka kwi-UC Browser

Okulandelayo sinezakhiwo ezithathu eziqulethe ubungakanani bedatha kunye nesalathisi kwidatha yesitshixo, i-vector yokuqalisa kunye nedatha efihliweyo.

Ukukhangela ubuthathaka kwi-UC Browser

Ekugqibeleni, vala ifayile, ubuyisele iirejista kwaye udlulise ulawulo kumsebenzi wangempela AES.

Siqokelela i-APK enelayibrari ekhutshiweyo, siyisayine, siyilayishe kwisixhobo/i-emulator, kwaye siyisungule. Siyabona ukuba ukulahla kwethu kuyadalwa, kwaye idatha eninzi ibhalwa apho. Umkhangeli zincwadi usebenzisa uguqulelo oluntsonkothileyo hayi kwitrafikhi kuphela, kwaye lonke ufihlo luhamba ngomsebenzi obuzwayo. Kodwa ngesizathu esithile idatha efunekayo ayikho, kwaye isicelo esifunekayo asibonakali kwi-traffic. Ukuze ungalindi de i-UC Browser ideyigne ukwenza isicelo esiyimfuneko, masithathe impendulo efihliweyo kwiseva efunyenwe ngaphambili kwaye siphinde sipeyishe isicelo kwakhona: yongeza ukuguqulelwa kwi-decryption kwi-Yenza owona msebenzi uphambili.

    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

Siyahlanganisa, sisayine, sifake, siqalise. Sifumana i-NullPointerException kuba indlela ibuyile.

Ngethuba lokuhlalutya ngakumbi ikhowudi, umsebenzi wafumanisa ukuba uchaza imigca enomdla: "META-INF /" kunye ne ".RSA". Kubonakala ngathi isicelo siqinisekisa isatifikethi saso. Okanye ivelise izitshixo kuyo. Andifuni kujongana nento eyenzekayo ngesatifikethi, ke siya kusityibilika nje isatifikethi esichanekileyo. Masifake umgca ofihliweyo ukuze endaweni ye "META-INF /" sifumane "BLABLINF /", yenza ifolda enelo gama kwi-APK kwaye ungeze isatifikethi se-squirrel browser apho.

Siyahlanganisa, sisayine, sifake, siqalise. Ibhingo! Sinesitshixo!

MitM

Sifumene isitshixo kunye nevektha yokuqalisa elingana nesitshixo. Makhe sizame ukucima impendulo yomncedisi kwimo ye-CBC.

Ukukhangela ubuthathaka kwi-UC Browser

Sibona i-URL ye-archive, into efana ne-MD5, "extract_unzipsize" kunye nenani. Sijonga: i-MD5 ye-archive iyafana, ubukhulu bethala leencwadi elingapakishwanga buyafana. Sizama ukupeyisha eli thala leencwadi kwaye silinike isikhangeli. Ukubonisa ukuba ilayibrari yethu ekhutshiweyo ilayishiwe, siya kuphehlelela iNjongo yokwenza iSMS enombhalo othi β€œPWNED!” Siza kuthatha indawo yeempendulo ezimbini kwiseva: puds.ucweb.com/upgrade/index.xhtml kunye nokukhuphela indawo yokugcina. Kwiyokuqala sithatha indawo ye-MD5 (ubungakanani abutshintshi emva kokukhupha), okwesibini sinika i-archive kunye nelayibrari edibeneyo.

Isikhangeli sizama ukukhuphela i-archive izihlandlo ezininzi, emva koko sinika impazamo. Ngokucacileyo into
akathandi. Njengesiphumo sokuhlalutya le fomati imfiliba, kuye kwavela ukuba umncedisi ukwahambisa ubungakanani bogcino:

Ukukhangela ubuthathaka kwi-UC Browser

Ifakwe ngekhowudi kwi-LEB128. Emva kwepatch, ubungakanani bendawo yokugcina kunye nethala leencwadi yatshintsha kancinci, ngoko ke isikhangeli sithathele ingqalelo ukuba indawo yokugcina ikhutshelwe ngokugwenxa, kwaye emva kwemizamo emininzi iphose impazamo.

Silungisa ubungakanani bendawo yokugcina izinto ... Kwaye - uloyiso! πŸ™‚ Isiphumo sikwividiyo.

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

Iziphumo kunye nempendulo yomphuhlisi

Ngendlela efanayo, abahlaseli banokusebenzisa into engakhuselekanga ye-UC Browser ukusasaza kunye nokuqhuba iilayibrari ezinobungozi. La mathala eencwadi aya kusebenza kumxholo wesikhangeli, ngoko ke aya kufumana zonke iimvume zenkqubo yawo. Ngenxa yoko, ukukwazi ukubonisa i-phishing windows, kunye nokufikelela kwiifayile zokusebenza ze-orange squirrel yaseTshayina, kubandakanywa ukungena, amagama ayimfihlo kunye neecookies ezigcinwe kwisiseko sedatha.

Siqhagamshele abaphuhlisi be-UC Browser kwaye sabazisa malunga nengxaki esiyifumeneyo, sazama ukubonisa ukuba sesichengeni kunye nobungozi bayo, kodwa abazange baxoxe nantoni na nathi. Ngeli xesha, isikhangeli siqhubekile nokubonakalisa imbonakalo yaso eyingozi emehlweni acacileyo. Kodwa sakuba siveze iinkcukacha zokuba sesichengeni, bekungasekho ukuba singahoyi njengakuqala. NgoMatshi 27 kwaba
inguqulelo entsha ye-UC Browser 12.10.9.1193 yakhululwa, eyafikelela kwiseva ngeHTTPS: puds.ucweb.com/upgrade/index.xhtml.

Ukongeza, emva ko "ulungiso" kwaye kude kube lixesha lokubhala eli nqaku, ukuzama ukuvula iPDF kwisikhangeli kubangele umyalezo wempazamo ngombhalo othi "Oops, kukho into engalunganga!" Isicelo kumncedisi asenziwanga xa uzama ukuvula iPDF, kodwa isicelo senziwe xa isikhangeli siqalisiwe, esibonisa ukukwazi ukuqhubeka ukukhuphela ikhowudi ephunyeziweyo ngokuphulwa kwemithetho yeGoogle Play.

umthombo: www.habr.com

Yongeza izimvo