array(1,2,3)is_numeric检测变量是否为数字或数字字符串$input = array('2',2,3);
echo is_numeric($input[0]);// 可以通过类似2025abc的绕过,这让其既不是数字也不是数字字符串,但是比较大小时2025abc>2024
// 注意16进制的内容 如何0x12,is_numeric返回false,即不认为其是数字或数字字符
// 结果:1
生成随机数:echo rand(1,5);表示生成1-5范围内一个随机的数字
脚本睡眠:sleep(2)表示当前脚本睡眠2秒
检查变量是否已设置并且不为NULL:echo isset($input);
输出一条结束消息同时退出脚本:die('end...000');
md5加解密:
// 情况一:md5相等,但两值不相等的情况
//解释:在CTF常常遇到这样的题目if($v1 != $v2 && md5($v1) == md5($v2)),v1和v2不能相等,但是他们的md5值还要相等,此时利用到==判断会自动类型转换的问题
比如v1=240610708 v2=QNKCDZO
他们的md5 v1=0e462097431906509019562988736854 v2=0e830400451993494058024219903391
因为:0exxx意思为0的xxx次方,它们结果都为0(科学计数法)
// 情况二:md5函数无法正确解析数组(===强比较会成立)
//解释:在CTF常常遇到这样的题目if($v1 != $v2 && md5($v1) == md5($v2)),v1和v2不能相等,但是他们的md5值还要相等
此时如果$v1=['1'] $v2=['2']
此时md5($v1) === md5($v2)是成立的(strcmp也有这种情况)
//示例(没有@时不会报错,否则复现的时候就报错了但也会输出结果):
if(@md5(['1','2'])===@md5([])){ echo '相等';}
// 注意php get参数传递数组格式:http://114.67.175.224:11551/uname[]=1
函数特点:当传输参数不符那个函数的返回值就会为NULL
调用函数:call_user_func_array($functionName, $parameters)可以根据自己需要调用函数
// call_user_func('system','ls');其能够调用系统命令
function myFunction($param1, $param2) {
// 执行一些操作
}
$functionName = 'myFunction';
$parameters = array('parameter1', 'parameter2');
call_user_func_array($functionName, $parameters);
// 在上面这个例子里面call_user_func_array调用了myFunction这个函数并向其传递了参数
对字符串进行ROT13编码:str_rot13($s)
// (原理在字母表中选择当前字母13位后的字母,类如对a进行编码,输出为n)
echo str_rot13('a'); //结果n
echo str_rot13('n'); //结果a
//由上可知解码只需要再执行一遍即可
获取字符串ascii码:ord
echo ord('a'); //结果97
将数字转换为ascii对应字符串:
echo chr(97);//结果a
正则匹配函数:preg_match(pattern,content,result)pattern表示匹配规则,content表示需要进行正则匹配的内容,result是匹配结果(数组)preg_match只找第一个匹配项目,preg_match_all()函数用于找到所有匹配项并返回结果
// 注意点:"/world/i"这个i表示大写WORLD或小写world都会匹配,如果没有i就是精确匹配(比如黑名单里面有select(即服务端会去匹配用户输入是否包含select)我就可以通过SELECT绕过)
if (preg_match("/world/i", "Hello World!", $matches)) {
echo "找到匹配项!";
print_r($matches);
} else {
echo "未找到匹配项!";
}
过滤和替换:$out=preg_filter(pattern,content,str)pattern表示匹配规则,content表示将匹配到的内容的位置替换为何内容,str表示对哪个字符串变量进行正则替换操作,过滤后的内容会赋值给$out
//下面的例子演示了preg_filter的语法,也展现了,写两遍()避免被过滤达到执行代码的效果
$str='echo getcwd(());';
$pattern = '/\(\)/';
$replacement = '';
echo $str;//echo getcwd(());
echo '*';
$out = preg_filter($pattern, $replacement,$str);
echo $out;//echo getcwd();
echo '**';
echo eval($out);//C:\phpstorm\test
截取:mb_substr(字符串,开始位置,长度)
$str = "Hello, World!";
$substr = mb_substr($str, 0, 5);
echo $substr; // 输出:Hello
字符串位置:mb_strpos(字符串,需要寻找的字符,开始的位置)
$str = "Hello, Hello, World!";
$position = mb_strpos($str, "Hwello", 7);
echo $position; // 输出:13 找不到返回false
//安全问题
//解释:下面的内容heo在hello第一次出现的位置是0,就会导致0==false
<?php
$str1 = "hello";
$str2 = "heo";
if(strpos($str1,$str2)==false)
{
echo "flag";
}
?>
替换:str_replace(需要替换的内容,替换为的内容,字符串)(区分大小写)
//安全问题:可以通过双写或者大小写进行绕过如下例子
$str = "Hello, worworldld!";
//$str = "hello, WORLD"; 因为区分大小写,这个WORLD并不会被替换
$newStr = str_replace("world", "", $str);
echo $newStr; // 输出:Hello, world!
查找:strstr(字符串,字串)(区分大小写;stristr不区分大小写)
$str = "Hello, World!";
$str1 = "";
$substring = "World";
$result = strstr($str, $substring);
echo $result; // 输出:World!
// 找不到返回false
比较:strcmp(字符串1,字符串2);(它逐字节比较两个字符串,并返回一个整数。如果两个字符串相等,strcmp 函数返回0;如果第一个字符串小于第二个字符串,strcmp 返回负数;如果第一个字符串大于第二个字符串,返回正数)
$str1 = "Hello World";
$str2 = "hello world";
$result = strcmp($str1, $str2);
if ($result == 0) {
echo "The strings are equal.";
} else if ($result < 0) {
echo "str1 is less than str2.";
} else {
echo "str1 is greater than str2.";
}
// 安全问题:当对比字符串与数组或者数组与数组时,strcmp都会返回0(@符号避免其报错(报错不会影响其运行))
if(!@strcmp(['1','2'],1)){
echo '相等';
}
返回内容下标:array_search('name',$a);返回内容下标(参数一查找内容,参数二查找函数,可设参数三设true这样对比为’==='而不是 ‘==’)
// php绕过
// 解释array_search在$bug数组里面寻找对比"bug",但是使用的是==号,此时$bug=array(0)即,"bug"==0的,想要避免可以在array_search加第三个参数为true即可
$bug=array(0);
$a=array_search("bug", $bug);
$a=== false?die("die"):NULL;
foreach($bug as $key=>$val){
$val==="bug"?die("die....."):NULL;
}
echo 'youflag';
//输出:youflag
是否在数组中:is_array('name',$a);不在数组返回false参数一查找内容,参数二为数组
//php绕过,解释如上
$bug=array(0);
$a=in_array("bug", $bug);
$a=== false?die("die"):NULL;
foreach($bug as $key=>$val){
$val==="bug"?die("die....."):NULL;
}
echo 'youflag';
//输出:youflag
html过滤
解释:htmlspecialchars($url)本质上是为了安全,其能将以下字符进行转码(单引号不会被转码),避免xss的发生,但是htmlspecialchars不是绝对安全,还要取决与上下代码环境,如下面例子
// 下面点击Link将弹出XSS
$url = 'javascript:alert("XSS")';
echo '. htmlspecialchars($url) . '">Link';
HTML、XML 以及 PHP 的标签过滤
解释:strip_tags(字符串,要保留的内容)剥去字符串中的 HTML、XML 以及 PHP 的标签,第二个参数是过滤时,不删除某标签,如下例所示
$str = "This is a link to a website.
";
$clean_str = strip_tags($str,''
);
echo $clean_str;//结果:This is a link to a website.
在预定义的字符前添加反斜杠
解释:其会在\ " '前面加入反斜杠,避免通过引号闭合,造成问题
$str = "It's a beautiful day!";
$escapedStr = addslashes($str);
echo $escapedStr;//It\'s a beautiful day!
//在上述示例中,原始字符串是 "It's a beautiful day!"。调用 addslashes 函数后,单引号被转义为 \',从而避免将其解释为字符串的结束标记
// 但是在注入过程中遇到addslashes还是有解决办法,例如下面这种情节,通过不输入引号,直接在内部再次调用eval函数
$val="${eval($_GET[1])}&1=phpinfo();";
eval('$value="' . addslashes($val) . '";');
include:使用 include,你可以将包含其他 PHP 文件的代码插入到主文件中,从而在执行期间将这些文件和主文件合并为一个整体(多次引用会多次执行)
a文件
$flag=123;
?>
b文件
include 'a.php';
echo $flag;//123
?>
require:require 函数与 include 关键字类似,也用于将外部文件包含到当前文件中。但与 include 不同的是,当被包含的文件不存在或路径不正确时,require 会生成一个致命错误,并终止脚本的执行(多次引用也只会引用一次)
highlight_file:让代码高亮显示,highlight_file(要显示的文件,返回值)
$filename = "myfile.php";
$highlightedCode = highlight_file($filename, true);
echo $highlightedCode;
?>
file_get_contents:把整个文件读入一个字符串中
$filename = "a.txt";
$content = file_get_contents($filename);
echo $content;// a.txt的内容
file:把整个文件读入一个数组,数组中的每个单元都是文件中相应的一行
$filename = "a.txt";
$content = file($filename);
echo $content;
print_r($content);
$var_array = array("color" => "blue",
"size" => "medium",
"shape" => "sphere");
extract($var_array);
echo $color . $size . $shape;
// bluemediumsphere
extract($_GET)
http://127.0.0.1/?user_name=123
// 执行后
echo user_name; // 123
// 简单绕过
// 比如过滤_
// 我们可以http://127.0.0.1/?user name=123或http://127.0.0.1/?user[name=123
// 因为变量名正常不能如user name或user[name一般,有错误时,执行extract函数都会自动转换为user_name
eval:执行php语法内容(通过php也能执行系统命令)
eval('echo 1;')
// 输出 1
eval和assert都有一个要注意的点如下
eval('$value="' . '";');
1.可以用字符串拼接
2.$val="${eval($_GET[1])}&1=phpinfo();";使用${}(在eval里面遇到addslashes过滤函数的情况)
exec:直接执行系统命令,执行结果会返回给php
exec('ipconfig', $result);
var_dump($result);
// 输出 0 => string '' (length=0)
1 => string 'Windows IP ����' (length=15)
2 => string '' (length=0)
3 => string '' (length=0)
4 => string '���߾����������� ��������* 28:' (length=30)
5 => string '' (length=0)
6 => string ' ý��״̬ . . . . . . . . . . . . : ý���ѶϿ�����' (length=53)
7 => string ' �����ض��� DNS �� . . . . . . . :' (length=38)
8 => string '' (length=0)
9 => string '���߾����������� ��������* 31:' (length=30)
10 => string '' (length=0)
11 => string ' ý��״̬ . . . . . . . . . . . . : ý���ѶϿ�����' (length=53)
12 => string ' �����ض��� DNS �� . . . . . . . :' (length=38)
13 => string '' (length=0)
14 => string '��̫�������� ��̫��:' (length=20)
15 => string '' (length=0)
16 => string ' ý��״̬ . . . . . . . . . . . . : ý���ѶϿ�����' (length=53)
17 => string ' �����ض��� DNS �� . . . . . . . :' (length=38)
18 => string '' (length=0)
19 => string '���߾����������� WLAN:' (length=22)
20 => string '' (length=0)
21 => string ' �����ض��� DNS �� . . . . . . . :' (length=38)
22 => string ' IPv6 ��ַ . . . . . . . . . . . . : 2408:841e:410:3a93:511e:9cf3:9989:3565' (length=77)
23 => string ' ��ʱ IPv6 ��ַ. . . . . . . . . . : 2408:841e:410:3a93:1c15:66d3:f014:32ae' (length=77)
system:也能直接执行系统命令,执行内容会直接打印输出出来
$command = 'ipconfig';
system($command);
Wireless LAN adapter ��������* 28:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Wireless LAN adapter ��������* 31:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Ethernet adapter ��̫��:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Wireless LAN adapter WLAN:
assert:断言一个表达式的真实性
// 危险在于字符串可构造类似eval,例如下面$name是用户输入的
$name = 'flag.php';
// 意思是检查$name有没有php字符串如果有就die执行停止,否则包含某文件
assert("strpos('$name', 'php') === false") or die("die!!!");
require_once $name;
// 恶意构造
$name = 'flag.php\',\'123\')===false and system(\'ipconfig\') and strpos(\'2';
// 相当于执行了
assert("strpos('flag.php','123')===false and system('ipconfig') and strpos('2', 'php') === false") or die("die!!!");
// 其中system('ipconfig')可以执行任意语句
eval和assert都有一个要注意的点如下
eval('$value="' . '";');
1.可以用字符串拼接
2.$val="${eval($_GET[1])}&1=phpinfo();";使用${}(在eval里面遇到addslashes过滤函数的情况)
preg_replace:用于通过正则表达式进行字符串替换
用法示例:
$string = "Hello World";
$pattern = "/World/";
$replacement = "Universe";
$result = preg_replace($pattern, $replacement, $string);
echo $result; // 输出:Hello Universe
恶意用法(该漏洞存在于php5.5.4以下版本):
1./e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码,并且在preg_replace的正则被触发时会去执行replacement 里面的php代码
例如:preg_replace('/cat/e','system("ipconfig")',$data); // 当$data含有cat时,system("ipconfig")将会被执行