前言



过年过的很不顺,家里领导和我本人接连生病,年前腊月29才都治好出院,大年初六家里的拉布拉多爱犬又因为细小医治无效离开了,没能过年回家,花了好多钱,狗狗还离世了。所以也就没什么心思更新博客。今天初七,正式上班了,更新一篇吧,把bWAPP中常见的web漏洞也就一次性更新完毕,完成这个系列,虽然有点虎头蛇尾,但是也颇感无奈了。去年立的flag也还有两个大系列没有完成,一个是互联网公司常见漏洞分析,一个是C语言基础自学笔记,要看的东西太多了,也就是借着努力学习工作来忘却生活的打击和痛苦吧。

文件和目录遍历



从本质上说,二者的漏洞原因没啥不一样,尤其是linux系统中,一般都出现在文件阅读、下载、展示、或者可以列出目录的地方。

PHP代码


function directory_traversal_check_1($data)
{ // Not bulletproof $directory_traversal_error = ""; // Searches for special characters in the GET parameter
if(strpos($data, "../") !== false ||
strpos($data, "..\\") !== false ||
strpos($data, "/..") !== false ||
strpos($data, "\..") !== false) { $directory_traversal_error = "Directory Traversal detected!"; } /*
else
{ echo "Good path!"; }
*/ return $directory_traversal_error; } function directory_traversal_check_2($data)
{ // Not bulletproof $directory_traversal_error = ""; // Searches for special characters in the GET parameter
if(strpos($data, "../") !== false ||
strpos($data, "..\\") !== false ||
strpos($data, "/..") !== false ||
strpos($data, "\..") !== false ||
strpos($data, ".") !== false) { $directory_traversal_error = "Directory Traversal detected!"; } /*
else
{ echo "Good path!"; }
*/ return $directory_traversal_error; } function directory_traversal_check_3($user_path,$base_path = "")
{ $directory_traversal_error = ""; $real_base_path = realpath($base_path); // echo "base path: " . $base_path . " real base path: " . $real_base_path . "<br />"; $real_user_path = realpath($user_path); // echo "user path: " . $user_path . " real user path: " . $real_user_path . "<br />"; // int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
// URL: http://php.net/manual/en/function.strpos.php
if(strpos($real_user_path, $real_base_path) === false)
{ $directory_traversal_error = "<font color=\"red\">An error occurred, please try again.</font>"; } /*
else
{ echo "Good path!"; }
*/ return $directory_traversal_error; }

代码分析


函数一过滤了../ ..\ /.. .. , 函数二还过滤了. 但是绕过都很简单,直接使用绝对路径,不使用相对路径即可,例如/etc/passwd。函数三则对相对路径转为绝对路径后,和允许访问的绝对路径比对,如果不一致则禁止访问,真正做到了约束和防御。

文件上传



PHP代码

function file_upload_check_1($file, $file_extensions  = array("asp", "aspx", "dll", "exe", "jsp", "php"), $directory = "images")
{ $file_error = ""; // Checks if the input field is empty
if($file["name"] == "")
{ $file_error = "Please select a file..."; return $file_error; } // Checks if there is an error with the file
switch($file["error"]) // URL: http://php.net/manual/en/features.file-upload.errors.php { case 1 : $file_error = "Sorry, the file is too large. Please try again...";
break; case 2 : $file_error = "Sorry, the file is too large. Please try again...";
break; case 3 : $file_error = "Sorry, the file was only partially uploaded. Please try again...";
break; case 6 : $file_error = "Sorry, a temporary folder is missing. Please try again...";
break; case 7 : $file_error = "Sorry, the file could not be written. Please try again...";
break; case 8 : $file_error = "Sorry, a PHP extension stopped the file upload. Please try again...";
break; } if($file_error)
{ return $file_error; } // Breaks the file in pieces (.) All pieces are put in an array
$file_array = explode(".", $file["name"]); // Puts the last part of the array (= the file extension) in a new variabele
// Converts the characters to lower case
$file_extension = strtolower($file_array[count($file_array) - 1]); // Searches if the file extension exists in the 'allowed' file extensions array
if(in_array($file_extension, $file_extensions))
{ $file_error = "Sorry, the file extension is not allowed. The following extensions are blocked: <b>" . join(", ", $file_extensions) . "</b>"; return $file_error; } // Checks if the file already exists in the directory
if(is_file("$directory/" . $file["name"]))
{ $file_error = "Sorry, the file already exists. Please rename the file..."; } return $file_error; } function file_upload_check_2($file, $file_extensions = array("jpeg", "jpg", "png", "gif"), $directory = "images")
{ $file_error = ""; // Checks if the input field is empty
if($file["name"] == "")
{ $file_error = "Please select a file..."; return $file_error; } // Checks if there is an error with the file
switch($file["error"]) // URL: http://php.net/manual/en/features.file-upload.errors.php { case 1 : $file_error = "Sorry, the file is too large. Please try again...";
break; case 2 : $file_error = "Sorry, the file is too large. Please try again...";
break; case 3 : $file_error = "Sorry, the file was only partially uploaded. Please try again...";
break; case 6 : $file_error = "Sorry, a temporary folder is missing. Please try again...";
break; case 7 : $file_error = "Sorry, the file could not be written. Please try again...";
break; case 8 : $file_error = "Sorry, a PHP extension stopped the file upload. Please try again...";
break; } if($file_error)
{ return $file_error; } // Breaks the file in pieces (.) All pieces are put in an array
$file_array = explode(".", $file["name"]); // Puts the last part of the array (= the file extension) in a new variabele
// Converts the characters to lower case
$file_extension = strtolower($file_array[count($file_array) - 1]); // Searches if the file extension exists in the 'allowed' file extensions array
if(!in_array($file_extension, $file_extensions))
{ $file_error = "Sorry, the file extension is not allowed. Only the following extensions are allowed: <b>" . join(", ", $file_extensions) . "</b>"; return $file_error; } // Checks if the file already exists in the directory
if(is_file("$directory/" . $file["name"]))
{ $file_error = "Sorry, the file already exists. Please rename the file..."; } return $file_error; }

