外的題果然考得與眾不同
[secrypt_cen.html]
這次是HTML網(wǎng)頁,然后JS加密判斷
翻看JS代碼
{width="5.75in" height="3.375in"}
很顯然,關(guān)鍵的代碼在checkPassword
JS混淆是必備的
去混淆一條龍走起
先將關(guān)鍵代碼提取出來
JavaScript
function _0x4857(_0x398c7a, _0x2b4590) { const _0x104914 =
_0x25ec(); _0x4857 = function (_0x22f014, _0x212d58) { _0x22f014 =
_0x22f014 - (0x347 + 0x46a * -0x7 + 0x1cc6); let _0x321373 =
_0x104914[_0x22f014]; return _0x321373; }; return
_0x4857(_0x398c7a, _0x2b4590); } (function (_0x414f9c, _0x3d4799)
{
//...................省略大量代碼
} function safe_add(a, b) { var c = (65535 & a) + (65535 & b); return
(a >> 16) + (b >> 16) + (c >> 16) << 16 | 65535 & c } function
bit_rol(a, b) { return a << b | a >>> 32 - b }
使用在線的javascript去混淆即可
deobfuscate.relative.im
得到去混淆后的結(jié)果
function checkPassword(_0x38d32a) {
try {
if (_0x38d32a.length !== 21) {
return false
}
if (
//......省略大量代碼
return [c, d, j, k]
}
function md5_cmn(a, b, c, d, e, f) {
return safe_add(bit_rol(safe_add(safe_add(b, a), safe_add(d, f)), e),
c)
}
function md5_ff(a, b, c, d, e, f, g) {
return md5_cmn((b & c) | (~b & d), a, b, e, f, g)
}
function md5_gg(a, b, c, d, e, f, g) {
return md5_cmn((b & d) | (c & ~d), a, b, e, f, g)
}
function md5_hh(a, b, c, d, e, f, g) {
return md5_cmn(b ^ c ^ d, a, b, e, f, g)
}
function md5_ii(a, b, c, d, e, f, g) {
return md5_cmn(c ^ (b | ~d), a, b, e, f, g)
}
function safe_add(a, b) {
var c = (65535 & a) + (65535 & b)
return (((a >> 16) + (b >> 16) + (c >> 16)) << 16) | (65535 &
c)
}
function bit_rol(a, b) {
return (a << b) | (a >>> (32 - b))
}
flag長(zhǎng)度21
發(fā)現(xiàn)了MD5加密,和兩個(gè)MD5字符串
看起來無關(guān)聯(lián)?
后來審計(jì)整個(gè)代碼發(fā)現(xiàn),對(duì)輸入的flag分部分進(jìn)行判斷比較
寫出對(duì)應(yīng)的部分,在控制臺(tái)console輸出相關(guān)信息是一個(gè)不錯(cuò)的選擇
function checkPassword(_0x38d32a) {
try {
// Password length is 21.
if (_0x38d32a.length !== 21) {
return false;
}
if (
_0x38d32a.slice(1, 2) !==
(String.fromCodePoint + "")[
parseInt((parseInt + "").charCodeAt(3), 16) - 147
] /* password[1] = 'o' */ ||
_0x38d32a[(parseInt(41, 6) >> 2) - 2] !==
String.fromCodePoint(123) /* password[4] = '{' */ ||
_0x38d32a[4].charCodeAt(0) !==
_0x38d32a[7].charCodeAt(0) + 72 /* password[7] = '3'. */ ||
JSON.stringify(
Array.from(
_0x38d32a.slice(5, 7).split("").reverse().join(),
(_0x2d4d73) => _0x2d4d73.codePointAt(0)
).map((_0x5b85c5) => _0x5b85c5 + 213)
) !==
JSON.stringify([
285, 257, 297,
]) /* password[5] = 'T', password[6] = 'H' password[7] =
'3'*/
) {
return false;
}
/* For password[8], password[9], password[10], password[11]
*/
let _0x3c7a5c = _0x38d32a.slice(8, 12).split("").reverse();
try {
for (let _0x396662 = 0; _0x396662 < 5; _0x396662++) {
_0x3c7a5c[_0x396662] =
_0x3c7a5c[_0x396662].charCodeAt(0) + _0x396662 +
getAdder(_0x396662);
}
} catch (_0x1fbd51) {
_0x3c7a5c = _0x3c7a5c.map(
(_0x24cda7) => (_0x24cda7 += _0x1fbd51.constructor.name.length -
4)
);
}
if (
MD5(String.fromCodePoint(..._0x3c7a5c)) !==
"098f6bcd4621d373cade4e832627b4f6" /* password[8] = '0',
password[9] = 'R', password[10] = '3', password[11] = 'M'
*/
) {
return false;
}
if (
MD5(_0x38d32a.charCodeAt(12) + "") !==
"812b4ba287f5ee0bc9d43bbf5bbe87fb" /* password[12] = '_' */
) {
return false;
}
_0x3c7a5c = (_0x38d32a[8] + _0x38d32a[11]).split("");
_0x3c7a5c.push(_0x3c7a5c.shift());
if (
_0x38d32a.substring(14, 16) !==
String.fromCodePoint(
..._0x3c7a5c.map((_0x5b5ec8) =>
Number.isNaN(+_0x5b5ec8) ? _0x5b5ec8.charCodeAt(0) + 5 : 48
)
) /* password[14] = 'R' password[15] = '0' */ ||
_0x38d32a[_0x38d32a[7] - _0x38d32a[10]] !==
atob("dQ==") /* password[0] = 'u' */ ||
_0x38d32a.indexOf(String.fromCharCode(117)) !==
_0x38d32a[7] - _0x38d32a[17] /* password[17] = '3' */ ||
JSON.stringify(
_0x38d32a
.slice(2, 4)
.split("")
.map(
(_0x7bf0a6) =>
_0x7bf0a6.charCodeAt(0) ^
getAdder.name[_0x38d32a[7]].charCodeAt(0)
)
) !==
JSON.stringify(
[72, 90].map(
(_0x40ab0d) =>
_0x40ab0d ^
String.fromCodePoint.name[_0x38d32a[17] - 1].charCodeAt(0)
)
) /* password[2] = 'f', password[3] = 't' */
) {
return false;
}
if (
String.fromCodePoint(
..._0x38d32a
.split("")
.filter(
(_0x5edfac, _0x2965d2) => _0x2965d2 > 15 && _0x2965d2 % 2 == 0
)
.map(
(_0x2ffa6d) =>
_0x2ffa6d.charCodeAt(0) ^ (_0x38d32a.length + _0x38d32a[7])
)
) !==
atob(
"g5Go"
) /* password[16] = 'V', password[18] = 'D', password[20] =
'}' */
) {
return false;
}
if (
_0x38d32a[_0x38d32a.length - 2] !==
String.fromCharCode(Math.floor((({} + "").charCodeAt(0) + 9) / 3))
||
_0x38d32a[1 + _0x38d32a[7]] !== giggity()[5] /* password[19]
= ! */
) {
return false;
}
return true;
} catch (_0x4d4983) {
return false;
}
}
function getAdder(_0x430c9d) {
switch (_0x430c9d) {
case 0:
return 34;
case 1:
return 44;
case 2:
return 26;
case 3:
return 60;
}
return 101;
}
function giggity() {
return giggity.caller.name;
}
得到flag
uoft{TH30R3M_PR0V3D!}
使用某插件的過程中,大量個(gè)性化需求不能滿足,于是我有了更改源碼的沖動(dòng)。翻遍所有角落,只找了一份壓縮混淆的 js 文件。
一、場(chǎng)景復(fù)現(xiàn)
先來說說幾種我們迫切需要知道源碼的情況:
1.閱讀源碼,當(dāng)然,大部分開源的代碼都是可以直接查看的;
2.對(duì)某插件做個(gè)性化的需求更改,這時(shí)候你渴望看到未混淆壓縮的代碼;
3.為了增加代碼分析的難度,混淆(obfuscate)工具被應(yīng)用到了許多惡意軟件(如 0day 掛馬、跨站攻擊等)當(dāng)中。
分析人員為了掀開惡意軟件的面紗,首先就得對(duì)腳本進(jìn)行反混淆(deobfuscate)處理。
4.當(dāng)你準(zhǔn)備抄襲別人代碼時(shí),這個(gè)稍微有點(diǎn)不可描述;
二、尋求方案
為了快速的解決問題,我們首先嘗試一下現(xiàn)有方案:
http://jsnice.org/
一個(gè)簡(jiǎn)單的示例:
解析后:
是不是反混淆之后,可讀性強(qiáng)了很多。
2.js 代碼混淆站長(zhǎng)工具
我們先從 Lodash 找一段演示代碼,如下:
普通混淆后,就變成了這樣:
為了測(cè)試一下如何反混淆,我們將混淆后代碼拷貝到 jsnice :
好的,我們加大力度,采用加密壓縮方式。這次代碼明顯多了,而 jsnice 也反混淆失敗了:
這段代碼,地球人已經(jīng)沒法讀懂了,亂七八糟的。那么,問題來了,加密混淆的代碼真的沒有辦法復(fù)原嗎?
三、思維突破
從上面的演示可以看出來,加密之后的混淆,已經(jīng)完全無法反混淆了。
除非我們知道混淆算法,可是混淆方式不計(jì)其數(shù),你需要知曉它的混淆方式,并制定出反混淆算法,那估計(jì)會(huì)累死。
眾所周知,JavaScript 是解釋性語言,它嚴(yán)重依賴游覽器。不管 JavaScript 如何混淆,最終瀏覽器都會(huì)知道最真實(shí)的代碼。所以,我們還得以瀏覽器為突破口。
首先,同步一下原始代碼:
其次,確定源碼中是否包含在 eval 中,參考代碼如下:
然后,查找關(guān)鍵字 throw,如果有,那就成功了一大步;
最后,改動(dòng)源碼,讓源碼拋出異常,讓 Eval Code 還原出真實(shí)代碼;
四、相關(guān)工具介紹
我們先來看一下,目前常用的混淆工具:
反混淆工具:
了解更多,請(qǐng)參考:幾種常見的JavaScript混淆和反混淆工具分析實(shí)戰(zhàn)
五、了解混淆手段
1.base62 編碼,其最明顯的特征是生成的代碼以 eval(function(p,a,c,k,e,r)) 開頭;
這類混淆的關(guān)鍵思想在于將需要執(zhí)行的代碼進(jìn)行一次編碼,在執(zhí)行的時(shí)候還原出瀏覽器可執(zhí)行的合法的腳本,然后執(zhí)行之。
看上去和可執(zhí)行文件的加殼有那么點(diǎn)類似。Javascript 提供了將字符串當(dāng)做代碼執(zhí)行(evaluate)的能力,可以通過 Function 構(gòu)造器、eval、setTimeout、setInterval 將字符串傳遞給 js 引擎進(jìn)行解析執(zhí)行。
無論代碼如何進(jìn)行變形,其最終都要調(diào)用一次 eval 等函數(shù)。
解密的方法不需要對(duì)其算法做任何分析,只需要簡(jiǎn)單地找到這個(gè)最終的調(diào)用,改為 console.log 或者其他方式,將程序解碼后的結(jié)果按照字符串輸出即可。
2.隱寫術(shù)
嚴(yán)格說這不能稱之為混淆,只是將 js 代碼隱藏到了特定的介質(zhì)當(dāng)中。
如通過最低有效位(LSB)算法嵌入到圖片的 RGB 通道、隱藏在圖片 EXIF 元數(shù)據(jù)、隱藏在 HTML 空白字符等。
比如這個(gè)聳人聽聞的議題:《一張圖片黑掉你》在圖片中嵌入惡意程序,正是使用了最低有效位平面算法。結(jié)合 HTML5 的 canvas 或者處理二進(jìn)制數(shù)據(jù)的 TypeArray,腳本可以抽取出載體中隱藏的數(shù)據(jù)(如代碼)。
隱寫的方式同樣需要解碼程序和動(dòng)態(tài)執(zhí)行,所以破解的方式和前者相同,在瀏覽器上下文中劫持替換關(guān)鍵函數(shù)調(diào)用的行為,改為文本輸出即可得到載體中隱藏的代碼。
3.復(fù)雜表達(dá)式
代碼混淆不一定會(huì)調(diào)用 eval,也可以通過在代碼中填充無效的指令來增加代碼復(fù)雜度,極大地降低可讀性。
Javascript 中存在許多稱得上喪心病狂的特性,這些特性組合起來,可以把原本簡(jiǎn)單的字面量(Literal)、成員訪問(MemberExpression)、函數(shù)調(diào)用(CallExpression)等代碼片段變得難以閱讀。
在 js 中可以找到許多這樣互逆的運(yùn)算,通過使用隨機(jī)生成的方式將其組合使用,可以把簡(jiǎn)單的表達(dá)式無限復(fù)雜化。
深入了解,請(qǐng)移步使用 estools 輔助反混淆 Javascript。
六、寫在最后
JavaScript 作為一個(gè)以函數(shù)式為核心的多范式動(dòng)態(tài)弱類型腳本語言,因?yàn)樗撵`活性,導(dǎo)致了源代碼在經(jīng)過一些壓縮工具處理后,變得極難還原。
也有可能,當(dāng)我們費(fèi)勁心思還原出來的代碼,也許只是與源代碼運(yùn)行流程一致的另一套代碼。當(dāng)然,我們可以繼續(xù)探索,發(fā)掘未知的領(lǐng)域。
七、熱門原創(chuàng)文章
1.戲說 API 和 SDK
2.JS 基礎(chǔ)|搞懂 typeof 和 instanceof
3.大公司面試前端,為什么喜歡問 BFC?
混淆是軟件開發(fā)中常用的技術(shù),用于使代碼更難理解、分析和逆向工程。它將代碼轉(zhuǎn)化為一種復(fù)雜而紛繁的形式,同時(shí)保留其功能。混淆的主要目標(biāo)是阻礙對(duì)代碼的未經(jīng)授權(quán)訪問,保護(hù)軟件的知識(shí)產(chǎn)權(quán)或者隱藏軟件的真實(shí)行為。
在Android APK中,常用多種混淆技術(shù)來保護(hù)代碼,使其更難理解或逆向工程。其中一種技術(shù)是代碼混淆,它將源代碼轉(zhuǎn)換為等效但更復(fù)雜的形式,使其難以解讀和分析。另一種常用的技術(shù)是字符串加密,在這種技術(shù)中,敏感字符串(如API密鑰或URL)被加密,以防止輕易提取。此外,還采用控制流混淆來干擾代碼的邏輯流程,使其難以跟蹤程序的執(zhí)行路徑和理解其功能。
混淆技術(shù)的使用增加了安全研究分析的難度,并使一些基于簽名的檢測(cè)方法失效。字符串加密使得追蹤關(guān)鍵信息變得具有挑戰(zhàn)性。這些措施使得惡意軟件更難以識(shí)別和追蹤。
出于這些原因,我們的公司——Liansecurity開發(fā)了一款名為"Incinerator"的產(chǎn)品,旨在提供高效、準(zhǔn)確和自動(dòng)化的逆向工程服務(wù)。通過對(duì)惡意軟件的廣泛分析和先前混淆檢測(cè)技術(shù)的研究,在我們的Android APK逆向工程產(chǎn)品“焚化爐"中實(shí)現(xiàn)了一種基于文本分類的混淆檢測(cè)方法。根據(jù)我們的測(cè)試,我們的方法實(shí)現(xiàn)了98%的準(zhǔn)確率,這超出了我們的期望。在接下來的章節(jié)中,我們將詳細(xì)描述我們的方法。
在檢測(cè)Android應(yīng)用程序中的混淆技術(shù)方面,最先進(jìn)的系統(tǒng)是"AndrODet"。在這項(xiàng)工作中,作者構(gòu)建了一個(gè)混淆檢測(cè)系統(tǒng),針對(duì)每種混淆類型提取不同的特征,然后訓(xùn)練一個(gè)在線機(jī)器學(xué)習(xí)模型。下面列出了目標(biāo)混淆類型和AndrODet實(shí)現(xiàn)后的測(cè)試結(jié)果:
在Android的背景下,AndrODet面臨某些限制,影響其作為靜態(tài)代碼分析工具的準(zhǔn)確性和有效性。主要集中在兩個(gè)方面:
AndrODet計(jì)算其度量指標(biāo)是基于整個(gè)APK,包括核心業(yè)務(wù)代碼和關(guān)聯(lián)的庫(kù)文件。在Android生態(tài)系統(tǒng)中,依賴庫(kù)可能會(huì)非常龐大,有時(shí)甚至比核心業(yè)務(wù)代碼本身還要大。而且大多數(shù)情況下,依賴庫(kù)并不需要進(jìn)行混淆。當(dāng)僅依靠整個(gè)APK進(jìn)行計(jì)算時(shí),這些大型未混淆的庫(kù)的存在削弱了混淆部分的重要性,最終影響了AndrODet進(jìn)行正確判斷的準(zhǔn)確性。
AndrODet計(jì)算距離的方法局限于ASCII編碼。然而,使用Unicode編碼進(jìn)行混淆技術(shù)的使用越來越普遍。因此,AndrODet無法處理和分析使用Unicode編碼進(jìn)行混淆的代碼。這個(gè)限制阻礙了該工具在真實(shí)生產(chǎn)場(chǎng)景中準(zhǔn)確檢測(cè)和評(píng)估混淆代碼的安全性和質(zhì)量方面的能力。
AndrODet的限制對(duì)其在真實(shí)生產(chǎn)場(chǎng)景中的準(zhǔn)確性構(gòu)成了挑戰(zhàn)。了解這些限制及其對(duì)真實(shí)生產(chǎn)環(huán)境的影響對(duì)于尋求改進(jìn)Android應(yīng)用程序安全領(lǐng)域代碼分析工具能力的研究人員和從業(yè)者至關(guān)重要。
我們的方法主要解決了代碼混淆技術(shù)中最常見的標(biāo)識(shí)符重命名的識(shí)別問題,這是惡意軟件常用的混淆技術(shù)。我們的方法也可以擴(kuò)展到字符串加密。在我們的研究中,我們觀察到,當(dāng)研究人員評(píng)估一個(gè)代碼片段是否被混淆時(shí),他們最初的判斷依賴于類名、方法名和變量名的可理解性,以及可識(shí)別和常用的編碼約定,即所謂的“編碼英語”,與類似'a'、'Zb'、'c4'、'1li'、'0Oo'等不容易理解的名稱進(jìn)行對(duì)比。最初,我們嘗試了算法方法來解決這個(gè)問題,但測(cè)試結(jié)果不怎么理想。然而,我們突然想到,這實(shí)際上是一個(gè)經(jīng)典的自然語言(NLP)分類問題。
憑借這一靈感,我們將混淆檢測(cè)問題轉(zhuǎn)化為文本分類問題,而深度神經(jīng)網(wǎng)絡(luò)處理文本分類,已經(jīng)非常成熟。我們的測(cè)試結(jié)果也證明了這種轉(zhuǎn)換非常成功。“字符串加密”本質(zhì)上也是一個(gè)文本分類問題,因此我們相信這種方法可以輕松擴(kuò)展到字符串加密。
第1步涉及反編譯AndroidAPK和提取Smali代碼。在我們的實(shí)現(xiàn)中,我們使用我們自己的反編譯引擎"Reactor”。其他開源工具,如AndroGuard或Apktools也可以。從每個(gè)類中,我們提取類名和類變量名,這些是下一步分析的輸入。理論上可以提取更多特征,如函數(shù)參數(shù)名稱和局部變量,但提取更多的特征對(duì)準(zhǔn)確率沒有太大的提升,因?yàn)榍懊娴娜齻€(gè)特征已經(jīng)達(dá)到了很高的準(zhǔn)確性。
創(chuàng)建兩個(gè)不同的訓(xùn)練集。第1個(gè)訓(xùn)練集是混淆的類生成的數(shù)據(jù),標(biāo)記為1。第2個(gè)訓(xùn)練集是未混淆的類生成的數(shù)據(jù),標(biāo)記為0。
我們構(gòu)建了一個(gè)文本分類神經(jīng)網(wǎng)絡(luò)。該神經(jīng)網(wǎng)絡(luò)使用步驟1中提取的特征和步驟2中的相應(yīng)標(biāo)簽進(jìn)行訓(xùn)練。通過利用深度學(xué)習(xí)網(wǎng)絡(luò)模型進(jìn)行訓(xùn)練。
該模型分成3層:嵌入層、LSTM層和密集層。
1)嵌入層:嵌入層將輸入整數(shù)序列轉(zhuǎn)換為密集矢量表示。
2)LSTM層:LSTM(長(zhǎng)短期記憶)層是一種能夠處理序列數(shù)據(jù)和捕獲長(zhǎng)期依賴關(guān)系的循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)。在該模型中,使用了具有128個(gè)單元的LSTM層。
3)Dense層:Dense層是一個(gè)全連接層,對(duì)LSTM層的輸出進(jìn)行線性變換并應(yīng)用sigmoid激活函數(shù)。
我們從1000個(gè)數(shù)據(jù)樣本開始,發(fā)現(xiàn)結(jié)果已經(jīng)非常不錯(cuò)。隨著我們將樣本量增加到10000,準(zhǔn)確率和驗(yàn)證準(zhǔn)確率都變得非常令人滿意。最終,我們的模型使用100000個(gè)數(shù)據(jù)樣本進(jìn)行了訓(xùn)練。我們?cè)噲D進(jìn)一步擴(kuò)充數(shù)據(jù)集,但準(zhǔn)確率和驗(yàn)證準(zhǔn)確率沒有提高。為了避免由單個(gè)APK生成的數(shù)據(jù)引起的偏差,我們從數(shù)據(jù)庫(kù)中隨機(jī)提取了幾百個(gè)APK來生成我們的數(shù)據(jù)。從生成的數(shù)百萬個(gè)數(shù)據(jù)樣本中,我們隨機(jī)選擇了100000個(gè)進(jìn)行訓(xùn)練。
訓(xùn)練結(jié)果如下:
訓(xùn)練準(zhǔn)確率:99.75%
驗(yàn)證準(zhǔn)確率:98.50%
在實(shí)際應(yīng)用中,為了確定一個(gè)APK是否被混淆,我們使用了一種方法,該方法涉及檢查APK內(nèi)的每個(gè)類是否進(jìn)行混淆。通過將混淆類的數(shù)量除以類的總數(shù),我們可以計(jì)算APK中混淆代碼的比例。盡管在理論,針對(duì)每個(gè)類,判斷可能出現(xiàn)假陽或者假陰,但是在判斷一個(gè)APK是否存在現(xiàn)象時(shí),很難出錯(cuò),因?yàn)橐粋€(gè)被混淆的APK,需要確保它的大部分代碼很難理解,這正是混淆的目的和最終呈現(xiàn),大部分難以理解的類,是不能逃過模型的檢測(cè)的。因此,我們的模型在確定APK中是否存在混淆時(shí)達(dá)到了接近100%的準(zhǔn)確率。
第一輪訓(xùn)練后,我們從Fdroid和Abuse各獲取了1000個(gè)APK,進(jìn)行驗(yàn)證測(cè)試。FDroid代表良性apk, abuse代表惡意 apks,測(cè)試后,我們發(fā)現(xiàn)有較高概率出現(xiàn)假陽,一些非常短的內(nèi)部類,例如”Class: MainActivity ExternalSyntheticLambda15; Method: <init> run Field: f>第一輪訓(xùn)練后,我們從Fdroid和Abuse各獲取了1000個(gè)APK,進(jìn)行驗(yàn)證測(cè)試。FDroid代表良性apk, abuse代表惡意 apks,測(cè)試后,我們發(fā)現(xiàn)有較高概率出現(xiàn)假陽,一些非常短的內(nèi)部類,例如”Class: MainActivity ExternalSyntheticLambda15; Method: <init> run Field: f$0 f$1 f$2 “ 這樣的情況,模型無法判斷是否是混淆。為了解決這個(gè)問題,我們從假陽的apk中,抽取了3000條數(shù)據(jù)樣本,加入訓(xùn)練集合。重新訓(xùn)練,再次訓(xùn)練后,極大的降低了假陽。< f f “ 這樣的情況,模型無法判斷是否是混淆。為了解決這個(gè)問題,我們從假陽的apk中,抽取了3000條數(shù)據(jù)樣本,加入訓(xùn)練集合。重新訓(xùn)練,再次訓(xùn)練后,極大的降低了假陽。
下面是我們抽取隨機(jī)的100個(gè)測(cè)試樣本,因?yàn)槲覀兊哪P托r?yàn)準(zhǔn)確率是98.5%,所以測(cè)試結(jié)果中,混淆覆蓋率1%,2%這樣的情況,應(yīng)該判斷為沒有混淆。剩下結(jié)果中的4%(md5:8328cd96c931d06d25f67d42a50fd20d)這個(gè)是誤報(bào),分析原因是因?yàn)檫@個(gè)apk的類非常少,三條假陽數(shù)據(jù)導(dǎo)致了這個(gè)錯(cuò)誤。其他的5%(923df6854199e999fdd274729b28a1ad),7%(71e293f29e636112e0a00ebac8cf3eb8)都是真實(shí)存在的混淆。所以這個(gè)模型,判斷混淆的準(zhǔn)確率接近100%,而且APK中存在非常少量的混淆也是可以檢測(cè)出來。
我們的訓(xùn)練集中并沒有出現(xiàn) unicode的混淆樣本,但是在測(cè)試的時(shí)候,這種情況也會(huì)被識(shí)別為混淆,因?yàn)槟P蛯?duì)非混淆的文本有非常好的識(shí)別,所以即便出現(xiàn)樣本中沒有出現(xiàn)的其他混淆情況,也可以識(shí)別。
APK | APK Md5 | Obfuscation Coverage |
et.nWifiManager.apk | 11c43f6d781457352e5e61e725998ea8 | 0% |
jackpal.androidterm.apk | 8bbc3d9173e6d6b19e561a8651e83731 | 0% |
com.boombuler.widgets.contacts.apk | 8328cd96c931d06d25f67d42a50fd20d | 4% |
cz.jirkovsky.lukas.chmupocasi.apk | 86f763c8cf4530e1c46c75d26374855a | 99% |
com.example.poleidoscope.apk | 08cf9be157669f3e0f7dd88975fdc22c | 1% |
dufmvh.frdnoj.oggtsh.apk | cf2f9963933457dcdd1f28fec054cd07 | 56% |
ua.com.radiokot.lnaddr2invoice.apk | c1ade85027c6178e43daac2e957ba9b1 | 96% |
org.openbmap.unifiedNlp.apk | 79ce98b9d38490625ad15f5948afe32f | 0% |
com.dekics.chat.message.apk | dc84f225fdb1c21071ee70d43af39224 | 50% |
org.getdisconnected.libreipsum.apk | a394d3131303bd24bdcddc7e0a507f0d | 1% |
com.pnr.engproverbsandsayings.apk | 1d28e138a9ecf1c9b3240868879bbd54 | 10% |
org.ligi.blexplorer.apk | 49619da57858ffdd6bd55bb5b962efe3 | 1% |
net.osmand.srtmPlugin.paid.apk | c7dd9b418933ceea723527487bd94268 | 1% |
org.broeuschmeul.android.gps.bluetooth.provider.apk | cf1d9aa2d5eec5a8e0af76d9708a8da0 | 0% |
com.intense.pub1.sbgs.apk | e272df5c9abd7d4c03982bb506922428 | 15% |
tgr.kitach.messenger.apk | cd4acd78cf29adf56837e944c0ea3791 | 50% |
com.github.lamarios.clipious.apk | 0e728b50b101456d74329f97552ea2db | 94% |
com.ctbcad.cnove01.apk | 782216c3d9db96da2ef0285daddbdcdb | 0% |
in.ac.iitb.cse.cartsbusboarding.apk | ee83d9a3c3fcffbd833f1b73d28d28cd | 2% |
de.reimardoeffinger.quickdic.apk | 8e5e7cc0e581fac6c5d83802dadc0095 | 98% |
com.fastcleaner.forphoneandroid.freenoads.apk | c31ca58e67d55bb20a06e0f986cf04c1 | 92% |
com.gh4a.apk | 22556b8c3b0f4196b0db777d64cac5ee | 1% |
nznm.qfvxs.apk | a827ee829d6067eda9c19f1dee15b9af | 1% |
com.freezingwind.animereleasenotifier.apk | c0786ccbcfe7cb57f82f36a66040d452 | 1% |
ogjp.otmyswhz.apk | ef3c97b748088019dc986dce53ae0755 | 1% |
com.scare.obscure.apk | b11e72c94d810958df65d8716d853bc3 | 46% |
org.smc.inputmethod.indic.apk | c9eeb111666c723e3a4f78e2e11ab10d | 1% |
com.blame.annual.apk | 376fc34c1eb64a348311156b1f22763e | 45% |
org.xapek.andiodine.apk | 923df6854199e999fdd274729b28a1ad | 5% |
ir.PluTus.pluto.apk | dc9f73c8ec88a8b493a15a3cbcb36f15 | 33% |
org.sufficientlysecure.viewer.apk | dcb35395a9a3fa0aea0bd9c876c4fadc | 1% |
ir.shz.shzkisi.apk | 7ec247424733c287c3322fc49f1a7766 | 33% |
com.mimic.left.apk | 4076db4387eb8ddf8f2010e3db8c8b07 | 59% |
com.igllc.reign.apk | bb78d33aac9b1c0c741b9e66d1ad9710 | 96% |
org.tuxpaint.apk | 5f1d4d542004efd946a40a26166aed00 | 1% |
Adliran.ir.apk | 3c0cccf2790ba49a122d0235225dbceb | 26% |
com.believe.blouse.apk | 768ec2246d2c92330ba8fafe6513963e | 5% |
Rahbar.Api.apk | 2f1570b5b5723d3f4ddd615905e8c08f | 27% |
net.everythingandroid.smspopup.apk | 1e5d955dabdd0ee548054c8cdc223653 | 1% |
com.cointrend.apk | cb3726beeb870d96e2dd458da66af96b | 97% |
com.junjunguo.pocketmaps.apk | 0be11a3a032b35e2ce8021d32780cf32 | 21% |
com.kabood.koroshkabir.apk | 6129cc4392d2e10ffdb80db67ca2534b | 24% |
site.leos.setter.apk | 2f03d669939c74b508a3959838fbba4c | 94% |
jp.co.qsdn.android.jinbei3d.apk | f25da1334e4db5d6c14c2361ba4defa8 | 1% |
ir.game.co.apk | 9849247aef1aa1ae82c4dc06a638f29d | 1% |
fr.xgouchet.texteditor.apk | a3f79b347a1c06140697326acb04581a | 1% |
org.smssecure.smssecure.apk | a6dcb00ee7482256f8070b2d2eb23f62 | 2% |
com.ebaschiera.triplecamel.apk | d36cd1850f8dfec7298c08e8eed3f997 | 1% |
org.y20k.trackbook.apk | d4054bf60b2fbcfc152b32397cb861b0 | 97% |
com.comfort.digital.apk | a32c36009a37893be90e4f385b26b5ee | 35% |
com.kylecorry.trail_sense.apk | 42501430e5b199df00f0068b3bd59db4 | 92% |
com.helphomestickers.heartcarejingchat.apk | fec9d39eb80814e1eec29e52e0fede2d | 50% |
de.markusfisch.android.pielauncher.apk | d0cf7f183b84ff040f237da0d7e89c58 | 90% |
org.xcsoar.apk | 35923a4197bcd2efd8d22a167af3f028 | 1% |
com.takela.message.apk | 55774d1c8251ee3c12ce08af65000bd7 | 16% |
tech.bogomolov.incomingsmsgateway.apk | 85d0288b9b04c7d71bfd8185a916490b | 1% |
com.rmowa.wpamz.apk | 23e49cc28a5feeed4b9e362aa43e158a | 65% |
piste.security.path.vf.apk | 95d33595783ede50bd428a18823ca0a9 | 20% |
de.rwth_aachen.phyphox.apk | 0a3fa3b09980e629c6a983a2c33d0400 | 1% |
com.brief.blouse.apk | be9d61e3363c3399b55a44895fd1cf60 | 47% |
xjl.lrl.jzk.xkbnif.apk | f140ec3c051717491aac1a477c0f453a | 44% |
net.goroid.maya.apk | 9b1de8718bb348e74ecde66dfa7332a8 | 19% |
eu.polarclock.apk | c3c6f8ba040f1715d32ac7563d7d9b0c | 33% |
tube.chikichiki.sako.apk | d79144a6e4aad73e78bc25af25e8f8d1 | 1% |
org.dyndns.fules.ck.apk | 7c1e243288ff30b602976d2ce634b0f3 | 0% |
com.nima.demomusix.apk | 93a79a8f1b2ad1eb2b670782e571107d | 1% |
aps.js.piste.asd.apk | b1e0ad60b4113ecfdf74e930848dcab4 | 21% |
com.tutpro.baresip.apk | 702d0800421413f73f0f3d65a577986e | 1% |
iroj.jnafjk.apk | d0118fe80f1af4cf2fad4579fa7f8741 | 1% |
de.monocles.mail.apk | 21ce417bd40a12c2333ab505a0095891 | 1% |
com.example.myapplication.apk | 52a5b10ae074459fbbeb1a0e8c297eac | 1% |
com.piolang.transltor.voice.apk | c4c0982149feaf5266d6b2a9c4634858 | 84% |
net.sourceforge.kid3.apk | 7bff47951d893d50b7bf1bb151225006 | 1% |
com.burtonben.goodlauncher.apk | d7ffbdf8e491f0c3e53901cf830f10b2 | 9% |
com.howwatchfunsms.locktextmessage.apk | d59b366ab1870d17f9abdd4824461327 | 0% |
free.vpn.unblock.proxy.turbovpn.apk | 1fd53adfc1ff5f6262567592dfc88fd4 | 70% |
com.yshlhh.com.apk | f0c84c3ffcc77a88ce344e7f632afb2d | 67% |
com.feis.bphealthy.blood.apk | 6e05b674fb8725a4f1faae9d39be1b94 | 14% |
org.servalproject.apk | 8b2df68517574eb0c7d1b42858403695 | 1% |
plus.H59300BC9.apk | 889e1c52bdebe6e1ae952bcc38b5daf1 | 11% |
mon.suxzgi.apk | b48f43a3c6b7c4ef07b7f87b62f64d61 | 1% |
com.seleuco.easshs.apk | 013a0f9ddc9db42f06ae2cd1b6228c8f | 31% |
com.vicman.toonmeapp.apk | f724e92bdf978fb3bbdac308d4ba800c | 73% |
com.hugo.apk | 6320c822ba4ce417ffb82746dbf6f6f8 | 27% |
org.segin.bfinterpreter.apk | 69d3cd2ef0e619193f145c89b22ce920 | 1% |
de.jonasbernard.tudarmstadtmoodlewrapper.apk | 29bf40b35ce52d6e44c61304fdd8561a | 1% |
com.belt.space.apk | 71e293f29e636112e0a00ebac8cf3eb8 | 7% |
center.bestlinks.samuraivpn.apk | f6e5f704bf5910b4d0aff44df2a77a8b | 91% |
com.dev.xavier.tempusromanum.apk | 1d51ef04566cc66661358f7708c0a9d3 | 1% |
com.zanghh.pdfreader.apk | e9133a533614dafee5780d50b29484c3 | 91% |
org.avmedia.gshockGoogleSync.apk | f942cf3de1107400be084ddd596016d9 | 1% |
com.github.igrmk.smsq.apk | 72dfae851b1c93838094fe3b059ac5b1 | 1% |
com.ljechbei.apk | 87118a9b63adebe8ad642509ff76818b | 16% |
org.courville.nova.apk | 7041af61162329c4e2022d82939a2d2d | 1% |
com.cliambrown.easynoise.apk | 8755ffdd6fe155593af77536bc8d1da1 | 1% |
net.mullvad.mullvadvpn.apk | 956659e2df6362a79e110fac0fda3534 | 65% |
nl.eduvpn.app.apk | aa2099699b3c8b68aa33925899ad9e84 | 96% |
com.cheogram.android.apk | 4987ea46c3679a191434c1546231bade | 1% |
io.pslab.apk | 37f9a2a3e4c906bf2cc3c14895620b1e | 1% |
ru.yanus171.feedexfork.apk | 742aebc4c88564678e78276dbf29e935 | 1% |
本文討論的都是針對(duì)標(biāo)識(shí)符重命名的混淆檢測(cè),相同的辦法可以應(yīng)用到字符串檢測(cè)上。但是不能應(yīng)用到控制流混淆檢測(cè)。AndrODet的結(jié)果在這方面的表現(xiàn)也不盡如人意。未來我們會(huì)針對(duì)控制流檢測(cè)專門設(shè)計(jì)新的模型。
與AndrODet相比,我們的模型需要相對(duì)更多的時(shí)間來確定APK是否被混淆,因?yàn)樗枰獑为?dú)檢測(cè)每個(gè)類。雖然可以批量檢測(cè),但APK可能包含數(shù)千甚至數(shù)萬個(gè)類。然而,在生產(chǎn)環(huán)境中,這是可以接受的,因?yàn)榉治鯝PK涉及靜態(tài)分析、動(dòng)態(tài)分析等各個(gè)方面,需要更長(zhǎng)的時(shí)間來執(zhí)行。因此,在我們的產(chǎn)品中,混淆檢測(cè)的等待時(shí)間是合理的。此外,這個(gè)時(shí)間也可以通過并行架構(gòu)處理來緩解。
我們提出了一種基于文本分類的方法來檢測(cè)APK是否被混淆。這種方法以前在現(xiàn)有研究中沒有應(yīng)用過,可以擴(kuò)展到其他軟件中的混淆檢測(cè)以及字符串加密檢測(cè)。此外,我們建議APK中混淆的檢測(cè)應(yīng)該在類級(jí)別進(jìn)行,因?yàn)檫@樣可以達(dá)到基本100%的準(zhǔn)確率。
我們已經(jīng)在正式生產(chǎn)環(huán)境中實(shí)現(xiàn)了這種方法。
from https://www.freebuf.com/articles/mobile/370247.html
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。