首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Coding
V2EX  ›  程序员

准备升级一个开源的 php 加密扩展 跪求破解高手打脸

  •  
  •   rekulas · 2016-06-21 10:50:53 +08:00 · 11586 次点击
    这是一个创建于 1270 天前的主题,其中的信息可能已经有所发展或是发生改变。

    基于据说日本人写的 php screw
    然后进行了些修改,为了区分暂时命名为 screw plus 然后做了以下改进
    增加了批量加密
    升级了加密算法,更加安全可靠
    加密函数是用的网上找的基于 php 的 authcode 算法,然后稍微进行了些小优化
    加密的优点:
    可防止源码泄露,别以为 vps 就绝对安全了,我有个朋友的 vps 就被工作人员直接破解了,原因是另一个客户记错了 ip ,没核对信息就。。。
    商业源码可加密核心功能,只开放接口给客户
    部分公司需要团队开发的,可防止源码泄露
    其他。。。我编不出来了
    下面是演示对比:
    PHP 原生代码:

    screw 加密:

    screw plus 加密:

    之所以要用扩展来加密是因为这是最安全的方法,不需要扩展的加密都是可以破解的,唯一不同的就是破解时间的区别(当然,扩展加密也是可以破解的,但是破解时间不是破解者所能承受的毕竟没人能活几万年)

    有兴趣的朋友可以关注下,完全完成后我会上传到 github 和 oschina

    有破解能力的可以尝试下破解以下 code 来打我脸,加密函数在这里 http://filedoc.s3.sinaapp.com/myfiles/cauthcode.c

    code:

    f83c0c86454591265c9f772eb499ea4a3+Mrn7H3huTwgitNLGtAZlrixw5BLaHDeoYUJR8xg3NgVz8wlTWYV0x9dgW7q6eRVexLVBWOipqQgK74mdMNe/fyx42uf607MUfpPLNiBNCtHbB8rnrnpxKqVXJVUu/83GVFfwOTrt4Bge3erdYUp38DyHgLXlKGevf4MW7SB1hwd9P1rsyDQHzvzxltBU9+fanOC5Vp+uuz4BhXJsnhJTlM8pRjEwfnH9D+KkxryKNnC0YwmCrGYWDODanCzyDOOjadr5GovnGyzPmhZjlSy6zSWX0OVjESSO+evaN4tB5V5WWqC0cjZTTfHIjFt5i5Gut8qpOM8oWKzCUd5B8NOwFoNsotlM6feRHQajRDOQiXURco1yvHeUGWT07mg9h+65jJxVxF0gx8OFQrxxFxMBXEUdzb9T6V6jwA8jcyjn2U8HESLo+t4YC8P//afy6yXicSeW1LGeLyng7RITLnFSPPxRHeuAMSBqvXhxXSbIv+HCLst/edoWUtBq09Ig0UXuLo1MWce/DuqDg2QHe9NQM4AVUE9VD2p0DTcmgrCDXRjufiSqzh2pPnWkw6yNUqp6SNSAGVSzrMm8OvoLKt6bwTB22FNAsI5ANlVvgRnth+sSeZ1FdTKOt0vQckMBgxLi2emm8V6PD6NQhlJisX0K21uySiQIZRMlNhAHGMgM6s7dYgGwQUNWfmrgTfNvLaA2BL7cRbLmb9BK2n+VI/fP4xY4NbvhtykImOVXTY9g8gyZqykbTo7WHwXleRl7qj6rIh7WZKmrn+IURZbm0lFd8g4YKs5kOcEDAlZequv2sAGMECLLx5qPSTnuUVTrDBGIWG5Uy4IsOnkeRBKMNN4L1UlT3jPygqc5Dd9axGcnvOM5FGZU/Xj7CBFtNwTkcBeUd40t2FiQ0ZgDy+rP7eRV5fCSosd2ol2bpzbbYQjjAASqz7duknPM+y8daSRIuvS83eJUe/5gIYDaJqNPgS1cl6L6feij1xiV4syZ4UD5byaZreMHKGTtdh5iGHjTakdje5Tt5OxoRr/JK74QqVaXDibUFQuZKAsGkrR3S3JgL//cPkvymSlVed355BZHPPMZ0x+0o3MFWkJZL5mSgHxmO6WzW34wMGIY8N/yhSgJflGElSgm61O1E8yYrOBD2UWmXr55WvcnivkemY4pLzAnQRn6tug89yseEELG46w87TIfes9zTtmr1/mogZzbGcjEU3j+kR8pLMSE03LtVp2QSxEHxepc6ngSxXiWugMyfWaOlTK+1X1AyN4IGvZBdkM7HEQx2iHGJ+yT2lEqrwiD0/yuD6T7pWOhTmx6W/UAdopciiUPraoeEJcAw7eSMOn1xZbq7SBgzzSAWcFXYoZZeejsSHZGSXWM+IXKzjJ6pTiuErPykMUvu698z7Cpb235f2vI0tIRE0UOKrnaGGgGVIJCORlpoccLKuzkNuU3HmNEKCfTL1QgsxWMNGgZlWKZsQWbYJNOj0xFUu12CUcwnpjB2faRh3CKXNZtOweKnLTfF/wgLHA7tNs4mZydLxad4dwkvfXl69bn3K+D7NRT22BYbnACbGODFQTZ+dWi033YbXr/bPAwULVnWh56DC/Q2NFKzQYND+gML/8IqSNq4g+rCGzziNtysV0IIpNdptoLcH9GB/fEQkpfHPS1Bh/wTG
    
    第 1 条附言  ·  2016-06-22 14:08:51 +08:00
    开源地址

    https://github.com/del-xiong/screw-plus

    http://git.oschina.net/splot/php-screw-plus

    ### 使用方法:
    1. 下载本程序并解压到某个目录
    2. 在 screw plus 目录中执行 php bin 中的 phpize 自动生成扩展所需文件(如果你的 php 里没有可以去官网下载)
    3. 执行./configure --with-php=config=[php config path] 进行配置,[php config path]是你的 php-config 的绝对路径
    4. 修改 php_screw_plus.h 中的 CAKEY ,改为一个你认为安全的字符串
    5. 执行 make 生成扩展 modules/php_screw_plus.so
    6. 把扩展路径加入 php.ini 中 重启 php
    7. 进入 tools 文件夹 执行 make
    8. 执行./screw [目录或文件] ,后面带上你要加密的目录或文件即可自动开始加密
    第 2 条附言  ·  2016-06-24 16:25:41 +08:00
    2016/06/24 更新:改进了加密算法 使用高强度的 AES256 CBC 模式进行加密
    第 3 条附言  ·  2016-06-24 23:08:21 +08:00
    性能测试结果:
    阿里云 ecs 最低配置 vps 测试单核 1g 内存
    进行 10 万次 13kb 大小的数据循环加解密
    耗时约 12s
    处理速度:约 105MB/S
    每毫秒处理速度约 107kb
    按照平均每个网页加载 20 个 13kb 大小的页面算,多消耗 2.4 毫秒 按 100 个(1.3MB)算增加 12 毫秒
    56 回复  |  直到 2018-07-27 17:09:57 +08:00
        1
    leopku   2016-06-21 11:09:45 +08:00
    沙发支持
        2
    pyengwoei   2016-06-21 11:26:17 +08:00
    楼主给个联系方式吗
        3
    rekulas   2016-06-21 11:30:57 +08:00
    @pyengwoei cTc4MjYxMzAyOA==
    base64
        4
    shuax   2016-06-21 11:31:35 +08:00
    难道不是应该把扩展丢出来吗。
        5
    m3   2016-06-21 11:45:24 +08:00
    mark
        6
    zhangfan   2016-06-21 11:53:06 +08:00
    支持!
        7
    fcicq   2016-06-21 12:06:44 +08:00
    重点不是加密啊, 而是你能不能实现一个能运行加密 OPCODE 的虚拟机. 否则必然还是有一个时间点在虚拟机里可以复原. 你的加密破不破没有意义.
        8
    rekulas   2016-06-21 12:12:30 +08:00
    @shuax 还有点小工作 就这几天就丢出来,话说你是 shuax 的作者吗?我之前经常上你 blog ,就羡慕你这种压力小、技术好、有众多产品的程序猿
        9
    rekulas   2016-06-21 12:15:58 +08:00
    @fcicq 那个难度太高了,目前来看只要 php 代码无法被破解就已经足够安全了

    如果要防 vps 整体被破解的安全,我觉得只能修改 php 内核了,反正我这种小白是无实力的
        10
    rekulas   2016-06-21 12:22:14 +08:00
    @fcicq 我觉得可以通过一些取巧的办法来预防,比如
    解密必须要对应的扩展,把扩展放到仅限 root 和 php 访问的路径,当 vps 有任何用户登录后,需要提供更安全的有效凭证,不然扩展拒绝工作,同时检测 linux root 密码,如果被更改过也拒绝工作,除非重新编译
    没有办法 100%防止,但能防绝大部分了
        11
    fcicq   2016-06-21 12:25:26 +08:00
    @rekulas 你只是把可破解的钩子从语言层移动到了 C 的函数调用层. 所以没什么特别的, 确实如你所说你只有这个实力. 有加密的 OPCODE 也不是彻底方案, 因为重映射有可能仍然可行, 但这应当足以过很多传统杀毒软件了.
        12
    fcicq   2016-06-21 12:26:42 +08:00
    @rekulas 你的防御方法用一个动态库链接就绕过去了.
        13
    breeswish   2016-06-21 15:31:19 +08:00   ♥ 1
    没理解错的话,这是对源代码的加密混淆?或者说这是加壳?以及使用的是自己设计的一套加密算法?
    那么破解方式有几种:
    1/ 在 Zend 层拦截解密后的代码
    2/ 破解加密密钥
    3/ 从密码学上找到加密算法的缺陷进行破解
        14
    lz3259   2016-06-21 16:23:58 +08:00
    对源码进行字符串加密是没有任何意义的
        15
    q397064399   2016-06-21 20:26:07 +08:00
    @rekulas 貌似没有意义吧,如果是 VPS 的话 在宿主机上面 dump 你的物理内存,分析出代码段应该压力不大,毕竟你的密文最后还是要被解析成 PHP 代码 copy 到内存里面被 php 解析器解析的
        16
    q397064399   2016-06-21 20:33:00 +08:00
    你的想法应该是 在 php 里面
    通过 php 的 eval(de_crypto("your_crypto_code"))
    然后把 de_crypto 写成 php 解密扩展 对吧?
        17
    q397064399   2016-06-21 20:35:55 +08:00
    如果是这样意义不大, eval 函数应该是在内存里面开辟一道连续的内存区域,这样 VPS 宿主机 dump 然后稍微分析下,你源代码就出来了
        18
    rekulas   2016-06-21 20:36:53 +08:00
    @fcicq 这个确实容易被绕过,不过还有个办法,把扩展和环境绑定,用环境变量计算出 hash 然后作为 key 进行加密,这样必须拷贝整个 vps 才有可能进行下一步的破解工作,难度就更加大了

    @breeswish 确实是源代码的加密,运行时动态解密执行, 2 和 3 比较好解决,都可以通过使用更复杂的算法来解决, 1 从算法无法解决,但可以参考上条回复,极大的加大破解难度
        19
    rekulas   2016-06-21 20:39:31 +08:00
    @lz3259
    @q397064399 请参考 ioncube ,有市场就有需求,有需求说明有意义
    假设这样一个场景,某团队开发了一套程序,因为一个 bug 导致被黑客下载了整站,然后源码全部泄露,如果加了密,那么简单的 web 入侵黑客是无法破解源码的。
        20
    rekulas   2016-06-21 20:42:07 +08:00
    @q397064399 流程有点类似你说的,不过不是 eval 执行, eval 是无法执行所有的 php 代码的,是调用 php 的时候动态解密成源码返回给 zend 引擎,至于防 vps 破解可以看对 fcicq 的回复,只能增加破解难度,无法绝对防御
        21
    q397064399   2016-06-21 20:56:14 +08:00
    @rekulas 只是防 WEB 入侵,够用了, web 黑客一般很难提权到 root 权限的
        22
    q397064399   2016-06-21 20:59:15 +08:00
    @rekulas 另外重新写下 php 词法解析器的代码 然后把词法分析那段代码进行加密, VPS 宿主机应该也很难 dump 源码了, 我最近在读词法分析之类的书,这个难度应该不是很大,
        23
    rekulas   2016-06-21 21:01:27 +08:00
    @q397064399 可能吧 不过我觉得能防 web 破解已经足够了,毕竟应该没有人用 php 来写需要达到这种安全保密级别的吧
        24
    allenhu   2016-06-22 08:55:34 +08:00 via Android
    玩具
        25
    realpg   2016-06-22 09:17:26 +08:00
    @rekulas
    用了这个以后 opcache 还有用么?还是你内置了一个 opcache 优化实现?
        26
    SunnyMeow   2016-06-22 10:58:56 +08:00
    如果我没理解错的话楼主的算法其实就是 RC4 吧,有统计学弱点,但光凭一条密文做唯密文攻击是很困难的
    不过这不代表不能玩已知明文攻击啊,楼主愿意的话再用相同的密钥加密一串等长随机字符串,把明文和密文都发上来就可以玩了。
        27
    rekulas   2016-06-22 13:12:55 +08:00
    @realpg 对 opcache 不太了解,有空我测试下看看有无影响,不过个人感觉应该不会冲突的
    @SunnyMeow
    你大概需要多少条,我可以批量给你生成
        28
    rekulas   2016-06-22 13:15:16 +08:00
    @SunnyMeow 这算法也比较流行,对已知明文攻击的防御强度肯定是大于 RC4 的,但具体有多高我也不确定,所以打算下一步升级到 AES 加密
        29
    SlipStupig   2016-06-22 13:55:59 +08:00
    你这个不是在验证你扩展的安全性,而是加密算法的安全性,如果扩展一旦泄露本地搭建一个环境就可以解密出来了,如果服务器是安全的,也没办法偷你的代码啊.....
        30
    rekulas   2016-06-22 14:12:51 +08:00
    @SlipStupig 服务器安全不代表 web 安全,其实 web 泄露的情况还是比较严重的,扩展泄露你也得拿到 key 才行,而由于是开源的,你可以用更复杂的方法来隐藏你的 key
        31
    SunnyMeow   2016-06-22 14:48:15 +08:00
    @rekulas 我看下来就是完完全全的 RC4 啊,都没什么改变。
    理论上做已知明文攻击只要一条明文密文对就行了,要求是加密用的密钥和你给出的挑战用密文使用的密钥是一样的,明文的长度不小于挑战用明文,其他没什么了,我想试试看。
        32
    rekulas   2016-06-22 15:00:05 +08:00
    @SunnyMeow
    给几个简单的吧,你说明文的长度不小于挑战用明文什么意思
    abc 3HiOEZkAmaIEFsKEwoLDlxPDsXc6S8OpwozCrcOnwro8w4p6wp4AOn3CgFDCtTLDsBBqaQ=
    123 UjKOk16aHf57GHlzIsK6XcOuZE9iw5daKE7Cn8OZw7zCq8OiJ8KUVnPDlzVCw758w4M
    111 qdYoNQN5zVmocUPDk8Ohwq5jdQ4+w7HChV7DgC/Dk3QFQwUjUQQMAQ3CgsOUAcKy
        33
    rekulas   2016-06-22 15:04:42 +08:00
    @SunnyMeow 上面加密用的是 js 版本的,不过算法都是一样的,但 js 版本可能更难分析一些,如果需要 c 版本的我可以重新生成
        34
    SunnyMeow   2016-06-22 15:07:05 +08:00
    @rekulas
    你在帖子正文中附了一串挑战用的 code ,是一串经过你的算法加密后的密文,这条密文对应的明文长度比如说是 100 ,我现在需要的就是长度大于 100 的使用同样密钥加密的明文密文对
        35
    rekulas   2016-06-22 15:13:58 +08:00
    @SunnyMeow http://filedoc.s3.sinaapp.com/myfiles/FILE.zip 0 是源代码 1 是加密后的 密钥都是同一个,加解密算法在项目里面 http://git.oschina.net/splot/php-screw-plus
        36
    SunnyMeow   2016-06-22 15:30:33 +08:00
    @rekulas 你提供的压缩包里一共有 8 个文件,其中`install_var.php`, `install_extvar.php`, `install_mysqli.php`这三个文件的加密密钥和其他五个文件不同,同时这两个加密密钥和你在主贴里提供的以`f83c0c86454591265c9f772eb499ea4a3+Mrn7H3huTwgitNLGtAZlrixw5B`开头的密文使用的密钥也是不一样的
        37
    rekulas   2016-06-22 15:37:46 +08:00
    @SunnyMeow 压缩包里用的密钥都是同一个
        38
    SunnyMeow   2016-06-22 15:38:44 +08:00
    @rekulas 好吧是我理解错了,撤回上一条回复
        39
    SunnyMeow   2016-06-22 18:00:03 +08:00
    @rekulas
    我又仔细读了一下算法,发现自己漏看了 keyC 是随时间变化这个关键点,所以选择明文攻击只能有限度的进行
    吐槽一下那段 c 代码,看起来很头大,很多循环和变量完全都可以合并在一起,很多地方看起来很危险很容易越界的样子

    下面是我看出来的一些弱点:
    1. 使用了基于时间的 IV
    这是最大的弱点,其使得选择明文攻击得以成为可能。仔细观察一下,你可以注意到挂出来的那个文件夹里 5+3 个文件都共享了相同的 IV ,如果计算速度足够快,就有可能整个项目共享一个 IV ,相同 IV 的文件中只要一个文件的明文已知就可以推出其他文件中至少一部分的明文内容了。原理是 ciphertext xor plaintext = key ,不详述了。

    2. 加密方法暴露了密钥长度
    算法没有规定最小密钥长度,这本来不算大问题,但是对 keyC 画蛇添足进行截断就会暴露原始密钥的长度。试想使用者如果设定了一个较短长度(比如 32bit )的密钥,攻击者就可以在十几分钟内通过穷举攻击破解出来。

    3. 密钥空间不够大
    算法一开始就把输入的 key 做了 md5 ,然后平分拆成 keyA 和 keyB , md5 输出一共才 128bit ,拆一半只有 64bit 了,由于 keyC 随密文提供,完全秘密的只有这 64bit 的 keyA ,虽然穷举 2^64 也是非常困难,但我觉得在现代密码中这也能算得上是一个设计弱点了。

    4. MAC 设计有问题
    我读了算法发现前面被分出来的 keyB 只在预处理明文的时候被用到过,结合上下文我大胆的猜想你是想要实现 MAC 机制。然而 MAC 机制本不需要用到密钥来实现,这里分出 keyB 既没有好处,也影响到了密钥空间的大小。

    5. 过期机制的实现有问题
    源码里有提到 expire 的概念,相信你是想提供过期机制吧,但这个过期只能在逻辑上做判断,并没有提供数学上的保证,如果攻击者在过期后获取到密钥,仍然可以构造出 keyA 并对文件进行解密。

    综上所述,这个算法的核心就是一个内部基于 RC4 ,并且提供了初始向量支持的代码加密算法。先不说对解释执行的代码进行加密是否有意义,即使作为纯文本加密,也是有很多弱点的,而这些弱点并非理论本身的缺陷,都是在你设计加密算法时不慎引入的,我没有接受过系统的信息安全训练都能看出那么多问题,所以不建议自己设计加密算法的原因就在这里。
        40
    rekulas   2016-06-22 19:26:25 +08:00
    首先说明下这个算法不是我写的,原来是 php 里的后来被人翻译到 c 我之前还翻译过一个 js 版本的 http://git.oschina.net/splot/dopass/blob/master/crypt.js
    密钥问题其实早就注意到了,不过之前忘了修改这里,下午我重新提交了个版本 http://git.oschina.net/splot/php-screw-plus/blob/master/cauthcode.c 增加了个 hiddenKey 来预防这个,不过实际使用中如果用户没有更改自己的 hiddenKey 仍然存在风险,过期机制是原 PHP 算法里的,其实是没有意义的只是还未删去,算法确实还存在攻击风险,不过不会再更新,因为下个版本打算使用 aes 加密并且初始化时动态生成 hiddenKey ,这样至少在算法上是可以保证安全了。
    另外能不能加好友下, c 新手想请教些问题 我的 q 在三楼
        41
    rekulas   2016-06-22 19:27:06 +08:00
    @SunnyMeow 最后非常感谢你的耐心分析
        42
    msg7086   2016-06-22 20:37:49 +08:00
    只想吐槽为什么你会觉得 VPS 是安全的。
    VPS 本来就在服务商的硬件上,有硬件访问权限就可以得到所有你的数据,除非你从文件系统级别去加密。
    (然而密钥一样会存在内存里,一个 dump 解决问题。)
        43
    rekulas   2016-06-22 21:04:00 +08:00
    @msg7086 你这个属于钻牛角尖,对于小的 idc ,是这样的,权限管理混乱。大的云公司,我相信他们有成熟的管理方案来防范这种风险。就比如小公司程序员很容易就能把用户数据库给 down 下来,大公司可能只有顶层人物才有这个权限。
        44
    SunnyMeow   2016-06-22 21:43:41 +08:00
    @rekulas 我也只是略微知晓一点,所以技术上的讨论还是放在这里吧,有更厉害的看到了也能指点一下。私以为 hiddenkey 没有太大用处。如果让我设计的话,最简单的就是最保险的,每个文件随机产生一个定长 IV ,正确使用 AES 产生伪随机数并与明文异或,最后把 IV 放在密文之前就行了,如果需要 MAC 的话可以用 HMAC 附在明文后,简单方便,几乎避免了我上面提到的所有问题
        45
    peablog   2016-06-24 18:01:03 +08:00
    有测试性能影响吗?
        46
    rekulas   2016-06-24 19:29:10 +08:00
    @peablog 测试过 运行 discuz 未见明显影响 首页加载几十个文件都是 50-60 毫秒 不过测试还不严谨 晚上我再出个测试报告
    性能影响肯定是有的,但处于忽略的水平(<5ms)
        47
    rekulas   2016-06-24 23:07:55 +08:00
    @peablog
    阿里云 ecs 最低配置 vps 测试单核 1g 内存
    进行 10 万次 13kb 大小的数据循环加解密
    耗时约 12s
    处理速度:约 105MB/S
    每毫秒处理速度约 107kb
    按照平均每个网页加载 20 个 13kb 大小的页面算,多消耗 2.4 毫秒 按 100 个(1.3MB)算增加 12 毫秒

    这个性能损失个人认为是可以接受的,比起网络传输性能损失微不足道
        48
    liexusong   2016-06-29 15:03:44 +08:00
        49
    rekulas   2016-06-29 15:31:26 +08:00
    @liexusong 我之前已经看到过了 刚刚买了你的书 没想到你也在 v2 潜水
        50
    rekulas   2016-06-29 15:33:39 +08:00
    @liexusong 能加好友吗
        51
    liexusong   2016-06-29 17:08:06 +08:00
    @rekulas 加 QQ : 280259971 吧
        52
    rekulas   2016-06-29 17:29:07 +08:00
    @liexusong 我已经加了 下午加你的那个就是我
        53
    firebroo   2016-10-24 16:28:45 +08:00
    很容易破啊。。 ida 逆向一下你的 so ,分分钟找到 key 。。
        54
    rekulas   2016-12-04 22:55:09 +08:00
    @firebroo 又不是防服务器破解的,要防服务器破解可没这么简单。可以把解密程序装载到内存,一旦检测到异常登录就清除,至少除了机房托管公司没有人能够破解了。
        55
    whj   2018-07-11 13:46:57 +08:00
    另外起个拓展 也接管 zend_compile_file,直接就能输出解密后的原始文件了?
        56
    solaro   2018-07-27 17:09:57 +08:00
    用起来了,好屌
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2402 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 28ms · UTC 14:11 · PVG 22:11 · LAX 06:11 · JFK 09:11
    ♥ Do have faith in what you're doing.