Raadinta dayacanka UC Browser

Raadinta dayacanka UC Browser

Horudhac

Dhamaadka March waxaan la sheegay, in ay heleen awood qarsoon oo ay ku shuban karaan oo ay ku socodsiinayaan koodka aan la xaqiijin ee UC Browser. Maanta waxaan si faahfaahsan u eegi doonaa sida uu u dhaco soo dejintan iyo sida ay tuugtu ugu isticmaali karaan ujeedooyinkooda.

Waqti ka hor, UC Browser ayaa la xayeysiiyay oo loo qaybiyay si aad u daran: waxaa lagu rakibay aaladaha isticmaaleyaasha iyadoo la adeegsanayo malware, laga qaybiyay goobo kala duwan oo hoos yimaada faylalka fiidiyowga (ie, isticmaalayaashu waxay u maleeyeen inay soo dejinayaan, tusaale ahaan, fiidiyoow lulataaye, laakiin halkii uu ka helay APK browser-kan), waxay adeegsadeen boorar cabsi leh oo wata fariimo sheegaya in browserku uu duugoobay, nugul, iyo wax la mid ah. Kooxda rasmiga ah ee UC Browser ee VK waxaa jira mawduuc, kaas oo isticmaalayaashu ay ka caban karaan xayaysiisyada aan caddaaladda ahayn, waxaa jira tusaalooyin badan. 2016 waxaa jiray xitaa xayeysiis muuqaal ah ruushka (haa, xayaysiinta browser-ka xannibaya).

Waqtiga qorista, UC Browser wuxuu leeyahay in ka badan 500 rakibo Google Play. Tani waa cajiib - Google Chrome kaliya ayaa leh wax badan. Ka mid ah faallooyinka waxaad arki kartaa cabashooyin aad u badan oo ku saabsan xayaysiisyada iyo dib u habeynta codsiyada Google Play. Tani waxay ahayd sababta cilmi-baaristayada: waxaan go'aansanay inaan aragno haddii UC Browser uu sameynayo wax xun. Oo waxay noqotay inuu sameeyo!

Koodhka codsiga, awooda lagu soo dejiyo oo socodsiiyo kood la fulin karo ayaa la ogaaday, taasoo lid ku ah shuruucda daabacaada codsiyada Google Play. Marka laga soo tago soo dejinta koodka la fulin karo, UC Browser wuxuu sidaas u sameeyaa si aan ammaan ahayn, kaas oo loo isticmaali karo in lagu qaado weerarka MitM. Aynu eegno haddii aan qaadi karno weerarkan oo kale.

Wax kasta oo hoos ku qoran waxay khuseeyaan nooca UC Browser ee laga heli karo Google Play wakhtiga daraasadda:

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

Weerar vector

Muujinta UC Browser waxaad ka heli kartaa adeeg leh magac is-sharaxaya com.uc.deployment.UpgradeDeployment Service.

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

Marka adeegani bilowdo, browser-ku waxa uu sameeyaa codsi POST ah puds.ucweb.com/upgrade/index.xhtml, kaas oo lagu arki karo gaadiidka wakhti ka dib bilawga. Isagoo ka jawaabaya, waxaa laga yaabaa inuu helo amar si uu u soo dejiyo xoogaa cusbooneysiin ah ama cutub cusub. Inta lagu jiro falanqaynta, server-ku ma bixin amarradan oo kale, laakiin waxaan ogaanay in marka aan isku dayeyno inaan furno PDF-ka browserka, uu sameeyo codsi labaad oo ku saabsan ciwaanka kor ku xusan, ka dib markii uu soo dejiyo maktabadda hooyo. Si loo fuliyo weerarka, waxaan go'aansanay inaan isticmaalno qaabkan UC Browser: awoodda lagu furo PDF iyadoo la adeegsanayo maktabadda waddaniga ah, taas oo aan ku jirin APK-ka oo ay ka soo dejiso internetka haddii loo baahdo. Waxaa xusid mudan in aragti ahaan, UC Browser lagu qasbi karo inuu soo dejiyo shay iyada oo aan la isticmaalin isticmaale - haddii aad bixiso jawaab si fiican loo qaabeeyey codsiga la fuliyo ka dib marka browserka la furo. Laakiin si tan loo sameeyo, waxaan u baahannahay inaan si faahfaahsan u baranno nidaamka isdhexgalka ee server-ka, markaa waxaan go'aansannay inay sahlanaan doonto in la saxo jawaabta la xannibay oo lagu beddelo maktabadda si loogu shaqeeyo PDF.

