Neman rauni a cikin UC Browser

Neman rauni a cikin UC Browser

Gabatarwar

A karshen Maris mu ya ruwaito, cewa sun gano wata ɓoyayyiyar ikon lodawa da sarrafa lambar da ba a tantance ba a cikin UC Browser. A yau za mu duba dalla-dalla yadda wannan zazzagewar ke faruwa da kuma yadda masu kutse za su iya amfani da shi don amfanin kansu.

A wani lokaci da suka wuce, an yi tallan UC Browser kuma an rarraba shi da tsauri: an shigar da shi akan na'urorin masu amfani ta hanyar amfani da malware, ana rarraba shi daga shafuka daban-daban a ƙarƙashin sunan fayilolin bidiyo (watau masu amfani suna tunanin cewa suna zazzagewa, misali, bidiyon batsa, amma). a maimakon haka sami apk tare da wannan burauzar), yi amfani da banners masu ban tsoro tare da saƙon cewa mai binciken ya tsufa, mai rauni, da makamantansu. A cikin rukunin UC Browser na hukuma akan VK akwai take, wanda masu amfani za su iya yin gunaguni game da tallan da ba su dace ba, akwai misalai da yawa a can. A cikin 2016 akwai ma tallan bidiyo a cikin harshen Rashanci (e, talla don mai binciken toshe talla).

A lokacin rubutawa, UC Browser yana da abubuwan shigarwa sama da 500 akan Google Play. Wannan abin ban sha'awa ne - Google Chrome kawai yana da ƙari. Daga cikin sake dubawa, zaku iya ganin koke-koke da yawa game da talla da turawa zuwa wasu aikace-aikace akan Google Play. Wannan shi ne dalilin bincikenmu: mun yanke shawarar ganin ko UC Browser yana yin wani abu mara kyau. Sai ya zama yana yi!

A cikin lambar aikace-aikacen, an gano ikon saukewa da gudanar da lambar aiwatarwa, wanda ya saba wa ka'idojin buga aikace-aikacen akan Google Play. Baya ga zazzage lambar da za a iya aiwatarwa, UC Browser yana yin haka ta hanyar da ba ta da tsaro, wacce za a iya amfani da ita don ƙaddamar da harin MitM. Mu gani ko za mu iya kai irin wannan harin.

Duk abin da aka rubuta a ƙasa ya dace da sigar UC Browser wanda yake samuwa akan Google Play a lokacin binciken:

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

Kai hari vector

A cikin bayyanuwar UC Browser zaka iya samun sabis tare da suna mai bayyana kansa com.uc.deployment.UpgradeDeployeeService.

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

Lokacin da wannan sabis ɗin ya fara, mai binciken yana yin buƙatar POST zuwa puds.ucweb.com/upgrade/index.xhtml, wanda za'a iya gani a cikin zirga-zirga wasu lokaci bayan farawa. Don amsawa, yana iya karɓar umarni don zazzage wani sabuntawa ko sabon tsari. A lokacin bincike, uwar garken ba ta ba da irin waɗannan umarni ba, amma mun lura cewa lokacin da muke ƙoƙarin buɗe PDF a cikin mai binciken, yana yin buƙatu na biyu zuwa adireshin da aka ƙayyade a sama, bayan haka yana zazzage ɗakin karatu na asali. Don aiwatar da harin, mun yanke shawarar amfani da wannan fasalin na UC Browser: ikon buɗe PDF ta amfani da ɗakin karatu na asali, wanda ba ya cikin apk kuma wanda yake saukewa daga Intanet idan ya cancanta. Yana da kyau a lura cewa, a ka'idar, UC Browser na iya tilasta saukar da wani abu ba tare da hulɗar mai amfani ba - idan kun samar da ingantaccen amsa ga buƙatar da aka aiwatar bayan ƙaddamar da mai binciken. Amma don yin wannan, muna buƙatar yin nazarin ka'idar hulɗa tare da uwar garke daki-daki, don haka mun yanke shawarar cewa zai zama da sauƙi don gyara amsawar da aka katse da maye gurbin ɗakin karatu don aiki tare da PDF.

