├── .DS_Store ├── img └── logo.png ├── README.md ├── manifest.json ├── popup.js ├── popup.html └── background.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnrstar/anti-honeypot/HEAD/.DS_Store -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnrstar/anti-honeypot/HEAD/img/logo.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 更新 2 | V1.0.2: 3 | 增加个启动/暂定按钮 4 | 优化了一些代码实现逻辑 5 | 加个版本更新提示 6 | # 背景 7 | + 在真实攻防演习中,蓝队不再像以前只是被动防守,而是慢慢开始转变到主动出击的角色。对蓝队反制红队帮助最大的想来非蜜罐莫属,现在的商业蜜罐除了会模拟一个虚拟的靶机之外,还承担了一个很重要的任务:溯源黑客真实身份。相当一部分黑客因为浏览器没开隐身模式导致被利用jsonhijack漏洞抓到真实ID,虽然可以反手一个举报到src换积分,但是在漏洞修复之前,又是一批战友被溯源。相信很对已经被溯源的红方选手对此更有体会。 8 | + 在这种背景下,各位红方老司机应当很需要一个能自动识别这种WEB蜜罐,因此我们写了个简单的chrome插件,用来帮助我们摆脱被溯源到真实ID的困境。插件有两个功能,一是识别当前访问的网站是否是蜜罐,是的话就弹框预警;二是对访问的jsonp接口进行重置,防止对方获取到真实ID。所采用的原理非常简单粗暴,就是判断当前网站域和jsonp接口的域是否是同一个,是的话就预警并阻断。比如我访问一个`http://1.2.3.4/`的网站,结果这个网站里的js去请求了一个baidu.com的api,那妥妥的有问题了。但是粗暴判断也会带来误报,比如我正常访问`baidu.com`,但是其引用了个`apibaidu.com`的jsonp,就一样也会报警和拦截,这种情况下就暂时用白名单来解决了。 9 | # 使用 10 | + 打开chrome的插件管理 chrome://extensions/。 11 | + 打开开发者模式,并点击”加载已解压的扩展程序”,选择对应的目录导入即可 12 | 13 | # TODO 14 | + 加入jsonp漏洞的自动挖掘 15 | + 借鉴另外一个[项目](https://github.com/iiiusky/AntiHoneypot-Chrome-simple)的通过特定js脚本名称和内容识别已知厂商的蜜罐 -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Anti-HoneyPot[By-MegaVector]", 3 | "version": "1.0.2", 4 | "manifest_version": 2, 5 | "description": "", 6 | "icons": { 7 | "128": "/img/logo.png" 8 | }, 9 | "browser_action": { 10 | "default_popup": "popup.html", 11 | "default_title": "Anti-HoneyPot[By-MegaVector]", 12 | "default_icon": "./img/logo.png" 13 | }, 14 | "background": { 15 | "persistent": true, 16 | "scripts": [ 17 | "background.js" 18 | ] 19 | }, 20 | "permissions": [ 21 | "notifications", 22 | "activeTab", 23 | "tabs", 24 | "storage", 25 | "https://*/*", 26 | "http://*/*", 27 | "webRequest", 28 | "webRequestBlocking" 29 | ], 30 | "web_accessible_resources": ["*"], 31 | "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'" 32 | } -------------------------------------------------------------------------------- /popup.js: -------------------------------------------------------------------------------- 1 | // popup.js 2 | 3 | // 初始化插件状态为已启动 4 | let isEnabled = true; 5 | 6 | // 从 storage 中读取插件状态 7 | chrome.storage.sync.get('isEnabled', function(data) { 8 | // 如果之前存储了状态,则使用该状态,否则默认为已启动 9 | isEnabled = data.isEnabled !== undefined ? data.isEnabled : true; 10 | updateButtonAndStatus(); 11 | }); 12 | 13 | // 更新按钮文本和状态显示 14 | function updateButtonAndStatus() { 15 | const toggleButton = document.getElementById('toggleButton'); 16 | const statusElement = document.getElementById('status'); 17 | if (isEnabled) { 18 | toggleButton.textContent = '暂停插件'; 19 | statusElement.textContent = '当前状态: 运行中'; 20 | } else { 21 | toggleButton.textContent = '启动插件'; 22 | statusElement.textContent = '当前状态: 已暂停'; 23 | } 24 | } 25 | 26 | // 切换插件状态 27 | function toggleExtension() { 28 | isEnabled = !isEnabled; 29 | updateButtonAndStatus(); 30 | // 存储新的插件状态 31 | chrome.storage.sync.set({isEnabled: isEnabled}, function() { 32 | // 发送消息给 background.js 更新插件状态 33 | chrome.runtime.sendMessage({action: "toggleExtension", enabled: isEnabled}); 34 | }); 35 | } 36 | 37 | // 为按钮添加点击事件监听器 38 | document.getElementById('toggleButton').addEventListener('click', toggleExtension); 39 | -------------------------------------------------------------------------------- /popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 蜜罐检测插件 7 | 47 | 48 | 49 |
50 |

