浅谈蜜罐原理与规避

2025-01-28 9 0

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

蜜罐(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":"[email protected]"})

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

蜜罐分析

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

下面举个例子:

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

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

浅谈蜜罐原理与规避插图

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

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

浅谈蜜罐原理与规避插图1

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

  • qq:

    浅谈蜜罐原理与规避插图2

  • 搜狗:

    浅谈蜜罐原理与规避插图3

  • 新浪:

    浅谈蜜罐原理与规避插图4

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

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

浅谈蜜罐原理与规避插图5

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

XSS蜜罐

XSS的原理就不过多解释了

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

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

WebRTC获取IP

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

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

浅谈蜜罐原理与规避插图6

而上面这个技术仅通过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/[email protected]/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/[email protected]"></script>
    <script src="https://unpkg.com/[email protected]/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"   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>

本地搭建即可测试:

浅谈蜜罐原理与规避插图7

其他

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

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

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

识别与规避

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

浅谈蜜罐原理与规避插图8

如果想要进行规避,可以尝试写一个蜜罐扫描器,将渗透测试的目标清单进行自动化的筛选,可能用到的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


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

2025最新&模拟器微信小程序抓包&小程序反编译
新威胁组织GamaCopy模仿俄罗斯Gamaredon APT,针对俄语目标发起攻击
Windows_xp_win7-驱动编译与双虚拟机调试环境搭建
勒索软件利用隐秘SSH隧道攻击ESXi系统,实现C2通信
[Meachines] [Easy] GoodGames SQLI+Flask SSTI+Docker逃逸权限提升
BUUCTF-reverse wp(二)

发布评论