Don haka, lokacin da mai amfani yana son buɗe PDF kai tsaye a cikin mai bincike, ana iya ganin buƙatun masu zuwa a cikin zirga-zirga:

Neman rauni a cikin UC Browser

Da farko akwai bukatar POST zuwa puds.ucweb.com/upgrade/index.xhtml, sannan
Ana zazzage majigi tare da ɗakin karatu don duba PDF da tsarin ofis. Yana da ma'ana a ɗauka cewa buƙatun farko yana watsa bayanai game da tsarin (aƙalla tsarin gine-gine don samar da ɗakin karatu da ake buƙata), kuma don amsa shi mai bincike yana karɓar wasu bayanai game da ɗakin karatu wanda ke buƙatar saukewa: adireshin da, mai yiwuwa. , wani abu dabam. Matsalar ita ce an ɓoye wannan buƙatar.

Nemi guntu

Amsa guntu

Neman rauni a cikin UC Browser

Neman rauni a cikin UC Browser

Laburaren da kansa yana kunshe a cikin ZIP kuma ba a ɓoye shi ba.

Neman rauni a cikin UC Browser

Bincika lambar ɓarnar hanya

Bari mu yi ƙoƙari mu warware amsar uwar garken. Bari mu dubi lambar aji com.uc.deployment.UpgradeDeployeeService: daga hanya a kanStartCommand je zuwa com.uc. ƙaddamarwa.bx, kuma daga gare ta zuwa 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);
}

Muna ganin samuwar buƙatun POST anan. Muna mai da hankali ga ƙirƙirar tsararrun bytes 16 da cikon sa: 0x5F, 0, 0x1F, -50 (= 0xCE). Yayi daidai da abin da muka gani a cikin buƙatar da ke sama.

A cikin aji ɗaya zaka iya ganin ajin gida wanda ke da wata hanya mai ban sha'awa:

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

Hanyar tana ɗaukar jeri na bytes azaman shigarwa kuma bincika cewa sifili byte 0x60 ko byte na uku shine 0xD0, kuma byte na biyu shine 1, 11 ko 0x1F. Muna kallon martani daga uwar garken: sifili byte shine 0x60, na biyu shine 0x1F, na uku shine 0x60. Sauti kamar abin da muke bukata. Yin la'akari da layukan ("up_decrypt", alal misali), ya kamata a kira wata hanya a nan wacce za ta yanke martanin uwar garken.
Bari mu ci gaba zuwa hanyar gj. Lura cewa hujja ta farko ita ce byte a biya 2 (watau 0x1F a cikin yanayinmu), kuma na biyu shine amsawar uwar garke ba tare da
farko 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;
}

A bayyane yake, a nan mun zaɓi algorithm decryption, kuma wannan byte ɗin da ke cikin mu
shari'ar daidai da 0x1F, yana nuna ɗayan zaɓuɓɓuka uku masu yiwuwa.

Muna ci gaba da nazarin lambar. Bayan tsalle-tsalle biyu mun sami kanmu a cikin wata hanya tare da suna mai bayyana kansa decryptBytesByKey.

Anan an raba ƙarin bytes guda biyu daga amsawarmu, kuma an sami kirtani daga gare su. A bayyane yake cewa ta wannan hanyar an zaɓi maɓallin ɓoye saƙon.

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

Duban gaba, mun lura cewa a wannan matakin ba mu sami maɓalli ba tukuna, amma “mai ganowa”. Samun maɓallin yana da ɗan rikitarwa.

A cikin hanya ta gaba, ana ƙara ƙarin sigogi guda biyu zuwa waɗanda ke wanzu, suna yin huɗu daga cikinsu: lambar sihiri 16, mai gano maɓalli, bayanan ɓoye, da kirtani mara fahimta (a cikin yanayinmu, fanko).

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

