整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

[总结]HTML+JS逆向混淆混合

外的题果然考得与众不同

[secrypt_cen.html]

这次是HTML网页,然后JS加密判断

翻看JS代码

{width="5.75in" height="3.375in"}

很显然,关键的代码在checkPassword


JS混淆是必备的

去混淆一条龙走起

先将关键代码提取出来


  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


得到去混淆后的结果


  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长度21


发现了MD5加密,和两个MD5字符串


看起来无关联?

后来审计整个代码发现,对输入的flag分部分进行判断比较


写出对应的部分,在控制台console输出相关信息是一个不错的选择



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

使用某插件的过程中,大量个性化需求不能满足,于是我有了更改源码的冲动。翻遍所有角落,只找了一份压缩混淆的 js 文件

能否反混淆,这是本节讨论的重点。

一、场景复现

先来说说几种我们迫切需要知道源码的情况:

1.阅读源码,当然,大部分开源的代码都是可以直接查看的;

2.对某插件做个性化的需求更改,这时候你渴望看到未混淆压缩的代码;

3.为了增加代码分析的难度,混淆(obfuscate)工具被应用到了许多恶意软件(如 0day 挂马、跨站攻击等)当中。

分析人员为了掀开恶意软件的面纱,首先就得对脚本进行反混淆(deobfuscate)处理。

4.当你准备抄袭别人代码时,这个稍微有点不可描述;

本文,我们假设是在前两种场景的条件下,来探索一下 js 反混淆问题。

二、寻求方案

为了快速的解决问题,我们首先尝试一下现有方案:

http://jsnice.org/

一个简单的示例:

解析后:

是不是反混淆之后,可读性强了很多。

2.js 代码混淆站长工具

我们先从 Lodash 找一段演示代码,如下:

普通混淆后,就变成了这样:

为了测试一下如何反混淆,我们将混淆后代码拷贝到 jsnice :

可以看到,普通混淆后,代码还是可以做一些复原。

好的,我们加大力度,采用加密压缩方式。这次代码明显多了,而 jsnice 也反混淆失败了:

这段代码,地球人已经没法读懂了,乱七八糟的。那么,问题来了,加密混淆的代码真的没有办法复原吗?

三、思维突破

从上面的演示可以看出来,加密之后的混淆,已经完全无法反混淆了。

除非我们知道混淆算法,可是混淆方式不计其数,你需要知晓它的混淆方式,并制定出反混淆算法,那估计会累死。

如果我们这么想的话,那么就陷入了泥潭,甚至无法自救。那么,突破点到底在哪里呢?

众所周知,JavaScript 是解释性语言,它严重依赖游览器。不管 JavaScript 如何混淆,最终浏览器都会知道最真实的代码。所以,我们还得以浏览器为突破口。

首先,同步一下原始代码:

其次,确定源码中是否包含在 eval 中,参考代码如下:

然后,查找关键字 throw,如果有,那就成功了一大步;

最后,改动源码,让源码抛出异常,让 Eval Code 还原出真实代码;

可以看到,为了演示,我们让源代码具有某些特性,然而实际情况会远远复杂于此;

四、相关工具介绍

我们先来看一下,目前常用的混淆工具:

  • YUI Compressor
  • Google Closure Compiler
  • UglifyJS
  • JScrambler

反混淆工具:

  • jsbeautifier
  • JSDetox

了解更多,请参考:几种常见的JavaScript混淆和反混淆工具分析实战

五、了解混淆手段

1.base62 编码,其最明显的特征是生成的代码以 eval(function(p,a,c,k,e,r)) 开头;

看到这里,上述站长工具的加密方式,就不难理解了。

这类混淆的关键思想在于将需要执行的代码进行一次编码,在执行的时候还原出浏览器可执行的合法的脚本,然后执行之。

看上去和可执行文件的加壳有那么点类似。Javascript 提供了将字符串当做代码执行(evaluate)的能力,可以通过 Function 构造器、eval、setTimeout、setInterval 将字符串传递给 js 引擎进行解析执行。

