<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>MrWu</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://mrwu.me/</id>
  <link href="https://mrwu.me/" rel="alternate"/>
  <link href="https://mrwu.me/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, MrWu</rights>
  <subtitle>一杯茶, 一包烟, 一个破站搞一天. | 还看（；´д｀）ゞ</subtitle>
  <title>MrWu</title>
  <updated>2026-04-26T19:19:53.819Z</updated>
  <entry>
    <author>
      <name>MrWu</name>
    </author>
    <category term="攻防类" scheme="https://mrwu.me/categories/defensive/"/>
    <category term="代码审计" scheme="https://mrwu.me/tags/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/"/>
    <category term="漏洞挖掘" scheme="https://mrwu.me/tags/%E6%BC%8F%E6%B4%9E%E6%8C%96%E6%8E%98/"/>
    <category term="任意文件上传" scheme="https://mrwu.me/tags/%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0/"/>
    <category term="SQL注入" scheme="https://mrwu.me/tags/SQL%E6%B3%A8%E5%85%A5/"/>
    <category term="ThinkPHP" scheme="https://mrwu.me/tags/ThinkPHP/"/>
    <content>
      <![CDATA[<div class="tag-plugin colorful note" color="颜色" child="codeblock/tabs"><div class="title"><strong><p>本文摘要</p></strong></div><div class="body"><p>分享一个关于代码审计挖掘漏洞，以及后续技术修复防御失败的案例，过程有点曲折，也有点意思 (￣▽￣)”</p></div></div><span id="more"></span><h2 id="漏洞成因"><a href="#漏洞成因" class="headerlink" title="漏洞成因"></a>漏洞成因</h2><p>对一套典型 PHP 商城框架代码进行审计学习，本次审计主要发现了两个高危漏洞：后台任意文件上传和前台 SQL 报错注入。</p><h3 id="任意文件上传"><a href="#任意文件上传" class="headerlink" title="任意文件上传"></a>任意文件上传</h3><p>该源码项目在后台调用了 Ueditor 编辑器，关键问题在于没有对上传接口做鉴权，并且还调用了其他的上传方法。</p><p>先看编辑器上传入口处的部分代码：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 百度编辑器上传</span></span><br><span class="line"><span class="comment"> * 版本 1.0.6</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Ueditor</span> <span class="keyword">extends</span> <span class="title">Controller</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">index</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="title function_ invoke__">date_default_timezone_set</span>(<span class="string">&quot;Asia/chongqing&quot;</span>);</span><br><span class="line">        <span class="title function_ invoke__">error_reporting</span>(E_ERROR);</span><br><span class="line">        <span class="title function_ invoke__">header</span>(<span class="string">&quot;Content-Type: text/html; charset=utf-8&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="variable">$CONFIG</span> = <span class="title function_ invoke__">json_decode</span>(<span class="title function_ invoke__">preg_replace</span>(<span class="string">&quot;/\/\*[\s\S]+?\*\//&quot;</span>, <span class="string">&quot;&quot;</span>, <span class="title function_ invoke__">file_get_contents</span>(<span class="string">&quot;./public/static/ext/ueditor/php/config.json&quot;</span>)), <span class="literal">true</span>);</span><br><span class="line">        <span class="variable">$action</span> = <span class="variable">$_GET</span>[ <span class="string">&#x27;action&#x27;</span> ];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">switch</span> ( <span class="variable">$action</span> ) &#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;config&#x27;</span>:</span><br><span class="line">                <span class="variable">$result</span> = <span class="title function_ invoke__">json_encode</span>(<span class="variable">$CONFIG</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="comment">/* 上传图片 */</span></span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;uploadimage&#x27;</span>:</span><br><span class="line">                <span class="variable">$fieldName</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;imageFieldName&#x27;</span> ];</span><br><span class="line">                <span class="variable">$result</span> = <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">upImage</span>(<span class="variable">$fieldName</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="comment">/* 上传涂鸦 */</span></span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;uploadscrawl&#x27;</span>:</span><br><span class="line">                <span class="variable">$config</span> = <span class="keyword">array</span> (</span><br><span class="line">                    <span class="string">&quot;pathFormat&quot;</span> =&gt; <span class="variable">$CONFIG</span>[ <span class="string">&#x27;scrawlPathFormat&#x27;</span> ],</span><br><span class="line">                    <span class="string">&quot;maxSize&quot;</span> =&gt; <span class="variable">$CONFIG</span>[ <span class="string">&#x27;scrawlMaxSize&#x27;</span> ],</span><br><span class="line">                    <span class="string">&quot;allowFiles&quot;</span> =&gt; <span class="variable">$CONFIG</span>[ <span class="string">&#x27;scrawlAllowFiles&#x27;</span> ],</span><br><span class="line">                    <span class="string">&quot;oriName&quot;</span> =&gt; <span class="string">&quot;scrawl.png&quot;</span></span><br><span class="line">                );</span><br><span class="line">                <span class="variable">$fieldName</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;scrawlFieldName&#x27;</span> ];</span><br><span class="line">                <span class="variable">$base64</span> = <span class="string">&quot;base64&quot;</span>;</span><br><span class="line">                <span class="variable">$result</span> = <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">upBase64</span>(<span class="variable">$config</span>, <span class="variable">$fieldName</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="comment">/* 上传视频 */</span></span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;uploadvideo&#x27;</span>:</span><br><span class="line">                <span class="variable">$fieldName</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;videoFieldName&#x27;</span> ];</span><br><span class="line">                <span class="variable">$result</span> = <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">upVideo</span>(<span class="variable">$fieldName</span>, <span class="variable">$CONFIG</span>[ <span class="string">&#x27;videoMaxSize&#x27;</span> ]);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="comment">/* 上传文件 */</span></span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;uploadfile&#x27;</span>:</span><br><span class="line">                <span class="variable">$fieldName</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;fileFieldName&#x27;</span> ];</span><br><span class="line">                <span class="variable">$result</span> = <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">upFile</span>(<span class="variable">$fieldName</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="comment">/* 列出图片 */</span></span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;listimage&#x27;</span>:</span><br><span class="line">                <span class="variable">$allowFiles</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;imageManagerAllowFiles&#x27;</span> ];</span><br><span class="line">                <span class="variable">$listSize</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;imageManagerListSize&#x27;</span> ];</span><br><span class="line">                <span class="variable">$path</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;imageManagerListPath&#x27;</span> ];</span><br><span class="line">                <span class="variable">$get</span> = <span class="variable">$_GET</span>;</span><br><span class="line">                <span class="variable">$result</span> = <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">fileList</span>(<span class="variable">$allowFiles</span>, <span class="variable">$listSize</span>, <span class="variable">$get</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="comment">/* 列出文件 */</span></span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;listfile&#x27;</span>:</span><br><span class="line">                <span class="variable">$allowFiles</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;fileManagerAllowFiles&#x27;</span> ];</span><br><span class="line">                <span class="variable">$listSize</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;fileManagerListSize&#x27;</span> ];</span><br><span class="line">                <span class="variable">$path</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;fileManagerListPath&#x27;</span> ];</span><br><span class="line">                <span class="variable">$get</span> = <span class="variable">$_GET</span>;</span><br><span class="line">                <span class="variable">$result</span> = <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">fileList</span>(<span class="variable">$allowFiles</span>, <span class="variable">$listSize</span>, <span class="variable">$get</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="comment">/* 抓取远程文件 */</span></span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;catchimage&#x27;</span>:</span><br><span class="line">                <span class="variable">$config</span> = <span class="keyword">array</span> (</span><br><span class="line">                    <span class="string">&quot;pathFormat&quot;</span> =&gt; <span class="variable">$CONFIG</span>[ <span class="string">&#x27;catcherPathFormat&#x27;</span> ],</span><br><span class="line">                    <span class="string">&quot;maxSize&quot;</span> =&gt; <span class="variable">$CONFIG</span>[ <span class="string">&#x27;catcherMaxSize&#x27;</span> ],</span><br><span class="line">                    <span class="string">&quot;allowFiles&quot;</span> =&gt; <span class="variable">$CONFIG</span>[ <span class="string">&#x27;catcherAllowFiles&#x27;</span> ],</span><br><span class="line">                    <span class="string">&quot;oriName&quot;</span> =&gt; <span class="string">&quot;remote.png&quot;</span></span><br><span class="line">                );</span><br><span class="line">                <span class="variable">$fieldName</span> = <span class="variable">$CONFIG</span>[ <span class="string">&#x27;catcherFieldName&#x27;</span> ];</span><br><span class="line">                <span class="comment">/* 抓取远程图片 */</span></span><br><span class="line">                <span class="variable">$list</span> = <span class="keyword">array</span> ();</span><br><span class="line">                <span class="keyword">isset</span>(<span class="variable">$_POST</span>[ <span class="variable">$fieldName</span> ]) ? <span class="variable">$source</span> = <span class="variable">$_POST</span>[ <span class="variable">$fieldName</span> ] : <span class="variable">$source</span> = <span class="variable">$_GET</span>[ <span class="variable">$fieldName</span> ];</span><br><span class="line"></span><br><span class="line">                <span class="keyword">foreach</span> (<span class="variable">$source</span> <span class="keyword">as</span> <span class="variable">$imgUrl</span>) &#123;</span><br><span class="line">                    <span class="variable">$info</span> = <span class="title function_ invoke__">json_decode</span>(<span class="variable">$this</span>-&gt;<span class="title function_ invoke__">saveRemote</span>(<span class="variable">$config</span>, <span class="variable">$imgUrl</span>), <span class="literal">true</span>);</span><br><span class="line">                    <span class="title function_ invoke__">array_push</span>(<span class="variable">$list</span>, <span class="keyword">array</span> (</span><br><span class="line">                        <span class="string">&quot;state&quot;</span> =&gt; <span class="variable">$info</span>[ <span class="string">&quot;state&quot;</span> ],</span><br><span class="line">                        <span class="string">&quot;url&quot;</span> =&gt; <span class="variable">$info</span>[ <span class="string">&quot;url&quot;</span> ],</span><br><span class="line">                        <span class="string">&quot;size&quot;</span> =&gt; <span class="variable">$info</span>[ <span class="string">&quot;size&quot;</span> ],</span><br><span class="line">                        <span class="string">&quot;title&quot;</span> =&gt; <span class="title function_ invoke__">htmlspecialchars</span>(<span class="variable">$info</span>[ <span class="string">&quot;title&quot;</span> ]),</span><br><span class="line">                        <span class="string">&quot;original&quot;</span> =&gt; <span class="title function_ invoke__">htmlspecialchars</span>(<span class="variable">$info</span>[ <span class="string">&quot;original&quot;</span> ]),</span><br><span class="line">                        <span class="string">&quot;source&quot;</span> =&gt; <span class="title function_ invoke__">htmlspecialchars</span>(<span class="variable">$imgUrl</span>)</span><br><span class="line">                    ));</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="variable">$result</span> = <span class="title function_ invoke__">json_encode</span>(<span class="keyword">array</span> (</span><br><span class="line">                    <span class="string">&#x27;state&#x27;</span> =&gt; <span class="title function_ invoke__">count</span>(<span class="variable">$list</span>) ? <span class="string">&#x27;SUCCESS&#x27;</span> : <span class="string">&#x27;ERROR&#x27;</span>,</span><br><span class="line">                    <span class="string">&#x27;list&#x27;</span> =&gt; <span class="variable">$list</span></span><br><span class="line">                ));</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">default</span>:</span><br><span class="line">                <span class="variable">$result</span> = <span class="title function_ invoke__">json_encode</span>(<span class="keyword">array</span> (</span><br><span class="line">                    <span class="string">&#x27;state&#x27;</span> =&gt; <span class="string">&#x27;请求地址出错&#x27;</span></span><br><span class="line">                ));</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/* 输出结果 */</span></span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">isset</span>(<span class="variable">$_GET</span>[ <span class="string">&quot;callback&quot;</span> ])) &#123;</span><br><span class="line">            <span class="keyword">if</span> (<span class="title function_ invoke__">preg_match</span>(<span class="string">&quot;/^[\w_]+$/&quot;</span>, <span class="variable">$_GET</span>[ <span class="string">&quot;callback&quot;</span> ])) &#123;</span><br><span class="line">                <span class="keyword">echo</span> <span class="title function_ invoke__">htmlspecialchars</span>(<span class="variable">$_GET</span>[ <span class="string">&quot;callback&quot;</span> ]) . <span class="string">&#x27;(&#x27;</span> . <span class="variable">$result</span> . <span class="string">&#x27;)&#x27;</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">echo</span> <span class="title function_ invoke__">json_encode</span>(<span class="keyword">array</span> (</span><br><span class="line">                    <span class="string">&#x27;state&#x27;</span> =&gt; <span class="string">&#x27;callback参数不合法&#x27;</span></span><br><span class="line">                ));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">echo</span> <span class="variable">$result</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">upVideo</span>(<span class="params"><span class="variable">$fieldName</span>, <span class="variable">$size</span></span>)</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="variable">$upload_service</span> = <span class="keyword">new</span> <span class="title class_">UploadModel</span>();</span><br><span class="line">        <span class="keyword">if</span> (!<span class="keyword">empty</span>(<span class="variable">$_FILES</span>[ <span class="variable">$fieldName</span> ])) &#123;<span class="comment">//上传成功</span></span><br><span class="line">            <span class="variable">$info</span> = <span class="variable">$upload_service</span>-&gt;<span class="title function_ invoke__">setPath</span>(<span class="string">&quot;common/video/&quot;</span> . <span class="title function_ invoke__">date</span>(<span class="string">&quot;Ymd&quot;</span>) . <span class="string">&#x27;/&#x27;</span>)-&gt;<span class="title function_ invoke__">video</span>([</span><br><span class="line">                <span class="string">&#x27;name&#x27;</span> =&gt; <span class="variable">$fieldName</span>,</span><br><span class="line">            ]);</span><br><span class="line">            <span class="keyword">if</span> (<span class="variable">$info</span>[ <span class="string">&#x27;code&#x27;</span> ] &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="variable">$data</span> = <span class="keyword">array</span> (</span><br><span class="line">                    <span class="string">&#x27;state&#x27;</span> =&gt; <span class="string">&#x27;SUCCESS&#x27;</span>,</span><br><span class="line">                    <span class="string">&#x27;url&#x27;</span> =&gt; <span class="variable">$info</span>[ <span class="string">&#x27;data&#x27;</span> ][ <span class="string">&#x27;path&#x27;</span> ],</span><br><span class="line">                    <span class="string">&#x27;title&#x27;</span> =&gt; <span class="variable">$info</span>[ <span class="string">&#x27;data&#x27;</span> ][ <span class="string">&#x27;path&#x27;</span> ],</span><br><span class="line">                    <span class="string">&#x27;original&#x27;</span> =&gt; <span class="variable">$info</span>[ <span class="string">&#x27;data&#x27;</span> ][ <span class="string">&#x27;path&#x27;</span> ]</span><br><span class="line">                );</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="variable">$data</span> = <span class="keyword">array</span> (</span><br><span class="line">                    <span class="string">&#x27;state&#x27;</span> =&gt; <span class="string">&#x27;FAIL&#x27;</span></span><br><span class="line">                );</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="variable">$data</span> = <span class="keyword">array</span> (</span><br><span class="line">                <span class="string">&#x27;state&#x27;</span> =&gt; <span class="string">&#x27;上传文件为空&#x27;</span>,</span><br><span class="line">            );</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="title function_ invoke__">json_encode</span>(<span class="variable">$data</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>我们可以看到，<code>index</code> 方法的 <code>action</code> 参数如果设置为 <code>uploadvideo</code>，就可以直接调用 <code>upVideo</code> 上传方法。而在 <code>upVideo</code> 方法中，又调用了 <code>model</code> 中的 <code>upload</code> 方法，这才是真正产生任意上传漏洞的核心点。</p><p>继续看 <code>video</code> 方法的实现：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 视频上传</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $param</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">video</span>(<span class="params"><span class="variable">$param</span></span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="variable">$check_res</span> = <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">checkFile</span>();</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$check_res</span>[ <span class="string">&quot;code&quot;</span> ] &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="comment">// 获取表单上传文件</span></span><br><span class="line">        <span class="variable">$file</span> = <span class="title function_ invoke__">request</span>()-&gt;<span class="title function_ invoke__">file</span>(<span class="variable">$param</span>[ <span class="string">&quot;name&quot;</span> ]);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="variable">$extend_name</span> = <span class="variable">$file</span>-&gt;<span class="title function_ invoke__">getOriginalExtension</span>();</span><br><span class="line">            <span class="variable">$new_name</span> = <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">createNewFileName</span>() . <span class="string">&quot;.&quot;</span> . <span class="variable">$extend_name</span>;</span><br><span class="line"></span><br><span class="line">            <span class="variable">$file_path</span> = <span class="variable language_">$this</span>-&gt;path;</span><br><span class="line">            \think\facade<span class="title class_">\Filesystem</span>::<span class="title function_ invoke__">disk</span>(<span class="string">&#x27;public&#x27;</span>)-&gt;<span class="title function_ invoke__">putFileAs</span>(<span class="variable">$file_path</span>, <span class="variable">$file</span>, <span class="variable">$new_name</span>);</span><br><span class="line">            <span class="variable">$file_name</span> = <span class="variable">$file_path</span> . <span class="variable">$new_name</span>;</span><br><span class="line">            <span class="variable">$result</span> = <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">fileCloud</span>(<span class="variable">$file_name</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">success</span>([ <span class="string">&quot;path&quot;</span> =&gt; <span class="variable">$result</span>[ <span class="string">&#x27;data&#x27;</span> ] ?? <span class="string">&#x27;&#x27;</span> ], <span class="string">&quot;UPLOAD_SUCCESS&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (\think\exception\ValidateException <span class="variable">$e</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">error</span>(<span class="string">&#x27;&#x27;</span>, <span class="variable">$e</span>-&gt;<span class="title function_ invoke__">getMessage</span>());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$check_res</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><div class="tag-plugin quot p"><p class="content"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from BoxIcons Solid by Atisa - https://creativecommons.org/licenses/by/4.0/ --><path fill="currentColor" d="M3.691 6.292C5.094 4.771 7.217 4 10 4h1v2.819l-.804.161c-1.37.274-2.323.813-2.833 1.604A2.9 2.9 0 0 0 6.925 10H10a1 1 0 0 1 1 1v7c0 1.103-.897 2-2 2H3a1 1 0 0 1-1-1v-5l.003-2.919c-.009-.111-.199-2.741 1.688-4.789M20 20h-6a1 1 0 0 1-1-1v-5l.003-2.919c-.009-.111-.199-2.741 1.688-4.789C16.094 4.771 18.217 4 21 4h1v2.819l-.804.161c-1.37.274-2.323.813-2.833 1.604A2.9 2.9 0 0 0 17.925 10H21a1 1 0 0 1 1 1v7c0 1.103-.897 2-2 2"/></svg><span class="text">漏洞核心点</span><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from BoxIcons Solid by Atisa - https://creativecommons.org/licenses/by/4.0/ --><path fill="currentColor" d="M20.309 17.708C22.196 15.66 22.006 13.03 22 13V5a1 1 0 0 0-1-1h-6c-1.103 0-2 .897-2 2v7a1 1 0 0 0 1 1h3.078a2.9 2.9 0 0 1-.429 1.396c-.508.801-1.465 1.348-2.846 1.624l-.803.16V20h1c2.783 0 4.906-.771 6.309-2.292m-11.007 0C11.19 15.66 10.999 13.03 10.993 13V5a1 1 0 0 0-1-1h-6c-1.103 0-2 .897-2 2v7a1 1 0 0 0 1 1h3.078a2.9 2.9 0 0 1-.429 1.396c-.508.801-1.465 1.348-2.846 1.624l-.803.16V20h1c2.783 0 4.906-.771 6.309-2.292"/></svg></p></div><p>漏洞点在于 <code>disk(&#39;public&#39;)-&gt;putFileAs($file_path, $file, $new_name);</code>。从入口调用到 <code>video</code> 方法，没有任何的过滤限制，最终形成了任意文件上传漏洞。</p><h3 id="前台-SQL-报错注入"><a href="#前台-SQL-报错注入" class="headerlink" title="前台 SQL 报错注入"></a>前台 SQL 报错注入</h3><p>再来看看前台 SQL 注入的问题。入口代码如下：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Store</span> <span class="keyword">extends</span> <span class="title">BaseApi</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 列表信息</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">page</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">//        $page = isset($this-&gt;params[&#x27;page&#x27;]) ? $this-&gt;params[&#x27;page&#x27;] : 1;</span></span><br><span class="line"><span class="comment">//        $page_size = isset($this-&gt;params[&#x27;page_size&#x27;]) ? $this-&gt;params[&#x27;page_size&#x27;] : PAGE_LIST_ROWS;</span></span><br><span class="line">        <span class="variable">$latitude</span> = <span class="keyword">isset</span>(<span class="variable language_">$this</span>-&gt;params[ <span class="string">&#x27;latitude&#x27;</span> ]) ? <span class="variable language_">$this</span>-&gt;params[ <span class="string">&#x27;latitude&#x27;</span> ] : <span class="literal">null</span>; <span class="comment">// 纬度</span></span><br><span class="line">        <span class="variable">$longitude</span> = <span class="keyword">isset</span>(<span class="variable language_">$this</span>-&gt;params[ <span class="string">&#x27;longitude&#x27;</span> ]) ? <span class="variable language_">$this</span>-&gt;params[ <span class="string">&#x27;longitude&#x27;</span> ] : <span class="literal">null</span>; <span class="comment">// 经度</span></span><br><span class="line">        <span class="variable">$store_id</span> = <span class="keyword">isset</span>(<span class="variable language_">$this</span>-&gt;params[ <span class="string">&#x27;store_id&#x27;</span> ]) ? <span class="variable language_">$this</span>-&gt;params[ <span class="string">&#x27;store_id&#x27;</span> ] : <span class="number">0</span>; <span class="comment">// 默认门店</span></span><br><span class="line">        <span class="variable">$store_model</span> = <span class="keyword">new</span> <span class="title class_">StoreModel</span>();</span><br><span class="line">        <span class="variable">$condition</span> = [</span><br><span class="line">            [ <span class="string">&#x27;site_id&#x27;</span>, <span class="string">&quot;=&quot;</span>, <span class="variable language_">$this</span>-&gt;site_id ],</span><br><span class="line">            [ <span class="string">&#x27;status&#x27;</span>, <span class="string">&#x27;=&#x27;</span>, <span class="number">1</span> ],</span><br><span class="line">            [ <span class="string">&#x27;is_frozen&#x27;</span>, <span class="string">&#x27;=&#x27;</span>, <span class="number">0</span> ],</span><br><span class="line">            [ <span class="string">&#x27;is_pickup&#x27;</span>, <span class="string">&#x27;=&#x27;</span>, <span class="number">1</span> ]</span><br><span class="line">        ];</span><br><span class="line"></span><br><span class="line">        <span class="variable">$latlng</span> = <span class="keyword">array</span> (</span><br><span class="line">            <span class="string">&#x27;lat&#x27;</span> =&gt; <span class="variable">$latitude</span>,</span><br><span class="line">            <span class="string">&#x27;lng&#x27;</span> =&gt; <span class="variable">$longitude</span>,</span><br><span class="line">        );</span><br><span class="line">        <span class="variable">$field</span> = <span class="string">&#x27;*&#x27;</span>;</span><br><span class="line">        <span class="variable">$list_result</span> = <span class="variable">$store_model</span>-&gt;<span class="title function_ invoke__">getLocationStoreList</span>(<span class="variable">$condition</span>, <span class="variable">$field</span>, <span class="variable">$latlng</span>);</span><br><span class="line"></span><br><span class="line">        <span class="variable">$list</span> = <span class="variable">$list_result</span>[ <span class="string">&#x27;data&#x27;</span> ];</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!<span class="keyword">empty</span>(<span class="variable">$longitude</span>) &amp;&amp; !<span class="keyword">empty</span>(<span class="variable">$latitude</span>) &amp;&amp; !<span class="keyword">empty</span>(<span class="variable">$list</span>)) &#123;</span><br><span class="line">            <span class="keyword">foreach</span> (<span class="variable">$list</span> <span class="keyword">as</span> <span class="variable">$k</span> =&gt; <span class="variable">$item</span>) &#123;</span><br><span class="line">                <span class="keyword">if</span> (<span class="variable">$item</span>[ <span class="string">&#x27;longitude&#x27;</span> ] &amp;&amp; <span class="variable">$item</span>[ <span class="string">&#x27;latitude&#x27;</span> ]) &#123;</span><br><span class="line">                    <span class="variable">$distance</span> = <span class="title function_ invoke__">getDistance</span>((<span class="keyword">float</span>) <span class="variable">$item</span>[ <span class="string">&#x27;longitude&#x27;</span> ], (<span class="keyword">float</span>) <span class="variable">$item</span>[ <span class="string">&#x27;latitude&#x27;</span> ], (<span class="keyword">float</span>) <span class="variable">$longitude</span>, (<span class="keyword">float</span>) <span class="variable">$latitude</span>);</span><br><span class="line">                    <span class="variable">$list</span>[ <span class="variable">$k</span> ][ <span class="string">&#x27;distance&#x27;</span> ] = <span class="variable">$distance</span> / <span class="number">1000</span>;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="variable">$list</span>[ <span class="variable">$k</span> ][ <span class="string">&#x27;distance&#x27;</span> ] = <span class="number">0</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 按距离就近排序</span></span><br><span class="line">            <span class="title function_ invoke__">array_multisort</span>(<span class="title function_ invoke__">array_column</span>(<span class="variable">$list</span>, <span class="string">&#x27;distance&#x27;</span>), SORT_ASC, <span class="variable">$list</span>);</span><br><span class="line">        &#125;</span><br><span class="line"><span class="comment">//        array_multisort(array_column($list, &#x27;distance&#x27;), SORT_ASC, $list);</span></span><br><span class="line">        <span class="variable">$default_store_id</span> = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">if</span> (!<span class="keyword">empty</span>(<span class="variable">$list</span>)) &#123;</span><br><span class="line">            <span class="variable">$default_store_id</span> = <span class="variable">$list</span>[ <span class="number">0</span> ][ <span class="string">&#x27;store_id&#x27;</span> ];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">response</span>(<span class="variable">$this</span>-&gt;<span class="title function_ invoke__">success</span>([ <span class="string">&#x27;list&#x27;</span> =&gt; <span class="variable">$list</span>, <span class="string">&#x27;store_id&#x27;</span> =&gt; <span class="variable">$default_store_id</span> ]));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>漏洞点位于 <code>getLocationStoreList</code> 方法中：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 查询门店  带有距离</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $condition</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $lnglat</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">getLocationStoreList</span>(<span class="params"><span class="variable">$condition</span>, <span class="variable">$field</span>, <span class="variable">$lnglat</span></span>)</span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="variable">$order</span> = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$lnglat</span>[ <span class="string">&#x27;lat&#x27;</span> ] !== <span class="literal">null</span> &amp;&amp; <span class="variable">$lnglat</span>[ <span class="string">&#x27;lng&#x27;</span> ] !== <span class="literal">null</span>) &#123;</span><br><span class="line">        <span class="variable">$field</span> .= <span class="string">&#x27; , ROUND(st_distance ( point ( &#x27;</span> . <span class="variable">$lnglat</span>[ <span class="string">&#x27;lng&#x27;</span> ] . <span class="string">&#x27;, &#x27;</span> . <span class="variable">$lnglat</span>[ <span class="string">&#x27;lat&#x27;</span> ] . <span class="string">&#x27; ), point ( longitude, latitude ) ) * 111195 / 1000, 2) as distance &#x27;</span>;</span><br><span class="line">        <span class="variable">$condition</span>[] = [ <span class="string">&#x27;&#x27;</span>, <span class="string">&#x27;exp&#x27;</span>, <span class="title class_">Db</span>::<span class="title function_ invoke__">raw</span>(<span class="string">&#x27; FORMAT(st_distance ( point ( &#x27;</span> . <span class="variable">$lnglat</span>[ <span class="string">&#x27;lng&#x27;</span> ] . <span class="string">&#x27;, &#x27;</span> . <span class="variable">$lnglat</span>[ <span class="string">&#x27;lat&#x27;</span> ] . <span class="string">&#x27; ), point ( longitude, latitude ) ) * 111195 / 1000, 2) &lt; 10000&#x27;</span>) ];</span><br><span class="line">        <span class="variable">$order</span> = <span class="string">&#x27;distance asc&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="variable">$list</span> = <span class="title function_ invoke__">model</span>(<span class="string">&#x27;store&#x27;</span>)-&gt;<span class="title function_ invoke__">getList</span>(<span class="variable">$condition</span>, <span class="variable">$field</span>, <span class="variable">$order</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="variable language_">$this</span>-&gt;<span class="title function_ invoke__">success</span>(<span class="variable">$list</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>可以看到，整个数据传递没有任何过滤，然后在 <code>getLocationStoreList</code> 方法中直接将参数 <code>$lnglat</code> 拼接到了 SQL 语句中，导致了 SQL 注入。</p><h2 id="技术防御方式"><a href="#技术防御方式" class="headerlink" title="技术防御方式"></a>技术防御方式</h2><p>面对这两个漏洞，开发者的修复方式可谓是“别出心裁”。</p><h3 id="上传漏洞的“迷之”修复"><a href="#上传漏洞的“迷之”修复" class="headerlink" title="上传漏洞的“迷之”修复"></a>上传漏洞的“迷之”修复</h3><p>对于上传点漏洞，技术的防御方式是真的太粗暴了——直接禁了 <code>common/video/</code> 这个上传目录的写入权限。这也是大写的服 (¬_¬”)。</p><h3 id="SQL-注入的“自研”WAF"><a href="#SQL-注入的“自研”WAF" class="headerlink" title="SQL 注入的“自研”WAF"></a>SQL 注入的“自研”WAF</h3><p>对于前台 SQL 报错注入，技术倒是有点水平了，但也就只是有点点水平了。他在 <code>index.php</code> 入口文件增加了一段全局过滤代码：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// +----------------------------------------------------------------------</span></span><br><span class="line"><span class="comment">// | ThinkPHP [ WE CAN DO IT JUST THINK ]</span></span><br><span class="line"><span class="comment">// +----------------------------------------------------------------------</span></span><br><span class="line"><span class="comment">// | Copyright (c) 2006-2019 http://thinkphp.cn All rights reserved.</span></span><br><span class="line"><span class="comment">// +----------------------------------------------------------------------</span></span><br><span class="line"><span class="comment">// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )</span></span><br><span class="line"><span class="comment">// +----------------------------------------------------------------------</span></span><br><span class="line"><span class="comment">// | Author: liu21st &lt;liu21st@gmail.com&gt;</span></span><br><span class="line"><span class="comment">// +----------------------------------------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// [ 应用入口文件 ]</span></span><br><span class="line"><span class="keyword">namespace</span> <span class="title class_">think</span>;</span><br><span class="line"><span class="keyword">if</span> (<span class="title function_ invoke__">version_compare</span>(PHP_VERSION, <span class="string">&#x27;7.1.0&#x27;</span>, <span class="string">&#x27;&lt;&#x27;</span>))</span><br><span class="line"><span class="keyword">die</span>(<span class="string">&#x27;require PHP &gt; 7.1.0 !&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 检测PHP环境  允许前端跨域请求</span></span><br><span class="line"><span class="title function_ invoke__">header</span>(<span class="string">&quot;Access-Control-Allow-Origin:*&quot;</span>);</span><br><span class="line"><span class="comment">// 响应类型</span></span><br><span class="line"><span class="title function_ invoke__">header</span>(<span class="string">&#x27;Access-Control-Allow-Methods:GET, POST, PUT, DELETE&#x27;</span>);</span><br><span class="line"><span class="comment">// 响应头设置</span></span><br><span class="line"><span class="title function_ invoke__">header</span>(<span class="string">&#x27;Access-Control-Allow-Headers:x-requested-with, content-type&#x27;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="variable">$query_string</span> = <span class="title function_ invoke__">substr</span>(<span class="variable">$_SERVER</span>[<span class="string">&quot;QUERY_STRING&quot;</span>], -<span class="number">3</span>);</span><br><span class="line"><span class="variable">$array</span> = [ <span class="string">&#x27;jpg&#x27;</span>, <span class="string">&#x27;png&#x27;</span>, <span class="string">&#x27;css&#x27;</span>, <span class="string">&#x27;.js&#x27;</span>, <span class="string">&#x27;txt&#x27;</span>, <span class="string">&#x27;doc&#x27;</span>, <span class="string">&#x27;ocx&#x27;</span>, <span class="string">&#x27;peg&#x27;</span> ];</span><br><span class="line"><span class="keyword">if</span> (<span class="title function_ invoke__">in_array</span>(<span class="variable">$query_string</span>, <span class="variable">$array</span>)) &#123;</span><br><span class="line"><span class="keyword">exit</span>();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//header(&quot;Content-Security-Policy: default-src &#x27;self&#x27;; script-src &#x27;self&#x27; object-src &#x27;none&#x27;; base-uri &#x27;none&#x27;; report-uri /csp-report.php&quot;); </span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">check_param</span>(<span class="params"><span class="variable">$value</span>=<span class="literal">null</span></span>) </span>&#123;</span><br><span class="line"><span class="keyword">if</span>(<span class="title function_ invoke__">is_array</span>(<span class="variable">$value</span>))&#123;</span><br><span class="line"><span class="keyword">foreach</span>(<span class="variable">$value</span> <span class="keyword">as</span> <span class="variable">$k</span>=&gt;<span class="variable">$v</span>)&#123;</span><br><span class="line"><span class="title function_ invoke__">check_param</span>(<span class="variable">$v</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span>;</span><br><span class="line">&#125; </span><br><span class="line">        <span class="comment">#  select|insert|update|delete|\&#x27;|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile</span></span><br><span class="line"> </span><br><span class="line">    <span class="variable">$str</span> = <span class="string">&#x27;/select[^a-zA-Z]*|insert\s|\sand\s|\sor\s|update\s|delete\s|union\s|into\s|load_file|outfile|script/i&#x27;</span>;</span><br><span class="line"><span class="comment">//echo $_value;</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="variable">$value</span>&amp;&amp;<span class="title function_ invoke__">preg_match</span>(<span class="variable">$str</span>, <span class="variable">$value</span>)) &#123;</span><br><span class="line">        <span class="variable">$res</span>[<span class="string">&#x27;state&#x27;</span>]=<span class="string">&#x27;fail&#x27;</span>;</span><br><span class="line"><span class="variable">$res</span>[<span class="string">&#x27;code&#x27;</span>]=<span class="number">0</span>;</span><br><span class="line"><span class="variable">$res</span>[<span class="string">&#x27;msg&#x27;</span>]=<span class="string">&#x27;method不可为空[God bless you]&#x27;</span>;</span><br><span class="line">        <span class="keyword">echo</span> <span class="title function_ invoke__">json_encode</span>(<span class="variable">$res</span>,JSON_UNESCAPED_UNICODE);</span><br><span class="line"><span class="keyword">exit</span>;</span><br><span class="line">    &#125;</span><br><span class="line">     </span><br><span class="line">&#125; </span><br><span class="line"><span class="title function_ invoke__">check_param</span>(<span class="variable">$_GET</span>);</span><br><span class="line"><span class="title function_ invoke__">check_param</span>(<span class="variable">$_POST</span>);</span><br><span class="line"><span class="title function_ invoke__">check_param</span>(<span class="title function_ invoke__">file_get_contents</span>(<span class="string">&#x27;php://input&#x27;</span>)); </span><br><span class="line"></span><br><span class="line"><span class="keyword">require</span> <span class="keyword">__DIR__</span> . <span class="string">&#x27;/vendor/autoload.php&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 执行HTTP应用并响应</span></span><br><span class="line"><span class="variable">$http</span> = (<span class="keyword">new</span> <span class="title class_">App</span>())-&gt;http;</span><br><span class="line"></span><br><span class="line"><span class="variable">$response</span> = <span class="variable">$http</span>-&gt;<span class="title function_ invoke__">run</span>();</span><br><span class="line"></span><br><span class="line"><span class="variable">$response</span>-&gt;<span class="title function_ invoke__">send</span>();</span><br><span class="line"></span><br><span class="line"><span class="variable">$http</span>-&gt;<span class="title function_ invoke__">end</span>(<span class="variable">$response</span>);</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>通过关键词递归检查的方式来拦截了 <code>select</code> 等关键词。说他有点水平，是因为这个注入点是在 <code>st_distance ( point</code> 中，他本身这个拦截有很多种可以尝试绕过的方式，但是因为注入点语句整体结构情况，直接导致了 <code>select</code> 无法绕过，绕过了也无法执行成功。</p><p>不过这套源码可不止这么一处注入呀，只能说，有点菜还得练 (￣<em>,￣ )。自写防御的行为可以点赞，但顺手嘲讽 <code>[God bless you]</code> 就有点飘了，任意上传那个漏洞也是因为这个嘲讽而诞生的 (^</em>^)a。</p><h2 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h2><p>针对上述漏洞，给出正经的修复建议：</p><h3 id="上传漏洞修复建议"><a href="#上传漏洞修复建议" class="headerlink" title="上传漏洞修复建议"></a>上传漏洞修复建议</h3><ol><li><strong>鉴权</strong>：对编辑器的调用进行严格的后台鉴权，防止未授权访问。</li><li><strong>白名单校验</strong>：对上传扩展名进行白名单校验，或者直接使用编辑器自带的上传方法，而不是调用 model 中的方法。这也是我不太理解的点，代码有些混乱，action 调用，有的是直接用的编辑器的，有的是用的 model 的，太乱了。</li><li><strong>目录解析限制</strong>：可以通过在上传目录创建 <code>.htaccess</code> 文件（如果是 Apache），在文件中通过规则禁用目录的所有解析权限，防止上传的脚本文件被执行。</li></ol><h3 id="前台-SQL-注入修复建议"><a href="#前台-SQL-注入修复建议" class="headerlink" title="前台 SQL 注入修复建议"></a>前台 SQL 注入修复建议</h3><ul><li><strong>参数过滤&#x2F;预编译</strong>：这个就比较简单了，注入点防御方式都是一样，对传入的参数进行过滤或使用预编译语句。他代码很多地方写的都很规范，用的 ThinkPHP 标准写法，不知道为什么这个点会直接拼接。建议统一使用参数绑定或查询构造器，避免手动拼接 SQL。</li></ul>]]>
    </content>
    <id>https://mrwu.me/defensive/202604/1/</id>
    <link href="https://mrwu.me/defensive/202604/1/"/>
    <published>2026-04-27T03:02:20.000Z</published>
    <summary>
      <![CDATA[<div class="tag-plugin colorful note" color="颜色" child="codeblock/tabs"><div class="title"><strong><p>本文摘要</p>
</strong></div><div class="body"><p>分享一个关于代码审计挖掘漏洞，以及后续技术修复防御失败的案例，过程有点曲折，也有点意思 (￣▽￣)”</p></div></div>]]>
    </summary>
    <title>代码审计案例：Ueditor 任意文件上传与 SQL 注入的“迷之”防御</title>
    <updated>2026-04-26T19:19:53.819Z</updated>
  </entry>
</feed>