Bayan jerin sauye-sauye mun isa hanyar staticBinarySafeDecryptNoB64 dubawa com.alibaba.wireless.security.open.staticdataencrypt.IStaticDataEncryptComponent. Babu azuzuwan a cikin babban lambar aikace-aikacen da ke aiwatar da wannan ƙirar. Akwai irin wannan aji a cikin fayil ɗin lib/armeabi-v7a/libsgmain.so, wanda a zahiri ba .so ba ne, amma .jar. Ana aiwatar da hanyar da muke sha'awar kamar haka:

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

Anan an ƙara lissafin sigoginmu tare da ƙarin lamba biyu: 2 da 0. Yin hukunci ta
komai, 2 yana nufin decryption, kamar yadda a cikin hanyar doFinal tsarin tsarin Javax.crypto.Cipher. Kuma duk wannan yana canjawa wuri zuwa wani na'ura mai ba da hanya tsakanin hanyoyin sadarwa tare da lamba 10601 - wannan shi ne a fili lambar umarni.

Bayan jerin juzu'i na gaba za mu sami aji wanda ke aiwatar da dubawa IrouterComponent da hanya 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);
}
}

Da kuma class JNICLIbrary, wanda a cikinsa aka bayyana hanyar asali DoCommandNative:

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

Wannan yana nufin muna buƙatar nemo hanya a cikin lambar asali DoCommandNative. Kuma wannan shi ne inda nishaɗi ya fara.

Rufe lambar injin

A cikin fayil libsgmain.so (wanda a zahiri .jar ne kuma a cikinsa ne muka sami aiwatar da wasu hanyoyin sadarwa masu alaƙa da ɓoye a sama) akwai ɗakin karatu na asali guda ɗaya: libsgmainso-6.4.36.so. Mun buɗe shi a cikin IDA kuma muna samun tarin akwatunan maganganu tare da kurakurai. Matsalar ita ce teburin taken sashe ba shi da inganci. Ana yin wannan da gangan don rikitar da bincike.

Neman rauni a cikin UC Browser

Amma ba a buƙata: don ɗaukar fayil ɗin ELF daidai kuma bincika shi, teburin taken shirin ya isa. Don haka, muna share teburin sashe kawai, muna cire filayen da suka dace a cikin taken.

Neman rauni a cikin UC Browser

Buɗe fayil ɗin a cikin IDA kuma.

Akwai hanyoyi guda biyu don gaya wa na'urar kama-da-wane ta Java inda daidai a cikin ɗakin karatu na asali aiwatar da hanyar da aka ayyana a cikin lambar Java azaman ɗan ƙasa. Na farko shine a ba shi sunan jinsi Java_package_name_ClassName_Hanyar Sunan.

Na biyu shine yin rijistar lokacin da ake loda ɗakin karatu (a cikin aikin JNI_Load)
ta amfani da kiran aiki 'Yan ƙasa masu rijista.

A wajenmu, idan muka yi amfani da hanyar farko, sunan ya kamata ya kasance kamar haka: Java_com_taobao_wireless_security_adapter_JNIClibrary_doCommandNative.

Babu irin wannan aikin tsakanin ayyukan da aka fitar, wanda ke nufin kana buƙatar neman kira 'Yan ƙasa masu rijista.
Mu je aikin JNI_Load kuma muna ganin wannan hoton:

Neman rauni a cikin UC Browser

Me ke faruwa a nan? A kallon farko, farawa da ƙarshen aikin sune na yau da kullun don gine-ginen ARM. Umarni na farko akan tari yana adana abubuwan da ke cikin rajistar da aikin zai yi amfani da shi a cikin aikinsa (a cikin wannan yanayin, R0, R1 da R2), da kuma abubuwan da ke cikin rajistar LR, wanda ya ƙunshi adireshin dawowa daga aikin. . Umarni na ƙarshe yana mayar da rajistar da aka adana, kuma ana sanya adireshin dawowa nan da nan a cikin rajistar PC - don haka dawowa daga aikin. Amma idan ka duba da kyau, za ka lura cewa koyarwar ta canza adireshin komawa da aka adana a cikin tari. Bari mu lissafta yadda zai kasance bayan
code kisa. Ana loda wani adireshin 1xB0 a cikin R130, ana cire 5 daga ciki, sannan a canza shi zuwa R0 kuma a saka 0x10 a ciki. Yana juya 0xB13B. Don haka, IDA tana tunanin cewa umarni na ƙarshe shine dawowar aiki na yau da kullun, amma a zahiri yana zuwa adireshin ƙididdigewa 0xB13B.