无论代码如何进行变形,其最终都要调用一次 eval 等函数。

解密的方法不需要对其算法做任何分析,只需要简单地找到这个最终的调用,改为 console.log 或者其他方式,将程序解码后的结果按照字符串输出即可。

2.隐写术

严格说这不能称之为混淆,只是将 js 代码隐藏到了特定的介质当中。

如通过最低有效位(LSB)算法嵌入到图片的 RGB 通道、隐藏在图片 EXIF 元数据、隐藏在 HTML 空白字符等。

比如这个耸人听闻的议题:《一张图片黑掉你》在图片中嵌入恶意程序,正是使用了最低有效位平面算法。结合 HTML5 的 canvas 或者处理二进制数据的 TypeArray,脚本可以抽取出载体中隐藏的数据(如代码)。

隐写的方式同样需要解码程序和动态执行,所以破解的方式和前者相同,在浏览器上下文中劫持替换关键函数调用的行为,改为文本输出即可得到载体中隐藏的代码。

3.复杂表达式

代码混淆不一定会调用 eval,也可以通过在代码中填充无效的指令来增加代码复杂度,极大地降低可读性。

Javascript 中存在许多称得上丧心病狂的特性,这些特性组合起来,可以把原本简单的字面量(Literal)、成员访问(MemberExpression)、函数调用(CallExpression)等代码片段变得难以阅读。

在 js 中可以找到许多这样互逆的运算,通过使用随机生成的方式将其组合使用,可以把简单的表达式无限复杂化。

深入了解,请移步使用 estools 辅助反混淆 Javascript

六、写在最后

JavaScript 作为一个以函数式为核心的多范式动态弱类型脚本语言,因为它的灵活性,导致了源代码在经过一些压缩工具处理后,变得极难还原。

也有可能,当我们费劲心思还原出来的代码,也许只是与源代码运行流程一致的另一套代码。当然,我们可以继续探索,发掘未知的领域。

七、热门原创文章

1.戏说 API 和 SDK

2.JS 基础|搞懂 typeof 和 instanceof

3.大公司面试前端,为什么喜欢问 BFC?

安卓APK中的混淆

混淆是软件开发中常用的技术,用于使代码更难理解、分析和逆向工程。它将代码转化为一种复杂而纷繁的形式,同时保留其功能。混淆的主要目标是阻碍对代码的未经授权访问,保护软件的知识产权或者隐藏软件的真实行为。

在Android APK中,常用多种混淆技术来保护代码,使其更难理解或逆向工程。其中一种技术是代码混淆,它将源代码转换为等效但更复杂的形式,使其难以解读和分析。另一种常用的技术是字符串加密,在这种技术中,敏感字符串(如API密钥或URL)被加密,以防止轻易提取。此外,还采用控制流混淆来干扰代码的逻辑流程,使其难以跟踪程序的执行路径和理解其功能。

混淆对Android安全的影响

混淆技术的使用增加了安全研究分析的难度,并使一些基于签名的检测方法失效。字符串加密使得追踪关键信息变得具有挑战性。这些措施使得恶意软件更难以识别和追踪。

一种基于文本分类的软件包混淆检测方法

出于这些原因,我们的公司——Liansecurity开发了一款名为"Incinerator"的产品,旨在提供高效、准确和自动化的逆向工程服务。通过对恶意软件的广泛分析和先前混淆检测技术的研究,在我们的Android APK逆向工程产品“焚化炉"中实现了一种基于文本分类的混淆检测方法。根据我们的测试,我们的方法实现了98%的准确率,这超出了我们的期望。在接下来的章节中,我们将详细描述我们的方法。

背景

在检测Android应用程序中的混淆技术方面,最先进的系统是"AndrODet"。在这项工作中,作者构建了一个混淆检测系统,针对每种混淆类型提取不同的特征,然后训练一个在线机器学习模型。下面列出了目标混淆类型和AndrODet实现后的测试结果:

  • 标识符重命名:0.92
  • 字符串加密:0.79
  • 控制流混淆:0.67

