文件上传(做完upload靶场的总结)

一、文件上传

1.漏洞成因

具备上传文件功能的Web等应用,未对用户选择上传的文件进行校验,使得非法用户可通过上传可执行脚本而获取应用的控制权限。

2.防护与绕过

1.前端验证

表现:利用js进行前端的验证,一般情况下只是对文件后缀名进行验证,一般判断是否是前端验证的方法可以通过上传不符合要求的文件后是否会弹出浏览器的网页弹窗,若出现,则代表室前端验证。

解决方式:可以利用浏览器自带的设置去设置禁用js,则文件就可以绕过验证直接上传。或者还可以使用bp去抓包修改文件后缀的方法去将前端验证绕过实现上传

例题:upload-labs第一题

2.后端验证

文件头类型验证绕过(也就是bp抓包中的content-type)

表现:对上传文件的文件拓展名进行验证,这种情况无法通过直接去修改文件的后缀名去绕过。

解决方法:使用bp去抓包并且找到content-type这一项,然后去修改成能够上传的类型

常⻅的Content-Type:

• text/html : HTML格式

• text/plain :纯⽂本格式

• text/xml : XML格式

• image/gif :gif图⽚格式

• image/jpeg :jpg图⽚格式

• image/png:png图⽚格式

• application/xhtml+xml :XHTML格式

• application/xml: XML数据格式

• application/atom+xml :Atom XML聚合格式

• application/json: JSON数据格式

• application/pdf:pdf格式

• application/msword : Word⽂档格式

• application/octet-stream : ⼆进制流数据(如常⻅的⽂件下载)

例题:upload-labs第二关

 检测文件头判断文件类型

此时虽然检查的也是文件类型,但是是使用getimagesize()函数来获取文件的MIME类型,此时检测的不是数据包中的content-type,而是图片的文件头,常见的图片文件头如下:

gif(GIF89a) : 47 49 46 38 39 61

jpg、jpeg : FF D8 FF

png : 89 50 4E 47 0D 0A

绕过方法:

当上传php文件时,可以使用winhex、010editor等十六进制处理工具,在数据最前面添加图片的文件头,从而绕过检测

③文件后缀绕过
1.验证黑名单遗漏

文件后缀进行黑名单验证

(1)漏掉一些不常见的后缀,就比如.phtml .php5 .php3,这些都可以起到和.php后缀相同的效果。

例题:upload-labs第三关

(2)其次就还有一种情况是大小写的绕过,有些黑名单中没有将大小写去包含其中,这个时候我们就可以去修改文件后缀中部分字母大小写去完成绕过。

例题:upload-labs第六关

(3)然后就是.htaccess后缀的遗漏

我们可以去先上传一个.htaccess文件,这样就可以使后面上传的图片马被解析为php文件从而实现一句话木马的注入。

笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。
.htaccess内容一般如下:

  SetHandler application/x-httpd-php

图片马的内容一般是:
GIF89a

例题:upload-labs第四关

(4).user.ini.

黑名单所限制的后缀之中没有.ini,这个时候我们就可以使用这种方法。首先先介绍一下.ini相关内容

user.ini : 自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被
   CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用
   .htaccess 文件有同样效果。
   
   除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web
   根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
   
   在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI
   设置可被识别。
   
   两个新的 INI 指令,user_ini.filename 和 user_ini.cache_ttl 控制着用户 INI 文件的使用。
   
   user_ini.filename 设定了 PHP 会在每个目录下搜寻的文件名;如果设定为空字符串则 PHP 不会搜寻。默认值是
   .user.ini。
   
   user_ini.cache_ttl 控制着重新读取用户 INI 文件的间隔时间。默认是 300 秒(5 分钟)。

php.ini 是 php的配置文件,.user.ini 中的字段也会被 php 视为配置文件来处理,从而导致 php 的文件解析漏洞。

但是想要引发 .user.ini 解析漏洞需要三个前提条件