Marka, marka isticmaaluhu rabo inuu si toos ah uga furo PDF browserka, codsiyada soo socda ayaa lagu arki karaa taraafikada:

Raadinta dayacanka UC Browser

Marka hore waxa jira codsi POST ah puds.ucweb.com/upgrade/index.xhtml, markaa
Kaydka leh maktabad lagu daawado PDF iyo qaababka xafiisyada waa la soo dejiyay. Waa wax macquul ah in la qiyaaso in codsiga ugu horreeya uu gudbiyo macluumaadka ku saabsan nidaamka (ugu yaraan dhismaha si uu u bixiyo maktabadda loo baahan yahay), iyo iyada oo laga jawaabayo browserku wuxuu helayaa macluumaad ku saabsan maktabadda oo u baahan in la soo dejiyo: cinwaanka iyo, suurtogalka ah. , wax kale. Dhibaatadu waxay tahay codsigan waa la siryay.

Codso jajab

Ka jawaab jajab

Raadinta dayacanka UC Browser

Raadinta dayacanka UC Browser

Maktabadu lafteedu waxay ku xidhan tahay sibka mana aha sir.

Raadinta dayacanka UC Browser

Ka raadi koodka furista gaadiidka

Aan isku dayno inaan kala saarno jawaabta serverka. Aynu eegno xeerka fasalka com.uc.deployment.UpgradeDeployment Service: laga bilaabo habka onStartCommand u tag com.uc.geynta.bx, oo laga bilaabo ilaa 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);
}

Waxaan ku aragnaa samaynta codsiga POST halkan. Waxaan fiiro gaar ah u siineynaa abuuritaanka 16 bytes iyo buuxintiisa: 0x5F, 0, 0x1F, -50 (= 0xCE). Waxay ku beegan tahay wixii aan ku aragnay codsiga kore.

Isla fasalka waxaad ku arki kartaa fasal buul leh oo leh hab kale oo xiiso leh:

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

Habkani waxa uu qaadanayaa hab-raacyo bytes ah oo la gelinayo oo hubinaya in eberku yahay 0x60 ama byte saddexaad waa 0xD0, iyo byte labaad waa 1, 11 ama 0x1F. Waxaan eegnaa jawaabta server-ka: eber byte waa 0x60, ka labaadna waa 0x1F, kan saddexaad waa 0x60. Waxay u egtahay waxa aan u baahanahay. Iyadoo lagu xukumayo xariiqyada ("up_decrypt", tusaale ahaan), hab waa in halkan loogu yeeraa kaas oo furfuri doona jawaabta serverka.
Aan u gudubno habka gj. Ogsoonow in doodda koowaad ay tahay byte at offset 2 (ie. 0x1F kiiskeena), iyo tan labaad waa jawaabta serverka iyada oo aan
ugu horeysay 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;
}

Sida iska cad, halkan waxaan ku dooranaynaa algorithm decryption, iyo isla byte ku jira annaga
Kiis u dhigma 0x1F, waxay tilmaamaysaa mid ka mid ah saddexda ikhtiyaar ee suurtogalka ah.

Waxaan sii wadeynaa falanqaynta koodhka. Dhawr jeer oo booday ka dib waxaynu isku aragnaa hab leh magac is-sharaxaya decryptByteByKey.

Halkan waxaa laga soocay laba bytes oo kale oo ka jawaabaya, oo xadhig ayaa laga helay. Way caddahay in sidan oo kale loo xushay furaha furaha fariinta.

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

Inaga oo hore u sii eegayna, waxa aanu ogaanay in marxaladdan aynaan weli helin fure, laakiin kaliya β€œaqoonsigeeda”. Helitaanka furaha ayaa ka sii dhib badan.

Habka soo socda, laba qaybood oo dheeraad ah ayaa lagu daraa kuwa jira, taas oo ka dhigaysa afar ka mid ah: lambarka sixirka 16, aqoonsiga muhiimka ah, xogta sirta ah, iyo xadhig aan la fahmi karin (xaaladkeena, madhan).

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

Kala-guuro isdaba-joog ah ka dib waxaan gaadhnay habka staticBinarySafeDecryptNoB64 interface com.alibaba.wireless.security.open.staticdataencrypt.IStaticDataEncryptComponent. Ma jiraan wax fasallo ah oo ku jira koodka arjiga ugu weyn ee hirgeliya is-dhexgalkan. Faylka waxaa ku jira fasalkan lib/armeabi-v7a/libsgmain.so, kaas oo aan ahayn .so, laakiin .jar ah. Habka aan xiisayneyno waa sida soo socota:

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

