本文章较长,建议收藏
以便后续学习实战时可以用上
黑战士
关注网络安全,为网络安全而战
直接使用别人的靶场总感觉不太好,那么就干脆自己写一个自己的文件上传靶场吧。正好博客之前也没有单独总结过文件上传的知识点,那么就顺便水一篇文章,岂不是一举两得。当然关于文件上传 upload-labs 总结的比较全面了,非强迫症患者建议直接去刷 upload-labs ,本文很多核心代码也都是直接用了 upload-labs 的轮子的…
前言
国光有一台 XPS15 里面运行着 macOS 和 Ubuntu 双系统,其中 XPS 主要系统就是 Ubuntu,国光在 Ubuntu 里面搭建了一个离线的 CTFd 里面还运行着 Docker、宝塔。基本上很多服务都可以在我的 XPS 上运行起来了,出去讲课的时候会带着我的 XPS 和 MBP 一起,离线靶场一开美滋滋,更关键的是往自己的靶场里面填充题目有一种养成游戏的感觉,很有成就感。
又因为最近出书的问题,需要一个自己的靶场,那么就顺便开发一个自己的文件上传靶场吧,从简单到复杂根据自己的上课节奏来,开发完顺便放到 CTFd 中。本文写详细一点的话就可以做我自己靶场的官方 WP 了,也方便学生们课后自己消化吸收。当然如果也可以帮助到看到本文的其他朋友的话,这篇文章也变得就更加有意义了。
目前靶场一共有 13 题,感觉基本上的上传姿势点都覆盖了,除了 Windows 下的 点、空格、::$DATA 特性没有覆盖到,其他的感(这个偷懒理由针不戳!)
靶场部署
DockerHub 项目地址:https://hub.docker.com/r/sqlsec/ggctf-upload
Github 项目地址:https://github.com/sqlsec/upload-labs-docker
BASH
代码语言:javascript复制# 进入项目文件夹
cd upload-labs-docker
# 一键部署运行
docker-compose up -d
默认 13 个关卡运行的端口为 30001-30013 这 13 个端口上,如果要自定义端口信息的话,自行修改 docker-compose.yml 文件即可。
一共 13 个 Docker 容器,可能第一次部署需要一定的时间,有点硬伤, 耐心等待一下即可
本项目的优势:
- Docker 一键部署很方便,可以灵活的导入到 CTFd 中
- 题目更侧重于教学,注重对选手解题的引导,而不是一味地刁难选手
- 配套保姆级 WP,妈妈再也不用担心不会解题啦
- 前端界面在同行的衬托下没有那么丑
JS
国光认为好的题目就应该让选手在做题的时候给予线索引导,让他们可以从题目中真正学到些什么。
如何判断是否是前端验证呢?首先抓包监听,如果上传文件的时候还没有抓取到数据包,但是浏览器就提示文件类型不正确的话,那么这个多半就是前端校验了:
解法一:抓包
因为是前段验证的问题,可以直接将 shell.php 重命名为 shell.png 上传抓包的时候再将文件名修改为 shell.php 即可绕过前段限制,成功上传 webshell。
解法二:禁用 JS
因为 JS 来校验文件后缀的原因,所以可以直接在浏览器上禁用 JS 这样就可以直接上传文件了。Chrome 内核的浏览器在审查元素的状态下可以找到 Settings 选项,然后找到 「Debugger」 选项下面直接勾选 「Disable JavaScript」即可。
解法三:调试 JS
这种解法就类似于孔乙己中的茴香豆的 「茴」有几种写法?,纯粹就是为了炫技,但是并不实用,那么国光下面就简单说下调试 JS 的过程吧。
首先审查元素下下断点:
单行单步调试,找到 whitelist
变量,双击元素然后直接修改数组元素的值 :
放掉数据包,之前的 shell.php 可直接上传成功:
成功拿到根目录下的 flag:
MIME
这样下去感觉上课都不需要 PPT 了,关键姿势点都直接贴在了题目中了:
因为提示了 MIME 类型校验,所以抓取上传的数据包然后直接修改 Content-Type
类型为:image/png
等合法的类型即可:
文件头
本题配图中里面包含了 GIF89a 已经很明显了,答案就在题目中:
本题校验了图片的文件头也就是校验图片内容的,这个时候使用一个标准的图马是可以成功绕过的,由于国光的这个代码只校验了前面几个字节,所以直接写 GIF89a 即可成功绕过:
缺陷的代码 - 1
本题的图片上的第 2 行代码是一个有缺陷的代码,黑名单关键词替换为空的操作是一种不安全的写法:
因为代码开发者的错误写法,这种情况下可以直接使用嵌套后缀绕过:
缺陷的代码 - 2
本地属于理论上漏洞,因为题目环境是 Docker 容器运行的 Linux 系统,所以本题国光修改成了 Windows 的特性
同理图片提示中的第 2 行代码也是有缺陷的,可以仅用了 str_replace
替换,这样很容易就被大小写绕过,因为 Windows 环境下不区分大小写,所以就可以让 .PHp 当做 .php 来解析了,但是 Linux 下这种大小写如果的话完全没作用,所以本题是国光自己造的漏洞,用来伪造 Windows 环境下的大小写不区分的情况:
黑名单
本题同样题目的配图中暗示已经比较明显了,默认情况下 Apache 把 phtml、pht、php、php3、php4、php5 解析为 PHP:
那么这里 Fuzz 一下,发现这些稍微冷门的后缀都可以直接绕过:
解析规则
本题的暗示也已经很明显了,只要选手查询 htaccess 怎么解析的话,就可以很顺利的解题:
因为题目是考擦 htaccess 这个上传知识点,所以先准备一个解析规则:
BASH
代码语言:javascript复制$ cat .htaccess
AddType application/x-httpd-php .png
然后先上传这个 .htaccess 文件到服务器的 upload 目录下:
这表示将 upload 目录下的所有 png 图片都当做 php 来解析,然后再上传一个 shell.png 即可:
此时这个 shell.png 就已经被当做 PHP 解析了:
古老的漏洞 - 1
本题依然在题目中科普了 00 截断是啥,以及 00 截断的利用条件:
00 截断多配合路径来截断,我们来抓包看看应该是存在路径信息的,然后直接在路径后面使用 来截断一下就可以成功绕过,为啥 直接就可以绕过了呢?这是因为路径信息是从 GET 方式传递个后端的,这样默认会进行一次 URL 解码, 解码后就是空字节:
这样保存的文件名就是这样的效果:
BASH
代码语言:javascript复制/usr/local/apache2/htdocs/upload/new.php shell.png
因为