Yana da kyau a tuna a nan cewa masu sarrafawa na ARM suna da hanyoyi guda biyu da umarni guda biyu: ARM da Thumb. Mafi ƙanƙanci mafi ƙanƙanta adreshin yana gaya wa mai sarrafa abin da saitin koyarwa ake amfani da shi. Wato, adreshin shine ainihin 0xB13A, kuma ɗayan a cikin mafi ƙarancin mahimmanci yana nuna yanayin Thumb.

An ƙara irin wannan "adaftar" zuwa farkon kowane aiki a cikin wannan ɗakin karatu da
lambar shara. Ba za mu ƙara yin magana a kansu dalla-dalla ba - muna tunawa kawai
cewa ainihin farkon kusan dukkanin ayyuka yana ɗan gaba kaɗan.

Tun da lambar ba ta yi tsalle kai tsaye zuwa 0xB13A ba, IDA kanta ba ta gane cewa lambar tana nan a wannan wuri ba. Don wannan dalili, baya gane yawancin lambar a ɗakin karatu a matsayin lamba, wanda ke sa bincike ya ɗan yi wahala. Mun gaya wa IDA cewa wannan shine lambar, kuma abin da ya faru ke nan:

Neman rauni a cikin UC Browser

Teburin yana farawa a fili a 0xB144. Menene a cikin sub_494C?

Neman rauni a cikin UC Browser

Lokacin kiran wannan aikin a cikin rajistar LR, muna samun adireshin teburin da aka ambata a baya (0xB144). A R0 - index a cikin wannan tebur. Wato, ana ɗaukar ƙimar daga tebur, ƙara zuwa LR kuma sakamakon shine
adireshin da za a je. Mu gwada lissafinsa: 0xB144 + [0xB144 + 8* 4] = 0xB144 + 0x120 = 0xB264. Muna zuwa adireshin da aka karɓa kuma mu ga ainihin wasu umarni masu amfani kuma mu sake zuwa 0xB140:

Neman rauni a cikin UC Browser

Yanzu za a sami canji a biya tare da index 0x20 daga tebur.

Yin la'akari da girman tebur, za a sami yawancin irin waɗannan canje-canje a cikin lambar. Tambayar ta taso ko zai yiwu a ko ta yaya a magance wannan ta atomatik, ba tare da ƙididdige adireshi da hannu ba. Kuma rubutun da ikon facin code a cikin IDA suna zuwa taimakonmu:

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"

Sanya siginan kwamfuta akan layi 0xB26A, gudanar da rubutun kuma duba canjin zuwa 0xB4B0:

Neman rauni a cikin UC Browser

IDA ba ta sake gane wannan yanki a matsayin lamba ba. Muna taimaka mata kuma mu ga wani zane a can:

Neman rauni a cikin UC Browser

Umarnin bayan BLX ba su da ma'ana sosai, yana da kama da wani nau'in ƙaura. Bari mu duba sub_4964:

Neman rauni a cikin UC Browser

Kuma lalle ne, a nan an ɗauki dword a adireshin da ke kwance a cikin LR, an ƙara shi zuwa wannan adireshin, bayan haka an ɗauki darajar a adireshin da aka samo kuma a saka shi a kan tari. Hakanan, ana ƙara 4 zuwa LR ta yadda bayan dawowa daga aikin, an tsallake wannan koma baya. Bayan haka umarnin POP {R1} yana ɗaukar ƙimar da aka samu daga tarin. Idan ka duba abin da ke a adireshin 0xB4BA + 0xEA = 0xB5A4, za ka ga wani abu mai kama da teburin adireshin:

Neman rauni a cikin UC Browser