Halkan liiskayada cabbiraadaha waxa lagu kabay laba tirooyin oo kale: 2 iyo 0. Marka lagu qiimeeyo
wax walba, 2 macnaheedu waa decryption, sida habka doFinal fasalka nidaamka Javax.crypto.Cipher. Oo waxaas oo dhan waxaa loo wareejiyaa router gaar ah oo leh nambarka 10601 - kani waa sida muuqata lambarka amarka.

Ka dib silsiladda soo socota ee kala-guurka waxaan helnaa fasal fulinaya interface-ka IRouterComponent iyo habka amar:

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

Iyo waliba fasalka JNICLibrary, kaas oo habka hooyo lagu dhawaaqay doCommandNative:

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

Tani waxay ka dhigan tahay inaan u baahanahay inaan helno hab ku jira koodka hooyo doCommandNative. Waana halka madadaalada ay ka bilaabato.

Xiritaanka koodhka mashiinka

Faylka ku jira libsgmain.so (taas oo dhab ahaantii ah .jar iyo taas oo aan ka helnay hirgelinta qaar ka mid ah is-dhexgalka sirta la xiriira ee kor ku xusan) waxaa jira hal maktabad oo hooyo ah: libsgmainso-6.4.36.so. Waxaan ku furaynaa IDA oo aan helnaa sanduuqyo wada hadal ah oo leh khaladaad. Dhibaatadu waxay tahay in miiska madaxa qaybta uu yahay mid aan shaqayn. Tan waxaa loo sameeyaa si ula kac ah si loo adkeeyo falanqaynta.

Raadinta dayacanka UC Browser

Laakiin looma baahna: in si sax ah loo shubo faylka ELF oo loo falanqeeyo, miiska madaxa barnaamijka ayaa ku filan. Sidaa darteed, waxaan si fudud u tirtirnaa miiska qaybta, anagoo eber ka saarayna meelaha u dhigma ee madaxa.

Raadinta dayacanka UC Browser

Mar labaad ku fur faylka IDA

Waxaa jira laba siyaabood oo lagu sheegi karo mashiinka farsamada Java halkaasoo sida saxda ah ee maktabadda waddaniga ah hirgelinta habka lagu sheegay koodka Java inuu yahay hooyo. Marka hore waa in la siiyo magac nooc ah Java_package_name_ClassName_QaabkaName.

Midda labaad waa in la diiwaan geliyo marka la soo shubayo maktabadda (in function JNI_Load)
iyadoo la isticmaalayo wicitaan shaqo Dhaladka diiwaangashan.

Xaaladeena, haddii aan isticmaalno habka koowaad, magacu waa inuu ahaadaa sidan. Java_com_taobao_wireless_security_adapter_JNICLibrary_doCommandNative.

Ma jiro shaqo noocaas ah oo ka mid ah shaqooyinka la dhoofiyo, taas oo macnaheedu yahay inaad u baahan tahay inaad raadiso wicitaan Dhaladka diiwaangashan.
Aan tagno shaqada JNI_Load waxaana aragnaa sawirkan:

Raadinta dayacanka UC Browser

Maxaa halkan ka socda? Jaleecada hore, bilawga iyo dhamaadka shaqadu waxay caadi u yihiin dhismaha ARM. Tilmaamaha ugu horreeya ee ku saabsan xirmooyinka ayaa kaydiya waxyaabaha ku jira diiwaannada ay shaqadu u isticmaali doonto hawlgalkeeda (kiiskan, R0, R1 iyo R2), iyo sidoo kale waxyaabaha ku jira diiwaanka LR, oo ka kooban ciwaanka soo celinta shaqada . Tilmaamaha ugu dambeeya ayaa dib u soo celinaya diiwaannada la keydiyay, cinwaanka soo celinta ayaa isla markiiba la geliyaa diiwaanka PC - sidaas darteed ka soo noqoshada shaqada. Laakin haddii aad si dhow u eegto, waxaad ogaan doontaa in tilmaanta ugu xuni ay beddesho ciwaanka soo celinta ee lagu kaydiyey xirmada. Aynu xisaabino sida ay noqon doonto ka dib
fulinta code. Cinwaan gaar ah oo 1xB0 ah ayaa lagu shubaa R130, 5 ayaa laga jarayaa, ka dib waxaa loo wareejinayaa R0 waxaana lagu daraa 0x10. Waxay soo baxday 0xB13B. Markaa, IDA waxay u malaynaysaa in tilmaanta ugu dambaysa ay tahay soo celinta shaqada caadiga ah, laakiin dhab ahaantii waxay ku socotaa cinwaanka la xisaabiyay 0xB13B.