服务器脚本语言为PHP  

服务器使用CGI/FastCGI模式  

上传目录下要有可执行的php文件

什么是 CGI
    CGI 的全称为“通用网关接口”(Common Gateway Interface),为 HTTP 服务器与其他机器上的程序服务通信交流的一种工具, CGI 程序须运行在网络服务器上。
   
    传统 CGI 接口方式的主要缺点是性能较差,因为每次 HTTP 服务器遇到动态程序时都需要重新启动解析器来执行解析,之后结果才会被返回给 HTTP
    服务器。这在处理高并发访问时几乎是不可用的,因此就诞生了 FastCGI。另外,传统的 CGI 接口方式安全性也很差,故而现在已经很少被使用了。

什么是 FastCGI
    FastCGI 是一个可伸缩地、高速地在 HTTP 服务器和动态服务脚本语言间通信的接口(在 Linux 下, FastCGI 接口即为 socket,这个socket 可以是文件 socket,也可以是IP socket),主要优点是把动态语言和 HTTP
    服务器分离开来。多数流行的 HTTP 服务器都支持 FastCGI,包括 Apache 、 Nginx 和 Lighttpd 等。   
    同时,FastCGI也被许多脚本语言所支持,例如当前比较流行的脚本语言PHP。FastCGI 接口采用的是C/S架构,它可以将 HTTP 服务器和脚本服务器分开,同时还能在脚本解析服务器上启动一个或多个脚本来解析守护进程。当 HTTP
    服务器遇到动态程序时,可以将其直接交付给 FastCGI 进程来执行,然后将得到结果返回给浏览器。这种方式可以让 HTTP
    服务器专一地处理静态请求,或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高整个应用系统的性能。

 都是网上有的资料

这个时候我们就可以去创建一个.user.ini的文件,内容为

auto_prepend_file=hack.jpg

.user.ini文件里的意思是:所有的php文件都自动包含hack.jpg文件。.user.ini相当于一个用户自定义的php.ini

接着上传hack.jpg文件,文件内容为一句话木马即可,这样一句话木马的内容就可以被当为php文件给读取,我们就可以使用蚁剑去连接了。

例题:upload-labs第五关

(5)空格点号绕过

可以直接在文件后缀中添加空格或者点号,从而去绕过过滤。

例题:upload-labs第七八关

(6)特殊字符绕过

当黑名单中未包含::$DATA时,我们可以利用这一点去绕过,首先可以先了解一下相关的知识

补充知识:php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持"::$DATA"之前的文件名 他的目的就是不检查后缀名。

这样的话我们就可以在文件名之后添加::$DATA,这样也就可以实现绕过验证了。

例题:upload-labs第九关

2.白名单绕过

白名单相对与黑名单就安全许多,要求只能是特定扩展名的文件才能上传,虽然我们无法从代码层面来绕过,但这样也不是绝对的安全,可以利用其他漏洞来绕过

1.使用%00截断文件名来上传

%00截断

截断的原理可以类比编程里的分号,如我们一条语句要以分号结尾,或者相当于把空字节之后的内容注释掉。具体的原理讲解可参考以下博文:

[基本实验] %00截断攻击的探索

CTF实验吧-上传绕过【0x00截断】

示例:
如目标网站不允许上传php后缀的文件,而我们的目标是要上传一个php文件。此时将文件修改为允许的格式,然后bp抓包,将文件名改为xxx.php%00.jpg,%00要进行URL编码。此时服务器看到%00会认为文件名已经结束从而使得上传到目标网站的文件为xxx.php

2.如果目标还存在文件包含漏洞,那么就可以上传图片马再文件包含来拿shell
3.get00截断和post00截断

(1)get:白名单,最终文件的存放位置是以拼接的方式,使用get方法,这个时候就可以使用get00截断(原理:php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00。)

例题:upload-labs第十二关

