PHP 8.4 发布,包含属性钩子、无需额外括号的类实例化等
hello呀,朋友们。许久不见了,因php8.4的发布,特回归我的头条来为php做做宣传。其实有看到很多关于php的评论,其中最多的评价都在说PHP老了,无法媲美正火的几种编程怨言,坚持就要饿死。有个评论感概到:“廉颇老矣,尚能干?”。小编看后,也有些许思考。不过,我很快有了自己的看法:凭我之实力和经验,虽也有不同语言开发经历,但没法去定论php是否软了,也不能说坚持走这条路要饿死,存在即合理,每个人认知和接触领域不同,在我认知的领域却发挥着重大作用,身边很多人也靠它吃饭。所以,小编希望它越来越好。
回归正题,小编放了最新的排行榜,从11月的编程语言排行榜来看,php活跃度有所增长。借着,我们来聊聊8.4给我带来了哪些特性吧。
PHP 团队发布了 PHP 8.4,其中包含新的数组查找函数、属性挂钩、无需额外括号的类实例化等:
- PHP 8.4 中的新数组查找函数 (RFC)
- PHP 8.4 中的属性挂钩 (RFC)
- PHP 8.4 中无需额外括号的类实例化 (RFC)
- 新 mb_trim 函数 (RFC)
- 新 mb_ucfirst() 和 mb_lcfirst() 函数 (RFC)
- PHP 8.4 中的非对称属性可见性 (RFC)
- 还有更多…
具体可看RFC:https://wiki.php.net/rfc#php_84
现代 PHP 历史上最大的变化之一:能够定义属性钩子,从而无需大量样板代码。属性钩子受到 Kotlin、C# 和 Swift 等语言的启发,其语法包括两种类似于短闭包和多行闭包的语法变体:
案例1
属性钩子的目标是通过允许每个属性定义自己的 get 和 set 钩子来删除大量的 getter 和 setter。钩子是可选的,您不必在特定属性上同时添加它们。例如,只有 get 钩子的属性是虚拟属性。
案例2
属性钩子将有助于消除属性 getter 和 setter 的样板,允许属性使用钩子定义访问和更新。
PHP 8.4 将附带新的数组查找函数,包括:
- array_find()
- array_find_key()
- array_any()
- array_all()
array_find()
PHP 8.4 中添加了一个非常简单的新函数,我想大多数开发人员已经习惯了第三方集合类,看着很亲切,和array_filter()也有相似之处。
array_find 返回 $callback 返回 true 的第一个元素的值。如果未找到匹配的元素,则函数返回 NULL:
由于引入了实例化期间的成员访问,因此必须将 new MyClass() 调用括在括号中,否则会出现解析错误。建议的语法将允许您访问常量、属性和方法,而无需额外的括号:
此更新修复了 papercut,使类成员访问变得更简单,无需添加括号或使用静态构造函数方法。此语法更改还使 PHP 与其他 C 语言(如 Java、C# 和 TypeScript)更加一致,这些语言不需要括号。
在 PHP 8.4 中,使用新的 createFromTimestamp() 方法从 Unix 时间戳创建 DateTime 将更加方便。它将支持典型的 Unix 时间戳以及包含微秒的时间戳:
在早期版本的 PHP 中,有几种方法可以根据时间戳创建 DateTime 实例,例如 createFromFormat() 方法:
PHP 8.4 的另一个突破性功能是不对称可见性。不对称可见性允许类属性根据读取或写入上下文定义其可见性(公共、受保护或私有)。不对称可见性的最常见示例是只能在类内部更改的公共属性。这样的属性如下所示:
因为“只能在私有上下文中更改的公共属性”是不对称可见性的最常见用例,所以也有可用的简写:
当然,你也可以使属性仅在受保护的范围内可写:
当然,该语法也适用于提升的属性:
PHP 很早就有 trim、ltrim、rtrim、ucfirst 和 lcfirst 函数,现在 PHP 8.4 为这些函数添加了 mb_ 多字节字符串支持。
- mb_trim()
- mb_ltrim()
- mb_rtrim()
- mb_ucfirst()
- mb_lcfirst()
PHP 8.4 添加了 \\Dom\\HTMLDocument 类,该类能够正确解析 HTML5 代码。旧版 \\DOMDocument 类仍可用,以实现向后兼容。
< 8.4
PHP 8.4 改变了 JIT 的启用方式。以前,您必须将 opcache.jit_buffer_size 设置为 0 才能禁用 JIT,但现在您可以像这样禁用它:
用户唯一会受到此更改影响的情况是,他们指定了 opcache.jit_buffer_size,但没有指定 opcache.jit。在这种情况下,您必须添加 opcache.jit=tracing 才能再次启用 JIT。
最后,JIT 也进行了一些改进,在某些情况下,JIT 的运行速度更快,并且占用的内存更少。
PHP 8.4 添加了对惰性对象的原生支持,这是框架用于构建代理对象的常见模式。
总之,8.4带来了很多新特性,更多内容参考:https://www.php.net/releases/8.4/zh.php。同时,本文内容参考自:
- https://www.php.net/releases/8.4/zh.php
- https://laravel-news.com/php-8-4-0
- https://stitcher.io/blog/new-in-php-84
php免杀合集(提高安全软件应变策略,严禁违法违规操作)
严正申明:请遵守法律法规,文章旨在提高安全软件的应变策略,严禁非法使用,后果自负。
可以看到这里非常简单的混淆就能绕过安全狗
可以看到这简单的混淆是无法绕过宝塔的
但是如果我们不使用敏感函数作为参数的话
还是可以发现其实只是过滤参数里的内容,其实依旧比较好绕过,下下面的字符串处理中,我们会使用到函数来进行流量加密和代码加密
在这里我们使用base64加参数加密
可以看到绕过,成功了。。。。。可以看到对于收费的waf而言依旧比较好绕过,其实在webshell上的查杀大部分都是在于规则上的匹配,对于php而言如果想绕过的话基本上都是\”功夫不负有心人\”,只要去花时间都是可以绕过的。如何在根本上去减少webshell带给服务器的危险,其实直接禁用一些关键函数,和不使用有危险的扩展是非常有效的方法。虽说现在我们已经绕过了常见的waf,但是在真正的渗透中,目标都使用的是更高级的云waf,不但规则更新的比较快而且,还会将被拦截webshell进行记录,存在被溯源,和绕过的新思路被发现的可能,因此学习更多的混淆技巧,是比较重要的。
接下来讲解一下不常用的函数
可以看到这里解压后的内容变成了一堆乱码,在这里值得注意的是,如果我们利用方式依旧像base64一样是行不通,因为这一串乱码是无法提过字符串的形式准确的返回给服务端的
这里笔者提供两个思路:
1.base64编码
再次利用base64编码,如果没有经验的兄弟可能会认为这是多此一举,我直接用base64不就完了么,其实在真正的对抗当中,很多安全设备是可以识别base64编码的,可以自动解码判断解码后的内容。这一不其实就是为了,防止被解码后,内容被识别
2.伪装成文件,以二进制方式传输
这种发送迷惑性比较大,很少有waf会去识别二进制流中的内容,顶多就是一些简单的正则表达式去匹配一些字符串,乱码根本就不全去识别
由于不能直接防止粘贴,因此需要在本地生成二进制文件
在本地搭建一个上传页面只为获取数据包
源码如下
可以看到这些后缀和mime这些都是文件上传的敏感点,只要我们不去触发的话,waf还是会对我们很信任的
可以看到这里执行了phpinfo,关键在于这串字符是非常难解析的,一般的waf是无法解析出来的
如果有经验的同学可能会觉得这个和hex2bin非常相似,其实pack函数比hex2bin强大得多
语法:
此函数提供了多中格式,可以将文件或者流量变得更加复杂
openssl_encrypt方法详解:
openssl_decrypt方法详解:
函数基本使用:
实际利用:
这种方式也比较简单,在很多ctf题目中都喜欢考与,或,取反,异或等进行绕过,其中可以直接用他们进行加密操作,当然如果学过密码学,一些简单的加密方式其实也行,凯莎密码,维吉尼亚密码,替换加密等都是可以尝试的,但是更复杂的算法还是建议,能使用现成的扩展就直接用,没必要花太多时间去研究这些算法。
下面就以异或加密为例:
在看一下vt的查杀率
可以看到这没有一个查出来,讲了这么多,大家其实已经发现的webshell的免杀远比木马免杀容易得多,其实我们的目光不能再放在什么某狗,某盾,某塔,这些waf上,应该将目标定为于新型的云waf上。当然这只是免杀的一部分,后面还有继续讲解其他免杀方式。
在这里解释一下为什么,需要讲述传参方式,由于在很多情况下,以请求头作为参数传递并非waf和人工排查的重中之重且非常误导和隐藏,下面就是常用的几种方式
由于Cookie基本上是每个web应用都需要使用到的,php应用在默认情况下,在Cookies请求头中会存在一个PHPSESSID=xxxx这样的cookie,其实这个就可以成为我们的传参位置
使用burp抓包
将内容改成base64加密后的命令
可以看到已经执行成功了,可以看到这个迷惑去非常强,如果不仔细排查是不容易发现的,由于webshell的session和网站本身业务并没有关系,所以这个PHPSESSID可以随意修改
session的传参方式其实算是一种间接传产方式,由于session的内容是需要通过源码设置的,并不能想cookie一样直接在请求头中修改,因此需要准备两个文件,一个是将输入的参数传入session,另一个就是将session中的内容取出并执行命令
这里依旧沿用上面的cookie传参
给session传入参数
取出session内容并执行,其实下面的代码是可以直接插入到正常页面中的,增加迷惑性,因为一般正常页面返回的html代码是比较多的,如果我们将内容回显的正常页面当中是比较难发现的
在test.php下通过cookie添加session,注意这个PHPSESSID的值其实就是一个session文件,每当有一个新的sessionid都会生成一个新的session文件,因此这个文件名我们是可以随意修改的,在这里的sessionid不但是文件名,而且也是我们的base64加密后的命令,这里只需要了解一下即可
访问命令执行的页面,并添加其cookie,即可跨页面传递参数,如果用这种方式传参是比较难发现的
总结:session传参其实就是一种参数转移的感觉
自定义请求头其实也是作为一种伪装的请求方式,你可以选择完全自定义一个请求头进行参数传递,但是很多waf也会检测一些没出现过的请求头容易被识别出来,且一旦在日志中被找到一个以这种方式传参,很容易就能查找到使用数据包,还是不稳当,与cookie相比,cookie本身就是一堆随机数不好区分
在这里为什么我会将特征绕过,而并没有像其他博客上写的那些,整一堆混淆的方法,原因就是因为,waf毕竟还是通过特征判断的,只有知道了,waf匹配的正则表达式大概是什么样的,webshell的免杀有真正的意义
看这个特征可以发现很明显的是一个获取参数的语句,但为什么我会将起列举出来了,因为在很多情况下,现在的web应用大多都是使用的框架,基本上所有的获取请求参数内容的方法都是经过框架封装过的,最原始的获取参数内容的方式已经非常少见了,很容易通过一些命令如linux下的find命令通过正则表达式即可找到对应的webshell,很容易被发现,因此不使用该特征是很有必要的
使用{}来替代[]是在ctf中十分常见的绕过方式
利用复合变量加foreach,获取参数中的内容,其特点并没有[],不容易被识别
使用自定义的请求头同样是没有上面的特征
这个特征大致就是某盾,某狗等的正则表达式匹配的内容,只要去消除此特征即可免杀
该原理就是\”\”中的变量不会被当做字符串使用,会被解析,经过测试该方法基本失效
可以用到的4种魔术常量
以上的4种基于魔术常量的免杀webshell都是可以绕过某盾的
当然在实战种还是要像上一篇文章一样,将传入的参数进行加密处理,如果再把传参方式改为cookie的那就很完美了
顾名思义,就是将一个马拆分成两部分,及使用file_get_contents()将内容读取出来,为什么不使用include等这些文件包含函数了?因为webshell的免杀在于动态函数的调用,最终还是要拼接在一起,绕过的原则其实就是绕过waf的正则表达式,如果直接include其实和写在一个文件里没啥区别
这种方式和sql注入差不多,原理就是php允许在括号中添加注释符和空白符并不会影响代码正常运行
这里方式可以绕某狗,但过不了某盾
反射类及反射类方法
通过属性名免杀
通过注释免杀
类方法调用
类的静态方法
webshell的免杀前提是要分析出waf大概的规则,如果盲目尝试是无法有更快的提示,正所谓大道至简,本文以最简单的代码解释了免杀的方法,原理以及waf背后的逻辑,对于更高级的waf,本文列举了很多种方法,在必要的时候是需要将多种方法合并使用的,以达到最好效果,最后有的绕过方式实在是太老了就没必要讲,如无特征马说是无特征,但这所谓的无特征就是它的最大特征,物联网是人类创造的,所有的东西都满足人类逻辑,不要死记硬背那些复杂的免杀马,只有清楚背后的逻辑才能真正的有所提升。
这里是利用phpjiami网站进行加密,进而达到加密效果
https://www.phpjiami.com/
加密前:
查杀效果
可以看到这里D某和某狗都查杀里用php加密后效果
查杀效果
可以看到这里只有D某会显示加密脚本,而某狗直接绕过
http://dezend.qiling.org/encrypt.html
免杀效果
可以看到dezend加密的特征还是太过明显
https://z5encrypt.com/encrypt/build
工具下载https://github.com/naneau/php-obfuscator在线工具https://www.phpobfuscator.cn/
不太行
工具下载https://github.com/pk-fr/yakpro-po在线工具https://www.php-obfuscator.com/?demo
免杀效果
并不太行
http://www.phpjm.net/encode.html
加密后效果
免杀效果
工具下载https://shell.virbox.com/apply.htmlVirbox已经属于是商业源码加密,基本上没有任何特征但是由于这个是需要将生成好的php-cqi.exe原有的php-cqi.exe才能达到解密的效果,因此只能说作为一个权限维持的方式,先拿到权限后,修改php-cqi.exe,在上这种加密马,作为一个权限维持
加密过程:https://baijiahao.baidu.com/s?id=1671004157804653895&wfr=spider&for=pc
以上总结了webshell加密的工具,其实在非扩展的加密工具中,其原理很多就是混淆变量名和函数名,类名,命名空间等等,可以配合多个加密工具进行多种加密,当然也可以和之前文章的免杀进行结合
由于很多企业为了防止源码泄露,都会使用加密扩展将代码进行加密,那么我们就可以就将计就计,将webshell也利用扩展加密,将特征消除,从而达到免杀的效果
扩展地址https://github.com/liexusong/php-beasthttps://github.com/imaben/php-beast-binaries下载dll,并添加至ext中
在php.ini 中添加该扩展
当然也可以不使用默认密钥在aes_algo_handler.c中可以修改默认密钥
当然如果没有密钥其实是无法生成一个能被解析的php文件,因此还需要通过逆向获取dll中的密钥
破解参考:http://www.phpheidong.com/blog/article/337644/71c2cabcc769f99d7808/
环境搭建https://blog.oioweb.cn/64.htmlhttps://newsn.net/say/php-screw-plus.html
破解参考:https://www.cnblogs.com/StudyCat/p/11268399.html
基于扩展的免杀,如果知道密钥,经加密后的webshell是不具备任何特征的,基本上直接通杀。具体步骤通过phpinfo获取扩展信息,根据不同的加密扩展进行尝试利用默认密钥进行加密,通过访问webshell来判断密钥是否正确,当然,这种方法其实只能用于权限维持需要拿到权限后获取扩展文件破解后,才能稳定获取密钥,进而加密webshell
array_map_recursive函数分析
这里存在一个call_user_func命令执行函数
免杀效果
免杀效果
B函数分析
exec函数分析
在exec函数用存在有个类调用,且所有的参数都可控
免杀效果
smarty_php_tag函数分析
直接存在命令执行,且参数可控
免杀效果
免杀效果
eval命令执行函数,参数可控
免杀效果
存在一个eval函数
免杀效果
免杀效果
通过文件包含框架文件,用框架内置的函数来替换一句话木马中的功能函数,达到绕过特征匹配,如果后期规则增强,可以通过搜索新的函数来间接调用函数,像反序列化利用链一样,当然,还有很多其他函数可以使用在这里就不多列举。
refer https://tttang.com/archive/1740/
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。