Waxaa mudan in halkan lagu xasuusto in soo-saareyaasha ARM ay leeyihiin laba hab iyo laba hab oo tilmaamo ah: ARM iyo Suulka. Inta ugu yar ee muhiimka ah ee ciwaanka ayaa u sheega processor-ka hab-tilmaameedka la isticmaalayo. Taasi waa, ciwaanku runtii waa 0xB13A, mid ka mid ah kuwa ugu yar ee muhiimka ah ayaa tilmaamaya qaabka Suulka.

Qalab la mid ah "adapter" ayaa lagu daray bilowga hawl kasta oo maktabaddan iyo
koodhka qashinka. Si faahfaahsan uga hadli mayno iyaga - kaliya waan xasuusannahay
in bilowga dhabta ah ee ku dhawaad ​​​​dhammaan hawluhu ay wax yar ka fog yihiin.

Mar haddii koodka uusan si cad ugu boodin 0xB13A, IDA lafteedu ma aqoonsan in koodka uu yaallo goobtan. Isla sababtaas awgeed, uma aqoonsana inta badan koodka maktabadda inuu yahay kood, taasoo ka dhigaysa falanqaynta xoogaa adag. Waxaan u sheegaynaa IDA in kani yahay koodka, oo tani waa waxa dhacaya:

Raadinta dayacanka UC Browser

Jadwalku wuxuu si cad uga bilaabmaa 0xB144. Maxaa ku jira sub_494C?

Raadinta dayacanka UC Browser

Markaad shaqadan ugu wacdo diiwaanka LR, waxaan heleynaa ciwaanka miiska hore loo sheegay (0xB144). In R0 - index ee shaxdan. Taasi waa, qiimaha ayaa laga soo qaaday miiska, lagu daray LR natiijaduna waa
ciwaanka la aadayo. Aan isku dayno inaan xisaabino: 0xB144 + [0xB144 + 8* 4] = 0xB144 + 0x120 = 0xB264. Waxaan tagnaa cinwaanka la helay oo aan aragno macno ahaan dhowr tilmaamo oo faa'iido leh oo mar labaad tag 0xB140:

Raadinta dayacanka UC Browser

Hadda waxaa jiri doona kala-guurka marka la barbar dhigo index 0x20 miiska.

Marka la eego cabbirka miiska, waxaa jiri doona isbeddelo badan oo noocaas ah oo ku jira koodhka. Su'aashu waxay soo baxaysaa haddii ay suurtogal tahay in si toos ah arrintan wax looga qabto, iyada oo aan gacanta lagu xisaabin cinwaannada. Qoraalada iyo kartida lagu dhejin karo koodka IDA ayaa na caawiya:

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"

Dhig cursorka xariiqda 0xB26A, maamul qoraalka oo arag u gudubka 0xB4B0:

Raadinta dayacanka UC Browser

IDA mar kale uma aqoonsan aaggan kood ahaan. Waanu caawinay oo ku aragnaa nashqad kale halkaas:

Raadinta dayacanka UC Browser

Tilmaamaha ka dambeeya BLX uma muuqdaan kuwo macno badan samaynaya, waxay u badan tahay nooc barokac ah. Aynu eegno sub_4964:

Raadinta dayacanka UC Browser

Oo runtii, halkan dword ayaa laga qaadayaa ciwaanka ku yaal LR, oo lagu daray cinwaankan, ka dib markaa qiimaha ciwaanka ka soo baxa ayaa la qaadayaa oo la saarayaa. Sidoo kale, 4 ayaa lagu daraa LR si markaa ka dib marka laga soo laabto shaqada, isla lacagtaas la dhaafo. Taas ka dib amarka POP {R1} wuxuu ka qaadanayaa qiimaha ka soo baxa xirmada. Haddii aad eegto waxa ku yaal ciwaanka 0xB4BA + 0xEA = 0xB5A4, waxaad arki doontaa wax la mid ah miiska ciwaanka:

Raadinta dayacanka UC Browser