Don facin wannan ƙira, kuna buƙatar samun sigogi biyu daga lambar: kashewa da lambar rajista wanda kuke son sanya sakamakon. Ga kowane mai yuwuwar rajista, za ku shirya wani yanki a gaba.

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"

Muna sanya siginan kwamfuta a farkon tsarin da muke son maye gurbin - 0xB4B2 - kuma mu gudanar da rubutun:

Neman rauni a cikin UC Browser

Baya ga sifofin da aka ambata, lambar kuma ta ƙunshi abubuwa masu zuwa:

Neman rauni a cikin UC Browser

Kamar yadda yake a cikin shari'ar da ta gabata, bayan umarnin BLX akwai kashewa:

Neman rauni a cikin UC Browser

Muna ɗaukar kashewa zuwa adireshin daga LR, ƙara shi zuwa LR kuma je can. 0x72044 + 0xC = 0x72050. Rubutun wannan ƙira abu ne mai sauƙ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"

Sakamakon aiwatar da rubutun:

Neman rauni a cikin UC Browser

Da zarar an daidaita komai a cikin aikin, zaku iya nuna IDA zuwa ainihin farkon sa. Zata yanki duk lambar aikin, kuma ana iya haɗa ta ta amfani da HexRays.

Ƙididdigar igiyoyi

Mun koyi yadda ake magance toshe lambar na'ura a cikin ɗakin karatu libsgmainso-6.4.36.so daga UC Browser kuma ya karɓi lambar aikin JNI_Load.

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

Bari mu kalli wadannan layukan da kyau:

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

A cikin aiki sub_73E24 Sunan ajin yana bayyana a fili ana yankewa. A matsayin ma'auni na wannan aikin, mai nuni ga bayanai mai kama da rufaffen bayanai, an wuce takamammen buffer da lamba. Babu shakka, bayan kiran aikin, za a sami layin da aka ɓoye a cikin buffer, tunda an wuce shi zuwa aikin. NemoClass, wanda ke ɗaukar sunan ajin a matsayin siga na biyu. Don haka, lambar ita ce girman buffer ko tsawon layin. Bari mu yi kokarin gano sunan ajin, ya kamata ya gaya mana ko muna tafiya daidai. Bari mu dubi abin da ke faruwa a ciki 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;
}

aiki sub_7AF78 yana ƙirƙira misalin akwati don tsararrun byte na ƙayyadaddun girman (ba za mu zauna kan waɗannan kwantena dalla-dalla ba). Anan an ƙirƙiri irin waɗannan kwantena guda biyu: ɗaya ya ƙunshi layi "DcO/lcK+h?m3c*q@" (Abu ne mai sauƙi a yi tsammani cewa wannan maɓalli ne), ɗayan ya ƙunshi ɓoyayyen bayanai. Na gaba, an sanya abubuwa biyu a cikin wani tsari, wanda aka wuce zuwa aikin sub_6115C. Bari kuma mu sanya filin da darajar 3 a cikin wannan tsarin. Bari mu ga abin da zai faru da wannan tsarin na gaba.

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

Ma'aunin sauyawa filin tsari ne wanda a baya aka sanya darajar 3. Duba harka 3: zuwa aikin sub_6364C ana wuce sigogi daga tsarin da aka ƙara a can a cikin aikin da ya gabata, watau maɓalli da bayanan ɓoye. Idan ka duba da kyau sub_6364C, za ku iya gane RC4 algorithm a ciki.

Muna da algorithm da maɓalli. Bari mu yi kokarin decipher sunan ajin. Ga abin da ya faru: com/taobao/wireless/security/adapter/JNICLibrary. Mai girma! Muna kan hanya madaidaiciya.

Bishiyar umarni

Yanzu muna bukatar mu sami kalubale 'Yan ƙasa masu rijista, wanda zai nuna mana aikin DoCommandNative. Bari mu dubi ayyukan da ake kira daga JNI_Load, kuma mun same shi a ciki 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;
}

Kuma lalle ne, an yi rajistar hanyar asali tare da sunan a nan DoCommandNative. Yanzu mun san adireshinsa. Bari mu ga abin da yake yi.

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