代码分析


上面的代码对于防文件上传不是特别典型,就不分析了,我们看一下正确的PHP文件上传的代码

  • 1、扩展名检查(要白名单不能黑名单,一般就是允许jpg、jpeg、png等等)。
  • 2、重命名随机新文件名,且该新文件名不返回到前端,这个时候一定要注意扩展名。
  • 3、对图片进行二次渲染,如果不是上传图片文件就忽略这一点。
  • 4、文件转存到一个路径,该路径不要暴露。
  • 5、保证服务器版本,避免解析漏洞。
<?php
//配置属性
$upload_path = '/var/www/images/';
$target_file = md5(uniqid());
$allow_extend_filenames = array('jpg', 'jpeg', 'png');//限定可以上传的文件扩展名
//文件获取
if(isset($_POST['file'])){
checkToken($_REQUEST['csrfToken'], $_SESSION['csrfToken'], 'upload.php');
}
$file = $_FILES['file']; //获取文件属性
$name = $file['name'];
$type = $file['type'];
$size = $file['size'];
$tmp_name = $file['tmp_name']
$extend_name = strtolower(substr($name, strrops($name, '.') + 1)); //文件属性更新
$target_file = $upload_path . $target_file . '.'; //白名单检查
$dot_count = substr_count('.');
if ($dot_count > 1){
return 'filename error!';
} if(!in_array($extend_name, $allow_extend_filenames)){
return 'filetype error!';
} if ($type != 'image/jpeg' && $type != 'image/png'){
return 'filetype error!';
} //图片二次渲染
if($type == 'image/jpeg'){
$img = imagecreatefromjpeg($tmp_name);
imagejpeg($img, $target_file . 'jpg', 100);
}
else{
$img = imagecreatefrompng($tmp_name);
imagepng($img, $target_file . 'png', 9);
}
imagedestory($img); return 'upload success!'; generateSessionToken();
?>

SSRF



关键问题是对内部可能发起访问的地址,做白名单限制,或者按照自定义规则验证合法性,而不是任意发起,没有php级别的防御措施,是代码逻辑防御级别的。

CSRF



防御方式


表单隐藏随机token验证的方式防御,或者弹出验证码防御,后者是功能逻辑防御,影响用户体验但更安全,代码层面来介绍下前者。

防御代码

<input type="hideen" value="token_value" name="token"></input>
if($_SESSION['id'] &&  $_POST['csrfToken']  == $_SESSION['csrfToken']){
return true;
}
else{
return false;
}

XXE的PHP级别防御



防御原理


由于simplexml_load_string函数的XML解析问题出在libxml库上,所以加载实体前可以调用一个函数来禁用。

防御代码


<?php libxml_disable_entity_loader(true); ?>

文件包含的防御


防御远程文件包含

//PHP配置文件
allow_url_include = OFF

防御本地文件包含

//include类函数的参数不允许用户控制,或者在白名单内做限制。