Si aad u dhejisid nashqadan, waxaad u baahan doontaa inaad ka hesho laba qaybood oo ka mid ah koodhka: offset-ka iyo lambarka diiwaanka oo aad rabto inaad natiijada geliso. Diiwaan kasta oo suurtagal ah, waa inaad sii diyaarisaa gabal kood ah.

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"

Waxaan dhignaa cursor bilowga qaab dhismeedka aan rabno inaan bedelno - 0xB4B2 - oo aan socodsiinno qoraalka:

Raadinta dayacanka UC Browser

Marka lagu daro qaab-dhismeedka hore loo sheegay, koodka ayaa sidoo kale ka kooban kuwan soo socda:

Raadinta dayacanka UC Browser

Sida kiiskii hore, tilmaamaha BLX ka dib waxaa jira kabid:

Raadinta dayacanka UC Browser

Waxaan ka qaadeynaa ciwaanka LR, ku dar LR oo aad halkaas. 0x72044 + 0xC = 0x72050. Qoraalka nashqadani waa mid fudud:

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"

Natiijada fulinta qoraalka:

Raadinta dayacanka UC Browser

Marka wax walba lagu dhejiyo shaqada, waxaad tilmaami kartaa IDA bilowgeeda dhabta ah. Waxay isu geyn doontaa dhammaan koodka shaqada, waxaana lagu kala diri karaa iyadoo la adeegsanayo HexRays.

Xadhkaha goynta

Waxaan baranay inaan wax ka qabanno qariban koodka mashiinka ee maktabadda libsgmainso-6.4.36.so ka UC Browser oo helay code function 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;
}

Aynu si qoto dheer u eegno sadarradan soo socda:

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

In shaqada sub_73E24 Magaca fasalka si cad ayaa loo kala saarayaa. Sida cabbiraadaha shaqadan, tilmaame xogta la mid ah xogta sir ah, kayd gaar ah iyo tiro ayaa la gudbiyaa. Sida iska cad, ka dib marka la waco shaqada, waxaa jiri doona khad la furay oo ku dhex jira baqshadda, maadaama loo gudbiyo shaqada HelClass, Kaas oo magaca fasalka u qaadanaya cabbirka labaad. Sidaa darteed, nambarku waa cabbirka kaydka ama dhererka khadka. Aan isku dayno inaan qeexno magaca fasalka, waa inay noo sheegtaa haddii aan u socono jihada saxda ah. Aynu si qoto dheer u eegno waxa ka dhaca 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;
}

function hoos_7AF78 wuxuu abuuraa tusaale weel loogu talagalay habab-biyte oo cabbirka la cayimay ah ( si faahfaahsan ugama hadli doono weelashan). Halkan waxaa lagu abuuray laba weel oo noocaas ah: mid ka mid ah ayaa ka kooban khadka "DcO/lcK+h?m3c*q@" (waa ay fududahay in la qiyaaso in tani ay fure tahay), kan kalena waxa uu ka kooban yahay xog sir ah. Marka xigta, labada shay ayaa la dhigayaa qaab dhismeed gaar ah, kaas oo loo gudbiyo shaqada sub_6115C. Aynu sidoo kale calaamadeyno goob leh qiimaha 3 ee qaabkan. Aynu aragno waxa ku dhacaya dhismahan xiga.

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

Halbeegga beddelka waa goob dhisme oo hore loogu qoondeeyay qiimaha 3. U fiirso kiiska 3: shaqada sub_6364C cabbirada waxaa laga soo gudbay qaab-dhismeedka lagu daray halkaas ee hawshii hore, i.e. furaha iyo xogta sir ah. Haddaad si fiican u eegto sub_6364C, waxaad garan kartaa algorithm-ka RC4 ee ku jira.

Waxaan leenahay algorithm iyo fure. Aan isku dayno inaan qeexno magaca fasalka. Waa kan waxa dhacay: com/taobao/wireless/security/adapter/JNICLibrary. Wayn! Waxaan wadnaa wadadii saxda ahayd.

Geedka amar

Hadda waxaan u baahanahay inaan helno caqabad Dhaladka diiwaangashan, taas oo noo tilmaami doonta shaqada doCommandNative. Aynu eegno hawlaha loo yaqaan JNI_Raxan, waana ka helaynaa 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;
}

Oo runtii, hab asal ah oo magaca leh ayaa halkan ka diiwaan gashan doCommandNative. Hadda waxaan ognahay cinwaankiisa. Aan aragno waxa uu sameeyo.

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

Magaca ahaan waxaad qiyaasi kartaa in halkan ay tahay meesha laga soo galo dhammaan hawlaha ay horumariyayaashu go'aansadeen in ay u wareejiyaan maktabadda hooyo. Waxaan xiiseyneynaa lambarka shaqada 10601.

