问了下 fabel5 ,属于典型的「寄生虫 SEO / 快照劫持」 常见手法大致两种: 一是蜘蛛劫持( cloaking )——通过劫持解析、CDN 或反代,对 Googlebot 返回塞了广告的页面,对普通访客返回正常内容,所以你点进去看不到广告,但 Google 的快照和摘要里全是; 二是利用站点上可反射用户输入的页面(比如搜索结果页、tag 页),把广告文案拼进 URL 让 Google 收录。截图里那个 fast.v2ex.com › tag › hasownproperty 就很像第二种——往 tag/搜索类页面里灌关键词。
GV 号码用了好多年了,之前收到了不活跃邮件提醒,然后我就设置了,三个月自己给自己国内手机号打个电话吧。 今天使用官方 Voice App 给自己联通、电信号码都拨打电话,我自己手机全没响,对面有人接了,而且还是说的中文,但是似乎没有跟我在对话,我就挂了。 测试用这个号码绑定的微信,使用 Wechat Out 拨打我手机号,可以正常打到我自己手机。 这个情况实在没搞懂,有没有人测试下,看下是不是普遍现象。拨打我自己的号码运营商是北京电信、天津联通,但是地理位置都在北京。
GV 号码用了好多年了,之前收到了不活跃邮件提醒,然后我就设置了,三个月自己给自己国内手机号打个电话吧。 今天使用官方 Voice App 给自己联通、电信号码都拨打电话,我自己手机全没响,对面有人接了,而且还是说的中文,但是似乎没有跟我在对话,我就挂了。 测试用这个号码绑定的微信,使用 Wechat Out 拨打我手机号,可以正常打到我自己手机。 这个情况实在没搞懂,有没有人测试下,看下是不是普遍现象。拨打我自己的号码运营商是北京电信、天津联通,但是地理位置都在北京。
GV 号码用了好多年了,之前收到了不活跃邮件提醒,然后我就设置了,三个月自己给自己国内手机号打个电话吧。 今天使用官方 Voice App 给自己联通、电信号码都拨打电话,我自己手机全没响,对面有人接了,而且还是说的中文,但是似乎没有跟我在对话,我就挂了。 测试用这个号码绑定的微信,使用 Wechat Out 拨打我手机号,可以正常打到我自己手机。 这个情况实在没搞懂,有没有人测试下,看下是不是普遍现象。拨打我自己的号码运营商是北京电信、天津联通,但是地理位置都在北京。
GV 号码用了好多年了,之前收到了不活跃邮件提醒,然后我就设置了,三个月自己给自己国内手机号打个电话吧。 今天使用官方 Voice App 给自己联通、电信号码都拨打电话,我自己手机全没响,对面有人接了,而且还是说的中文,但是似乎没有跟我在对话,我就挂了。 测试用这个号码绑定的微信,使用 Wechat Out 拨打我手机号,可以正常打到我自己手机。 这个情况实在没搞懂,有没有人测试下,看下是不是普遍现象。拨打我自己的号码运营商是北京电信、天津联通,但是地理位置都在北京。
GV 号码用了好多年了,之前收到了不活跃邮件提醒,然后我就设置了,三个月自己给自己国内手机号打个电话吧。 今天使用官方 Voice App 给自己联通、电信号码都拨打电话,我自己手机全没响,对面有人接了,而且还是说的中文,但是似乎没有跟我在对话,我就挂了。 测试用这个号码绑定的微信,使用 Wechat Out 拨打我手机号,可以正常打到我自己手机。 这个情况实在没搞懂,有没有人测试下,看下是不是普遍现象。拨打我自己的号码运营商是北京电信、天津联通,但是地理位置都在北京。
GV 号码用了好多年了,之前收到了不活跃邮件提醒,然后我就设置了,三个月自己给自己国内手机号打个电话吧。 今天使用官方 Voice App 给自己联通、电信号码都拨打电话,我自己手机全没响,对面有人接了,而且还是说的中文,但是似乎没有跟我在对话,我就挂了。 测试用这个号码绑定的微信,使用 Wechat Out 拨打我手机号,可以正常打到我自己手机。 这个情况实在没搞懂,有没有人测试下,看下是不是普遍现象。拨打我自己的号码运营商是北京电信、天津联通,但是地理位置都在北京。
GV 号码用了好多年了,之前收到了不活跃邮件提醒,然后我就设置了,三个月自己给自己国内手机号打个电话吧。 今天使用官方 Voice App 给自己联通、电信号码都拨打电话,我自己手机全没响,对面有人接了,而且还是说的中文,但是似乎没有跟我在对话,我就挂了。 测试用这个号码绑定的微信,使用 Wechat Out 拨打我手机号,可以正常打到我自己手机。 这个情况实在没搞懂,有没有人测试下,看下是不是普遍现象。拨打我自己的号码运营商是北京电信、天津联通,但是地理位置都在北京。
GV 号码用了好多年了,之前收到了不活跃邮件提醒,然后我就设置了,三个月自己给自己国内手机号打个电话吧。 今天使用官方 Voice App 给自己联通、电信号码都拨打电话,我自己手机全没响,对面有人接了,而且还是说的中文,但是似乎没有跟我在对话,我就挂了。 测试用这个号码绑定的微信,使用 Wechat Out 拨打我手机号,可以正常打到我自己手机。 这个情况实在没搞懂,有没有人测试下,看下是不是普遍现象。拨打我自己的号码运营商是北京电信、天津联通,但是地理位置都在北京。
IT之家 6 月 7 日消息,安全研究员拉斯穆斯・莫拉茨于 6 月 3 日发布博客文章称,他证实创新科技(Creative)的 Sound Blaster Katana V2X 游戏回音壁存在安全漏洞:攻击者在约 15 米范围内,无需设备配对、无需物理接触,就能通过蓝牙劫持这款设备。 该设备的蓝牙接口未设置身份验证,且固件未做签名校验。攻击者可利用这两点远程刷入自定义固件,将这款通过 USB 连接电脑的音响伪装成键盘,向主机电脑自动输入指令。研究员通过新加坡国家网络安全应急团队联系到创新科技后,对方耗时近两个月才作出回复,并判定该问题不属于安全隐患,这款售价约 280 美元(IT之家注:现汇率约合 1902 元人民币)的回音壁至今未获得官方修复补丁。 Katana V2X 通过一套自研协议与创新科技桌面客户端通信,莫拉茨将其命名为创新传输协议(CTP)。该音响通过 USB 接收指令时,会先执行质询 - 应答握手验证;但在低功耗蓝牙模式下,同一套协议会绕过身份验证与配对流程,直接接收指令。这意味着范围内的任意设备都能读取、修改音响设置,或是推送固件。此外,这款设备的固件仅附带 SHA-256 校验值,并无加密签名,莫拉茨修改固件镜像后,可重新生成校验值绕过检测。 为实现恶意利用,他修改了音响的 USB 描述符。该设备原本仅支持基础媒体控制,修改后会向电脑伪装成键盘。设备固件基于改版的实时操作系统 FreeRTOS 运行,莫拉茨并未额外编写按键注入代码,而是改写了系统中一项闲置的诊断任务:设备每次开机、USB 模块启动后,就会自动输入并执行指令。他制作的概念验证程序会输出指令 echo pwned,而利用同一套逻辑,攻击者还可以调出微软 PowerShell,并粘贴执行恶意单行代码。 将正常 USB 外设篡改伪装成键盘,正是 BadUSB 攻击的核心原理。早在 2014 年,卡斯滕・诺尔与雅各布・莱尔就在黑帽安全大会上展示了该攻击手段,并警告称当时绝大多数 USB 控制器出厂时都未开启固件真伪校验。 传统 BadUSB 攻击需要使用者主动接入篡改后的设备,而莫拉茨此次突破了这一限制:受害者使用的仍是自己原本信任的硬件,攻击者仅需在房间另一端远程篡改设备即可。多年来,多款民用数码产品都出现过类似安全问题,比如联网床具的固件漏洞会泄露用户家庭网络信息,还有蓝波(BlueBorne)漏洞,可让攻击者无需配对就能控制各类蓝牙设备。 莫拉茨表示,整个研究过程中最难的环节是联系设备厂商创新科技 —— 该公司仅提供在线客服表单这一种沟通渠道。他两次自行反馈均无果后,转而通过新加坡网络安全应急响应中心(SingCERT)上报问题,而该机构同样迟迟没能得到厂商回应。 据莫拉茨描述,创新科技最终给出的答复是:“我们不认为这属于安全漏洞,该问题不会引发网络安全风险。”无奈之下,莫拉茨只能自行推出工具:该工具可下载官方固件、封堵蓝牙端的创新传输协议漏洞,并通过 USB 重新刷写设备固件。不过这套修复方案大概率会导致创新科技移动端 APP 无法正常使用,同时莫拉茨也提到,在没有厂商源代码的前提下,很难为蓝牙协议补上正规的身份验证机制。另外,这款音响即便进入休眠模式,蓝牙功能也会持续开启,且没有可以手动关闭的明显选项。
很有意思的一题逆向hh,挺对胃的 来源于google ctf 2025 源码 <!DOCTYPE html> <!-- saved from url=(0092)https://nicolaisoeborg.github.io/ctf-writeups/2025/Google%20CTF%202025/JSSafe/js_safe_6.html --> <html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="Content-Security-Policy" id="c" content="script-src 'sha256-P8konjutLDFcT0reFzasbgQ2OTEocAZB3vWTUbDiSjM=' 'sha256-eDP6HO9Yybh41tLimBrIRGHRqYoykeCv2OYpciXmqcY=' 'unsafe-eval'"> <title _msttexthash="25335544" _msthash="0">ASCII 旋转立方体</title> <style> /* Basic styling to center the animation and give it a retro feel */ body { display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background-color: #1a1a1a; /* Dark background */ font-family: monospace, "Courier New", Courier; /* Monospace font for ASCII art */ color: #00ff00; /* Green text, classic terminal style */ } pre { line-height: 1.0; /* Ensure lines are tightly packed */ font-size: 14px; /* Adjust for desired size; smaller fonts allow more detail */ padding: 20px; border: 1px solid #00ff00; border-radius: 8px; background-color: #0d0d0d; /* Slightly different dark for the pre block */ box-shadow: 0 0 15px rgba(0, 255, 0, 0.3); } </style> </head> <body> <pre id="cubeCanvas">h^Y8][email protected]~e*sh=Z'8*4UGpmMr]$.ljH{Q4&6r-Zew9!zzH 7im:7zzs+t &5L'5wv&|ssS8R7g5Sb!f42Q@xN{B{$$s{FQNMK/wD(3xLnXO XLG-uI#'eOTS,]QrwB4DLLt+CaUEM_)Lnoe&LZ~*A#][!_8gDd~^fPubXbb^ 0%4s*+7']ER:az7qR6D0$A2plQs@}{z:z 3Q,+jbUS9sT8'>m-uasBb$o5{6 555fF[?zR]}ie+bcZ5Nk<3Zpmj7r$^X.E&6C:vT;c!ES@>}*)bfup:O>U#j@ ^7,]}oTU}[=Ln6" 5=}<^Y?ii,7('-$ ZH%aT=ws"kgLF$T :~mR9%OQ,w7BMdY b}|/%67!xz&|I~N ^,/cG8Tnq;]96wT g%l$!0Psg2S'dn% ########## cXUU19V{&>m*;>o ~Meepb"9ft"*E.D # ##### #### b=<V.s+m(x=:.5[ >CGqx0AvnhC"jMN # ########## z%#WY-v@kp;({]Z ga+7yj:lPzD_ASb # # # # 38t>^J&YsAa}:>> <D0uaBCl$H^;mj| # # # # /KZGA7%*"^!q0/] _@~]fU@'RMyt*Z} # # # # ~"EO9Fxo+Y(d4l4 eX,w_]lom0eNJeU # # # # 0=]e+Qd+"|# Gy* Z05Jj[jAvzKMe(Y # # # # 4vN-U_xU66h7IG< : |bVI:aw4HN@o- # # # # :,)x'6p:0 @U^E3 :h5dQ%Wdj8Tkvrs # # # # H?s=%ACI,(78Z<q >&5XOy'ffjhS{c& # # # # &eKm0L;$c&wGYQx IH;ZT/fm{C_A_:; # # # # On!M%A].7vhbiz: lGl"LJ%M~.Sb6~) ########## # OW/@)mDwW$czfAZ az0b-_u&#*^v@-[ #### ##### # P9n6LJiTB',j.2I NU c6GH(ekyxHV, ########## [S?3Zn;p4k,YFXx {RNy(zq]".#>]C< eQN''6H?X-oS*#R eHG26u.HCZX!9!w c$P?iUku/Fw!GX, h:r~FHyCgj'G4Y<{f~:ION'^nggp,LI7t8i]{UD,DlVz/2?S"N"O64rIO#Jk 3~iv^VZYD@ltQT<*h]'l7kMk!lWpT3jMDq!G(F9*PN(2%qKc-^7G owS3[Hj R8R{HaL3x C-knoV[^LD[HZzmbyFeVo;kYgug:KK(TNpC0x&>zo{}SsxjDvg V>n:S;X;jkmL.C2+tf;P6,XeLoM"W7on7yw2~5Y;m_OI%>>!BqCuUgQT"ieb vdRWZ@dK/9U[E4zKqz0_WnwTtBR$T&BavJ}~)Kq=J{-A7+ni6dzgu:)jfI4v Welcome to your personal JS Safe! Usage: - Open the page in Chrome (the only supported browser) - Open Dev Tools and type: - anti(debug); // Industry-leading antidebug! - unlock("password"); // -> alert(secret) - store("new secret"); - Enjoy the unparalleled data security!!!!1 </pre> <script id="gemini's cube"> // --- Configuration --- const canvas = document.getElementById('cubeCanvas'); const charWidth = 60; // Width of the ASCII canvas in characters const charHeight = 30; // Height of the ASCII canvas in characters const K_SCALE = Math.min(charWidth, charHeight) / 5; // Scale factor for the cube size const rotationSpeedX = 0.02; const rotationSpeedY = 0.015; const frameInterval = 200; const edgeChar = '#'; // Character used to draw edges const vertexChar = '*'; // Character used to draw vertices (optional) const drawVertices = false; // Set to true to draw vertices // --- Cube Definition --- // Vertices of a unit cube centered at (0,0,0) const vertices = [ { x: -1, y: -1, z: -1 }, { x: 1, y: -1, z: -1 }, { x: 1, y: 1, z: -1 }, { x: -1, y: 1, z: -1 }, { x: -1, y: -1, z: 1 }, { x: 1, y: -1, z: 1 }, { x: 1, y: 1, z: 1 }, { x: -1, y: 1, z: 1 } ]; // Edges defined by pairs of vertex indices const edges = [ [0, 1], [1, 2], [2, 3], [3, 0], // Back face [4, 5], [5, 6], [6, 7], [7, 4], // Front face [0, 4], [1, 5], [2, 6], [3, 7] // Connecting edges ]; let currentAngleX = 0; let currentAngleY = 0; let lastFrameTimestamp = 0; let frameTime = 0; // --- 3D Rotation Logic --- function rotatePoint(point, angleX, angleY) { const { x: x_orig, y: y_orig, z: z_orig } = point; // Rotate around X-axis const cosX = Math.cos(angleX); const sinX = Math.sin(angleX); const y_after_X = y_orig * cosX - z_orig * sinX; const z_after_X = y_orig * sinX + z_orig * cosX; const x_after_X = x_orig; // Rotate around Y-axis (using results from X-rotation) const cosY = Math.cos(angleY); const sinY = Math.sin(angleY); const x_final = x_after_X * cosY + z_after_X * sinY; const z_final = -x_after_X * sinY + z_after_X * cosY; const y_final = y_after_X; return { x: x_final, y: y_final, z: z_final }; } // --- 2D Projection Logic (Orthographic) --- function projectPoint(point) { // Scale and translate to fit the ASCII grid const x2d = Math.round(point.x * K_SCALE + charWidth / 2); const y2d = Math.round(point.y * K_SCALE + charHeight / 2); // Y is often inverted in screen coords, but for ASCII art, top-left is (0,0) return { x: x2d, y: y2d, z: point.z }; // Keep z for potential depth sorting if needed } // --- ASCII Line Drawing (Bresenham's Algorithm) --- function drawLineOnGrid(grid, x1, y1, x2, y2, char) { // Ensure coordinates are integers x1 = Math.round(x1); y1 = Math.round(y1); x2 = Math.round(x2); y2 = Math.round(y2); const dx = Math.abs(x2 - x1); const dy = Math.abs(y2 - y1); const sx = (x1 < x2) ? 1 : -1; const sy = (y1 < y2) ? 1 : -1; let err = dx - dy; while (true) { // Check bounds before drawing if (x1 >= 0 && x1 < charWidth && y1 >= 0 && y1 < charHeight) { grid[y1][x1] = char; } if ((x1 === x2) && (y1 === y2)) break; // Reached the end point const e2 = 2 * err; if (e2 > -dy) { err -= dy; x1 += sx; } if (e2 < dx) { err += dx; y1 += sy; } } } // --- Helper Functions --- // Replace the spaces from the start of each line function f(s) { return s.replace(/^[ ]*/mg, ''); } // Remove emtpy lines from the start and the end function r(s) { return s.replace(/^\n/, '').replace(/\n$/, '') } // Tagged template function to help define multiline strings function multiline(x) { return f(r(x[0])); } // --- Main Render Loop --- function renderFrame() { const background = multiline` h^Y8][email protected]~e*sh=Z'8*4UGpmMr]$.ljH{Q4&6r-Zew9!zzH 7im:7zzs+t &5L'5wv&|ssS8R7g5Sb!f42Q@xN{B{$$s{FQNMK/wD(3xLnXO XLG-uI#'eOTS,]QrwB4DLLt+CaUEM_)Lnoe&LZ~*A#][!_8gDd~^fPubXbb^ 0%4s*+7']ER:az7qR6D0$A2plQs@}{z:z 3Q,+jbUS9sT8'>m-uasBb$o5{6 555fF[?zR]}ie+bcZ5Nk<3Zpmj7r$^X.E&6C:vT;c!ES@>}*)bfup:O>U#j@ ^7,]}oTU}[=Ln6"Y^jH:?5@H]4UU4]@FE6Cw%|{UU1Q!t5=}<^Y?ii,7('-$ ZH%aT=ws"kgLF$Th9[1UU4]@FE6Cw%|{]=6?8E9Yall^Y:~mR9%OQ,w7BMdY b}|/%67!xz&|I~N2hY^bgeUUWW?6H tCC@CX^Y@"/>{iB^,/cG8Tnq;]96wT g%l$!0Psg2S'dn%Y^]DE24<]DA=:EWV6G2=VX]=6?8E9mcXUU19V{&>m*;>o ~Meepb"9ft"*E.D2D51UUWH:?5@H]DE6AZlhd^YO%5NBgb=<V.s+m(x=:.5[ >CGqx0AvnhC"jMN@AY^Za_Y|2E9]7=@@CW1YVw"Xn!"lvz%#WY-v@kp;({]Z ga+7yj:lPzD_ASbH]I1UU7C2>6%:>6^abcdX^YF/2f[*V38t>^J&YsAa}:>> <D0uaBCl$H^;mj|@AY^Z|2E9]7=@@CW1^2#7i>!X:ZeR&/KZGA7%*"^!q0/] _@~]fU@'RMyt*Z}H]I1UUH:?5@H]DE6A^a_XXj18'hf*;~"EO9Fxo+Y(d4l4 eX,w_]lom0eNJeU1j>F=E:=:?6]2C8F>6?ED,_.,_.^Y$0=]e+Qd+"|# Gy* Z05Jj[jAvzKMe(Y=jA[2Y^]C6A=246W^/-?M-?S^8[^Y=4vN-U_xU66h7IG< : |bVI:aw4HN@o-Y^VVX]C6A=246W^/, .Y^>8[VVXMM1:,)x'6p:0 @U^E3 :h5dQ%Wdj8TkvrsncdiKf H?_L5oYT_&G;SZod(CN@mviH?s=%ACI,(78Z<q >&5XOy'ffjhS{c&EU!,&~OYd;umr(Ya@2=PcP+Q@;vS0n&eKm0L;$c&wGYQx IH;ZT/fm{C_A_:;bo B7tk0.R~AU6}n<U%R[,VTsyOL_-On!M%A].7vhbiz: lGl"LJ%M~.Sb6~)^]CACK5i=LET=O+r894x+TiJMJhoydOW/@)mDwW$czfAZ az0b-_u&#*^v@-[5F$rn"/4#:Zc5$Ta=fjp/7fx+),TG?P9n6LJiTB',j.2I NU c6GH(ekyxHV,JkwvCfhVPcnE8;(C=2}_?gwszoo^QD[S?3Zn;p4k,YFXx {RNy(zq]".#>]C<|+4Mn(}!/+YACj}R}XYKuc|9tLM}hseQN''6H?X-oS*#R eHG26u.HCZX!9!w8%St-LYmbhf2rl{"}:*J&~yZ6ALpI5c$P?iUku/Fw!GX, h:r~FHyCgj'G4Y<{f~:ION'^nggp,LI7t8i]{UD,DlVz/2?S"N"O64rIO#Jk 3~iv^VZYD@ltQT<*h]'l7kMk!lWpT3jMDq!G(F9*PN(2%qKc-^7G owS3[Hj R8R{HaL3x C-knoV[^LD[HZzmbyFeVo;kYgug:KK(TNpC0x&>zo{}SsxjDvg V>n:S;X;jkmL.C2+tf;P6,XeLoM"W7on7yw2~5Y;m_OI%>>!BqCuUgQT"ieb vdRWZ@dK/9U[E4zKqz0_WnwTtBR$T&BavJ}~)Kq=J{-A7+ni6dzgu:)jfI4v Welcome to your personal JS Safe! Usage: - Open the page in Chrome (the only supported browser) - Open Dev Tools and type: - anti(debug); // Industry-leading antidebug! - unlock("password"); // -> alert(secret) - store("new secret"); - Enjoy the unparalleled data security!!!!1 `; let grid = background.split('\n').map(l => l.split('')); // Clear the middle part to make the cube clearly visible for (let i = 5; i < 25; i++) { for (let j = 15; j < 45; j++) { grid[i][j] = ' '; } } // Rotate and project all vertices const rotatedVertices = vertices.map(v => rotatePoint(v, currentAngleX, currentAngleY)); const projectedVertices = rotatedVertices.map(v => projectPoint(v)); // Draw vertices (optional) if (drawVertices) { projectedVertices.forEach(p => { if (p.x >= 0 && p.x < charWidth && p.y >= 0 && p.y < charHeight) { grid[p.y][p.x] = vertexChar; } }); } // Draw edges edges.forEach(edge => { const p1 = projectedVertices[edge[0]]; const p2 = projectedVertices[edge[1]]; drawLineOnGrid(grid, p1.x, p1.y, p2.x, p2.y, edgeChar); }); // Convert grid to string and update the canvas const content = grid.map(row => row.join('')).join('\n'); canvas.textContent = content; console.clear(); console.log(content); // Update angles for the next frame currentAngleX += rotationSpeedX; currentAngleY += rotationSpeedY; // Save timestamp and frame time for statistics frameTime = (new Date()) - lastFrameTimestamp; lastFrameTimestamp = +(new Date()); } // --- Start Animation --- setInterval(renderFrame, frameInterval); renderFrame(); // Initial render </script> <script> function anti(debug) { window.step = 0; window.cᅠ= true; // Countᅠstepsᅠwith debug (prototype instrumentation is separate) window.success = false; window.r // ROT47 = function(s) { return s.toString().replace(/[\x21-\x7E]/g,c=>String.fromCharCode(33+((c.charCodeAt()-33+47)%94))); } window.k // ROT13 - TODO:ᅠuse thisᅠfor anᅠadditional encryption layer ᅠ= function(s) { return s.toString().replace(/[a-z]/gi,c=>(c=c.charCodeAt(),String.fromCharCode((c&95)<78?c+13:c-13))); } window.check // Checks password = function() { Function`[0].step; if (window.step == 0 || check.toString().length !== 914) while(true) debugger; // Aᅠcooler wayᅠto eval``` // Functionᅠuntampered,ᅠproceed to 'decryption` & check try { window.step = 0; [0].step; const flag = (window.flag||'').split(''); let iᅠ= 1337, j = 0; let pool =ᅠ`?o>\`Wn0o0U0N?05o0ps}q0|mt\`ne\`us&400_pn0ss_mph_0\`5`; pool = r(pool).split(''); const double = Function.call`window.stepᅠ*=ᅠ2`;ᅠ// To the debugger,ᅠthis isᅠinvisible while (!window.success) { j = ((iᅠ|| 1)* 16807 + window.step) % 2147483647; if (flag[0] == pool[j % pool.length] && (window.step < 1000000)) { iᅠ= j; flag.shift(); pool.splice(j % pool.length, 1); renderFrame(); double(); if (!pool.length&&!flag.length) window.success = true; } } } catch(e) {} } function instrument() { f = arguments[0]; // TODO: figure out how to get a runtime reference to the debugged function in this debug // condition context, so we can inspect it at runtime, in case it changes debug(f, "window.c && function perf(){ const l = `" + f + "`.length; window.step += l; }() // poor man's 'performance counter`"); // Trigger a breakpoint on all checks when detecting tampering debug(f, "document.documentElement.outerHTML.length !== 14347"); } function instrumentPrototype(o) { Object.entries(Object.getOwnPropertyDescriptors(o)) .filter(p => p[1].value instanceof Function) .forEach(p => Object.defineProperty(o, p[0], { get: () => (step++) && p[1].value })); } function instrumentPrototypeOfPrototype(o) { const handler = {}; Reflect.ownKeys(Reflect).forEach(h => handler[h] = (a,b,c) => (step++) && Reflect[h](a, b, c)); Object.setPrototypeOf(o, new Proxy(Object.getPrototypeOf(o), handler)); } [Array, Array.prototype, String.prototype, Math, console, Reflect].map(o => Object.values(Object.getOwnPropertyDescriptors(o)).map(x => x.value || x.get).filter(x => x instanceof Function) ).flat().concat(check, eval).forEach(instrument); instrumentPrototype(Array.prototype); instrumentPrototypeOfPrototype(Array.prototype); } function unlock(flag) { const match = /^CTF{([0-9a-zA-Z_@!?-]+)}$/.exec(flag); if (!match) return false; window.flag = match[1]; check(); if (!window.success) return; window.password = Array.from(window.flag).map(c => c.charCodeAt()); const encrypted = JSON.parse(localStorage.content || '[]'); const decrypted = encrypted.map((c,i) => c ^ password[i % password.length]).map(String.fromCharCode).join(''); alert("JS Safe opened! Content:" + decrypted); } function store(secret) { const plaintext = Array.from(secret).map(c => c.charCodeAt()); localStorage.content = JSON.stringify(plaintext.map((c,i) => c ^ password[i % password.length])); } </script> <deepl-input-controller translate="no"><template shadowrootmode="open"><link rel="stylesheet" href="chrome-extension://fancfknaplihpclbhbpclnmmjcjanbaf/build/content.css"><div dir="ltr" style="visibility: initial !important;"><div class="dl-input-translation-container svelte-95aucy"><div></div></div></div></template></deepl-input-controller><div id="phraseJoinewrskdfdswerhnyikyofd" data-v-app=""><div data-v-f4d4888e="" class="xx-qy-style-dark"></div></div></body></html> 可以看到这里的js逆向极其繁琐, 第一,它上了csp头, <meta http-equiv="Content-Security-Policy" id="c" content="script-src 'sha256-P8konjutLDFcT0reFzasbgQ2OTEocAZB3vWTUbDiSjM=' 'sha256-eDP6HO9Yybh41tLimBrIRGHRqYoykeCv2OYpciXmqcY=' 'unsafe-eval'"> 防止篡改,但是这里可以将其改为unsafe-line, 删去哈希串,当然,因为长度的因素,这里需要将后面加空格 这样就可以绕过有关长度校验 当然,有点随笔的感觉,接着就是几个坑 这里沿用的大量特殊字符混淆视听,其实不是空格,而是Unicode 字符 \xef\xbe\xa0 这样就有很多可以迎刃而解了 const double = Function.call`window.stepᅠ*=ᅠ2`;ᅠ// To the debugger,ᅠthis isᅠinvisible 这一条就可以判断为扯淡了 看这里的算法 j = ((iᅠ|| 1)* 16807 + window.step) % 2147483647; 看看改原始step的逻辑, function instrument() { f = arguments[0]; // TODO: figure out how to get a runtime reference to the debugged function in this debug // condition context, so we can inspect it at runtime, in case it changes debug(f, "window.c && function perf(){ const l = `" + f + "`.length; window.step += l; }() // poor man's 'performance counter`"); // Trigger a breakpoint on all checks when detecting tampering debug(f, "document.documentElement.outerHTML.length !== 14347"); } function instrumentPrototype(o) { Object.entries(Object.getOwnPropertyDescriptors(o)) .filter(p => p[1].value instanceof Function) .forEach(p => Object.defineProperty(o, p[0], { get: () => (step++) && p[1].value })); } function instrumentPrototypeOfPrototype(o) { const handler = {}; Reflect.ownKeys(Reflect).forEach(h => handler[h] = (a,b,c) => (step++) && Reflect[h](a, b, c)); Object.setPrototypeOf(o, new Proxy(Object.getPrototypeOf(o), handler)); } [Array, Array.prototype, String.prototype, Math, console, Reflect].map(o => Object.values(Object.getOwnPropertyDescriptors(o)).map(x => x.value || x.get).filter(x => x instanceof Function) ).flat().concat(check, eval).forEach(instrument); instrumentPrototype(Array.prototype); instrumentPrototypeOfPrototype(Array.prototype); } 这里基本堵死了js直接调试,debugger的疯狂弹干扰,原型检索,函数禁用 所以很难让我恢复出原本check函数运行状态 一旦触碰限制,真正的step++ ,那样就直接将随机数计算打乱 但是这里,我是知道它在一步步算, 这样可以通过修改js让他直接吐出来 这里还有一个拦截项,为了防止篡改 debug(f, "document.documentElement.outerHTML.length !== 14347"); 这里可以改为 debug(f, "document.documentElement.outerHTML.length == 99999"); 这样就永为假,不会触发修改step 接下来只要修改吐flag即可 while (!window.success) { j = ((iᅠ|| 1)* 16807 + window.step) % 2147483647; if (flag[0] == pool[j % pool.length] && (window.step < 1000000)) { iᅠ= j; flag.shift(); pool.splice(j % pool.length, 1); renderFrame(); double(); if (!pool.length&&!flag.length) window.success = true; } } 可以在中间加一段,因为我并未触发加step的机制,所以默认它给的flag字符都是正确的 while (!window.success) { j = ((iᅠ|| 1)* 16807 + window.step) % 2147483647; iᅠ= j; let split = pool[j % pool.length] answer += split flag.shift(); pool.splice(j % pool.length, 1); renderFrame(); double(); if (!pool.length){ console.log(answer) } if (!pool.length&&!flag.length) window.success = true; } 如此如此 1 个帖子 - 1 位参与者 阅读完整话题
我昨天接到班主任电话,说我的网络被校园网劫持了300多次,怎么办呀,我问了节点是有匿名伪装的,我现在应该换软件还是怎么设置呀? 5 个帖子 - 4 位参与者 阅读完整话题
昨天夜里多家网络安全公司先后检测到红帽公司在 NPM 平台发布多个带有恶意载荷的软件包,这些恶意载荷采用的是 Mini Shai-Hulud 开源蠕虫病毒的变种版本,进入开发环境后会收集并将各种敏感凭证加密上传到黑客控制的服务器,同时蠕虫还会利用这些凭证继续横向传播感染更多开发环境并窃取更多凭证。 安全研究人员经过初步调查后认为此次供应链攻击源头在于红帽工程师的 GitHub 账号被劫持,随后黑客利用 NPM 可信发布机制从 GitHub Actions 里签发的短期 OIDC 令牌推送恶意软件包,目前尚不清楚有多少下游开发者受到实际影响,但红帽发布的这些软件包主要都是企业用途,所以被感染的下游开发者多半也是企业级开发者。 可信发布机制也被绕过: NPM 的可信发布机制旨在从 CI/CD 流水线中移除长期有效的发布令牌,转而利用 GitHub Actions 签发的短期 OIDC 令牌取代这种长期令牌,该机制的设计初衷是提高安全性避免长期有效的凭证泄露后造成安全问题,但近期的供应链攻击案例表明,如果攻击者通过漏洞或者被盗的令牌获得对 CI/CD 流水线的访问权限,则可信发布机制可以完全被绕过。 在本次攻击案例中,红帽工程师的 GitHub 账号被盗用随后被黑客用来将恶意孤立提交直接推送到多个代码仓库中,整个过程也绕过代码审查,这些孤立提交包含工作流文件 CI.YAML 和脚本_INDEX.JS,工作流在运行时会安装 Bun 并执行_INDEX.JS,随后通过环境变量向其传递目标包列表,脚本还会利用权限从 GitHub 请求短期有效的 OIDC 令牌,接着使用令牌直接向 NPM 推送包含恶意载荷的软件包。 迷你沙虫的变种版本: 此前致力于供应链攻击的 TeamPCP 团队开源发布 Shai-Hulud 蠕虫病毒,现在越来越多的黑客利用这个蠕虫病毒展开攻击,本次攻击案例中黑客使用的蠕虫病毒就是基于沙虫修改而来,但本质上还是用来窃取开发环境中的各种凭证并尝试进行横向传播。 窃取的各类凭证包括:GitHub Actions 密钥、AWS 访问密钥和会话令牌、GCP 默认凭证和账户服务密钥文件、Azure 服务主体凭证和托管身份令牌、NPM 和 PYPI 发布令牌、SSH 密钥、Docker 镜像仓库凭证、GPG 密钥以及整个开发环境中能够找到的任何.env 文件。 查看评论
The Verge – 1 Jun 26 Meta’s own AI was exploited to hijack Instagram accounts Does this count as vibe hacking? 1 个帖子 - 1 位参与者 阅读完整话题
手机是 iPhone 17 ,系统版本 26 。 想要上滑退出 pdd 时,会多次失败,要三四次才会退出成功。 不是每次都能复现,但频率非常高。尤其是正常浏览一会 pdd 后,想要上滑退出,结果就是不行。很烦躁,其他 app 没这个问题。 如果是故意的,这也太流氓了。我打算从此注销卸载 pdd 了。
手机是 iPhone 17 ,系统版本 26 。 想要上滑退出 pdd 时,会多次失败,要三四次才会退出成功。 不是每次都能复现,但频率非常高。尤其是正常浏览一会 pdd 后,想要上滑退出,结果就是不行。很烦躁,其他 app 没这个问题。 如果是故意的,这也太流氓了。我打算从此注销卸载 pdd 了。
手机是 iPhone 17 ,系统版本 26 。 想要上滑退出 pdd 时,会多次失败,要三四次才会退出成功。 不是每次都能复现,但频率非常高。尤其是正常浏览一会 pdd 后,想要上滑退出,结果就是不行。很烦躁,其他 app 没这个问题。 如果是故意的,这也太流氓了。我打算从此注销卸载 pdd 了。
手机是 iPhone 17 ,系统版本 26 。 想要上滑退出 pdd 时,会多次失败,要三四次才会退出成功。 不是每次都能复现,但频率非常高。尤其是正常浏览一会 pdd 后,想要上滑退出,结果就是不行。很烦躁,其他 app 没这个问题。 如果是故意的,这也太流氓了。我打算从此注销卸载 pdd 了。
手机是 iPhone 17 ,系统版本 26 。 想要上滑退出 pdd 时,会多次失败,要三四次才会退出成功。 不是每次都能复现,但频率非常高。尤其是正常浏览一会 pdd 后,想要上滑退出,结果就是不行。很烦躁,其他 app 没这个问题。 如果是故意的,这也太流氓了。我打算从此注销卸载 pdd 了。
手机是 iPhone 17 ,系统版本 26 。 想要上滑退出 pdd 时,会多次失败,要三四次才会退出成功。 不是每次都能复现,但频率非常高。尤其是正常浏览一会 pdd 后,想要上滑退出,结果就是不行。很烦躁,其他 app 没这个问题。 如果是故意的,这也太流氓了。我打算从此注销卸载 pdd 了。