Da sunan za ku iya tsammani cewa a nan ne wurin shigarwa na duk ayyukan da masu haɓakawa suka yanke shawarar canjawa zuwa ɗakin karatu na asali. Muna sha'awar lambar aiki 10601.

Kuna iya gani daga lambar cewa lambar umarni tana samar da lambobi uku: umarni/10000, umarni% 10000/100 и umarni% 10, watau, a cikin yanayinmu, 1, 6 da 1. Waɗannan lambobi uku, da kuma mai nuni zuwa ga JNIEnv kuma muhawarar da aka wuce zuwa aikin ana ƙara su zuwa wani tsari kuma an wuce su. Yin amfani da lambobi uku da aka samu (bari mu nuna su N1, N2 da N3), an gina bishiyar umarni.

Wani abu kamar haka:

Neman rauni a cikin UC Browser

An cika bishiyar a hankali JNI_Load.
Lambobi uku suna ɓoye hanyar cikin itacen. Kowace ganyen bishiyar tana ɗauke da adireshi da aka ɗaure na aikin da ya dace. Makullin yana cikin kullin iyaye. Nemo wurin da ke cikin lambar inda aka ƙara aikin da muke buƙata zuwa itace ba shi da wahala idan kun fahimci duk tsarin da aka yi amfani da shi (ba mu kwatanta su ba don kada ku kumbura wani labarin da ya riga ya wuce).

Ƙarin rufewa

Mun karɓi adireshin aikin da yakamata ya yanke zirga-zirga: 0x5F1AC. Amma ya yi da wuri don murna: masu haɓaka UC Browser sun shirya mana wani abin mamaki.

Bayan karɓar sigogi daga tsararrun da aka kafa a cikin lambar Java, muna samun
zuwa aiki a adireshin 0x4D070. Kuma a nan wani nau'in ɓoye lambar yana jiran mu.

Mun sanya fihirisa guda biyu a cikin R7 da R4:

Neman rauni a cikin UC Browser

Muna matsawa fihirisar farko zuwa R11:

Neman rauni a cikin UC Browser

Don samun adireshi daga tebur, yi amfani da fihirisa:

Neman rauni a cikin UC Browser

Bayan zuwa adireshin farko, ana amfani da fihirisa na biyu, wanda ke cikin R4. Akwai abubuwa 230 a cikin tebur.

Me za a yi game da shi? Kuna iya gaya wa IDA cewa wannan maɓalli ne: Shirya -> Sauran -> Ƙayyade salon magana.

Neman rauni a cikin UC Browser

Sakamakon lambar yana da muni. Amma, yin hanyar ku ta cikin daji, za ku iya lura da kira zuwa wani aikin da muka saba sub_6115C:

Neman rauni a cikin UC Browser

Akwai canji wanda a cikin yanayin 3 an sami raguwa ta amfani da RC4 algorithm. Kuma a wannan yanayin, tsarin da aka wuce zuwa aikin yana cika daga sigogi da aka wuce zuwa DoCommandNative. Bari mu tuna da abin da muke da shi a can sihiriInt tare da darajar 16. Muna duban yanayin da ya dace - kuma bayan sau da yawa mun sami lambar da za a iya gano algorithm.

Neman rauni a cikin UC Browser

Wannan shine AES!

Algorithm ya wanzu, duk abin da ya rage shine don samun sigoginsa: yanayin, maɓalli da, mai yiwuwa, vector farawa (kasancewarsa ya dogara da yanayin aiki na AES algorithm). Dole ne a samar da tsarin tare da su a wani wuri kafin kiran aikin sub_6115C, amma wannan ɓangaren code ɗin yana da kyau sosai, don haka ra'ayin ya taso don daidaita lambar ta yadda za a jefar da duk sigogin aikin yankewa cikin fayil.

Faci

Domin kada a rubuta duk facin code a cikin yaren taro da hannu, zaku iya ƙaddamar da Android Studio, ku rubuta aikin a can wanda ke karɓar sigogin shigarwa iri ɗaya kamar aikin ɓarnawar mu kuma ya rubuta zuwa fayil, sannan ku kwafa lambar da mai tarawa zai yi. haifar.