Waxaad ka arki kartaa koodhka in lambarka amarku uu soo saaro saddex lambar: amar/10000, amar% 10000/100 ΠΈ amar% 10, tusaale ahaan, xaaladeena, 1, 6 iyo 1. Saddexdan lambar, iyo sidoo kale tilmaanta JNIEnv iyo doodaha loo gudbiyo shaqada ayaa lagu daraa qaab dhismeed oo loo gudbiyo. Iyadoo la adeegsanayo saddexda lambar ee la helay (aan tilmaamno N1, N2 iyo N3), geed amar ayaa la dhisay.

Wax sidan oo kale ah:

Raadinta dayacanka UC Browser

Geedka si firfircoon ayaa loo buuxiyey JNI_Load.
Saddex nambar ayaa calaamad u ah waddada geedka. Caleen kasta oo geedka ka mid ah waxay ka kooban tahay ciwaanka la jeexay ee shaqada u dhiganta. Furuhu wuxuu ku yaalaa qanjidhka waalidka. Helitaanka meesha koodka meesha shaqada aan u baahannahay lagu daro geedka ma aha mid adag haddii aad fahamto dhammaan qaab-dhismeedka loo isticmaalo (ma sifaynno si aan u bararsan maqaal horeba u weyn).

Qarsoodi badan

Waxa aanu helnay ciwaanka shaqada ee ah in uu kala saaro taraafikada: 0x5F1AC. Laakin waa goor hore in lagu farxo: soosaarayaasha UC Browser waxay noo diyaariyeen yaab kale.

Ka dib markii la helo xuduudaha ka soo diyaariyeen in lagu sameeyay code Java, waxaan helnaa
shaqada ciwaanka 0x4D070. Oo halkan nooc kale oo xannibaad kood ah ayaa nagu sugaya.

Waxaan dhignay laba tusmooyin R7 iyo R4:

Raadinta dayacanka UC Browser

Waxaan u beddeleynaa tusaha koowaad R11:

Raadinta dayacanka UC Browser

Si aad cinwaan uga hesho miiska, adeegso tusmo:

Raadinta dayacanka UC Browser

Ka dib marka aad tagto ciwaanka koowaad, tusaha labaad ayaa la isticmaalaa, kaas oo ku yaal R4. Shaxda waxa ku jira 230 curiye.

Maxaa laga yeelayaa? Waxaad u sheegi kartaa IDA in kani yahay beddel: Wax ka beddel -> Mid kale -> Sheeg sarbeebaha beddelka.

Raadinta dayacanka UC Browser

Koodhka ka soo baxay waa cabsi. Laakiin, samaynta jidka aad ku dhex marayso hawdkeeda, waxaad dareemi kartaa wacitaanka hawl horeba anaga naqaanay sub_6115C:

Raadinta dayacanka UC Browser

Waxaa jiray fur-furan kaas oo haddii ay dhacdo 3 uu jiro fur-furan iyadoo la adeegsanayo RC4 algorithm. Xaaladdan oo kale, qaab-dhismeedka loo gudbiyay shaqada ayaa laga buuxiyaa xuduudaha loo gudbiyay doCommandNative. Aynu xasuusanno waxa aan meesha ku haysanay magicInt oo leh qiimaha 16. Waxaan eegnaa kiis u dhigma - ka dib dhowr isbeddello waxaan helnaa koodka kaas oo algorithm lagu aqoonsan karo.

Raadinta dayacanka UC Browser

Tani waa AES!

Algorithm-ka ayaa jira, waxa soo haray oo dhan waa in la helo xuduudaheeda: qaabka, furaha iyo, suurtogalnimada, vector-ka bilawga ah (joogitaanka waxay kuxirantahay habka hawlgalka ee AES algorithm). Qaab dhismeedka iyaga wata waa in lagu sameeyaa meel ka hor inta aan la wicin shaqada sub_6115C, laakiin qaybtan ka mid ah koodka ayaa si gaar ah loo daboolay, markaa fikradda ayaa soo baxaysa in lagu dhejiyo koodka si dhammaan xuduudaha shaqada decryption loogu daadiyo fayl.

balastar

Si aanad gacanta ugu qorin dhammaan koodhka balastarrada ee luqadda kulanka, waxaad bilaabi kartaa Android Studio, waxaad ku qori kartaa shaqo halkaas oo hesha cabbiraadyo la mid ah tan shaqadayada decryption-ka oo aad ku qorto fayl, ka dib koobi-ku dheji koodka uu soo-biiriyuhu doonayo dhalin.

