freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

浅谈蜜罐原理与规避
2025-01-15 19:15:20
所属地 海外

随着攻防的不断发展,厂商和蓝队的防御手段越来越精进,也有了很多方法溯源攻击方,蜜罐就是其中的一种,前段时间受学长的指点,特地来研究一下蜜罐的原理和规避

蜜罐(honeypot),带蜜的罐子,进去吃了蜜,就出不来了,本质上就是一个陷阱,在网安领域上看,蜜罐就是针对渗透测试人员(比如红队)的一个陷阱

蜜罐的类型也很多,下面简单谈谈常见的几种蜜罐

WEB蜜罐

基于web网页的蜜罐,基本都是通过js代码实现攻击反制,首先就是比较常见的jsonp蜜罐和xss蜜罐了

jsonp蜜罐

顾名思义,这类蜜罐其实是利用了jsonp劫持的原理

jsonp跨域

jsonp是什么就不多解释了,这里用一个小demo讲讲什么是jsonp跨域:

  • 现在有一个用于jsonp的接口http://yuy0ung.fun/user?callback=,请求后会返回当前已登陆用户信息

  • 现在构造一个页面:

<script type="text/javascript">
function hackuser(result)
{
    alert(result.name);
}
</script>
<script type="text/javascript" src="http://yuy0ung.fun/user?callback=hackuser"></script>

用户访问之后会解析js,发送请求:http://yuy0ung.fun/user?callback=hackuser

网站B接收到请求后,解析请求的URL,以JSON 格式生成请求需要的数据,将封装的包含用户信息的JSON数据作为回调函数的参数返回给浏览器,比如:

hackuser({"id":1,"name":"Yuy0ung","email":"yuy0ung@test.com"})

这里就很明显会触发回调函数hackuser,将当前用户数据alert出来

蜜罐分析

和上面的jsonp跨域请求同理,蜜罐可以通过jsonp跨域主动获取访问者的信息,比如用户在其他已登陆网站上的用户名、手机号、IP

下面举个例子:

一部分蜜罐会在资源中加载/js/portrait.js

我在使用fofa语法body="/js/portrait.js" && country="CN"进行搜索后找到一个看似后台的网页:

image-20250104035349646

这里就可以用我们的burp来简单辨别是否为蜜罐,请求网页后查看burp的http history:

发现在加载网站上的这个/js/portrait.js后,就开始不断的请求其他常用社交媒体网站:

image-20250104034815719

可以看到:QQ、搜狗、新浪、搜狐等的网站都有被请求,再仔细看看这些请求包:

  • qq:

    img

  • 搜狗:

    img

  • 新浪:

    img

这里简单列举三个请求包,很明显都存在callback参数,很经典的jsonp跨域请求了

并且这里的jsonp回调函数格式都是jsonp_callback_+某字符串,看看/js/portrait.js

img

果然出现了这样的代码,现在可以断定这个网页就是一个蜜罐

XSS蜜罐

XSS的原理就不过多解释了

这里笔者理解的XSS蜜罐就是将存在XSS漏洞的URL存放在网页中,渗透测试人员点击后就会触发XSS

利用方式和常规XSS的利用方式一致,这里给出一种获取攻击者IP的案例

WebRTC获取IP

WebRTC是一个很老的技术,但是很少有人关注,现代浏览器基本都支持并默认开启,如果未曾关闭,则可能会暴露你的真实IP,即使你开的是全局代理

可以使用这个网站进行检测https://ip8.com/webrtc-test,笔者也中招了:

img

而上面这个技术仅通过javascript代码即可实现,这些js代码可能会被插入到网站中进行XSS利用

下面给出一段测试代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Get IP Addresses</title>
    <link rel="stylesheet" href="https://unpkg.com/element-ui@2.15.6/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/vue@2.6.14"></script>
    <script src="https://unpkg.com/element-ui@2.15.6/lib/index.js"></script>
</head>
<body>
    <div id="app">
        <el-container>
            <el-header>
                <h1>Your IP Addresses:</h1>
            </el-header>
            <el-main>
                <el-table :data="ipAddresses" style="width: 100%" border>
                    <el-table-column prop="type" label="Type" width="180"></el-table-column>
                    <el-table-column prop="address" label="IP Address"></el-table-column>
                </el-table>
            </el-main>
        </el-container>
    </div>    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    ipAddresses: [
                        { type: 'XFF or CDN IP Address', address: 'Loading...' },
                        { type: 'WebRTC Local IP Address', address: 'Loading...' },
                        { type: 'WebRTC IPv4 Address', address: 'Loading...' },
                        { type: 'WebRTC IPv6 Address', address: 'Loading...' }
                    ]
                };
            },
            mounted() {
                // Fetch XFF or CDN IP address
                const xhr = new XMLHttpRequest();
                xhr.open('GET', 'get_real_ip.php', true);
                xhr.onreadystatechange = () => {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        const jsonResponse = JSON.parse(xhr.responseText);
                        this.ipAddresses[0].address = jsonResponse.ip;
                    }
                };
                xhr.send();                // WebRTC IPs
                const iceServers = [
                    { urls: 'stun:stun.l.google.com:19302' },
                    { urls: 'stun:stun1.l.google.com:19302' },
                    { urls: 'stun:stun2.l.google.com:19302' },
                    { urls: 'stun:stun3.l.google.com:19302' },
                    { urls: 'stun:stun4.l.google.com:19302' },
                ];
                // getUserIPs function
                function getUserIPs(callback) {
                    const myPeerConnection = new RTCPeerConnection({ iceServers });
                    myPeerConnection.createDataChannel("");
                    myPeerConnection.createOffer().then(offer => myPeerConnection.setLocalDescription(offer));                    myPeerConnection.onicecandidate = function(event) {
                        if (event.candidate) {
                            const parts = event.candidate.candidate.split(' ');
                            const ip = parts[4];
                            callback(ip);
                        }
                    };
                }                getUserIPs((ip) => {
                    // ... (same as before)
                                const ipv4Regex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
            const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}(([0-9a-fA-F]{1,4}:){1,4}|((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
                    if (ipv4Regex.test(ip)) {
                        this.ipAddresses[2].address = ip;
                    } else if (ipv6Regex.test(ip)) {
                        this.ipAddresses[3].address = ip;
                    } else {
                        this.ipAddresses[1].address = ip;
                    }
                });
            }
        });
    </script>