AndrODet在Android环境中的局限性

在Android的背景下,AndrODet面临某些限制,影响其作为静态代码分析工具的准确性和有效性。主要集中在两个方面:

基于APK的计算和特征弱化

AndrODet计算其度量指标是基于整个APK,包括核心业务代码和关联的库文件。在Android生态系统中,依赖库可能会非常庞大,有时甚至比核心业务代码本身还要大。而且大多数情况下,依赖库并不需要进行混淆。当仅依靠整个APK进行计算时,这些大型未混淆的库的存在削弱了混淆部分的重要性,最终影响了AndrODet进行正确判断的准确性。

无法处理Unicode编码

AndrODet计算距离的方法局限于ASCII编码。然而,使用Unicode编码进行混淆技术的使用越来越普遍。因此,AndrODet无法处理和分析使用Unicode编码进行混淆的代码。这个限制阻碍了该工具在真实生产场景中准确检测和评估混淆代码的安全性和质量方面的能力。

AndrODet的限制对其在真实生产场景中的准确性构成了挑战。了解这些限制及其对真实生产环境的影响对于寻求改进Android应用程序安全领域代码分析工具能力的研究人员和从业者至关重要。

我们的方法

我们的方法主要解决了代码混淆技术中最常见的标识符重命名的识别问题,这是恶意软件常用的混淆技术。我们的方法也可以扩展到字符串加密。在我们的研究中,我们观察到,当研究人员评估一个代码片段是否被混淆时,他们最初的判断依赖于类名、方法名和变量名的可理解性,以及可识别和常用的编码约定,即所谓的“编码英语”,与类似'a'、'Zb'、'c4'、'1li'、'0Oo'等不容易理解的名称进行对比。最初,我们尝试了算法方法来解决这个问题,但测试结果不怎么理想。然而,我们突然想到,这实际上是一个经典的自然语言(NLP)分类问题。

凭借这一灵感,我们将混淆检测问题转化为文本分类问题,而深度神经网络处理文本分类,已经非常成熟。我们的测试结果也证明了这种转换非常成功。“字符串加密”本质上也是一个文本分类问题,因此我们相信这种方法可以轻松扩展到字符串加密。

方法说明

第1步:反编译和Smali提取

第1步涉及反编译AndroidAPK和提取Smali代码。在我们的实现中,我们使用我们自己的反编译引擎"Reactor”。其他开源工具,如AndroGuard或Apktools也可以。从每个类中,我们提取类名和类变量名,这些是下一步分析的输入。理论上可以提取更多特征,如函数参数名称和局部变量,但提取更多的特征对准确率没有太大的提升,因为前面的三个特征已经达到了很高的准确性。

第2步:创建训练集

创建两个不同的训练集。第1个训练集是混淆的类生成的数据,标记为1。第2个训练集是未混淆的类生成的数据,标记为0。

第3步:文本分类神经网络训练

我们构建了一个文本分类神经网络。该神经网络使用步骤1中提取的特征和步骤2中的相应标签进行训练。通过利用深度学习网络模型进行训练。

该模型分成3层:嵌入层、LSTM层和密集层。

1)嵌入层:嵌入层将输入整数序列转换为密集矢量表示。

2)LSTM层:LSTM(长短期记忆)层是一种能够处理序列数据和捕获长期依赖关系的循环神经网络(RNN)。在该模型中,使用了具有128个单元的LSTM层。

3)Dense层:Dense层是一个全连接层,对LSTM层的输出进行线性变换并应用sigmoid激活函数。

第4步:训练

我们从1000个数据样本开始,发现结果已经非常不错。随着我们将样本量增加到10000,准确率和验证准确率都变得非常令人满意。最终,我们的模型使用100000个数据样本进行了训练。我们试图进一步扩充数据集,但准确率和验证准确率没有提高。为了避免由单个APK生成的数据引起的偏差,我们从数据库中随机提取了几百个APK来生成我们的数据。从生成的数百万个数据样本中,我们随机选择了100000个进行训练。