Saaxiibadayada kooxda UC Browser waxay sidoo kale daryeeleen ku habboonaanta koodhka. Aynu xasuusanno in bilawga shaqo kasta aanu haysano koodka qashinka kaas oo si fudud loogu beddeli karo mid kale. Aad u habboon πŸ™‚ Si kastaba ha noqotee, bilowga shaqada bartilmaameedka ma jirto meel ku filan koodka kaas oo badbaadiya dhammaan xuduudaha faylka. Waxay ahayd inaan u kala qaybiyo qaybo oo aan isticmaalo qashinka qashinka ee hawlaha deriska ah. Guud ahaan waxay ahaayeen afar qaybood.

Qeybta koowaad:

Raadinta dayacanka UC Browser

Qaab dhismeedka ARM, afarta cabbir ee ugu horreeya ee shaqada waxaa lagu dhex maraa diiwaannada R0-R3, inta soo hartay, haddii ay jiraan, waxaa la dhex maraa xirmada. Diiwaanka LR wuxuu wataa ciwaanka celinta. Waxaas oo dhan waxay u baahan yihiin in la keydiyo si ay shaqadu u shaqeyso ka dib marka aan tuurno xuduudaheeda. Waxaan sidoo kale u baahannahay inaan keydinno dhammaan diiwaannada aan u isticmaali doono howsha, markaa waxaan sameyneynaa PUSH.W {R0-R10,LR}. R7 waxaan helnaa ciwaanka liiska cabirrada loo gudbiyay shaqada iyada oo loo marayo xirmada.

Isticmaalka shaqada fur aan furno faylka /data/local/tmp/aes qaabka "ab".
yacni ku darida. R0 waxaan ku dhejineynaa cinwaanka magaca faylka, R1 - ciwaanka xariiqa tilmaamaya qaabka. Oo halkan koodka qashinka ayaa ku dhammaanaya, markaa waxaan u gudubnaa shaqada xigta. Si ay u sii shaqeyso shaqada, waxaan bilownay u gudubka xeerka dhabta ah ee shaqada, ka gudubka qashinka, iyo halkii qashinka waxaan ku darnaa sii wadida balastar.

Raadinta dayacanka UC Browser

Wicida fur.

Saddexda cabbir ee hore ee shaqada aes nooc leeyihiin INT. Tan iyo markii aan ku badbaadinay diiwaannada bilowga, waxaan si fudud u gudbin karnaa shaqada qor ciwaanadooda oo ku dul yaal.

Raadinta dayacanka UC Browser

Marka xigta waxaan haynaa saddex qaab-dhismeed oo ka kooban cabbirka xogta iyo tilmaame xogta furaha, vector-ka bilowga iyo xogta sir ah.

Raadinta dayacanka UC Browser

Dhamaadka, xir faylka, soo celi diiwaannada oo u wareeji xakamaynta shaqada dhabta ah aes.

Waxaan soo aruurineynaa APK oo wata maktabad go'an, saxiix, ku dheji qalabka/ emulator-ka, oo aan bilowno. Waxaan aragnaa in qashinkayaga la abuurayo, oo xog badan lagu qorayo. browserku ma isticmaalo sirta kaliya ee taraafikada, iyo dhammaan sirta ayaa dhex mara shaqada su'aasha ah. Laakiin sabab qaar ka mid ah xogta lagama maarmaanka ah ma jiraan, codsiga loo baahan yahayna kama muuqanayo taraafikada. Si aan loo sugin ilaa UC Browser uu ka soo baxo codsiga lagama maarmaanka ah, aynu ka soo qaadano jawaabta sirta ah ee server-ka hore loo helay oo mar labaad ku dheji codsiga: ku dar fur-furitaanka onCreate ee hawsha ugu weyn.

    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

Waanu ururinay, saxeexnay, rakibnay, bilownay Waxaan helnaa NullPointerException sababtoo ah habka ayaa noqday mid buray.

Intii lagu gudajiray falanqaynta koodka, waxaa la ogaaday hawl-qabad ka tarjumaysa xadadka xiisaha leh: "META-INF/" iyo ".RSA". Waxay u egtahay in codsigu xaqiijinayo shahaadadiisa. Ama xitaa furayaasha ka soo saara. Runtii ma rabo inaan wax ka qabto waxa ku dhacaya shahaadada, markaa waxaanu kaliya ka siibi doonaa shahaadada saxda ah. Aynu dhejinno khadka sir ah si halkii "META-INF/" aan helno "BLABLINF/", ka samee fayl magacaas ku jira APK oo ku dar shahaadada browserka dabagaalaha halkaas.