</body>
</html>

本地搭建即可测试:

img

其他

当然,WEB蜜罐能获取的信息还有很多,比如下面这篇文章,提到了蜜罐能够获取使用手机热点的红队人员的手机号:

https://github.com/fuckjsonp/FuckJsonp-RCE-CVE-2022-26809-SQL-XSS-FuckJsonp

这个文章发布周期有点久了,但还是值得参考

识别与规避

对于jsonp蜜罐,最大的特征就是会请求一些常用的社交媒体网站,可以根据这个特征进行识别,除了上面通过查看httphistory,F12也可以查看网页请求成功的外部网站:

img

如果想要进行规避,可以尝试写一个蜜罐扫描器,将渗透测试的目标清单进行自动化的筛选,可能用到的trick如下:

  • 网站爬虫对目标网站的页面和request进行抓取

  • 对request中请求的外部网站以及请求数量进行自动化分析(基于上面提到的特征)

  • 你甚至可以把已识别的蜜罐中请求的request提取出来作为一个字典

  • 还可以把已识别的蜜罐中加载的js文件(比如上面jsonp蜜罐的/js/portrait.js)提取出来作为字典

当然,现在也有很多浏览器插件能够识别WEB蜜罐并拦截其js行为,Goby 红队版也支持对蜜罐的识别

MYSQL蜜罐

基础的原理是:mysql中有一个load data local infile函数能够读取本地文件到mysql数据库中

利用这个思路,MYSQL蜜罐诞生了一个攻击反制手段:只要渗透测试人员尝试连接该mysql蜜罐,就可以被蜜罐读取到本地配置文件,甚至不需要提供正确的用户名密码

如果想要了解详细的原理,建议参考互联网的文章自行制作一个mysql蜜罐,这里就不过多赘述了

蜜罐行为

由于该蜜罐可以读取连接方的本地文件,所以可以有很多获取连接方信息的思路,这里以windows主机举例:

  • 读取微信号

    win系统下,读取手机号和微信ID的方法(默认常见微信文件路径) :

    • 通过C:/Windows/PFRO.log获取windows用户名

    • 通过C:/Users/用户名/Documents/WeChat Files/All Users/config/config.data获取wxid

    • 通过C:/Users/用户名/Documents/WeChat Files/wx_id/config/AccInfo.dat获取微信号、手机号

  • 读取chrome的登录数据

    读取chrome的login data,虽然无法解密出密码,但是还是可以获取到对方的一些账号C:/Users/' + username + '/AppData/Local/Google/Chrome/User Data/Default/Login Data

  • chrome的历史记录

    chrome的历史记录文件C:/Users/' + username + '/AppData/Local/Google/Chrome/User Data/Default/History

  • CS连接信息

    只要是使用cs客户端连接过cs服务端的电脑,cs客户端都会在固定的文件夹下生成一个.aggressor.prop配置文件。对于Windows系统,那么文件位置是:C:\Users\Administrator\.aggressor.prop,这个配置文件里面就包含了cs远控的ip地址、端口、用户名及密码,而且都是明文的

  • ……

综上,MYSQL蜜罐同样有很多方法来获取渗透测试人员的敏感信息

蜜罐规避

个人认为,mysql蜜罐的识别可能会相对繁琐,需要根据连接时的协议返回特征、协议实现缺陷来判断,所以规避的最好方式就是在渗透测试时使用虚拟机

总结

上面只对常见的蜜罐进行了简单的阐述,还有很多变种或优化后的蜜罐,交互性和仿真性非常高,感兴趣可以继续了解

再提一提:

对于蜜罐的规避,个人认为,比起使用自己的个人电脑,最好还是参考 纯虚拟机(无任何个人信息)+ 多层网络代理 + 国外VPS这种思路来进行配置更加安全

本文作者:Track-yuy0ung

# 漏洞 # 渗透测试 # 黑客 # web安全 # 网络安全技术
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录