Abokanmu na ƙungiyar UC Browser suma sun kula da dacewar ƙara code. Bari mu tuna cewa a farkon kowane aiki muna da lambar shara wanda za'a iya maye gurbinsa da wani. Mafi dacewa 🙂 Koyaya, a farkon aikin manufa babu isasshen sarari don lambar da ke adana duk sigogi zuwa fayil. Dole ne in raba shi zuwa sassa kuma in yi amfani da tubalan datti daga ayyukan makwabta. Akwai sassa huɗu gabaɗaya.

Kashi na farko:

Neman rauni a cikin UC Browser

A cikin gine-ginen ARM, ana wuce sigogin ayyuka huɗu na farko ta hanyar rajista R0-R3, sauran, idan akwai, an wuce ta cikin tari. Rijistar LR tana ɗauke da adireshin dawowa. Duk wannan yana buƙatar adana don aikin ya yi aiki bayan mun zubar da sigoginsa. Hakanan muna buƙatar adana duk rajistar da za mu yi amfani da su yayin aiwatarwa, don haka muna yin PUSH.W {R0-R10,LR}. A cikin R7 muna samun adireshin jerin sigogi da aka wuce zuwa aikin ta hanyar tari.

Amfani da aikin zafi bari mu bude fayil din /data/local/tmp/aes in "ab" yanayin
watau don kari. A cikin R0 muna ɗaukar adireshin sunan fayil, a cikin R1 - adireshin layin da ke nuna yanayin. Kuma a nan lambar shara ta ƙare, don haka za mu ci gaba zuwa aiki na gaba. Domin ya ci gaba da aiki, mun sanya a farkon sauyawa zuwa ainihin lambar aikin, ƙetare datti, kuma maimakon datti mun ƙara ci gaba da facin.

Neman rauni a cikin UC Browser

Kira zafi.

Siffofin farko guda uku na aikin AES da type int. Tunda mun ajiye rijistar zuwa tari a farkon, zamu iya wuce aikin kawai rubuta adiresoshin su akan tari.

Neman rauni a cikin UC Browser

Bayan haka muna da tsari guda uku waɗanda ke ɗauke da girman bayanai da mai nuni ga bayanan maɓalli, vector na farawa da bayanan ɓoye.

Neman rauni a cikin UC Browser

A ƙarshe, rufe fayil ɗin, mayar da rajistar kuma canja wurin sarrafawa zuwa ainihin aikin AES.

Muna tattara apk tare da facin ɗakin karatu, sanya hannu, loda shi zuwa na'urar/ emulator, sannan mu ƙaddamar da shi. Muna ganin ana yin jujjuyawar mu, kuma ana rubuta bayanai da yawa a can. Mai binciken yana amfani da ɓoyayyen ɓoye ba kawai don zirga-zirga ba, kuma duk ɓoyayyen yana tafiya ta hanyar aikin da ake tambaya. Amma saboda wasu dalilai bayanan da ake buƙata ba su nan, kuma buƙatun da ake buƙata ba a gani a cikin zirga-zirga. Don kar a jira har sai UC Browser ya yanke shawarar yin buƙatun da ake buƙata, bari mu ɗauki rufaffiyar amsa daga uwar garken da aka karɓa a baya kuma mu sake facin aikace-aikacen: ƙara ƙaddamarwa zuwa kan Ƙirƙiri babban aiki.

    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

Muna tarawa, sa hannu, shigar, ƙaddamarwa. Muna karɓar NullPointerException saboda hanyar ta dawo banza.

A yayin ƙarin bincike na lambar, an gano wani aiki wanda ke rarraba layi mai ban sha'awa: "META-INF/" da ".RSA". Ga alama aikace-aikacen yana tabbatar da takardar shaidarsa. Ko ma yana samar da maɓalli daga gare ta. Ba na so in yi magana da abin da ke faruwa tare da takardar shaidar, don haka za mu zame shi daidai takardar shaidar. Bari mu faci layin da aka rufaffen don maimakon "META-INF/" mu sami "BLABLINF/", ƙirƙirar babban fayil mai suna a cikin APK kuma ƙara takaddun binciken squirrel a wurin.