训练结果如下:

训练准确率:99.75%

验证准确率:98.50%

实验结果与分析

在实际应用中,为了确定一个APK是否被混淆,我们使用了一种方法,该方法涉及检查APK内的每个类是否进行混淆。通过将混淆类的数量除以类的总数,我们可以计算APK中混淆代码的比例。尽管在理论,针对每个类,判断可能出现假阳或者假阴,但是在判断一个APK是否存在现象时,很难出错,因为一个被混淆的APK,需要确保它的大部分代码很难理解,这正是混淆的目的和最终呈现,大部分难以理解的类,是不能逃过模型的检测的。因此,我们的模型在确定APK中是否存在混淆时达到了接近100%的准确率。

第一轮训练后,我们从Fdroid和Abuse各获取了1000个APK,进行验证测试。FDroid代表良性apk, abuse代表恶意 apks,测试后,我们发现有较高概率出现假阳,一些非常短的内部类,例如”Class: MainActivity ExternalSyntheticLambda15; Method: <init> run Field: f>第一轮训练后,我们从Fdroid和Abuse各获取了1000个APK,进行验证测试。FDroid代表良性apk, abuse代表恶意 apks,测试后,我们发现有较高概率出现假阳,一些非常短的内部类,例如”Class: MainActivity ExternalSyntheticLambda15; Method: <init> run Field: f$0 f$1 f$2 “ 这样的情况,模型无法判断是否是混淆。为了解决这个问题,我们从假阳的apk中,抽取了3000条数据样本,加入训练集合。重新训练,再次训练后,极大的降低了假阳。< f f “ 这样的情况,模型无法判断是否是混淆。为了解决这个问题,我们从假阳的apk中,抽取了3000条数据样本,加入训练集合。重新训练,再次训练后,极大的降低了假阳。

下面是我们抽取随机的100个测试样本,因为我们的模型校验准确率是98.5%,所以测试结果中,混淆覆盖率1%,2%这样的情况,应该判断为没有混淆。剩下结果中的4%(md5:8328cd96c931d06d25f67d42a50fd20d)这个是误报,分析原因是因为这个apk的类非常少,三条假阳数据导致了这个错误。其他的5%(923df6854199e999fdd274729b28a1ad),7%(71e293f29e636112e0a00ebac8cf3eb8)都是真实存在的混淆。所以这个模型,判断混淆的准确率接近100%,而且APK中存在非常少量的混淆也是可以检测出来。

我们的训练集中并没有出现 unicode的混淆样本,但是在测试的时候,这种情况也会被识别为混淆,因为模型对非混淆的文本有非常好的识别,所以即便出现样本中没有出现的其他混淆情况,也可以识别。

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%

限制和未来方向

本文讨论的都是针对标识符重命名的混淆检测,相同的办法可以应用到字符串检测上。但是不能应用到控制流混淆检测。AndrODet的结果在这方面的表现也不尽如人意。未来我们会针对控制流检测专门设计新的模型。

与AndrODet相比,我们的模型需要相对更多的时间来确定APK是否被混淆,因为它需要单独检测每个类。虽然可以批量检测,但APK可能包含数千甚至数万个类。然而,在生产环境中,这是可以接受的,因为分析APK涉及静态分析、动态分析等各个方面,需要更长的时间来执行。因此,在我们的产品中,混淆检测的等待时间是合理的。此外,这个时间也可以通过并行架构处理来缓解。

结论

我们提出了一种基于文本分类的方法来检测APK是否被混淆。这种方法以前在现有研究中没有应用过,可以扩展到其他软件中的混淆检测以及字符串加密检测。此外,我们建议APK中混淆的检测应该在类级别进行,因为这样可以达到基本100%的准确率。

我们已经在正式生产环境中实现了这种方法。


from https://www.freebuf.com/articles/mobile/370247.html