line app 逆向分析(二):关于海外line客户端批量注册、群发、拉群的一些逆向思路

书接上回;
单词表
Line是使用两个 URL 来检索单词列表。如果使用非中文区域安装 LINE,则这些 URL 显然不会输入到设置数据库中,但可以在 LINE .apk 文件根部的 app-config.properties 文件中找到。这些 URL 自 v3.4.2 以来一直存在。

URL 及其内部描述是:

URL_CHINA_BAD_WORDS_INFO = http://line.naver.jp/app/resources/bwi
URL_CHINA_BAD_WORDS = https://line.naver.jp/app/resources/bwraw

文件 bwi 包含有关坏词文件版本的信息,其中包含一个如下所示的字符串:21,4320,v21,需要注意的事情是,如果没有上述 URL 中引用的内容,则无法通过 HTTP 直接访问该文件。用户代理字符串设置为“Android Mobile LA/xx”,其中 xx 是位置代码。但是,可以通过 HTTPS 访问它,无需 UA 字符串:

$ curl http://line.naver.jp/app/resources/bwi
<!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href=”http://line.naver.jp/en”>here</a>.</p>
</body></html>$ curl -A ‘Android Mobile LA/UK’ http://line.naver.jp/app/resources/bwi
21,4320,v21,$ curl https://line.naver.jp/app/resources/bwi
21,4320,v21,

原始文件实际上并未托管在上述 URL 上;上面的文件名附加了版本号。例如,v21 文件托管在 https://line.naver.jp/app/resources/bwraw.v21。截至 2013 年 10 月 31 日,v21 和 v20 的文件可用。该文件可以在没有上述用户代理字符串的情况下通过 HTTPS 访问,也可以在有用户代理字符串的情况下通过 HTTP 访问。

坏词文件采用 Base64 编码,并使用 AES 在密码块链接 (CBC) 模式下使用 PCKS#7 填充进行加密。解密使用存储在二进制文件中的静态密钥:

 private static final byte[] key = {
76, -86, -111, 47, -128, -21, 62, -44, 4, -91, 44, 60, 72, -46, 91, -42, -9, 46, -127, -110, -37, 85, -98, 73, -86, 27, -103, 103, -25, 81, 117, -89
}; public static String decrypt(String encryptedFile) { try { byte[] encryptedBytes = Base64encoder.decode(encryptedFile); SecretKeySpec secretKey = new SecretKeySpec(key, “AES”);

Cipher c = Cipher.getInstance(“AES/CBC/PKCS7Padding”);
c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(new byte[16])); String decryptedWords = new String(c.doFinal(encryptedBytes), “UTF-8”); return decryptedWords; }

作为参考,256 位 AES 密钥为:

4c aa 91 2f 80 eb 3e d4 04 a5 2c 3c 48 d2 5b d6
f7 2e 81 92 db 55 9e 49 aa 1b 99 67 e7 51 75 a7

坏词文件将以 cbw.dat 的形式存储在应用程序的缓存目录中。如果此列表不可用,LINE 将默认使用较小的内部列表:

private static Pattern g()
  {
File localFile = new File(n.b().getApplicationContext().getCacheDir(), “cbw.dat”);
    if (!localFile.exists())
      try
      {
Pattern localPattern2 = getInternalBadWords()1;
return localPattern2; } catch (bwd localbwd2) { a(“failed getDefaultWords”, localbwd2); return null; }

该应用程序还在下载的单词列表上设置偏好信息。10800000毫秒的延迟时间相当于3小时;

static void setWordListPreferences()
  {
    long l = System.currentTimeMillis();
    SharedPreferences.Editor localEditor = bgb.a(bga.h).edit();
localEditor.putLong(“word_list_update_delay”, 10800000L); localEditor.putLong(“word_list_update_date”, l); localEditor.putLong(“word_list_version”, 0L);
localEditor.commit(); }

内部审查单词列表也使用相同的密钥进行 Base64 编码和加密,并且自 v3.4.2 引入以来一直保持不变:

5mxphvUu6sGOrG+Qw8EsqlMmx+kNh11mTfMLXZgNmxLfH4grWErsAEsqw+j34zUbdxDUiitSMr77CBwBdEojckjIHvdBPtRFduMb5TgvBjbtzmlXHN+UmUsDVmto7rMdCwP6+/AE zLmKB6GsAEs+3Q8xEtejCqdMnuU262feg4m5OrNxlgX3wpifO/+9Q9lm4KzHAhs7ZSGCOZbE2j6wPOTTMA6TXh9G1gA560ZjGNu+tLPJStUd08Kkw+AQvLl3ZSC3CexDT83D+FK1MYAUmfc 6BIGh/AalsSszJcLyatT7hRUpeNl0/3i+0z2vtEZxEO6SU4mempEnR9ErjGWLpUIbNdWxFVf32Le1UaLE000+fl0y06lopoFyGIjELHg+dbtmGFRMpxhmZauEFmkIeElCVctonsX1866+c3qXVf DnXZg30BXb9Octrytti5C81/P9M0yDrbtDod2IKX1k39IDrsdqTPUC3+TYyuAOACGnAN/FNkRQmeBbhzpY7Du2+F2fLm8QlFhm2MczaHyj9aDjMfUAEukNDtYi+Jj3MS+h8/F9FW3gMHjn eviLWBBe0fRJBbrxRvUKDtvS6vrMO/J2 +nxiz/3dBgkG2kXFR6Y9PfV7X0fmBW/ZZLM3MMUk8LMmAJIuhcaiKhaHg4721pXqT7v7U2FmHLLiKJIev4a0lG+bxg9nM2m9IcDRSq7Uca08JefErOSSUOWUoeWhNTtr1dhu07HgbhBaHx dHvurl9Ld+FHiKrJZNbZEnuNK5+xOrmBVemDc8untuB5IhotpDU3yAnZNmvZSDJ00/PH05jOCbf4SgW+rkVOjsgodSpljGar7OBSfGR+hMujN4gay3hHm9Ygg5zN8LlME31CCADlFRCixo0p3b3VxMlAvBHSRITE/B/QwxKsG/IY7y2LCu6wJrctgfPYW/px2ItSOnd4LtztEpCBhQT3/CZbO6c0OLWaDPufjnZYuyEXyA6677+aMCIAA0RpInRMmzw Yg7eG4PnuygTgDWhm6mc5C8Raz2teUysHhsIP26WAjdBQ+IPWgRvKLDzgpKaOI+moYqXarkTRBBdtMEOp4d4+sU953rE4i8sWtVHSzpV9sprJ5FgdayGOleKnZoy9GX1l38ey983hX8+LnM syVKpjw8I9NWCFdknigP9QvAAYaDAqE0g4Y0oD3G1YAikkHCV0Foc8lUww++9XpECxlED7znaF9USMeXV+ZyzRjztUk/kg==

仅当 LINE 设置中存储的区域为“CN”时,才会执行异常检查;

public static final boolean c()
  {
    add.a();
    if (add.c());
    String str;
    do
    {
      return true;
      add.a();
      if (jl.d(add.a(cya.a)))
        return false;
      af localaf = b();
      if (localaf == null)
        break;
      str = localaf.c();
    }
    while ((jl.d(str)) && (
Locale.CHINA.getCountry().equalsIgnoreCase(str)
)); return false; }

未完待续。。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值