跟bWAPP学WEB安全(PHP代码)--终结篇:文件目录遍历、文件上传、SSRF、CSRF、XXE、文件包含的更多相关文章

  1. 跟bWAPP学WEB安全(PHP代码)--OS命令注入

    背景 这是温故知新的一个系列,也是重新拾起WEB安全的一个系列,同时希望能稍微有点对初学者的帮助.第一篇先来讲讲OS命令注入 bWAPP里面有两个页面也就是两个漏洞,来验证OS命令注入.一个是有回显的 ...

  2. 跟bWAPP学WEB安全(PHP代码)--认证绕过与会话管理

    背景 这里主要是代码逻辑问题,而不是代码使用函数的问题,因此在这个里面就不粘贴具体代码了,而是分类介绍下bWAPP中涉及的安全问题: 验证码问题 找回问题 账号口令问题 Cookies问题 Sessi ...

  3. 跟bWAPP学WEB安全(PHP代码)--SQL注入的一些技巧

    背景 模拟环境还是 bWAPP,只不过这个bWAPP的SQL注入有点多,一一写意义不大,在这边就利用这个环境来尝试一些SQL注入的技巧.并研究下PHP的防御代码. 普通的bWAPPSQL注入的简单介绍 ...

  4. 跟bWAPP学WEB安全(PHP代码)--PHP代码注入

    ---恢复内容开始--- 背景 今天我们换一个方式来分析这个漏洞,从渗透的角度去搞. 渗透过程 测试漏洞 先来看看,观察URL是:http://192.168.195.195/bWAPP/phpi.p ...

  5. 跟bWAPP学WEB安全(PHP代码)--邮件头和LDAP注入

    背景 由于时间限制和这俩漏洞也不是特别常用,在这里就不搭建环境了,我们从注入原来和代码审计的角度来看看. 邮件头注入 注入原理: 这个地方首先要说一下邮件的结构,分为信封(MAIL FROM.RCPT ...

  6. 跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击

    背景 这个系列有很多题,但是其实考察的相近,类似的就不在多说,我们来看吧.主要分几个点来讲: 反射型 存储型 JSON XM 头部字段相关 分类介绍 反射型 在请求中构造了XSS的Payload,一般 ...

  7. 跟bWAPP学WEB安全(PHP代码)--XPath注入

    XML/Xpath注入 看了下,A2里面是认证与会话管理的破坏或称之为绕过,没有特别要写的,很多就是小问题,可能会将这类问题放在最后写一下.一篇博客,这里还是更多的着重在能够获取信息或者服务器权限的漏 ...

  8. 跟bWAPP学WEB安全(PHP代码)--SSL(Server-Side-Include)漏洞

    什么是Server-Side-Include漏洞 服务端包含漏洞是指发送指令到服务器,服务器会将指令运行完,把运行结果包含在返回文件中发送给你.利用这种漏洞可以获取服务端的信息甚至执行命令,这样的指令 ...

  9. 跟bWAPP学WEB安全(PHP代码)--HTML注入和iFrame注入

    背景 这里讲解HTML注入和iFrame注入,其他的本质都是HTML的改变.那么有人会问,XSS与HTML注入有啥区别呢?其实本质上都是没有区别的,改变前端代码,来攻击客户端,但是XSS可以理解为注入 ...

随机推荐

  1. 查询返回JSON数据结果集

    查询返回JSON数据结果集 设计目标: 1)一次性可以返回N个数据表的JSON数据 2)跨数据库引擎 { "tables": [ { "cols": [ { & ...

  2. su 与 su - 比较

    原文地址:http://blog.chinaunix.net/uid-25557346-id-2889329.html   今天有一同事说在切换用户的时候,找不到该用户下用户命令,后来仔细检查了一下过 ...

  3. .net里Release的pdb文件有什么用 是否可以删除

    程序数据库 (PDB) 文件保存着调试和项目状态信息,使用这些信息可以对程序的调试配置进行增量链接. 在使用 /debug 生成时,会创建一个 PDB 文件. 可以使用 /debug:full 或 / ...

  4. Python学习笔记(十四):模块高级

    以Mark Lutz著的<Python学习手册>为教程,每天花1个小时左右时间学习,争取两周完成. --- 写在前面的话 2013-7-23 21:30 学习笔记 1,包导入是把计算机上的 ...

  5. jQuery()方法的第二个参数

    关于jQuery()方法的第二个参数,有下面这几种用法: 1.jQuery(selector, [context]) 这种用法,相当于 $(context).find(selector) 或者 con ...

  6. CentOS 7搭建Linux GPU服务器

    1. CUDA Toolkit的安装 到https://developer.nvidia.com/cuda-gpus查询GPU支持的CUDA版本: 到https://developer.nvidia. ...

  7. 【PHP】php生成一个不重复的数字(订单号、会员号)

    1.目的:利用php的do .. while 生成一个不重复的字符串或者数组,比如(订单号.会员号) 2.不废话,代码来: $repeat_order = array(); do{ $ordersn ...

  8. 自建Kubernetes logtail日志采集客户端安装方式

    自建Kubernetes安装方式 前提条件 Kubernetes集群版本1.8及以上. 已经安装Helm命令,版本2.6.4及以上. 安装步骤 在日志服务控制台创建一个Project,Project名 ...

  9. 什么是同源策略,什么是跨域,如何跨域,Jsonp/CORS跨域

    同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响. 可以说Web是构建在同源策略基础之上 ...

  10. rdlc报表在vs2008下编辑正常,在vs2012上编辑就报错

    最近我们的系统的开发工具由vs2008升级到了2012,由于系统中很多报表都是用rdlc来开发的,今天 遇到有报表需要改动的需求,就直接使用vs2012对rdlc报表进行了编辑,结果改完后,怎么预览报 ...