上传hack.php用BP抓包修改参数,把upload/后面加上hack.php%00(即图二),下面的filename=”hack.php”改为hack.png
文件上传(做完upload靶场的总结)_第1张图片
文件上传(做完upload靶场的总结)_第2张图片
放包之后用蚁剑连接
这里有一个细节,蚁剑连接时要把后面的一大串编码删掉,只留下文件名最后就可以了

(2)post00截断

白名单,文件上传路径拼接生成,而且使用了post发送的数据进行拼接,我们可以控制post数据进行0x00截断绕过白名单

例题:upload-labs第十三关

上传hack.php用BP抓包修改参数,然后修改后的结果为如下图二

文件上传(做完upload靶场的总结)_第3张图片

 文件上传(做完upload靶场的总结)_第4张图片

+号的Hex是2b,这里我们要把它改为00(效果如下图二) 

 

 文件上传(做完upload靶场的总结)_第5张图片

 然后就可以放包了,复制图片地址并用蚁剑进行连接

但是这里要注意一下,蚁剑连接填的URL地址要把php后面部分要删掉

④文件内容文件名替换
(1)文件后缀替换

黑名单,使用str_ireplace()函数寻找文件名中存在的黑名单字符串,将它替换成空(即将它删掉),可以使用双写绕过黑名单,这样文件就可以成功上传了。

例题:upload-labs第十一关

(2) 文件内容部分替换

将上传图片马的内容进行部分替换,从而使其中所包含的一句话木马变为其他。

解决方法:将上传后的文件与上传前的文件一一对比,找到没有被替换改变的一小部分,并将一句话木马放在这个位置即可。

图片二次渲染(后端重写文件内容)

对上传图片进行了判断了后缀名content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染,但是后端二次渲染需要找到渲染后的图片里面没有发生变化的Hex地方,添加一句话,通过文件包含漏洞执行一句话,使用蚁剑进行连接

上传正常的GIF图片下载回显的图片,用010Editor编辑器进行对比两个GIF图片内容,找到相同的地方(指的是上传前和上传后,两张图片的部分Hex仍然保持不变的位置)并插入PHP一句话,上传带有PHP一句话木马的GIF图片

最后在利用文件包含去访问该图片马,这样就能成功执行一句话木马,从而去使用蚁剑去连接。

例题:upload-labs第十七关

④条件竞争

从源码来看,服务器先是将上传的文件保存下来,然后将文件的后缀名同白名单对比,如果是jpg、png、gif中的一种,就将文件进行重命名。如果不符合的话,unlink()函数就会删除该文件。

这么看来如果我们还是上传一个图片马的话,网站依旧存在文件包含漏洞我们还是可以进行利用。但是如果没有文件包含漏洞的话,我们就只能上传一个php木马来解析运行了。

那还怎么搞?上传上去就被删除了,我还怎么去访问啊。

不慌不慌,要知道代码执行的过程是需要耗费时间的。如果我们能在上传的一句话被删除之前访问不就成了。这个也就叫做条件竞争上传绕过。

我们可以利用burp多线程发包,然后不断在浏览器访问我们的webshell,会有一瞬间的访问成功。

把这个php文件通过burp一直不停的重放,然后再去不停的访问我们上传的这个文件,总会有那么一瞬间是还没来得及删除就可以被访问到的,一旦访问到该文件就会在当前目录下生成一个Tony.php的一句话。在正常的渗透测试中这也是个好办法。因为单纯的去访问带有phpinfo()的文件并没有什么效果。一旦删除了还是无法利用。但是这个办法生成的Tony.php服务器是不会删除的,我们就可以通过蚁剑去链接了。

总结

防御

  1. 不要暴露上传文件的位置
  2. 禁用上传文件的执行权限
  3. 黑白名单(尽可能采用更加安全的白名单)
  4. 对上传的文件重命名,不易被猜测
  5. 对文件内容进行二次渲染
  6. 对上传的内容进行读取检查

你可能感兴趣的:(安全)