蜜罐检测插件

51 |
已拦截蜜罐数量: 0
52 | 53 |
当前状态: 已启动
54 | 版本 V1.01 55 |
56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // 初始化插件状态和计数器 3 | let isEnabled = true; 4 | 5 | const currentVersion = chrome.runtime.getManifest().version; 6 | // 更新检查地址 7 | const updateUrl = 'http://chatcs.megavector.cn/antihonypot.txt'; 8 | 9 | // 当插件安装或更新时,或者Chrome启动时,检查更新 10 | chrome.runtime.onInstalled.addListener(() => { 11 | checkForUpdate(); 12 | }); 13 | 14 | chrome.runtime.onStartup.addListener(() => { 15 | checkForUpdate(); 16 | }); 17 | 18 | // 检查更新的函数 19 | function checkForUpdate() { 20 | fetch(updateUrl) 21 | .then(response => response.text()) 22 | .then(text => { 23 | // 假设txt文件内容是形如 "1.0.0" 的版本号字符串 24 | const latestVersion = text.trim(); 25 | const v2 = parseInt(latestVersion.replace(/\./g, '')); 26 | const v1 = parseInt(currentVersion.replace(/\./g, '')); 27 | // 比较版本号,这里使用了简单的字符串比较,实际应用中可能需要更复杂的版本比较逻辑 28 | if (v2 > v1) { 29 | notifyUserToUpdate(latestVersion); 30 | } 31 | }) 32 | .catch(error => { 33 | console.log('Error checking for update:', error); 34 | }); 35 | } 36 | 37 | // 通知用户更新的函数 38 | function notifyUserToUpdate(latestVersion) { 39 | const options = { 40 | type: 'basic', 41 | iconUrl: 'img/logo.png', // 插件的图标 42 | title: '插件更新可用', 43 | message: `发现新版本 ${latestVersion},请访问插件页面下载更新。` 44 | }; 45 | 46 | chrome.notifications.create('updateNotification', options, () => {}); 47 | } 48 | 49 | // 监听通知点击事件,当用户点击通知时,可以打开插件的页面 50 | chrome.notifications.onClicked.addListener(notificationId => { 51 | if (notificationId === 'updateNotification') { 52 | chrome.tabs.create({ url: 'chrome://extensions/' }); 53 | } 54 | }); 55 | 56 | 57 | // 假设这是你用于处理网络请求的监听函数 58 | function handleWebRequest(details) { 59 | //url:当前的url;initiator:浏览器状态栏里的domain 60 | let { 61 | url, 62 | initiator 63 | } = details; 64 | 65 | //如果发起者为空,直接赋值url 66 | if (typeof (initiator) == "undefined") { 67 | initiator = url; 68 | } 69 | const protocal = url.split("://")[0]; 70 | 71 | //根据url返回域名和对应的path 72 | function GetHostAndPath(url) { 73 | const urlObj = new URL(url); 74 | return [urlObj.hostname, urlObj.pathname + urlObj.search]; 75 | } 76 | 77 | //根据url获取主域名 78 | function get_domain(url){ 79 | if (!url) return null; 80 | var re_domain = /([a-zA-Z0-9-]+)(?:.com\b|.net\b|.edu\b|.miz\b|.biz\b|.cn\b|.cc\b|.org\b)/; 81 | var domain = url.match(re_domain); 82 | return domain ? domain[0] : null; 83 | } 84 | //判断host是否在黑名单内 85 | function inBlackList(host) { 86 | //黑名单host来自长亭D-sensor的溯源api,共47个 87 | const BlackList = ["account.itpub.net", "accounts.ctrip.com", "ajax.58pic.com", "api.csdn.net", "api.ip.sb", "api.passport.pptv.com", "bbs.zhibo8.cc", "bit.ly", "blog.csdn.net", "blog.itpub.net", "c.v.qq.com", "chinaunix.net", "cmstool.youku.com", "comment.api.163.com", "databack.dangdang.com", "dimg01.c-ctrip.com", "down2.uc.cn", "github.com", "hd.huya.com", "home.51cto.com", "home.ctfile.com", "home.zhibo8.cc", "hudong.vip.youku.com", "i.jrj.com.cn", "iask.sina.com.cn", "itunes.apple.com", "m.ctrip.com", "m.game.weibo.cn", "mapp.jrj.com.cn", "my.zol.com.cn","passport.ctrip.com", "passport.game.renren.com", "passport.iqiyi.com", "playbill.api.mgtv.com", "renren.com", "skylink.io", "u.faloo.com", "ucenter.51cto.com", "v.huya.com", "v2.sohu.com", "vote2.pptv.com", "wap.sogou.com", "webapi.ctfile.com", "weibo.com", "www.58pic.com", "www.iqiyi.com", "www.iteye.com", "www.zbj.com", "www.cndns.com", "mozilla.github.io", "www.sitestar.cn", "api.fastadmin.net", "m.site.baidu.com", "restapi.amap.com", "login.sina.com.cn", "now.qq.com", "message.dangdang.com", "musicapi.taihe.com", "api-live.iqiyi.com", "api.m.jd.com", "tie.163.com", "pcw-api.iqiyi.com", "so.v.ifeng.com", "passport.baidu.com", "wz.cnblogs.com", "passport.cnblogs.com", "hzs14.cnzz.com", "mths.be", "validity.thatscaptaintoyou.com", "stc.iqiyipic.com", "s14.cnzz.com", "sb.scorecardresearch.com", "js.cndns.com", "datax.baidu.com", "assets.growingio.com", "www.gnu.org", "wappassalltest.baidu.com", "baike.baidu.com", "ka.sina.com.cn", "p.qiao.baidu.com", "map.baidu.com", "www.dangdang.com", "g.alicdn.com", "s.faloo.com", "msg.qy.net", "morn.cndns.com", "i.qr.weibo.cn", "github.comgithub.com", "uis.i.sohu.com", "www.tianya.cn", "passport.mop.com", "commapi.dangdang.com", "comment.money.163.com", "chaxun.1616.net", "tieba.baidu.com", "remind.hupu.com", "service.bilibili.com", "node.video.qq.com", "api.weibo.com", "www.jiyoujia.com"]; 88 | for (const BlackSite of BlackList) { 89 | if (host == BlackSite) { 90 | return true; 91 | } 92 | } 93 | return false; 94 | } 95 | 96 | var mainDomain = get_domain(initiator); //发起者的主域名 97 | var targetHost = GetHostAndPath(url)[0]; //跨域或本域访问的目标主机 98 | var targetPath = GetHostAndPath(url)[1]; //跨域或本域访问的目标路径 99 | var targetDomain = get_domain(url) //目标主域名 100 | 101 | const WhiteList = ['baidu.com', 'qq.com', 'csdn.net', 'weibo.com', 'cnblogs.com','aliyun.com','ctrip.com','weibo.cn','iqiyi.com','163.com','126.com','51cto.com','taobao.com','sogou.com','iteye.com','58.com','google.com','fofa.so','jd.com','tmall.com','github.io','github.com','sina.com.cn','mi.com'] //白名单 102 | for (var WhiteSite of WhiteList) { 103 | if (mainDomain == WhiteSite) { 104 | console.log('命中白名单'+mainDomain); 105 | return; 106 | } 107 | } 108 | 109 | let redirectUrl; 110 | 111 | if (mainDomain == targetDomain) { //如果相等表示正常域内访问 112 | console.log(targetDomain); 113 | } else { //如果不相等,可能是跨域访问,需要继续判断 114 | const blockQueryStringList = ['callback', 'jsonp', 'javascript']; 115 | for (const q of blockQueryStringList) { 116 | if (protocal == 'http' || protocal == 'https') { 117 | if (q && targetPath.includes(q)) { 118 | redirectUrl = 'data:text/javascript;charset=UTF-8;base64,' + btoa(`;`); 119 | if (inBlackList(targetHost)) { 120 | // 黑名单拦截 121 | new Notification('拦截黑名单' + targetHost); 122 | } else { 123 | // 普通拦截 124 | new Notification('拦截可疑溯源请求:' + targetHost); 125 | } 126 | } 127 | } 128 | } 129 | 130 | } 131 | if (redirectUrl) return { 132 | redirectUrl 133 | } 134 | else return {}; 135 | } 136 | 137 | 138 | // 设置监听器 139 | chrome.webRequest.onBeforeRequest.addListener( 140 | handleWebRequest, 141 | { 142 | urls: [""] 143 | }, 144 | ["blocking"] 145 | ); 146 | 147 | 148 | // 接收来自 popup.html 的消息 149 | chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { 150 | if (message.action === "toggleExtension") { 151 | isEnabled = message.enabled; 152 | if (isEnabled) { 153 | // 如果插件之前被禁用,重新添加监听器 154 | chrome.webRequest.onBeforeRequest.addListener( 155 | handleWebRequest, 156 | { 157 | urls: [""] 158 | }, 159 | ["blocking"] 160 | ); 161 | } else { 162 | // 如果插件被禁用,移除监听器 163 | chrome.webRequest.onBeforeRequest.removeListener(handleWebRequest); 164 | } 165 | } 166 | }); 167 | 168 | // 其他 background.js 代码逻辑... 169 | --------------------------------------------------------------------------------