<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>HYLUZ</title><link>https://hyluz.cn/</link><description>HYLUZ.CN</description><item><title>Armbian 斐讯N1 盒子变成 Read-only File System</title><link>https://hyluz.cn/post/90406.html</link><description>&lt;p&gt;Armbian 斐讯N1 盒子变成 Read-only File System&lt;br&gt;原因是 N1 盒子 emmc 出现坏块导致，解决方法：用 U 盘启动 N1 盒子进入 Armbian，然后输入下面的命令：&lt;/p&gt;
&lt;p&gt;e2fsck /dev/mmcblk1p2&lt;br&gt;修复成功后拔掉 U 盘重启 N1 盒子。&lt;/p&gt;
</description><pubDate>Sun, 04 Jan 2026 00:39:43 +0800</pubDate></item><item><title>飞牛相册获取搜索结果失败处理</title><link>https://hyluz.cn/post/90405.html</link><description>&lt;p&gt;飞牛相册获取搜索结果失败处理&lt;br&gt;相册中可以按地点聚档，但是点击地点后获取搜索结果失败&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/12/202512132141452063310.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;导出日志报错&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;time=&amp;quot;2025-12-13T21:17:57+08:00&amp;quot; level=error msg=&amp;quot;open photo index name:2 error: cannot open index, metadata corrupt&amp;quot;
time=&amp;quot;2025-12-13T21:17:57+08:00&amp;quot; level=error msg=&amp;quot;add new photo index error:cannot open index, metadata corrupt&amp;quot;
time=&amp;quot;2025-12-13T21:17:57+08:00&amp;quot; level=error msg=&amp;quot;query user photo id list error: cannot open index, metadata corrupt&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;像索引相关问题&lt;/p&gt;
&lt;p&gt;在相册设置中重建索引后回复正常&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/12/202512132144203374205.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/12/202512132143401563310.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</description><pubDate>Sat, 13 Dec 2025 21:41:22 +0800</pubDate></item><item><title>渗透测试中交换机资产的应用</title><link>https://hyluz.cn/post/90404.html</link><description>&lt;p&gt;攻防演练打点过程中拿到了一台交换机的ssh权限；需要尝试利用交换机做跳板进入内网&lt;/p&gt;
&lt;h3 id=&quot;h3-u4EA4u6362u673Au4FE1u606Fu6536u96C6&quot;&gt;&lt;a name=&quot;交换机信息收集&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;交换机信息收集&lt;/h3&gt;&lt;p&gt;可用命令查询&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&amp;lt;F100-C-XI&amp;gt;?
User view commands:
  archive             Archive configuration
  backup              Backup operation
  boot-loader         Software image file management
  bootrom             Update/read/backup/restore bootrom
  cd                  Change current directory
  clock               Specify the system clock
  copy                Copy a file
  debugging           Enable system debugging functions
  debugging-auto-off  Automatically turn off all debugging
  delete              Delete a file
  diagnostic          Generic OnLine Diagnostics (GOLD) module
  diagnostic-logfile  Diagnostic log file configuration
  dialer              Specify Dial-on-Demand Routing(DDR) configuration
                      information
  dir                 Display files and directories on the storage media
  display             Display current system information
  erase               Alias for &amp;#39;delete&amp;#39;
  exception           Exception information configuration
  exit                Alias for &amp;#39;quit&amp;#39;
  fdisk               Partition a storage medium
  firmware            Firmware management
  fixdisk             Check and repair a storage medium
  format              Format a storage medium
  free                Release a connection
  ftp                 Open an FTP connection
  fuser               Display processes that are using a file system, directory,
                      or file
  gunzip              Decompress file
  gzip                Compress file
  install             Perform package management operation
  issu                In-Service Software Upgrade module
  l2vpn               Layer 2 Virtual Private Network (L2VPN) module
  loadbalance         Load Balancing module
  local-guest         Manage guest users
  locator             Locate devices
  lock                Lock the current line
  logfile             Log file configuration
  md5sum              Compute the hash digest of a file using the MD5 algorithm
  mkdir               Create a new directory
  monitor             System monitor
  more                Display the contents of a file
  mount               Mount a storage medium
  move                Move a file
  no                  Alias for &amp;#39;undo&amp;#39;
  ping                Ping function
  process             Process management
  pwd                 Display current working directory
  python              Source using python script
  quit                Exit from current command view
  reboot              Reboot operation
  refresh             Do soft reset
  rename              Rename a file or directory
  repeat              Repeat executing history commands
  reset               Reset operation
  restore             Restore operation
  rmdir               Remove an existing directory
  save                Save current configuration
  scheduler           Scheduler configuration
  scp                 Establish an SCP connection to an SCP server
  screen-length       Multiple-screen output function
  security-logfile    Security log file configuration
  send                Send information to other lines
  sftp                Establish an SFTP connection to an SFTP server
  sha256sum           Compute the hash digest of a file using the SHA256
                      algorithm
  show                Alias for &amp;#39;display&amp;#39;
  ssh2                Establish an Stelnet connection to an Stelnet server
  startup             Specify system startup parameters
  super               Switch to a user role
  system-view         Enter the System View
  tar                 Archive management
  tclquit             Exit from TCL shell
  tclsh               Enter the TCL shell
  telnet              Establish a telnet connection
  terminal            Set the terminal line characteristics
  test-aaa            Perform an AAA test
  tftp                Open a TFTP connection
  tracert             Tracert function
  umount              Unmount a storage medium
  undelete            Recover a deleted file
  undo                Cancel current setting
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;交换机中可以使用python、sftp&lt;br&gt;那么可以使用sftp上传脚本后使用python搭建socks代理服务器&lt;br&gt;确定python版本，交换机使用的python版本为2.7.3，不支持python3的一些新特性。因此代理服务的写法需要使用2.7.3的语法来写。&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/11/202511042116309871626.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;&lt;strong&gt;确定关键模块是否可用&lt;/strong&gt;&lt;br&gt;主要用到 socket,select,struct,threading 几个模块&lt;br&gt;&lt;strong&gt;测试模块是否存在&lt;/strong&gt;&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/11/202511042118519657622.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;&lt;strong&gt;编写代理服务&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;#coding:utf-8
import socket,select,struct,threading
HOST,PORT=&amp;#39;0.0.0.0&amp;#39;,10801
def handle(c):
    try:
        if c.recv(3)[0]==&amp;#39;\x05&amp;#39;:
            c.send(&amp;#39;\x05\x00&amp;#39;)
            d=c.recv(1024)
            if d[1]==&amp;#39;\x01&amp;#39;:
                r=socket.socket()
                if d[3]==&amp;#39;\x01&amp;#39;:
                    ip=socket.inet_ntoa(d[4:8])
                    p=struct.unpack(&amp;#39;&amp;gt;H&amp;#39;,d[8:10])[0]
                elif d[3]==&amp;#39;\x03&amp;#39;:
                    l=ord(d[4])
                    ip=d[5:5+l]
                    p=struct.unpack(&amp;#39;&amp;gt;H&amp;#39;,d[5+l:7+l])[0]
                r.connect((ip,p))
                c.send(&amp;#39;\x05\x00\x00\x01&amp;#39;+socket.inet_aton(&amp;#39;0.0.0.0&amp;#39;)+struct.pack(&amp;#39;&amp;gt;H&amp;#39;,1080))
                while 1:
                    rd,_,_=select.select([c,r],[],[],30)
                    if c in rd:
                        data=c.recv(4096)
                        if not data:break
                        r.send(data)
                    if r in rd:
                        data=r.recv(4096)
                        if not data:break
                        c.send(data)
                r.close()
    except:pass
    c.close()
s=socket.socket()
s.bind((HOST,PORT))
s.listen(5)
print(&amp;quot;SOCKS5 proxy on %s:%s&amp;quot;%(HOST,PORT))
while 1:
    try:
        c,a=s.accept()
        t=threading.Thread(target=handle,args=(c,))
        t.daemon=True
        t.start()
    except:pass&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;开启SFTP服务&lt;/strong&gt;&lt;br&gt;直接使用SFTP连接发现连不上，交换机默认SFTP服务没打开&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/11/202511042121389878509.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;&lt;strong&gt;上传代理服务脚本&lt;/strong&gt;&lt;br&gt;开启sftp以后就可以进行文件管理了，使用winscp连接上传脚本&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/11/202511042122342557775.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;&lt;strong&gt;启动代理&lt;/strong&gt;&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/11/202511042122579737333.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-u8FDEu63A5u6D4Bu8BD5&quot;&gt;&lt;a name=&quot;连接测试&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;连接测试&lt;/h3&gt;&lt;p&gt;goby测试&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/11/202511042124343527306.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;浏览器代理测试&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/11/202511042125164494693.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</description><pubDate>Tue, 04 Nov 2025 21:12:01 +0800</pubDate></item><item><title>5ire接入HexStrike AI MCP Agents报错Error Messages with role 'tool' must be a response to a preceding ...</title><link>https://hyluz.cn/post/90403.html</link><description>&lt;h3 id=&quot;h3-u95EEu9898u73B0u8C61&quot;&gt;&lt;a name=&quot;问题现象&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;问题现象&lt;/h3&gt;&lt;p&gt;在kali上搭好HexStrike服务后使用5ire接入，渗透测试时会报错&lt;br&gt;Error Messages with role ‘tool’ must be a response to a preceding message with ‘tool_calls’&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/10/202510102023374364745.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-u89E3u51B3u65B9u6CD5&quot;&gt;&lt;a name=&quot;解决方法&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;解决方法&lt;/h3&gt;&lt;p&gt;5ire版本太高了，用的是0.14.1&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/10/202510102025406862943.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;换了0.13.2就正常了（太坑了）&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/10/202510102027033692093.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/10/202510102026451323668.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</description><pubDate>Fri, 10 Oct 2025 20:22:28 +0800</pubDate></item><item><title>js debugger各种方法的演示</title><link>https://hyluz.cn/post/90402.html</link><description>&lt;p&gt;做了个js debugger各种方法的演示，供绕过debugger学习用&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/08/202508271141144172822.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;quot;zh-CN&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot; /&amp;gt;
&amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;/&amp;gt;
&amp;lt;title&amp;gt;Debugger 策略与绕过演练台&amp;lt;/title&amp;gt;
&amp;lt;style&amp;gt;
  :root {
    --primary:#2563eb;
    --danger:#ef4444;
    --bg:#0b1220;
    --card:#0f172a;
    --muted:#94a3b8;
    --text:#e2e8f0;
    --accent:#22c55e;
  }
  *{box-sizing:border-box}
  body{
    margin:0;
    font-family: ui-sans-serif, system-ui, -apple-system, &amp;quot;Segoe UI&amp;quot;, Roboto, &amp;quot;Helvetica Neue&amp;quot;, Arial;
    background: radial-gradient(1200px 600px at 10% -10%, #172554 0%, #0b1220 45%) , var(--bg);
    color:var(--text);
    line-height:1.6;
  }
  header{
    max-width:1080px;margin:32px auto 8px;padding:0 16px;text-align:center;
  }
  h1{margin:0 0 8px 0;font-weight:800;letter-spacing:.2px}
  .sub{color:var(--muted);max-width:800px;margin:0 auto 20px}
  .wrap{max-width:1080px;margin:0 auto;padding:0 16px 32px}
  .card{
    background:linear-gradient(180deg, rgba(148,163,184,.1), transparent 30%) , var(--card);
    border:1px solid rgba(148,163,184,.15);
    border-radius:16px;
    padding:18px;
    margin-bottom:16px;
    box-shadow:0 10px 30px rgba(2,6,23,.4);
  }
  .grid{
    display:grid;
    grid-template-columns: repeat(2, minmax(0,1fr));
    gap:12px;
  }
  @media (min-width:860px){
    .grid{grid-template-columns: repeat(3, minmax(0,1fr));}
  }
  .row{
    display:flex;gap:8px;align-items:center;justify-content:flex-start;flex-wrap:wrap;
    padding:10px;border:1px dashed rgba(148,163,184,.2);border-radius:12px;background:rgba(30,41,59,.35)
  }
  .row h3{
    margin:0 8px 0 0;font-size:15px;font-weight:700;white-space:nowrap
  }
  button{
    padding:9px 12px;font-size:14px;border:none;border-radius:10px;color:white;cursor:pointer;
    background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.08)), var(--primary);
    transition:filter .2s, transform .02s;
  }
  button.small{padding:8px 10px;font-size:13px;background:#334155}
  button:hover{filter:brightness(1.08)}
  button:active{transform:translateY(1px)}
  button.red{background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.08)), var(--danger)}
  .log{
    height:200px;overflow:auto;background:rgba(15,23,42,.7);border-radius:12px;border:1px solid rgba(148,163,184,.15);
    padding:10px;font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;font-size:13px;
  }
  .log p{margin:4px 0}
  .hint{color:var(--muted);font-size:13px;margin:-6px 0 8px}
  /* Modal */
  .modal-backdrop{
    position:fixed;inset:0;background:rgba(2,6,23,.6);backdrop-filter: blur(3px);
    display:none;align-items:center;justify-content:center;padding:16px;z-index:40;
  }
  .modal{
    max-width:820px;width:100%;
    background:var(--card);border:1px solid rgba(148,163,184,.2);border-radius:14px;
    box-shadow:0 20px 60px rgba(2,6,23,.6);
    overflow:hidden;
  }
  .modal header{
    padding:14px 16px 0;margin:0;text-align:left;
  }
  .modal h2{margin:0 0 4px 0;font-size:18px}
  .modal .content{
    padding:4px 16px 16px;max-height:60vh;overflow:auto;color:#dbeafe;
  }
  .modal .content ul{padding-left:18px;margin:6px 0 0 0}
  .modal .content li{margin:4px 0}
  .modal .footer{
    padding:12px 16px;border-top:1px solid rgba(148,163,184,.2);display:flex;justify-content:flex-end;gap:8px
  }
  .badge{
    display:inline-block;padding:2px 8px;border-radius:999px;font-size:12px;color:white;background:#0ea5e9;margin-left:6px
  }
&amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;header&amp;gt;
    &amp;lt;h1&amp;gt;Debugger 策略与绕过演练台&amp;lt;/h1&amp;gt;
    &amp;lt;p class=&amp;quot;sub&amp;quot;&amp;gt;点击任意触发按钮开启对应的 &amp;lt;code&amp;gt;debugger&amp;lt;/code&amp;gt; 策略；旁边的“绕过提示”会给出常见规避方案与工具路径。适合在 DevTools 中练习反调试绕过。&amp;lt;/p&amp;gt;
  &amp;lt;/header&amp;gt;

  &amp;lt;div class=&amp;quot;wrap&amp;quot;&amp;gt;
    &amp;lt;section class=&amp;quot;card&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;hint&amp;quot;&amp;gt;▶ 建议开启 DevTools 的 &amp;lt;em&amp;gt;Pause on debugger&amp;lt;/em&amp;gt;，并试试条件断点、覆盖脚本、CSP 调整等。&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;grid&amp;quot; id=&amp;quot;btnGrid&amp;quot;&amp;gt;
        &amp;lt;!-- 按钮行通过 JS 注入，见下方 config --&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div style=&amp;quot;display:flex;gap:8px;margin-top:12px;flex-wrap:wrap&amp;quot;&amp;gt;
        &amp;lt;button id=&amp;quot;stopAllBtn&amp;quot; class=&amp;quot;red&amp;quot;&amp;gt;停止所有触发&amp;lt;/button&amp;gt;
        &amp;lt;button id=&amp;quot;clearLogBtn&amp;quot; class=&amp;quot;small&amp;quot;&amp;gt;清空日志&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;

    &amp;lt;section class=&amp;quot;card&amp;quot;&amp;gt;
      &amp;lt;h3 style=&amp;quot;margin:0 0 8px 0&amp;quot;&amp;gt;日志&amp;lt;/h3&amp;gt;
      &amp;lt;div class=&amp;quot;log&amp;quot; id=&amp;quot;logContainer&amp;quot;&amp;gt;&amp;lt;p&amp;gt;日志输出区域...&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;
  &amp;lt;/div&amp;gt;

  &amp;lt;!-- Modal --&amp;gt;
  &amp;lt;div class=&amp;quot;modal-backdrop&amp;quot; id=&amp;quot;modal&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;modal&amp;quot;&amp;gt;
      &amp;lt;header&amp;gt;
        &amp;lt;h2 id=&amp;quot;modalTitle&amp;quot;&amp;gt;绕过提示&amp;lt;/h2&amp;gt;
      &amp;lt;/header&amp;gt;
      &amp;lt;div class=&amp;quot;content&amp;quot; id=&amp;quot;modalContent&amp;quot;&amp;gt;
        &amp;lt;!-- 动态填充 --&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;footer&amp;quot;&amp;gt;
        &amp;lt;button id=&amp;quot;copyTipsBtn&amp;quot; class=&amp;quot;small&amp;quot;&amp;gt;复制内容&amp;lt;/button&amp;gt;
        &amp;lt;button id=&amp;quot;closeModalBtn&amp;quot;&amp;gt;关闭&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
/* ========= 日志 / 公共 ========= */
function log(message){
  const box = document.getElementById(&amp;#39;logContainer&amp;#39;);
  const p = document.createElement(&amp;#39;p&amp;#39;);
  p.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
  box.appendChild(p);
  box.scrollTop = box.scrollHeight;
}
window.log = log; // 供 new Function / Worker 使用

// 可清理资源的引用
const timers = {
  explicit:null, eval:null, fn:null, ctor:null, mixed:null,
  raf:null, timeout:null, promise:false, observer:null, getterInt:null, idle:null, worker:null,
  evThrottler:{ last:0, handler:null }
};

function jitter(base=1200, spread=600){
  return base - spread/2 + Math.random()*spread;
}

/* ========= 触发策略配置（名称、触发器、绕过指南） ========= */
const strategies = [
  {
    key:&amp;#39;explicit&amp;#39;,
    name:&amp;#39;显式 setInterval&amp;#39;,
    trigger(){
      if (timers.explicit) return log(&amp;#39;显式已在运行&amp;#39;);
      log(&amp;#39;启动：显式 setInterval&amp;#39;);
      function tick(){ debugger; log(&amp;#39;显式 debugger 触发&amp;#39;); }
      timers.explicit = setInterval(tick, 1000);
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;在 DevTools 勾选「从不在异常处暂停」/关闭 Pause on debugger。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;临时把 &amp;lt;code&amp;gt;debugger&amp;lt;/code&amp;gt; 改成空语句：在 Sources 里覆盖脚本（Override/Local Overrides）。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;在运行时重写 &amp;lt;code&amp;gt;window.Function.prototype.constructor&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;debugger&amp;lt;/code&amp;gt; 触发点（若可控）。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;全局禁用定时器：把 &amp;lt;code&amp;gt;setInterval&amp;lt;/code&amp;gt; 指向空函数（慎用，影响面大）。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;eval&amp;#39;,
    name:&amp;#39;eval 调用&amp;#39;,
    trigger(){
      if (timers.eval) return log(&amp;#39;eval 已在运行&amp;#39;);
      log(&amp;#39;启动：eval 调用&amp;#39;);
      timers.eval = setInterval(()=&amp;gt;{
        try { eval(&amp;quot;debugger; window.log(&amp;#39;eval debugger 触发&amp;#39;)&amp;quot;); }
        catch(e){ debugger; log(&amp;#39;eval 被 CSP 限制，降级显式触发&amp;#39;); }
      }, 1000);
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;站点有 CSP：在 Response Header 放宽 &amp;lt;code&amp;gt;script-src &amp;#39;unsafe-eval&amp;#39;&amp;lt;/code&amp;gt; 或调整 DevTools 的 Overrides 以去除限制（仅在可控环境调试）。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;直接将 &amp;lt;code&amp;gt;eval&amp;lt;/code&amp;gt; 指向安全实现：&amp;lt;code&amp;gt;window.eval = ()=&amp;gt;{}&amp;lt;/code&amp;gt;（可能影响站点其他逻辑）。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;改为条件断点：只在特定堆栈/URL 时暂停。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;fn&amp;#39;,
    name:&amp;#39;new Function&amp;#39;,
    trigger(){
      if (timers.fn) return log(&amp;#39;Function 已在运行&amp;#39;);
      log(&amp;#39;启动：new Function&amp;#39;);
      timers.fn = setInterval(()=&amp;gt;{
        try { new Function(&amp;quot;debugger; window.log(&amp;#39;Function debugger 触发&amp;#39;)&amp;quot;)(); }
        catch(e){ debugger; log(&amp;#39;new Function 被 CSP 限制，降级显式触发&amp;#39;); }
      }, 1000);
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;CSP 下常被拦截：同 &amp;lt;code&amp;gt;eval&amp;lt;/code&amp;gt; 绕过。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;在模块脚本中，它无法捕获局部变量；将依赖挂到 &amp;lt;code&amp;gt;window&amp;lt;/code&amp;gt;。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;可用 DevTools「黑盒」脚本避免进入该文件。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;ctor&amp;#39;,
    name:&amp;#39;Function.prototype.constructor&amp;#39;,
    trigger(){
      if (timers.ctor) return log(&amp;#39;Constructor 已在运行&amp;#39;);
      log(&amp;#39;启动：Function.prototype.constructor&amp;#39;);
      timers.ctor = setInterval(()=&amp;gt;{
        try { (function(){}).constructor(&amp;quot;debugger; window.log(&amp;#39;Constructor debugger 触发&amp;#39;)&amp;quot;)(); }
        catch(e){ debugger; log(&amp;#39;constructor 被 CSP 限制，降级显式触发&amp;#39;); }
      }, 1000);
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;与 &amp;lt;code&amp;gt;new Function&amp;lt;/code&amp;gt; 等价，亦受 CSP 约束。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;可以在运行时替换 &amp;lt;code&amp;gt;Function.prototype.constructor&amp;lt;/code&amp;gt; 返回的实现。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;mixed&amp;#39;,
    name:&amp;#39;混合随机&amp;#39;,
    trigger(){
      if (timers.mixed) return log(&amp;#39;混合已在运行&amp;#39;);
      log(&amp;#39;启动：混合随机（含降级、抖动）&amp;#39;);
      function once(){
        const arr = [
          ()=&amp;gt;{ debugger; log(&amp;#39;显式 触发&amp;#39;); },
          ()=&amp;gt;{ try{ eval(&amp;quot;debugger; window.log(&amp;#39;eval 触发&amp;#39;)&amp;quot;); }catch{ debugger; log(&amp;#39;eval 降级&amp;#39;); } },
          ()=&amp;gt;{ try{ new Function(&amp;quot;debugger; window.log(&amp;#39;Function 触发&amp;#39;)&amp;quot;)(); }catch{ debugger; log(&amp;#39;Function 降级&amp;#39;); } },
          ()=&amp;gt;{ try{ (function(){}).constructor(&amp;quot;debugger; window.log(&amp;#39;Ctor 触发&amp;#39;)&amp;quot;)(); }catch{ debugger; log(&amp;#39;Ctor 降级&amp;#39;); } }
        ];
        arr[Math.floor(Math.random()*arr.length)]();
      }
      (function loop(){
        once();
        timers.mixed = setTimeout(loop, jitter());
      })();
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;随机调度+多路径：用条件断点限制只在感兴趣的路径暂停。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;在 Overrides 中批量删改所有 &amp;lt;code&amp;gt;debugger;&amp;lt;/code&amp;gt;（正则查找）。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;raf&amp;#39;,
    name:&amp;#39;requestAnimationFrame&amp;#39;,
    trigger(){
      if (timers.raf) return log(&amp;#39;rAF 已在运行&amp;#39;);
      log(&amp;#39;启动：requestAnimationFrame 循环&amp;#39;);
      const loop=()=&amp;gt;{ debugger; log(&amp;#39;rAF 触发&amp;#39;); timers.raf = requestAnimationFrame(loop); };
      timers.raf = requestAnimationFrame(loop);
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;后台标签页 rAF 会暂停：切后台临时规避。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;DevTools「黑盒脚本」+ 移除 &amp;lt;code&amp;gt;debugger&amp;lt;/code&amp;gt;。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;timeout&amp;#39;,
    name:&amp;#39;setTimeout 递归（抖动）&amp;#39;,
    trigger(){
      if (timers.timeout) return log(&amp;#39;Timeout 已在运行&amp;#39;);
      log(&amp;#39;启动：setTimeout 递归（抖动）&amp;#39;);
      const run = ()=&amp;gt;{ debugger; log(&amp;#39;Timeout 触发&amp;#39;); timers.timeout = setTimeout(run, jitter()); };
      timers.timeout = setTimeout(run, 600);
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;重写 &amp;lt;code&amp;gt;setTimeout&amp;lt;/code&amp;gt;，拦截特定回调。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;条件断点过滤调用栈/脚本 URL。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;promise&amp;#39;,
    name:&amp;#39;Promise/Microtask&amp;#39;,
    trigger(){
      if (timers.promise) return log(&amp;#39;Promise 已在运行&amp;#39;);
      log(&amp;#39;启动：Promise/Microtask&amp;#39;);
      timers.promise = true;
      (function schedule(){
        if (!timers.promise) return;
        Promise.resolve().then(()=&amp;gt;{ debugger; log(&amp;#39;Promise 微任务触发&amp;#39;); })
          .finally(()=&amp;gt; setTimeout(schedule, 800));
      })();
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;微任务频繁：在 DevTools 里使用「Async 堆栈」辅助溯源。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;禁用/替换 &amp;lt;code&amp;gt;Promise&amp;lt;/code&amp;gt; 的 then 包装（风险大，不推荐生产）。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;mo&amp;#39;,
    name:&amp;#39;MutationObserver&amp;#39;,
    trigger(){
      if (timers.observer) return log(&amp;#39;MO 已在运行&amp;#39;);
      log(&amp;#39;启动：MutationObserver&amp;#39;);
      const target = document.getElementById(&amp;#39;logContainer&amp;#39;);
      const mo = new MutationObserver(()=&amp;gt;{ debugger; log(&amp;#39;MO 触发&amp;#39;); });
      mo.observe(target, {childList:true, characterData:true, subtree:true});
      timers.observer = mo;
      let i=0;
      (function poke(){
        if (!timers.observer) return;
        const p=document.createElement(&amp;#39;p&amp;#39;); p.textContent=&amp;#39;MO 心跳 &amp;#39;+(++i); target.appendChild(p);
        setTimeout(poke, 1500);
      })();
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;临时断开观察者：覆盖 &amp;lt;code&amp;gt;MutationObserver.prototype.observe&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;disconnect&amp;lt;/code&amp;gt;。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;避免 DOM 变更（若可控数据源）。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;getter&amp;#39;,
    name:&amp;#39;Getter/Proxy 访问&amp;#39;,
    trigger(){
      if (timers.getterInt) return log(&amp;#39;Getter 已在运行&amp;#39;);
      log(&amp;#39;启动：Getter/Proxy&amp;#39;);
      const carrier = {};
      Object.defineProperty(carrier,&amp;#39;x&amp;#39;,{get(){ debugger; log(&amp;#39;Getter 触发&amp;#39;); return 1; }});
      timers.getterInt = setInterval(()=&amp;gt;{ void carrier.x; }, 1000);
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;用 &amp;lt;code&amp;gt;Object.defineProperty&amp;lt;/code&amp;gt; 重新定义该属性，无副作用 getter。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;若为 Proxy，可替换 &amp;lt;code&amp;gt;Proxy&amp;lt;/code&amp;gt; 构造/handler。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;idle&amp;#39;,
    name:&amp;#39;requestIdleCallback&amp;#39;,
    trigger(){
      if (timers.idle) return log(&amp;#39;Idle 已在运行&amp;#39;);
      if (!(&amp;#39;requestIdleCallback&amp;#39; in window)){
        log(&amp;#39;不支持 requestIdleCallback，降级 setTimeout&amp;#39;);
        timers.idle = setTimeout(function tick(){ debugger; log(&amp;#39;Idle 降级触发&amp;#39;); timers.idle=setTimeout(tick,1200); }, 800);
        return;
      }
      log(&amp;#39;启动：requestIdleCallback&amp;#39;);
      const loop=()=&amp;gt;{ timers.idle = requestIdleCallback(()=&amp;gt;{ debugger; log(&amp;#39;Idle 触发&amp;#39;); loop(); }, {timeout:2000}); };
      loop();
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;空闲触发：让页面保持忙碌（动画/网络）以推迟触发。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;替换 &amp;lt;code&amp;gt;requestIdleCallback&amp;lt;/code&amp;gt; 为 no-op（仅测试用）。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;worker&amp;#39;,
    name:&amp;#39;Web Worker&amp;#39;,
    trigger(){
      if (timers.worker) return log(&amp;#39;Worker 已在运行&amp;#39;);
      log(&amp;#39;启动：Web Worker（需 DevTools 开启 Worker 源码调试）&amp;#39;);
      try{
        const blob=new Blob([`
          self.onmessage=()=&amp;gt;{};
          setInterval(()=&amp;gt;{ debugger; self.postMessage(&amp;#39;tick&amp;#39;); }, 1000);
        `],{type:&amp;#39;application/javascript&amp;#39;});
        const url=URL.createObjectURL(blob);
        const w=new Worker(url);
        w.onmessage = e =&amp;gt; { /* 占位 */ };
        timers.worker=w;
      }catch(e){
        log(&amp;#39;创建 Worker 失败（可能被 CSP 的 worker-src / blob 禁止）：&amp;#39;+e);
      }
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;Sources 面板展开「Workers」，单独禁用暂停或黑盒 worker 脚本。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;CSP 严格下可禁用 blob/worker-src，阻止加载（仅自测环境）。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  },
  {
    key:&amp;#39;event&amp;#39;,
    name:&amp;#39;事件监听（mousemove/keydown）&amp;#39;,
    trigger(){
      if (timers.evThrottler.handler) return log(&amp;#39;事件监听已在运行&amp;#39;);
      log(&amp;#39;启动：事件监听（1s 节流）&amp;#39;);
      const throttled = (e)=&amp;gt;{
        const now=Date.now(); if (now - timers.evThrottler.last &amp;lt; 1000) return;
        timers.evThrottler.last = now; debugger; log(`事件 ${e.type} 触发`);
      };
      timers.evThrottler.handler = throttled;
      window.addEventListener(&amp;#39;mousemove&amp;#39;, throttled, {passive:true});
      window.addEventListener(&amp;#39;keydown&amp;#39;, throttled, {passive:true});
    },
    tips:`
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;避免触发相关事件（或在控制台移除监听）。&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;运行时用 &amp;lt;code&amp;gt;getEventListeners(window)&amp;lt;/code&amp;gt;（Chrome）查找并 &amp;lt;code&amp;gt;removeEventListener&amp;lt;/code&amp;gt;。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;`
  }
];

/* ========= 注入按钮行 ========= */
const grid = document.getElementById(&amp;#39;btnGrid&amp;#39;);
strategies.forEach(s=&amp;gt;{
  const row = document.createElement(&amp;#39;div&amp;#39;);
  row.className = &amp;#39;row&amp;#39;;
  row.innerHTML = `
    &amp;lt;h3&amp;gt;${s.name}&amp;lt;/h3&amp;gt;
    &amp;lt;button data-key=&amp;quot;${s.key}&amp;quot;&amp;gt;触发&amp;lt;/button&amp;gt;
    &amp;lt;button class=&amp;quot;small&amp;quot; data-tip=&amp;quot;${s.key}&amp;quot;&amp;gt;绕过提示&amp;lt;/button&amp;gt;
    &amp;lt;span class=&amp;quot;badge&amp;quot;&amp;gt;ID: ${s.key}&amp;lt;/span&amp;gt;
  `;
  grid.appendChild(row);
});
grid.addEventListener(&amp;#39;click&amp;#39;,(e)=&amp;gt;{
  const triggerKey = e.target.getAttribute(&amp;#39;data-key&amp;#39;);
  const tipKey = e.target.getAttribute(&amp;#39;data-tip&amp;#39;);
  if (triggerKey){
    const s = strategies.find(x=&amp;gt;x.key===triggerKey);
    if (s) s.trigger();
  } else if (tipKey){
    const s = strategies.find(x=&amp;gt;x.key===tipKey);
    if (s) openTips(s.name, s.tips);
  }
});

/* ========= 停止/清理 ========= */
document.getElementById(&amp;#39;stopAllBtn&amp;#39;).addEventListener(&amp;#39;click&amp;#39;, ()=&amp;gt;{
  // interval 类
  [&amp;#39;explicit&amp;#39;,&amp;#39;eval&amp;#39;,&amp;#39;fn&amp;#39;,&amp;#39;ctor&amp;#39;,&amp;#39;getterInt&amp;#39;].forEach(k=&amp;gt;{
    if (timers[k]){ clearInterval(timers[k]); timers[k]=null; }
  });
  // timeout / mixed
  if (timers.timeout){ clearTimeout(timers.timeout); timers.timeout=null; }
  if (timers.mixed){ clearTimeout(timers.mixed); timers.mixed=null; }
  // rAF
  if (timers.raf){ cancelAnimationFrame(timers.raf); timers.raf=null; }
  // Promise 循环标志
  timers.promise = false;
  // MO
  if (timers.observer){ timers.observer.disconnect(); timers.observer=null; }
  // idle
  if (timers.idle){
    if (&amp;#39;cancelIdleCallback&amp;#39; in window) cancelIdleCallback(timers.idle);
    else clearTimeout(timers.idle);
    timers.idle=null;
  }
  // Worker
  if (timers.worker){ timers.worker.terminate(); timers.worker=null; }
  // 事件监听
  if (timers.evThrottler.handler){
    window.removeEventListener(&amp;#39;mousemove&amp;#39;, timers.evThrottler.handler);
    window.removeEventListener(&amp;#39;keydown&amp;#39;,  timers.evThrottler.handler);
    timers.evThrottler.handler=null; timers.evThrottler.last=0;
  }
  log(&amp;#39;已停止所有触发&amp;#39;);
});
document.getElementById(&amp;#39;clearLogBtn&amp;#39;).addEventListener(&amp;#39;click&amp;#39;, ()=&amp;gt;{
  const box=document.getElementById(&amp;#39;logContainer&amp;#39;);
  box.innerHTML = &amp;#39;&amp;lt;p&amp;gt;日志输出区域...&amp;lt;/p&amp;gt;&amp;#39;;
});

/* ========= Modal（绕过提示） ========= */
const modal = document.getElementById(&amp;#39;modal&amp;#39;);
const modalTitle = document.getElementById(&amp;#39;modalTitle&amp;#39;);
const modalContent = document.getElementById(&amp;#39;modalContent&amp;#39;);
const closeModalBtn = document.getElementById(&amp;#39;closeModalBtn&amp;#39;);
const copyTipsBtn  = document.getElementById(&amp;#39;copyTipsBtn&amp;#39;);

function openTips(title, html){
  modalTitle.textContent = `绕过提示 · ${title}`;
  modalContent.innerHTML = html + `
    &amp;lt;hr style=&amp;quot;border-color:rgba(148,163,184,.2)&amp;quot;&amp;gt;
    &amp;lt;p style=&amp;quot;margin:6px 0 0 0;color:#93c5fd;font-size:13px&amp;quot;&amp;gt;
    通用思路：条件断点（过滤堆栈/URL/调用参数） · 覆盖脚本移除 &amp;lt;code&amp;gt;debugger&amp;lt;/code&amp;gt; · 黑盒脚本 · 临时替换 API（&amp;lt;code&amp;gt;eval&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;Function&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;setInterval&amp;lt;/code&amp;gt;/Observers 等） · 关闭 Pause on debugger。
    &amp;lt;/p&amp;gt;`;
  modal.style.display = &amp;#39;flex&amp;#39;;
}
function closeTips(){ modal.style.display = &amp;#39;none&amp;#39;; }

closeModalBtn.addEventListener(&amp;#39;click&amp;#39;, closeTips);
modal.addEventListener(&amp;#39;click&amp;#39;,(e)=&amp;gt;{ if (e.target===modal) closeTips(); });
copyTipsBtn.addEventListener(&amp;#39;click&amp;#39;, async ()=&amp;gt;{
  const tmp = modalContent.innerText;
  try{
    await navigator.clipboard.writeText(tmp);
    log(&amp;#39;已复制绕过提示到剪贴板&amp;#39;);
  }catch{
    log(&amp;#39;复制失败：可能缺少权限&amp;#39;);
  }
});

&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</description><pubDate>Wed, 27 Aug 2025 11:26:39 +0800</pubDate></item><item><title>E01镜像仿真（E01镜像转VMware虚拟机）</title><link>https://hyluz.cn/post/90400.html</link><description>&lt;p&gt;电子取证中，经常见到硬盘分区直接打包成的E01镜像；有时候需要模拟一下镜像启动（仿真），但是所有的仿真软件都是收费的。因此做了这个脚本，可以把E01镜像转成VMDK磁盘镜像，同时生成VMX文件用于虚拟机启动。&lt;/p&gt;
&lt;h2 id=&quot;h2-u4EE3u7801&quot;&gt;&lt;a name=&quot;代码&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;代码&lt;/h2&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import tkinter as tk
from tkinter import filedialog, messagebox, ttk
import subprocess
import os
import shutil
from pathlib import Path

# --- 配置区 ---
# 请根据您的实际情况修改以下路径
EWFEXPORT_PATH = r&amp;quot;D:\ewfexport.exe&amp;quot;  # ewfexport.exe
QEMU_IMG_PATH = r&amp;quot;C:\qemu-img.exe&amp;quot;    # qemu-img.exe
# --- 配置区结束 ---

class E01ConverterApp:
    def __init__(self, root):
        self.root = root
        self.root.title(&amp;quot;E01 到 VMDK 转换器&amp;quot;)
        self.root.geometry(&amp;quot;600x580&amp;quot;)
        self.root.resizable(False, False)

        # 样式
        self.style = ttk.Style()
        self.style.configure(&amp;quot;TFrame&amp;quot;, padding=10, relief=&amp;quot;flat&amp;quot;)
        self.style.configure(&amp;quot;TLabel&amp;quot;, font=(&amp;quot;Segoe UI&amp;quot;, 10))
        self.style.configure(&amp;quot;TButton&amp;quot;, font=(&amp;quot;Segoe UI&amp;quot;, 10, &amp;quot;bold&amp;quot;))
        self.style.configure(&amp;quot;TEntry&amp;quot;, font=(&amp;quot;Segoe UI&amp;quot;, 10))
        self.style.configure(&amp;quot;TCombobox&amp;quot;, font=(&amp;quot;Segoe UI&amp;quot;, 10))
        self.style.configure(&amp;quot;TProgressbar&amp;quot;, thickness=15)

        # 主框架
        main_frame = ttk.Frame(root, padding=&amp;quot;15 15 15 15&amp;quot;)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # E01文件路径选择
        path_frame = ttk.LabelFrame(main_frame, text=&amp;quot;1. E01 文件路径&amp;quot;, padding=&amp;quot;10&amp;quot;)
        path_frame.pack(fill=tk.X, pady=10)

        self.e01_path_entry = ttk.Entry(path_frame, width=60)
        self.e01_path_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
        self.browse_button = ttk.Button(path_frame, text=&amp;quot;浏览...&amp;quot;, command=self.browse_e01_file)
        self.browse_button.pack(side=tk.RIGHT)

        # 输出目录选择
        output_frame = ttk.LabelFrame(main_frame, text=&amp;quot;2. 输出目录 (VMDK和VMX将生成在此)&amp;quot;, padding=&amp;quot;10&amp;quot;)
        output_frame.pack(fill=tk.X, pady=10)

        self.output_dir_entry = ttk.Entry(output_frame, width=60)
        self.output_dir_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
        self.browse_output_button = ttk.Button(output_frame, text=&amp;quot;选择目录...&amp;quot;, command=self.browse_output_dir)
        self.browse_output_button.pack(side=tk.RIGHT)

        # 操作系统和启动方式选择
        vm_config_frame = ttk.LabelFrame(main_frame, text=&amp;quot;3. 虚拟机配置 (用于生成VMX)&amp;quot;, padding=&amp;quot;10&amp;quot;)
        vm_config_frame.pack(fill=tk.X, pady=10)

        # 操作系统类型
        ttk.Label(vm_config_frame, text=&amp;quot;操作系统类型:&amp;quot;).grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
        self.os_type_options = [
            &amp;quot;Windows 10 64-bit&amp;quot;, &amp;quot;Windows 8 64-bit&amp;quot;, &amp;quot;Windows 7 64-bit&amp;quot;,
            &amp;quot;Windows XP 32-bit&amp;quot;, &amp;quot;Windows 2003 Server 32-bit&amp;quot;,
            &amp;quot;Ubuntu 64-bit&amp;quot;, &amp;quot;Debian 64-bit&amp;quot;, &amp;quot;CentOS 64-bit&amp;quot;, &amp;quot;Other Linux 64-bit&amp;quot;,
            &amp;quot;Other 64-bit&amp;quot;, &amp;quot;Other 32-bit&amp;quot;
        ]
        self.os_type_var = tk.StringVar(root)
        self.os_type_var.set(self.os_type_options[0]) # 默认值
        self.os_type_menu = ttk.Combobox(vm_config_frame, textvariable=self.os_type_var,
                                         values=self.os_type_options, state=&amp;quot;readonly&amp;quot;, width=30)
        self.os_type_menu.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)

        # 启动方式
        ttk.Label(vm_config_frame, text=&amp;quot;启动方式:&amp;quot;).grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
        self.boot_type_options = [&amp;quot;BIOS&amp;quot;, &amp;quot;EFI (UEFI)&amp;quot;]
        self.boot_type_var = tk.StringVar(root)
        self.boot_type_var.set(self.boot_type_options[0]) # 默认值
        self.boot_type_menu = ttk.Combobox(vm_config_frame, textvariable=self.boot_type_var,
                                           values=self.boot_type_options, state=&amp;quot;readonly&amp;quot;, width=30)
        self.boot_type_menu.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W)

        # 转换按钮
        self.convert_button = ttk.Button(main_frame, text=&amp;quot;开始转换&amp;quot;, command=self.start_conversion, style=&amp;quot;TButton&amp;quot;)
        self.convert_button.pack(pady=20, ipadx=20, ipady=10)

        # 进度条
        self.progress_bar = ttk.Progressbar(main_frame, orient=&amp;quot;horizontal&amp;quot;, length=500, mode=&amp;quot;determinate&amp;quot;, style=&amp;quot;TProgressbar&amp;quot;)
        self.progress_bar.pack(pady=10)

        # 日志输出
        log_frame = ttk.LabelFrame(main_frame, text=&amp;quot;日志输出&amp;quot;, padding=&amp;quot;10&amp;quot;)
        log_frame.pack(fill=tk.BOTH, expand=True, pady=10)

        self.log_text = tk.Text(log_frame, height=8, state=&amp;quot;disabled&amp;quot;, font=(&amp;quot;Consolas&amp;quot;, 9), bg=&amp;quot;#f0f0f0&amp;quot;)
        self.log_text.pack(fill=tk.BOTH, expand=True)
        self.log_text_scrollbar = ttk.Scrollbar(self.log_text, command=self.log_text.yview)
        self.log_text_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.log_text.config(yscrollcommand=self.log_text_scrollbar.set)

        self.initial_dir_set = False # 标记是否已设置初始输出目录

    def log_message(self, message):
        &amp;quot;&amp;quot;&amp;quot;向日志框输出信息&amp;quot;&amp;quot;&amp;quot;
        self.log_text.config(state=&amp;quot;normal&amp;quot;)
        self.log_text.insert(tk.END, message + &amp;quot;\n&amp;quot;)
        self.log_text.see(tk.END) # 自动滚动到底部
        self.log_text.config(state=&amp;quot;disabled&amp;quot;)
        self.root.update_idletasks() # 立即更新GUI

    def browse_e01_file(self):
        &amp;quot;&amp;quot;&amp;quot;选择E01文件&amp;quot;&amp;quot;&amp;quot;
        file_path = filedialog.askopenfilename(
            title=&amp;quot;选择 E01 文件&amp;quot;,
            filetypes=[(&amp;quot;E01 Files&amp;quot;, &amp;quot;*.e01&amp;quot;), (&amp;quot;All Files&amp;quot;, &amp;quot;*.*&amp;quot;)]
        )
        if file_path:
            self.e01_path_entry.delete(0, tk.END)
            self.e01_path_entry.insert(0, file_path)
            # 自动设置输出目录为E01文件所在目录
            if not self.initial_dir_set:
                output_dir = Path(file_path).parent
                self.output_dir_entry.delete(0, tk.END)
                self.output_dir_entry.insert(0, str(output_dir))
                self.initial_dir_set = True

    def browse_output_dir(self):
        &amp;quot;&amp;quot;&amp;quot;选择输出目录&amp;quot;&amp;quot;&amp;quot;
        dir_path = filedialog.askdirectory(title=&amp;quot;选择输出目录&amp;quot;)
        if dir_path:
            self.output_dir_entry.delete(0, tk.END)
            self.output_dir_entry.insert(0, dir_path)
            self.initial_dir_set = True

    def run_command(self, command, description, input_data=None, cwd=None):
        &amp;quot;&amp;quot;&amp;quot;执行外部命令并记录日志，支持传入输入数据&amp;quot;&amp;quot;&amp;quot;
        self.log_message(f&amp;quot;--- 正在执行: {description} ---&amp;quot;)
        self.log_message(f&amp;quot;命令: {&amp;#39; &amp;#39;.join(command)}&amp;quot;)
        try:
            process = subprocess.Popen(
                command,
                stdin=subprocess.PIPE,  # 允许写入标准输入
                stdout=subprocess.PIPE, # 捕获标准输出
                stderr=subprocess.PIPE, # 捕获标准错误
                text=True,              # 以文本模式处理输入输出
                encoding=&amp;#39;utf-8&amp;#39;,       # 尝试使用UTF-8编码，如果不行再尝试gbk
                errors=&amp;#39;replace&amp;#39;,       # 编码错误时替换字符
                cwd=cwd                 # 设置工作目录
            )

            # 写入输入数据（如果有）
            stdout, stderr = process.communicate(input=input_data)

            if process.returncode != 0:
                self.log_message(f&amp;quot;错误: {description} 命令执行失败，返回码 {process.returncode}&amp;quot;)
                self.log_message(&amp;quot;标准输出:\n&amp;quot; + stdout)
                self.log_message(&amp;quot;标准错误:\n&amp;quot; + stderr)
                # 尝试用gbk再次解码stderr，因为有些工具可能默认gbk
                try:
                    # 注意：这里是将已解码的字符串重新编码成UTF-8字节，再解码成GBK字符串
                    # 更好的方法是直接尝试不同的解码方式，但因为原始subprocess.run的编码问题，这里保持一致
                    stderr_gbk = stderr.encode(&amp;#39;utf-8&amp;#39;).decode(&amp;#39;gbk&amp;#39;, errors=&amp;#39;replace&amp;#39;)
                    if stderr_gbk != stderr: # 如果gbk解码不同，说明可能是编码问题
                         self.log_message(&amp;quot;标准错误 (GBK 解码尝试):\n&amp;quot; + stderr_gbk)
                except Exception:
                    pass

                messagebox.showerror(&amp;quot;错误&amp;quot;, f&amp;quot;{description} 失败！\n请检查日志获取详情。&amp;quot;)
                return False
            else:
                self.log_message(&amp;quot;命令执行成功！&amp;quot;)
                self.log_message(&amp;quot;标准输出:\n&amp;quot; + stdout)
                if stderr:
                    self.log_message(&amp;quot;标准错误 (可能包含信息，非错误):\n&amp;quot; + stderr)
                return True
        except FileNotFoundError:
            self.log_message(f&amp;quot;错误: 找不到 {command[0]}。请检查配置中的工具路径是否正确。&amp;quot;)
            messagebox.showerror(&amp;quot;错误&amp;quot;, f&amp;quot;找不到 {command[0]}。\n请检查配置中的工具路径是否正确。&amp;quot;)
            return False
        except Exception as e:
            self.log_message(f&amp;quot;执行 {description} 时发生未知错误: {e}&amp;quot;)
            messagebox.showerror(&amp;quot;错误&amp;quot;, f&amp;quot;未知错误: {e}&amp;quot;)
            return False

    def generate_vmx_content(self, vmdk_filename, os_type_selected, boot_type_selected):
        &amp;quot;&amp;quot;&amp;quot;根据选择生成VMX文件内容&amp;quot;&amp;quot;&amp;quot;
        # 将用户友好的OS类型映射到VMware的guestOS标识符
        os_type_map = {
            &amp;quot;Windows 10 64-bit&amp;quot;: &amp;quot;windows9-64&amp;quot;,
            &amp;quot;Windows 8 64-bit&amp;quot;: &amp;quot;windows8-64&amp;quot;,
            &amp;quot;Windows 7 64-bit&amp;quot;: &amp;quot;windows7-64&amp;quot;,
            &amp;quot;Windows XP 32-bit&amp;quot;: &amp;quot;winxp&amp;quot;,
            &amp;quot;Windows 2003 Server 32-bit&amp;quot;: &amp;quot;winnetstandard&amp;quot;,
            &amp;quot;Ubuntu 64-bit&amp;quot;: &amp;quot;ubuntu-64&amp;quot;,
            &amp;quot;Debian 64-bit&amp;quot;: &amp;quot;debian9-64&amp;quot;, # 较新的Debian
            &amp;quot;CentOS 64-bit&amp;quot;: &amp;quot;centos7-64&amp;quot;, # 较新的CentOS
            &amp;quot;Other Linux 64-bit&amp;quot;: &amp;quot;otherlinux-64&amp;quot;,
            &amp;quot;Other 64-bit&amp;quot;: &amp;quot;other-64&amp;quot;,
            &amp;quot;Other 32-bit&amp;quot;: &amp;quot;other&amp;quot;
        }
        vmware_guest_os = os_type_map.get(os_type_selected, &amp;quot;other-64&amp;quot;)

        # 根据启动方式设置firmware
        firmware_setting = &amp;quot;&amp;quot;
        if boot_type_selected == &amp;quot;EFI (UEFI)&amp;quot;:
            firmware_setting = &amp;quot;firmware = \&amp;quot;efi\&amp;quot;&amp;quot;

        # VMX 模板
        # 提供了常见的配置，您可以根据需要进行调整
        vmx_content = f&amp;quot;&amp;quot;&amp;quot;
.encoding = &amp;quot;GBK&amp;quot;
config.version = &amp;quot;8&amp;quot;
virtualHW.version = &amp;quot;17&amp;quot; # 可以是 10, 11, 12, 14, 15, 16, 17 (对应不同VMware版本)
vmci0.present = &amp;quot;TRUE&amp;quot;
memsize = &amp;quot;4096&amp;quot; # 内存大小，单位MB
numvcpus = &amp;quot;2&amp;quot;   # CPU核心数
displayName = &amp;quot;{Path(vmdk_filename).stem}_converted_vm&amp;quot; # 虚拟机显示名称
guestOS = &amp;quot;{vmware_guest_os}&amp;quot; # 操作系统类型

{firmware_setting} # UEFI 或 BIOS 设置

# 硬盘
ide0:0.fileName = &amp;quot;{vmdk_filename}&amp;quot;
ide0:0.present = &amp;quot;TRUE&amp;quot;
ide0:0.redo = &amp;quot;&amp;quot; # 如果您希望保留快照功能，可以移除此行或设置为&amp;quot;auto&amp;quot;
# scsi0:0.fileName = &amp;quot;{vmdk_filename}&amp;quot; # 如果是SCSI磁盘，请使用此行并注释掉IDE行
# scsi0:0.present = &amp;quot;TRUE&amp;quot;
# scsi0:0.redo = &amp;quot;&amp;quot;
# scsi0.virtualDev = &amp;quot;lsilogic&amp;quot; # LSI Logic for SCSI

# 网络适配器 (NAT模式)
ethernet0.present = &amp;quot;TRUE&amp;quot;
ethernet0.connectionType = &amp;quot;nat&amp;quot;
ethernet0.virtualDev = &amp;quot;e1000&amp;quot; # 或 &amp;quot;vmxnet3&amp;quot; 获取更好性能 (需要安装VMware Tools)
ethernet0.wakeOnPcktRcv = &amp;quot;FALSE&amp;quot;

# USB 控制器
usb.present = &amp;quot;TRUE&amp;quot;
usb.autoConnect.enabled = &amp;quot;TRUE&amp;quot;

# 声音
sound.present = &amp;quot;TRUE&amp;quot;
sound.virtualDev = &amp;quot;hdaudio&amp;quot;

# CD/DVD 驱动器 (自动检测物理驱动器)
ide1:0.present = &amp;quot;TRUE&amp;quot;
ide1:0.deviceType = &amp;quot;atapi-cdrom&amp;quot;
ide1:0.startConnected = &amp;quot;FALSE&amp;quot;
ide1:0.autodetect = &amp;quot;TRUE&amp;quot;

# 其他设置
isolation.tools.hgfs.disable = &amp;quot;TRUE&amp;quot; # 禁用共享文件夹，提高安全性
mks.enable3d = &amp;quot;TRUE&amp;quot; # 启用3D加速
bios.bootdelay = &amp;quot;2000&amp;quot; # 启动时延迟2秒，方便进入BIOS/EFI设置

# 工具
tools.syncTime = &amp;quot;TRUE&amp;quot;
tools.upgrade.policy = &amp;quot;manual&amp;quot;

# 快照 (如果不需要快照，可以禁用)
snapshot.action = &amp;quot;autoCommit&amp;quot;
snapshot.numSnapshots = &amp;quot;0&amp;quot;

&amp;quot;&amp;quot;&amp;quot;
        return vmx_content.strip()

    def start_conversion(self):
        &amp;quot;&amp;quot;&amp;quot;开始整个转换流程&amp;quot;&amp;quot;&amp;quot;
        e01_path_str = self.e01_path_entry.get().strip()
        output_dir_str = self.output_dir_entry.get().strip()
        os_type_selected = self.os_type_var.get()
        boot_type_selected = self.boot_type_var.get()

        if not e01_path_str:
            messagebox.showwarning(&amp;quot;输入错误&amp;quot;, &amp;quot;请选择 E01 文件。&amp;quot;)
            return
        if not output_dir_str:
            messagebox.showwarning(&amp;quot;输入错误&amp;quot;, &amp;quot;请选择输出目录。&amp;quot;)
            return
        if not Path(EWFEXPORT_PATH).is_file():
            messagebox.showerror(&amp;quot;工具错误&amp;quot;, f&amp;quot;找不到 ewfexport.exe。请检查配置中的路径: {EWFEXPORT_PATH}&amp;quot;)
            return
        if not Path(QEMU_IMG_PATH).is_file():
            messagebox.showerror(&amp;quot;工具错误&amp;quot;, f&amp;quot;找不到 qemu-img.exe。请检查配置中的路径: {QEMU_IMG_PATH}&amp;quot;)
            return

        e01_path = Path(e01_path_str)
        output_dir = Path(output_dir_str)
        output_dir.mkdir(parents=True, exist_ok=True)

        # 基于E01文件名生成中间RAW和最终VMDK的文件名
        base_name = e01_path.stem # 获取不带扩展名的文件名
        raw_path = output_dir / f&amp;quot;{base_name}.raw&amp;quot; # 完整的raw文件路径
        vmdk_path = output_dir / f&amp;quot;{base_name}.vmdk&amp;quot;
        vmx_path = output_dir / f&amp;quot;{base_name}.vmx&amp;quot;

        self.log_text.config(state=&amp;quot;normal&amp;quot;)
        self.log_text.delete(1.0, tk.END) # 清空日志
        self.log_text.config(state=&amp;quot;disabled&amp;quot;)
        self.log_message(&amp;quot;--- 开始转换流程 ---&amp;quot;)
        self.progress_bar[&amp;quot;value&amp;quot;] = 0
        self.convert_button.config(state=&amp;quot;disabled&amp;quot;) # 禁用按钮防止重复点击

        try:
            # 1. 调用 ewfexport.exe 将 E01 转换为 RAW
            self.log_message(f&amp;quot;阶段1/3: 正在将 E01 转换为 RAW ({raw_path})...&amp;quot;)
            # ewfexport 的输入数据：
            # 1. 格式选择 (raw) - 直接回车，因为 -f raw 已经指定
            # 2. 目标文件名 (Windows_Server) - raw_path.stem
            # 3. 段大小 (0 B) - 回车
            # 4. 起始偏移 (0) - 回车
            # 5. 导出字节数 (全部) - 回车
            ewf_input_data = f&amp;quot;\n{raw_path.stem}\n\n\n\n&amp;quot; # 5个换行符

            ewf_command = [
                EWFEXPORT_PATH,
                str(e01_path),
                &amp;quot;-f&amp;quot;, &amp;quot;raw&amp;quot;,  # 指定输出格式为 raw
                # 注意：这里不再包含 -o 参数，我们将通过 stdin 提供文件名
            ]
            # 运行 ewfexport，并将工作目录设置为输出目录，同时提供输入数据
            if not self.run_command(ewf_command, &amp;quot;E01 到 RAW 转换&amp;quot;, input_data=ewf_input_data, cwd=output_dir):
                raise Exception(&amp;quot;E01 转换失败&amp;quot;)
            self.progress_bar[&amp;quot;value&amp;quot;] = 33

            # 2. 调用 qemu-img.exe 将 RAW 转换为 VMDK
            self.log_message(f&amp;quot;阶段2/3: 正在将 RAW 转换为 VMDK ({vmdk_path})...&amp;quot;)
            qemu_command = [
                QEMU_IMG_PATH,
                &amp;quot;convert&amp;quot;,
                &amp;quot;-f&amp;quot;, &amp;quot;raw&amp;quot;,
                &amp;quot;-O&amp;quot;, &amp;quot;vmdk&amp;quot;,
                str(raw_path),
                str(vmdk_path)
            ]
            if not self.run_command(qemu_command, &amp;quot;RAW 到 VMDK 转换&amp;quot;):
                raise Exception(&amp;quot;RAW 转换失败&amp;quot;)
            self.progress_bar[&amp;quot;value&amp;quot;] = 66

            # 3. 生成 VMX 文件
            self.log_message(f&amp;quot;阶段3/3: 正在生成 VMX 文件 ({vmx_path})...&amp;quot;)
            vmx_content = self.generate_vmx_content(vmdk_path.name, os_type_selected, boot_type_selected)
            try:
                with open(vmx_path, &amp;quot;w&amp;quot;, encoding=&amp;quot;utf-8&amp;quot;) as f:
                    f.write(vmx_content)
                self.log_message(f&amp;quot;VMX 文件已成功生成: {vmx_path}&amp;quot;)
            except Exception as e:
                self.log_message(f&amp;quot;错误: 生成 VMX 文件失败: {e}&amp;quot;)
                raise Exception(&amp;quot;VMX 生成失败&amp;quot;)
            self.progress_bar[&amp;quot;value&amp;quot;] = 90

            # 4. 删除中间产物 RAW 文件
            self.log_message(f&amp;quot;正在删除中间产物 RAW 文件 ({raw_path})...&amp;quot;)
            try:
                os.remove(raw_path)
                self.log_message(&amp;quot;RAW 文件删除成功。&amp;quot;)
            except OSError as e:
                self.log_message(f&amp;quot;警告: 删除 RAW 文件失败: {e}&amp;quot;)
                messagebox.showwarning(&amp;quot;警告&amp;quot;, f&amp;quot;删除中间产物 RAW 文件失败。\n请手动删除: {raw_path}&amp;quot;)
            self.progress_bar[&amp;quot;value&amp;quot;] = 100

            self.log_message(&amp;quot;--- 所有操作完成！ ---&amp;quot;)
            messagebox.showinfo(&amp;quot;完成&amp;quot;, f&amp;quot;E01 文件已成功转换为 VMDK，并生成 VMX 文件！\n\nVMDK: {vmdk_path}\nVMX: {vmx_path}&amp;quot;)

        except Exception as e:
            self.log_message(f&amp;quot;流程中断: {e}&amp;quot;)
            self.log_message(&amp;quot;--- 转换流程失败 ---&amp;quot;)
        finally:
            self.convert_button.config(state=&amp;quot;normal&amp;quot;) # 重新启用按钮

if __name__ == &amp;quot;__main__&amp;quot;:
    root = tk.Tk()
    app = E01ConverterApp(root)
    root.mainloop()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要下载ewfexport和qemu，路径替换完就可以用了&lt;/p&gt;
&lt;h2 id=&quot;h2-u8FD0u884Cu622Au56FE&quot;&gt;&lt;a name=&quot;运行截图&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;运行截图&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/07/202507111306385227580.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</description><pubDate>Fri, 11 Jul 2025 13:02:31 +0800</pubDate></item><item><title>HTTP走私原理及应用</title><link>https://hyluz.cn/post/90398.html</link><description>&lt;h3 id=&quot;h3--strong-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;关键原因：协议解析差异&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;关键原因：协议解析差异&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;HTTP请求的解析涉及两个层面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前端服务器（如CDN/代理）&lt;/strong&gt;：通常基于标准HTTP规范（如RFC 7230）解析请求。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;后端服务器（如源站）&lt;/strong&gt;：可能采用非标准解析（如容忍畸形请求）。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;当两者对&lt;strong&gt;请求边界&lt;/strong&gt;（如&lt;code&gt;Content-Length&lt;/code&gt;和&lt;code&gt;Transfer-Encoding&lt;/code&gt;头）的解析不一致时，攻击者可构造特殊请求，使前后端服务器对“一个请求的结束和下一个请求的开始”产生分歧，导致请求走私。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--strong-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;主要攻击类型&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;主要攻击类型&lt;/strong&gt;&lt;/h3&gt;&lt;h4 id=&quot;h4--strong-1-cl-te-content-length-transfer-encoding-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;(1) CL-TE走私（前端用Content-Length，后端用Transfer-Encoding）&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;(1) CL-TE走私（前端用Content-Length，后端用Transfer-Encoding）&lt;/strong&gt;&lt;/h4&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;POST / HTTP/1.1
Host: example.com
Content-Length: 13
Transfer-Encoding: chunked

0

 smuggled&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前端&lt;/strong&gt;：以&lt;code&gt;Content-Length: 13&lt;/code&gt;为准，认为整个请求体长度为13字节（包括&lt;code&gt;0\r\n\r\n&lt;/code&gt;）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;后端&lt;/strong&gt;：启用分块编码（&lt;code&gt;Transfer-Encoding&lt;/code&gt;），遇到&lt;code&gt;0\r\n\r\n&lt;/code&gt;认为请求结束，剩余部分&lt;code&gt;smuggled&lt;/code&gt;被当作下一个请求的起始。&lt;/li&gt;&lt;/ul&gt;
&lt;h4 id=&quot;h4--strong-2-te-cl-transfer-encoding-content-length-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;(2) TE-CL走私（前端用Transfer-Encoding，后端用Content-Length）&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;(2) TE-CL走私（前端用Transfer-Encoding，后端用Content-Length）&lt;/strong&gt;&lt;/h4&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;POST / HTTP/1.1
Host: example.com
Content-Length: 3
Transfer-Encoding: chunked

8
 smuggled
0&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前端&lt;/strong&gt;：处理分块编码，读取&lt;code&gt;8\r\n smuggled\r\n0\r\n\r\n&lt;/code&gt;后结束。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;后端&lt;/strong&gt;：忽略分块编码，以&lt;code&gt;Content-Length: 3&lt;/code&gt;读取前3字节（&lt;code&gt;8\r\n&lt;/code&gt;），剩余部分&lt;code&gt;smuggled\r\n0\r\n\r\n&lt;/code&gt;被当作后续请求。&lt;/li&gt;&lt;/ul&gt;
&lt;h4 id=&quot;h4--strong-3-te-te-transfer-encoding-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;(3) TE-TE走私（前后端均用Transfer-Encoding，但处理不一致）&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;(3) TE-TE走私（前后端均用Transfer-Encoding，但处理不一致）&lt;/strong&gt;&lt;/h4&gt;&lt;p&gt;通过混淆分块编码格式（如重复头、非标准终止符），诱使后端忽略分块边界。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;你的疑问非常关键！确实，如果用户尚未登录，即使通过HTTP走私将&lt;code&gt;GET /index&lt;/code&gt;注入到请求流中，后端服务器通常仍会要求身份验证。但HTTP走私的绕过能力&lt;strong&gt;依赖于具体场景&lt;/strong&gt;，以下是更详细的解释：&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--strong-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;为什么“绕过权限检查”可能成立？&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;为什么“绕过权限检查”可能成立？&lt;/strong&gt;&lt;/h3&gt;&lt;h4 id=&quot;h4--strong-1-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;(1) 假设条件&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;(1) 假设条件&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前端代理的权限检查&lt;/strong&gt;：某些架构中，代理层（如CDN/WAF）会先验证&lt;code&gt;Cookie&lt;/code&gt;或&lt;code&gt;Authorization&lt;/code&gt;头，合法请求才转发到后端。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;后端信任代理&lt;/strong&gt;：后端可能默认“所有到达的请求已通过代理验证”，不再重复检查权限。&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;如果攻击者通过走私注入的请求&lt;strong&gt;被后端视为独立请求&lt;/strong&gt;，且代理未正确拦截，则可能绕过前端的权限验证。&lt;/p&gt;
&lt;h4 id=&quot;h4--strong-2-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;(2) 典型场景示例&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;(2) 典型场景示例&lt;/strong&gt;&lt;/h4&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;POST /api HTTP/1.1
Host: target.com
Content-Length: 50
Transfer-Encoding: chunked
Cookie: valid-user-token=...  # 合法用户的Cookie（攻击者无此权限）

0

GET /admin HTTP/1.1  # 走私的恶意请求
X-Forwarded-For: 127.0.0.1&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前端代理&lt;/strong&gt;：检查第一个请求的&lt;code&gt;Cookie&lt;/code&gt;合法，放行整个请求（未发现走私部分）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;后端服务器&lt;/strong&gt;：将&lt;code&gt;GET /admin&lt;/code&gt;视为独立请求，且可能因信任代理或&lt;code&gt;X-Forwarded-For&lt;/code&gt;头误判为内部请求，直接返回数据。&lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--&quot;&gt;&lt;a name=&quot;** 用户未登录时的利用限制**&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;** 用户未登录时的利用限制**&lt;/h3&gt;&lt;p&gt;如果&lt;strong&gt;所有请求均需身份验证&lt;/strong&gt;（无论前后端），且攻击者无法获取合法凭证，单纯走私未授权的&lt;code&gt;GET /index&lt;/code&gt;确实无效。但以下情况仍可能存在风险：&lt;/p&gt;
&lt;h4 id=&quot;h4--strong-1-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;(1) 端点权限配置错误&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;(1) 端点权限配置错误&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;某些API路径（如&lt;code&gt;/healthcheck&lt;/code&gt;、&lt;code&gt;/static/files&lt;/code&gt;）可能未强制验证身份，攻击者通过走私访问这些端点。&lt;/li&gt;&lt;li&gt;例如：走私请求访问&lt;code&gt;/admin/export?user=*&lt;/code&gt;导出所有用户数据（假设该端点仅限IP白名单，但后端误判走私请求为内部IP）。&lt;/li&gt;&lt;/ul&gt;
&lt;h4 id=&quot;h4--strong-2-session-confusion-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;(2) 会话混淆（Session Confusion）&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;(2) 会话混淆（Session Confusion）&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;如果后端使用连接复用（如HTTP Keep-Alive），走私请求可能“继承”前一个合法请求的会话上下文。&lt;/li&gt;&lt;li&gt;例如：&lt;ol&gt;
&lt;li&gt;合法用户登录后，连接未关闭。&lt;/li&gt;&lt;li&gt;攻击者通过同一连接走私请求，后端误认为该请求属于已认证会话。&lt;/li&gt;&lt;/ol&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;h4 id=&quot;h4--strong-3-cache-poisoning-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;(3) 缓存欺骗（Cache Poisoning）&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;(3) 缓存欺骗（Cache Poisoning）&lt;/strong&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;走私请求可能触发缓存（如CDN）存储恶意响应，后续其他用户访问同一URL时收到恶意内容（无需登录）。&lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--strong-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;攻击影响&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;攻击影响&lt;/strong&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;绕过安全控制&lt;/strong&gt;：如WAF规则、IP限制或身份验证。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;缓存投毒&lt;/strong&gt;：污染CDN缓存，返回恶意内容。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;会话劫持&lt;/strong&gt;：窃取其他用户的请求数据。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;反射型攻击&lt;/strong&gt;：将恶意请求转发给其他用户。&lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--strong-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;防御措施&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;防御措施&lt;/strong&gt;&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;标准化解析&lt;/strong&gt;：强制前后端使用一致的协议解析逻辑。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;禁用畸形请求&lt;/strong&gt;：拒绝含冲突头（如&lt;code&gt;Content-Length&lt;/code&gt;和&lt;code&gt;Transfer-Encoding&lt;/code&gt;共存）的请求。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;严格验证&lt;/strong&gt;：对请求边界进行严格校验（如分块编码的终止符）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;更新中间件&lt;/strong&gt;：修复已知的解析漏洞（如Apache/CVE-2022-22721、Nginx配置错误）。&lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--strong-strong-&quot;&gt;&lt;a name=&quot;&lt;strong&gt;示例场景&lt;/strong&gt;&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;&lt;strong&gt;示例场景&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;假设前端代理（Nginx）和后端（Apache）对以下请求解析不同：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;POST /admin HTTP/1.1
Host: target.com
Content-Length: 10
Transfer-Encoding: chunked

2
xx
0

GET /index HTTP/1.1&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;后端可能将&lt;code&gt;GET /index&lt;/code&gt;视为独立请求，从而绕过前端的权限检查。&lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;HTTP smuggling的复杂性在于不同服务器实现的细微差异，攻击者通过精心构造请求利用这些差异实现恶意目的。防御需全面审查HTTP请求处理链路的每一环节。&lt;/p&gt;
</description><pubDate>Tue, 25 Mar 2025 11:40:31 +0800</pubDate></item><item><title>远程桌面 Windows Server 音频服务未运行</title><link>https://hyluz.cn/post/90397.html</link><description>&lt;p&gt;远程桌面没有声音，声卡驱动是正常的&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/02/202502131523247262807.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;但是状态栏音频这里是个叉，提示音频服务未运行&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/02/202502131523536899525.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3-u5904u7406u529Eu6CD5&quot;&gt;&lt;a name=&quot;处理办法&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;处理办法&lt;/h3&gt;&lt;p&gt;打开服务&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/02/202502131524072411206.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;启动Windows Audio服务&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/02/202502131525003199492.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;正常了，也有声音了&lt;br&gt;&lt;img src=&quot;https://hyluz.cn/zb_users/upload/2025/02/202502131525571196831.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</description><pubDate>Thu, 13 Feb 2025 15:22:35 +0800</pubDate></item><item><title>多选题-烈士公祭是()而毕生奋斗、英勇牺牲的烈士的活动。</title><link>https://hyluz.cn/post/90380.html</link><description>多选题-烈士公祭是()而毕生奋斗、英勇牺牲的烈士的活动。

answer：['国家缅怀纪念为争取民族独立和人民解放', '实现国家富强和人民幸福', '促进世界和平和人类进步']</description><pubDate>Fri, 20 Dec 2024 13:35:26 +0800</pubDate></item><item><title>单选题-甲公司认为某电商平台内的网店销售的商品假冒其商标,通知该平台经营者采取必要措施,则该通知应当包括的证据要求是()。</title><link>https://hyluz.cn/post/90379.html</link><description>单选题-甲公司认为某电商平台内的网店销售的商品假冒其商标,通知该平台经营者采取必要措施,则该通知应当包括的证据要求是()。

answer：['通知应当包括构成侵权的初步证据']</description><pubDate>Fri, 20 Dec 2024 13:35:24 +0800</pubDate></item></channel></rss>