返回
39
0

1

micdy,2025-04-09 16:32

# web

## ez_path

在文章中给出了一个 result.pyc,先对其进行反编译

```python

#!/usr/bin/env python

# visit https://tool.lu/pyc/ for more information

# Version: Python 3.6

import os

import uuid

from flask import Flask, render_template, request, redirect

app = Flask(__name__)

ARTICLES_FOLDER = 'articles/'

articles = []

class Article:

def init(self, article_id, title, content):

self.article_id = article_id

self.title = title

self.content = content

def generate_article_id():

return str(uuid.uuid4())

def index():

return render_template('index.html', articles, **('articles',))

index = app.route('/')(index)

def upload():

if request.method == 'POST':

title = request.form['title']

content = request.form['content']

article_id = generate_article_id()

article = Article(article_id, title, content)

articles.append(article)

save_article(article_id, title, content)

return redirect('/')

return None('upload.html')

upload = app.route('/upload', [

'GET',

'POST'], **('methods',))(upload)

def article(article_id):

for article in articles:

if article.article_id == article_id:

title = article.title

sanitized_title = sanitize_filename(title)

article_path = os.path.join(ARTICLES_FOLDER, sanitized_title)

with open(article_path, 'r') as file:

content = file.read()

return render_template('articles.html', sanitized_title, content, article_path, **('title', 'content', 'article_path'))

return render_template('error.html')

article = app.route('/article/<article_id>')(article)

def save_article(article_id, title, content):

sanitized_title = sanitize_filename(title)

article_path = ARTICLES_FOLDER + '/' + sanitized_title

with open(article_path, 'w') as file:

file.write(content)

def sanitize_filename(filename):

sensitive_chars = [

':',

'*',

'?',

'"',

'<',

'>',

'|',

'.']

for char in sensitive_chars:

filename = filename.replace(char, '_')

return filename

if name == '__main__':

app.run(True, **('debug',))

```

其中利用了 os.path.join 的方法进行路径拼接,但实际上这个方法存在路径穿越漏洞(python 3.6)

例如

```

# os.path.join >>> os.path.join('/micdy/', '../../../etc/passwd')

>

/micdy/../../../etc/passwd

```

这样就可以回溯路径直接访问 /etc/passwd ,达到目录穿越的效果

python 3.6 中此方法还有一个机制,在拼接的过程中,如果某个路径的部分为绝对路径,则会抛弃之前所有的部分,直接使用绝对路劲的部分继续拼接。于是可以使用此方法穿越到任何路径

```

os.path.join('/micdy/home', '/opt/app/')

>

/opt/app

```

在源代码中

```python

article_path = os.path.join(ARTICLES_FOLDER, sanitized_title)

"""

其中对ARTICLES_FOLDER 和 sanitized_title 进行拼接

ARTICLES_FOLDER = 'articles/', 根据源码 title 由我们直接传入。

也对一些非法字符进行替换,但对我们没有什么影响

"""

```

题目也提示我们要穿越的路径

```

<!--secret在根目录f14444文件里面,别忘记了-->

```

路径为根目录,文章路径的拼接为全局变量和我们传入的文章title进行拼接,由于拼接到根目录,所以之前的路径会全部被抛弃

```

os.path.join('articles/', '/f14444')

>

/f14444

```

将上传的title设置为flag路径即可

```

# /f14444

GEEK{d6d4b9c8-d543-420d-8857-a0645d2db109}

Article Path: /f14444

```

暂无回复。你的想法是什么?