0x 01 简介
最近扫描工具扫到一个 Directory Listing,通过分析目录下的文件代码,结合上传覆盖 python 文件和代码中的 “dynamic import” ,获取到了服务器权限。文章没有什么高深的技术,个人觉得蛮有意思,整理了一下当时的利用过程,如有写不对或不准确的地方,欢迎大家指出
0x 02 环境搭建
因为涉及到漏洞,这里对代码做了一些脱敏和精简,环境使用 docker 搭建,代码文件在 github 上,运行以下命令启动环境
运行成功后,访问 http://127.0.0.1:30000/,可以看到有四个文件,分别是
httpServer.py:当前server的代码,是一个 python2 的 SimpleHTTPServer,除了列出目录文件外,还有一些其它接口,后面会分析
log.txt :server 输出日志文件
showDump.py:httpServer.py 中 import 到的文件
upload.html:一个可以上传文件页面
0x 03 接口分析
这里主要分析一下 httpServer.py 中的接口功能,主要代码在 类中的 和 方法中
GET /reload
精简代码:
访问接口会执行 server_path 的 bin 目录下的 脚本,并将执行结果输出到页面
GET /real_time_log?
精简代码:
访问接口,代码会读取 server_path 的 log 目录下,以 为后缀的 log文件内容, 的值为使用 分割 path 后的第一个元素,然后将文件内容输出到页面
GET /del_file_list?
精简代码:
取 path 中 之后的部分,列出目录下的文件,若是目录则显示进入和删除目录链接,若是文件,则显示删除链接
GET /del_file?
精简代码:
取 path 中 之后的部分作为路径(目录或文件),将其删除
GET /show_dump
精简代码:
从 文件中 import 函数 ,并调用执行
do_POST
精简代码:
对应的上传文件接口,使用 和 ,然后写入上传文件
0x 04 利用分析
先理一下环境和现有功能:
后端是一个 python2 的 SimpleHTTPServer
接口能够执行 shell script,但执行的文件路径不可控
接口能够读取文件内容,路径部分可控
能够列出目录下的文件,但无法看到内容
能够删除目录和文件
能够上传文件,上传目录和文件名都可控
从另一个py文件中 import 函数,并执行
因为无法通过直接上传python文件,然后访问url来执行代码,所以需要通过其它方式,这里列举一些当时想到的方式
覆盖shell文件
接口中,虽然执行的shell文件路径不可控,但 可以上传文件,且路径完全可控,可以尝试通过覆盖 shell 文件,再访问 接口来执行自己的 shell 脚本
But,经过尝试后,无法成功,查看 中会有如下错误
因为当前用户是,而 是在 ( 值为 ) 下,属于 用户, 用户没有写权限,所以无法成功
读取文件内容
接口中,读取文件的后缀是可控的,是否可以通过相对路径 ( ) 的方式来进入其他目录?
But,经过尝试后,使用 的方式在这里是不行的,因为 之前的路径必须是目录,且每一个目录都需要存在,可能说的有点不好理解
首先看一下文件目录
再来看几个例子,应该就能理解了
例一: 目录不存在
例二: 文件存在,但不是目录
例三:成功
那么有没办法创建 目录呢?
目录是在 下,没有写权限…
还有就是即使这里可以使用 的方式,细看一下代码,发现是以 的方式读取文件内容,然后输出到页面,所以只能读取到新写入的文件内容。
覆盖py文件
如果是修改 ,然后上传覆盖原有文件呢?
But,并不行,因为代码已经载入内存了,要想让修改后的新代码生效,需要重启 server。
想到覆盖文件,之前 接口中会从 文件 import 函数并执行,与顶层import 的只载入一次不同,这里每次访问接口都会重新从 文件中 import 函数,也就是说,我们可以通过上传覆盖这个文件,只要保持 函数的定义不变,函数内可以执行我们任意的 python代码
反弹 POC
将上述文件保存,然后通过 上传,新文件名填写 ,然后访问 接口
测试成功
领取专属 10元无门槛券
私享最新 技术干货