Waanu ururinay, saxeexnay, rakibnay, bilownay Bingo! Waxaan leenahay furaha!

MitM

Waxaan helnay furaha iyo vector bilowga ah oo la mid ah furaha. Aan isku dayno inaan furno jawaabta serverka qaabka CBC

Raadinta dayacanka UC Browser

Waxaan aragnaa URL-ka kaydka, wax la mid ah MD5, "saar_unzipsize" iyo lambar. Waxaan hubineynaa: MD5 ee kaydku waa isku mid, cabbirka maktabadda aan baakadnayn waa isku mid. Waxaan isku dayeynaa inaan balastar ka bixinno maktabadan oo aan siino browserka. Si aan u tusno in maktabadeena goglan ay soo shubatay, waxaan bilaabi doonaa ujeedo aan ku abuureyno SMS-ka qoraalka ah "PWNED!" Waxaan bedeli doonaa laba jawaabaha serverka: puds.ucweb.com/upgrade/index.xhtml iyo in la soo dejiyo kaydka. Marka hore waxaan ku bedelnaa MD5 (xajmiga ma beddelo ka dib marka la furo), kan labaadna waxaan ku siinnaa kaydka maktabadda dhejisan.

Browser-ku wuxuu isku dayaa inuu soo dejiyo kaydka dhowr jeer, ka dib markaa wuxuu bixiyaa qalad. Wax muuqda
ma jecla. Natiijadii falanqaynta qaabkan mugdiga ah, waxaa soo baxday in server-ku uu sidoo kale gudbiyo xajmiga kaydka:

Raadinta dayacanka UC Browser

Waxay ku qoran tahay LEB128. Ka dib balastarkii, cabbirka kaydka maktabadda leh ayaa isbeddelay wax yar, markaa browserku wuxuu tixgeliyey in kaydka si qalloocan loo soo dejiyo, isku dayo badan ka dib wuxuu tuuray qalad.

Waxaan hagaajineynaa cabbirka kaydka ... Iyo - guul! πŸ™‚ Natiijadu waxay ku jirtaa fiidiyowga.

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

Natiijooyinka iyo falcelinta horumariyaha

Si la mid ah, haakarisku waxay isticmaali karaan astaanta aan ammaan ahayn ee UC Browser si ay u qaybiyaan oo ay u maamulaan maktabadaha xaasidnimada leh. Maktabadahani waxay ku shaqayn doonaan macnaha browserka, si ay u helaan dhammaan oggolaanshaha nidaamka. Natiijo ahaan, awoodda lagu soo bandhigo daaqadaha phishing, iyo sidoo kale helitaanka faylasha shaqada ee dabagaallaha Shiinaha ee orange-ka, oo ay ku jiraan login, ereyada sirta ah iyo cookies-ka ee lagu kaydiyo xogta.

Waxaan la xiriirnay soosaarayaasha UC Browser, waxaana u sheegnay dhibaatada aan helnay, waxaan isku daynay inaan tilmaamno baylahda iyo khatarta ay leedahay, laakiin wax nagalama aysan hadlin. Dhanka kale, browserku wuxuu sii waday inuu si cad u muujiyo muuqaalkiisa khatarta ah. Laakiin mar aan shaaca ka qaadnay tafaasiisha dayacanka, ma suurta gal ahayn in la iska indho tiro sidii hore. March 27 waxay ahayd
Nooc cusub oo ah UC Browser 12.10.9.1193 ayaa la sii daayay, kaas oo ka galay server-ka HTTPS: puds.ucweb.com/upgrade/index.xhtml.

Intaa waxaa dheer, ka dib "hagaajinta" iyo ilaa wakhtiga qorista maqaalkan, isku dayga in lagu furo PDF browserka waxay keentay fariin qalad ah qoraalka "Oops, waxbaa khaldamay!" Codsiga server-ka lama samayn markii la isku dayay in la furo PDF, laakiin codsi ayaa la sameeyay markii browserka la furay, kaas oo tilmaamaya awoodda sii socota ee lagu soo dejiyo koodka la fulin karo iyada oo xadgudub ku ah xeerarka Google Play.

Source: www.habr.com

Add a comment