常用命令或是遇到的函数
1、liunx OS中:
php -i :可以查看PHP的配置信息 <==> PHP命令中的 phpinfo()
find / -name flag* : 查询所有flag开头的文件
cat $(find / -name flag*) : 查看所有以flag开头的文件的内容
2、若是代码中有shtml,则可能是考shtml
(简单来说就是能根据命令动态回显网页的某个部分,比如时间。可以注入,用来远程命令执行。格式:)
<!--#exec cmd="命令"--> 注意<!--#命令-->,主机没有空格
3、basename函数(PHP函数)
basename
可以理解为对传入的参数路径截取最后一段作为返回值,但是该函数发现最后一段为不可见字符时会退取上一层的目录,即:
$var1="/config.php/test" basename($var1) => test $var2="/config.php/%ff" basename($var2) => config.php
3、exif_imagetype (PHP中一个检查图片文件头的函数)
可以在文件第一行添加 GIF89a 进行绕过
5、mt_rand函数(PHP中的伪随机数函数,存在安全隐患)
mt_rand就是一个伪随机数生成函数,它由可确定的函数,通过一个种子
产生的伪随机数。这意味着:如果知道了种子,或者已经产生的随机数,都可能获得接下来随机数序列的信息(可预测性)。

Hg11vtADEm #已知的部分伪随机数 <?php #这不是抽奖程序的源代码!不许看! header("Content-Type: text/html;charset=utf-8"); session_start(); if(!isset($_SESSION['seed'])){ $_SESSION['seed']=rand(0,999999999); } mt_srand($_SESSION['seed']); $str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; #所有可能字符的字符串 $str=''; $len1=20; for ( $i = 0; $i < $len1; $i++ ){ $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1); } $str_show = substr($str, 0, 10); echo "<p id='p1'>".$str_show."</p>"; if(isset($_POST['num'])){ if($_POST['num']===$str){x echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>"; } else{ echo "<p id=flag>没抽中哦,再试试吧</p>"; } } show_source("check.php");
将已知的部分伪随机数转化为php_mt_seed工具可以看懂的数据
str1 ='RqpwmVQF3w' #已知的部分伪随机数 str2 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" #所以可能字符的字符串 result ='' length = str(len(str2)-1) for i in range(0,len(str1)): for j in range(0,len(str2)): if str1[i] == str2[j]: result += str(j) + ' ' +str(j) + ' ' + '0' + ' ' + length + ' ' break print(result)
得到:53 53 0 61 16 16 0 61 15 15 0 61 22 22 0 61 12 12 0 61 57 57 0 61 52 52 0 61 41 41 0 61 29 29 0 61 22 22 0 61
使用php_mt_seed工具得到种子
注意这里对应的php版本,利用种子得到完整字符时需要再对应版本下运行
<?php mt_srand(182345418); $str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $str=''; $len1=20; for ( $i = 0; $i < $len1; $i++ ){ $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1); } echo "<p id='p1'>".$str."</p>"; ?>
即可得到完整伪随机字符串:RqpwmVQF3wbMaZxk9Owt
注意:若是题目中生成伪随机数不止一个,则在我们运行时,也必须安照题目中的代码生成多个伪随机数,才能得到需要的且正确的伪随机数:
<?php mt_srand(1775196155); $str_long1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str=''; $len1=16; for ( $i = 0; $i < $len1; $i++ ){ $str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1); } echo "<p id='p1'>".$str."</p>"; $str1=''; $len1=12; for ( $i = 0; $i < $len1; $i++ ){ $str1.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1); } echo "<p id='p1'>".$str1."</p>"; ?>
以上述代码为例:若$str已知,$str1是我们需要得到的随机数,那么若是我们在生成随机数时,只执行生成$str1的代码(即从$str='' 到$str1=''之前的代码不执行),那么我们得到的$str1是错误的,它实际是$str的部分字符串。
参考:[GWCTF 2019]枯燥的抽奖-CSDN博客 CTF-Web25(php_mt_seed的使用)_php mt seed-CSDN博客
[MRCTF2020]Ezaudit |北歌 (kinsey973.github.io) (多个伪随机数的案例)
PHP在线编译器 - 在线编译工具 (online-compiler.com)(可以选择php版本)
6、addslashes(PHP函数) 及多行注释
$category = addslashes($_POST['category']); $sql = "insert into board set category = '$category', title = '$title', content = '$content'"; $result = mysql_query($sql); #存入数据库 $category = mysql_fetch_array($result)['category']; #从数据库中取出对应参数
addslashes函数会将参数加 \ 进行转义(主要是对单引号,双引号,反斜杠,NULL);但是在将参数的值存入数据库后,转义字符会被去掉,
即参数会被原封不动的存入数据库,不会被转义;我们从数据库中取出来的参数是没有被转义的
注意:$sql部分的sql语句是分行的,所以#,--+等单行注释不能用了,得使用/**/多行注释(好像%00截断也行,没有试过)
如构造:$category:' content=(语句),/*
$content:*/#
参考:[网鼎杯 2018]Comment题解,超详细!_网鼎杯2018 comment-CSDN博客
[网鼎杯 2018]Comment(二次注入,git泄露,git恢复)_[网鼎杯 2018]comment 1-CSDN博客
7、图片检测绕过
finfo_file() :检测图片类型;getimagesize() :检测图片长宽
若是在文件上传中使用了这两个函数检查图片的类型及长宽;可以用如下方式绕过:
利用图片工具,如: Hex Fiend 、Hex workshop等工具将其除文件头部分的所有数据删除,破坏掉文件长宽等其余信息,就可以绕过getimagesize()
函数的检验
以png图片为例,只保留 :89504E470D0A1A0A0000000D49484452
参考:BUUCTF [HarekazeCTF2019] Avatar Uploader 1_[harekazectf2019]avatar uploader 1-CSDN博客
8、parse_url解析漏洞
$keywords = ["flag","manage","ffffllllaaaaggg","info"]; $uri = parse_url($_SERVER["REQUEST_URI"]); parse_str($uri['query'], $query);
当url中出现下面这种情况的url,会解析错误,返回false,就可以利用该漏洞读取到指定文件了
//user.php?page=php://filter/convert.base64-encode/resource=ffffllllaaaaggg
?前多了个 /
原本是:/user.php?page=php://filter/convert.base64-encode/resource=ffffllllaaaaggg
参考:
BUUCTF:[N1CTF 2018]eating_cms-CSDN博客
[N1CTF 2018]eating_cms_mb5fed4c003aebe的技术博客_51CTO博客
9、变量覆盖漏洞
if(!preg_match("/^\w+$/",$args)){ die("args error!"); } eval("var_dump($$args);");
- 正则限制
/^\w+$/
仅允许字母数字下划线字符,但未过滤$
符号的变量引用 eval()
执行了var_dump($$args)
,形成双重变量解析,允许访问任意全局变量- 当
$args="GLOBALS"
时,$$args
会解析为$GLOBALS
超全局数组,泄露所有变量
- 直接获取flag:
?args=GLOBALS
可打印包含flag在内的所有全局变量 - 数组绕过:若正则处理数组异常,可尝试
?args[]=GLOBALS
使preg_match()
返回false - 变量链式访问:若存在其他有用变量,可通过
?args=existing_var
间接获取目标数据