系列目标

  • 常见加解密算法的基本原理
  • 在App逆向分析过程中快速识别其使用的算法

基本原理

加密的工作原理是将“明文”编码为“密文”,通常通过使用被称为算法的密码学数学模型来实现。要将数据解码回明文,需要使用解密密钥,也就是由某种算法创建的一串数字或密码。安全的加密方法会有大量的加密密钥,因此未经授权的人员既无法猜出正确的密钥,也无法使用计算机通过尝试每个可能的组合(称为暴力破解)轻松计算出正确的字符串。
解密的工作原理就是加密的逆过程。
notion image

分类

  1. 对称密码:即加密与解密时使用相同密钥典型的有RC4、DES、AES等。
    1. 序列密码(流密码):将明文消息按字符逐位进行加密。明文与密文长度一致。RC4是序列密码。
    2. 分组密码:将明文消息分组(每组有多个字符),逐组进行加密。由于进行了分组,最后一组可能长度不够而进行填充,所以密文可能比明文要长。
  1. 非对称密码:即加密与解密时使用不用密钥典型的有RSA、ECC椭圆曲线等。
  1. 散列算法:又称哈希函数,对不同长度的输入消息,产生固定长度的输出。这个固定长度的输出称为原输入消息的"散列"或"消息摘要"(Messagedigest)。

BASE64编码

BASE64不是一个加密算法,只是一个编码,它没有密钥。只要得到其编码算法,就能还原。
我们以字符串"Hello"为例,解释Base64算法:
  1. 将字符串"Hello"转换为二进制数据:
    1. 将这些二进制数据拼接在一起:
      1. 将这些二进制数据按照每3个字节(24位)进行分组:
        1. 将每个分组的24位数据分割成4个6位的小组:
          1. 将每个6位的小组转换为对应的Base64字符:
            1. 将这些Base64字符拼接在一起:
              在这个例子中,Hello经过Base64编码后的结果是SGVsbG8=。请注意,由于Hello的字节数不是3的倍数,因此会在编码结果中添加额外的=字符进行填充。
              可以想一下,编码完成前后字符长度的关系:
              上面的第5步是核心,它在转换的时候是有一个编码表的:
              notion image
              所以,如果我们改变这个表,比如交换一些字符的位置,就能实现一些base64的变种。
              了解了BASE64的原理,那BASE32也就好理解了,它就是使用32个可见字符做编码表,然后是5个bit作为一组,也有填充。
              notion image
              同理,BASE16也好理解。
              notion image
               

              例子1

              base64_ollvm.apk
              查看JNI函数:
              第一个参数改成 JNIEnv 指针类型,可读性会好一些。
              so里面方法不多,可以一个一个看过去,看谁比较可疑,也可以直接搜索编码表字符串,当然也有可能遇到字符串加密的情况。
              找到 sub_72c 函数,混淆的非常严重:
              notion image
              看反汇编还是可以看到编码表的:
              使用 frida 来主动调用一下这个函数,看看它的输入与输出:
              注意,这里使用 12.8.0 版本的 frida 来执行,15.2.2的在 cli 里面找不到函数,需要再研究研究。
              看结果:
              可以看到 sub_72C 这个函数就是做了一个 base64 编码操作。
              后来研究了一下 的使用,发现要对函数进行导出,导出名不可以有大写字母或者下划线。需要将代码写在 agent/index.ts 里面,使用 typescript 编写,体验也还不错。
              加载脚本,使用 npm run watch,脚本更新后自动编译到 _agent.js:
              不加 -f 参数就不会重新启动,但是需要传递进程 id:
              脚本如下:
              输出结果如下:

              例子2

              base64_ollvm_packer.apk
              这个就是上面的包加了个壳而已,使用 frida-dexdump dump一下就可以了。
              frida直接进行hook与调用,不需要考虑classLoader:
              当然如果想兼容性更好,还是要遍历 classLoader:
              查看输出:
               

              文件

               
              Loading...
              二手的程序员
              二手的程序员
              路漫漫其修远兮
              公告
               
              可以占个坑,虽然现在没人说话。
              QQ群:
              notion image
              Telegram群:
              notion image
               
              我的公众号:
              notion image
              我的微信:
              notion image