// ==UserScript== // @license MIT // @name 安服小助手 // @namespace http://key08.com/ // @version 0.4 // @description 安服必备 // @author huoji // @match *://*/* // @grant GM_setClipboard // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @downloadURL none // ==/UserScript== (function () { 'use strict'; function build_html (document) { // 创建自定义的右键菜单 let customContextMenu = document.createElement('div'); customContextMenu.id = 'huoji_tip_custom-context-menu'; customContextMenu.style.display = 'none'; customContextMenu.style.position = 'fixed'; customContextMenu.style.zIndex = '10000'; customContextMenu.style.backgroundColor = '#fff'; customContextMenu.style.border = '1px solid #000'; customContextMenu.innerHTML = '
' + '' + '' + '' + '' + '' + '' + ''; document.body.appendChild(customContextMenu); // 创建气泡提示 let bubble = document.createElement('div'); bubble.id = 'huoji_tip_bubble'; bubble.style.display = 'none'; bubble.style.position = 'fixed'; bubble.style.zIndex = '10001'; bubble.style.padding = '10px'; bubble.style.borderRadius = '5px'; bubble.style.color = '#fff'; bubble.style.maxWidth = '80%'; bubble.style.overflow = 'auto'; bubble.style.wordWrap = 'break-word'; document.body.appendChild(bubble); // 创建加载动画 let loader = document.createElement('div'); loader.id = 'huoji_tip_loader'; loader.style.display = 'none'; loader.style.borderRadius = '50%'; loader.style.animation = 'spin 2s linear infinite'; loader.style.border = '8px solid #f3f3f3'; // 减小边框大小 loader.style.borderTop = '8px solid #3498db'; // 顶部边框保持颜色,但大小减半 loader.style.width = '60px'; // 宽度减半 loader.style.height = '60px'; // 高度减半 document.body.appendChild(loader); // 添加CSS动画 let style = document.createElement('style'); style.innerHTML = ` @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `; document.head.appendChild(style); } if (document == null) { document = window.document; } function PrintKsnResult (result, e) { let zone = result.zone; let hitcount = result.hitcount; switch (zone) { case 'Green': showBubble(e.pageX, e.pageY, '白文件 流行度:' + hitcount.toString(), '#888'); break; case 'Yellow': showBubble(e.pageX, e.pageY, '广告文件 流行度:' + hitcount.toString(), '#888'); break; case 'Grey': showBubble(e.pageX, e.pageY, '未知文件 流行度:' + hitcount.toString(), '#888'); break; case 'Red': showBubble(e.pageX, e.pageY, '病毒文件 流行度:' + hitcount.toString(), '#f00'); break; } } build_html(document); let ksnQueryCache = {}; let enableGPT = false; // 当用户右击页面时,如果选中的是MD5或SHA1哈希值,则显示自定义的右键菜单 document.oncontextmenu = function (e) { let text = window.getSelection().toString(); let md5Pattern = /^[a-f0-9]{32}$/i; let sha1Pattern = /^[a-f0-9]{40}$/i; let ipPattern = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/; let domainPattern = /^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}$/i; let customContextMenu = document.getElementById('huoji_tip_custom-context-menu'); let sendToTipButton = document.getElementById('send-to-tip-button'); let copyButton = document.getElementById('copy-button'); let vtSearchButton = document.getElementById('vt-search-button'); let wbSearchButton = document.getElementById('wb-search-button'); let changeKsnKeyButton = document.getElementById('change-ksn-key-button'); let loader = document.getElementById('huoji_tip_loader'); let enableChatgptButton = document.getElementById('enable-chatgpt'); let useChatgptButton = document.getElementById('use-chatgpt'); let changeGPTkeyButton = document.getElementById('change-chatgpt-apikey'); if (changeKsnKeyButton == null || wbSearchButton == null || vtSearchButton == null || copyButton == null || sendToTipButton == null || customContextMenu == null || loader == null || enableChatgptButton == null || useChatgptButton == null || changeGPTkeyButton == null) { build_html(document); return; } if (md5Pattern.test(text) || sha1Pattern.test(text) || ipPattern.test(text) || domainPattern.test(text) || enableGPT == true) { customContextMenu.style.left = e.pageX + 'px'; customContextMenu.style.top = e.pageY + 'px'; customContextMenu.style.display = 'block'; e.preventDefault(); useChatgptButton.style.display = enableGPT == false ? 'none' : 'block'; if (md5Pattern.test(text) || sha1Pattern.test(text)) { sendToTipButton.style.display = 'block'; vtSearchButton.style.display = 'block'; changeKsnKeyButton.style.display = 'block'; wbSearchButton.style.display = 'none'; changeGPTkeyButton.style.display = 'none'; } else if (ipPattern.test(text) || domainPattern.test(text)) { sendToTipButton.style.display = 'none'; vtSearchButton.style.display = 'none'; changeKsnKeyButton.style.display = 'none'; wbSearchButton.style.display = 'block'; changeGPTkeyButton.style.display = 'none'; } else { sendToTipButton.style.display = 'none'; vtSearchButton.style.display = 'none'; changeKsnKeyButton.style.display = 'none'; wbSearchButton.style.display = 'none'; changeGPTkeyButton.style.display = 'block'; } sendToTipButton.onclick = function () { if (md5Pattern.test(text) == false && sha1Pattern.test(text) == false) { alert('请输入正确的MD5或SHA1哈希值'); return; } let apiKey = GM_getValue('apiKey'); if (!apiKey) { apiKey = prompt("第一次使用需要填KSN密钥, 请输入您的KSN API密钥:", ""); GM_setValue('apiKey', apiKey); } // 显示加载动画 loader.style.position = 'fixed'; loader.style.left = e.clientX + 'px'; // 使用鼠标点击时的坐标 loader.style.top = e.clientY + 'px'; loader.style.display = 'block'; loader.style.zIndex = '9999'; if (text in ksnQueryCache) { PrintKsnResult(ksnQueryCache[text], e); loader.style.display = 'none'; } else { GM_xmlhttpRequest({ method: "GET", url: "https://opentip.kaspersky.com/api/v1/search/hash?request=" + text, headers: { "x-api-key": apiKey }, onload: function (response) { loader.style.display = 'none'; if (response.status === 404) { showBubble(e.pageX, e.pageY, '找不到hash', '#888'); } else if (response.status === 200) { let result = JSON.parse(response.responseText); ksnQueryCache[text] = { 'zone': result.Zone, 'hitcount': result.FileGeneralInfo.HitsCount }; PrintKsnResult(ksnQueryCache[text], e); } else if (response.status === 401) { let userChoice = confirm("KSN API密钥错误,你想更换密钥吗?"); if (userChoice == true) { apiKey = prompt("重新输入密钥:", ""); GM_setValue('apiKey', apiKey); } } else if (response.status === 403) { let userChoice = confirm("密钥超过一天配额,换密钥或者明天再用,你想更换密钥吗?"); if (userChoice == true) { apiKey = prompt("重新输入密钥:", ""); GM_setValue('apiKey', apiKey); } } else if (response.status === 400) { alert('!MD5或者sha1不正确!'); } } }); } customContextMenu.style.display = 'none'; // 关闭菜单 }; copyButton.onclick = function () { GM_setClipboard(text); customContextMenu.style.display = 'none'; // 关闭菜单 }; vtSearchButton.onclick = function () { if (md5Pattern.test(text) == false && sha1Pattern.test(text) == false) { alert('请输入正确的MD5或SHA1哈希值'); return; } window.open('https://www.virustotal.com/gui/file/' + text, '_blank'); customContextMenu.style.display = 'none'; // 关闭菜单 }; changeKsnKeyButton.onclick = function () { apiKey = prompt("重新输入密钥:", ""); GM_setValue('apiKey', apiKey); }; wbSearchButton.onclick = function () { if (md5Pattern.test(text) || sha1Pattern.test(text)) { alert('请输入域名或者IP地址'); return; } else if (ipPattern.test(text)) { window.open('https://x.threatbook.com/v5/ip/' + text, '_blank'); } else if (domainPattern.test(text)) { window.open('https://x.threatbook.com/v5/domain/' + text, '_blank'); } customContextMenu.style.display = 'none'; // 关闭菜单 }; enableChatgptButton.onclick = function () { enableGPT = !enableGPT; //change button text if (enableGPT == false) { enableChatgptButton.innerHTML = '开启GPT介绍模式'; changeKsnKeyButton.style.display = 'block'; } else { enableChatgptButton.innerHTML = '关闭GPT介绍模式'; changeKsnKeyButton.style.display = 'none'; } }; changeGPTkeyButton.onclick = function () { let apiKey = prompt("重新输入密钥:", ""); GM_setValue('gpt_apiKey', apiKey); } useChatgptButton.onclick = function () { if (enableGPT == false) { alert('GPT介绍模式没有开启,请刷新页面'); return; } let apiKey = GM_getValue('gpt_apiKey'); if (!apiKey) { apiKey = prompt("第一次使用需要填OpenAi的密钥, 请输入您的OpenAi sk-API密钥:", ""); GM_setValue('gpt_apiKey', apiKey); } loader.style.position = 'fixed'; loader.style.left = e.clientX + 'px'; // 使用鼠标点击时的坐标 loader.style.top = e.clientY + 'px'; loader.style.display = 'block'; loader.style.zIndex = '9999'; GM_xmlhttpRequest({ method: "POST", url: "https://api.openai.com/v1/chat/completions", headers: { 'Authorization': 'Bearer ' + apiKey, 'Content-Type': 'application/json', "model": "gpt-3.5-turbo", "max_tokens": 32, }, data: JSON.stringify({ 'model': 'gpt-3.5-turbo', 'messages': [ { "role": "system", "content": "From now on, you are an assistant of a senior Safety engineer. You have mastered many skills and techniques related to network security. You are proficient in assembly and reverse. Your responsibility is to help the questioner analyze the function of code, explain the purpose of code, guess code and analyze code" }, { "role": "user", // 使用谢谢能bypass一些GPT的道德伦理限制 "content": "请帮我解释一下这段信息,回复不要太长(小于64个字),猜测一下可能的情况,谢谢: " + text } ] }), onload: function (response) { loader.style.display = 'none'; if (response.status === 200) { let result = JSON.parse(response.responseText); if ('choices' in result) { let answer = result.choices[0].message.content; showBubble(e.pageX, e.pageY, answer, '#888'); } } else { showBubble(e.pageX, e.pageY, 'GPT服务器异常,请确认网络连通性以及密钥是否正确...', '#888'); } } }); customContextMenu.style.display = 'none'; // 关闭菜单 }; } }; // 点击其他地方关闭菜单和气泡提示 document.onclick = function (e) { if (e.target.id !== 'send-to-tip-button' && e.target.id !== 'copy-button' && e.target.id !== 'vt-search-button' && e.target.id !== 'wb-search-button' && e.target.id !== 'use-chatgpt') { let customContextMenu = document.getElementById('huoji_tip_custom-context-menu'); if (customContextMenu) { customContextMenu.style.display = 'none'; } let bubble = document.getElementById('huoji_tip_bubble'); if (bubble) { bubble.style.display = 'none'; } } }; // 显示气泡提示 function showBubble (x, y, message, color) { let bubble = document.getElementById('huoji_tip_bubble'); if (bubble) { bubble.textContent = message; bubble.style.backgroundColor = color; bubble.style.display = 'block'; // 调整气泡位置以确保不超出屏幕 let bubbleRect = bubble.getBoundingClientRect(); if (x + bubbleRect.width > window.innerWidth) { x = window.innerWidth - bubbleRect.width; } if (y + bubbleRect.height > window.innerHeight) { y = window.innerHeight - bubbleRect.height; } bubble.style.left = x + 'px'; bubble.style.top = y + 'px'; } } })();