Muna tarawa, sa hannu, shigar, ƙaddamarwa. Bingo! Muna da maɓalli!

MitM

Mun sami maɓalli da maɓalli na farawa daidai da maɓalli. Bari mu yi ƙoƙari mu ɓoye martanin uwar garken a yanayin CBC.

Neman rauni a cikin UC Browser

Muna ganin URL ɗin ajiya, wani abu mai kama da MD5, “extract_unzipsize” da lamba. Muna duba: MD5 na ma'ajiyar kayan tarihin iri ɗaya ne, girman ɗakin ɗakin karatu da ba a tattara ba iri ɗaya ne. Muna ƙoƙarin facin wannan ɗakin karatu kuma mu ba shi ga mai lilo. Don nuna cewa ɗakin ɗakin karatu na mu ya yi lodi, za mu ƙaddamar da Niyya don ƙirƙirar SMS tare da rubutun "PWNED!" Za mu maye gurbin amsa guda biyu daga uwar garken: puds.ucweb.com/upgrade/index.xhtml da kuma zazzage kayan tarihin. A cikin farko muna maye gurbin MD5 (girman ba ya canzawa bayan an cire kaya), a cikin na biyu muna ba da tarihin tare da facin ɗakin karatu.

Mai binciken yana ƙoƙarin sauke ma'ajin sau da yawa, bayan haka ya ba da kuskure. A fili wani abu
ba ya so. Sakamakon nazarin wannan tsari mai banƙyama, ya nuna cewa uwar garken ita ma tana watsa girman ma'ajin.

Neman rauni a cikin UC Browser

An sanya shi a cikin LEB128. Bayan facin, girman ma'ajin tare da ɗakin karatu ya canza kaɗan, don haka mai binciken ya yi la'akari da cewa an zazzage ma'ajiyar a karkace, kuma bayan yunƙurin da yawa ya jefa kuskure.

Muna daidaita girman girman tarihin ... Kuma - nasara! 🙂 Sakamakon yana cikin bidiyo.

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

Sakamakon da halayen masu haɓakawa

Hakazalika, masu kutse za su iya amfani da yanayin rashin tsaro na UC Browser don rarrabawa da gudanar da dakunan karatu masu lalata. Waɗannan ɗakunan karatu za su yi aiki a cikin mahallin mai binciken, don haka za su karɓi duk izinin tsarin sa. A sakamakon haka, da ikon nuna phishing windows, da kuma samun damar yin amfani da fayilolin aiki na orange squirrel na kasar Sin, ciki har da shiga, kalmomin shiga da kukis da aka adana a cikin bayanan.

Mun tuntubi masu haɓaka UC Browser kuma mun sanar da su matsalar da muka gano, mun yi ƙoƙarin nuna rauni da haɗarinta, amma ba su tattauna komai da mu ba. A halin yanzu, mai binciken ya ci gaba da nuna fasalinsa mai haɗari a bayyane. Amma da zarar mun bayyana cikakkun bayanai game da raunin, ba zai yiwu a yi watsi da shi ba kamar da. Maris 27 ya kasance
An fito da sabon sigar UC Browser 12.10.9.1193, wanda ya shiga sabar ta HTTPS: puds.ucweb.com/upgrade/index.xhtml.

Bugu da ƙari, bayan "gyara" kuma har zuwa lokacin rubuta wannan labarin, ƙoƙarin buɗe PDF a cikin mai bincike ya haifar da saƙon kuskure tare da rubutun "Oop, wani abu ya faru!" Ba a yi buƙatu ga uwar garken lokacin da ake ƙoƙarin buɗe PDF ba, amma an yi buƙatu lokacin da aka ƙaddamar da mai binciken, wanda ke nuni ga ci gaba da zazzage lambar aiwatarwa wanda ya saba wa dokokin Google Play.

source: www.habr.com

Add a comment