一、从架构谈起:Web应用为何容易被攻破?
在很多CTF比赛和实战中,Web应用总是攻击的重点目标。这并不是巧合,而是由其架构和开发模式决定的。为了理解如何攻破一个网站,我们需要先了解它的工作方式。
典型的Web应用架构分为三大层:
- 前端展示层:HTML、CSS、JavaScript,用来和用户交互。
- 服务端逻辑层:通常由PHP、Ruby、Python等语言编写,负责处理请求并返回数据。
- 数据库持久层:存储用户数据、日志等关键信息,常用MySQL、PostgreSQL、MongoDB等。
这么分层的架构看起来很完美,但每一层都可能存在漏洞:
- 前端可能存在 XSS(跨站脚本攻击),允许攻击者注入恶意脚本。
- 服务端容易出现 SQL注入、文件上传、远程代码执行(RCE) 等漏洞。
- 数据库如果配置不当,可能被直接暴力破解或利用默认账户访问。
对于攻击者来说,这些漏洞就像摆在桌子上的钥匙,我们需要做的就是找到正确的方向并利用它。
---
二、信息是武器:攻破网站前的侦查
在攻击前,信息收集是关键的一步。这一步的目标是尽可能多地了解目标系统的情况,比如域名、子域名、服务器IP、开放端口、服务版本等。以下是一些常用的技术手段和工具。
子域名枚举
子域名往往包含敏感信息,比如管理后台、测试环境等。我们可以用工具自动化枚举,或者通过DNS暴力破解获取。
Ruby实现子域名爆破的简单代码: <pre><code class="language-ruby">require 'resolv'
domain = "example.com" # 修改为目标域名 subdomains = ["www", "admin", "test", "api", "dev", "staging"]
subdomains.each do |sub| begin ip = Resolv.getaddress("#{sub}.#{domain}") puts "[+] Found: #{sub}.#{domain} -> #{ip}" rescue puts "[-] Not found: #{sub}.#{domain}" end end</code></pre>

脚本运行后,会尝试解析指定的子域名,并输出有效的结果。找到子域名后,可以用浏览器访问,进一步检查是否存在开放的管理后台或测试系统。
目录和文件爆破
网站目录中可能隐藏敏感文件,比如.git目录、config.php配置文件等。我们可以用字典枚举的方法来发现这些目录。

Shell脚本实现目录爆破: <pre><code class="language-bash">#!/bin/bash
target="http://example.com" # 目标网站 wordlist="/usr/share/wordlists/dirs.txt" # 字典路径
while read -r line; do url="$target/$line" status=$(curl -o /dev/null -s -w "%{http_code}" "$url") if [ "$status" == "200" ]; then echo "[+] Found: $url" fi done < "$wordlist"</code></pre>
这个脚本会对每个目录进行HTTP请求,如果返回状态码为200,则表示目录存在。
---
三、SQL注入:经典漏洞的现代玩法
SQL注入是Web攻击中最经典的漏洞之一,但它从未过时。现代的SQL注入玩法已经从简单的UNION SELECT语句,进化到了盲注、时间注入甚至DNS注入。
漏洞成因
SQL注入的根本原因是开发者在拼接SQL语句时,没有对用户输入进行严格过滤。例如: <pre><code class="language-ruby"># 漏洞代码示例 require 'mysql2'
client = Mysql2::Client.new(:host => "localhost", :username => "root", :database => "test") username = params[:username] # 用户输入 password = params[:password]
query = "SELECT * FROM users WHERE username = '#{username}' AND password = '#{password}'" result = client.query(query)</code></pre>
如果攻击者输入: <pre><code>username=admin' -- password=anything</code></pre> SQL语句会变成: <pre><code class="language-sql">SELECT * FROM users WHERE username = 'admin' -- ' AND password = 'anything'</code></pre> 这里的--会注释掉后面的语句,从而绕过密码校验。
实战利用
如果我们发现一个网站存在SQL注入漏洞,可通过以下步骤进行攻击:
- 判断注入点:构造简单的Payload,比如
' or 1=1 --,测试是否返回异常或错误提示。 - 数据库信息探测:通过
UNION SELECT语句获取数据库名称和版本。 - 表名和字段名爆破:利用
information_schema库获取表结构。 - 数据提取:最终读取敏感数据,比如用户账号、密码哈希等。

---
四、绕过WAF的艺术
现代Web应用通常会部署WAF(Web应用防火墙)来拦截攻击流量。为了做到真正“隐形”,我们需要一些高级技巧。
Payload混淆
传统Payload很容易被WAF拦截,比如: <pre><code>admin' OR 1=1 --</code></pre> 我们可以通过混淆、编码来绕过:
- Unicode编码:将Payload转成Unicode形式,比如
admin%27%20OR%201%3D1%20--。 - 大小写变换:对SQL关键字进行大小写变换,比如
oR、SeLeCT。 - 空白符替换:用注释符
//替代空格,比如admin'//OR//1=1//--。
动态生成Payload
我们可以写一个Ruby脚本,自动化生成混淆后的Payload: <pre><code class="language-ruby">def obfuscate_payload(payload)
插入随机大小写
payload.chars.map { |c| rand(2).zero? ? c.upcase : c.downcase }.join end
original_payload = "admin' OR 1=1 --" puts "Original Payload: #{original_payload}" puts "Obfuscated Payload: #{obfuscate_payload(original_payload)}"</code></pre>
运行后,你会看到随机大小写的SQL注入Payload,有助于绕过静态规则检测。
---
五、痕迹清理与反侦察
攻击之后,如何不留下痕迹是每个红队需要考虑的问题。在日志中隐藏攻击行为,或者干脆删除日志,是常见的处理方式。
日志清理
如果我们获得了目标服务器的shell权限,可以通过以下命令清理日志: <pre><code class="language-bash"># 清空Apache访问日志和错误日志 echo > /var/log/apache2/access.log echo > /var/log/apache2/error.log</code></pre>
但需要注意的是,安全团队可以通过日志备份或远程日志服务器恢复记录,因此完全清理所有痕迹并不现实。
---
六、一些心得分享
在CTF和实战中,攻破网站的关键往往是细心和耐心。以下是一些经验之谈:
- 重视信息收集:很多时候,突破的起点就是一个隐藏的子域名或配置文件。
- 利用自动化工具:工具可以帮助节省时间,但不要盲目依赖,手工分析是关键。
- 绕过防御措施:现代应用的防御越来越强,绕过WAF和EDR需要真正掌握攻击原理。
攻击是技术与策略的结合。希望这篇文章能启发你,在合法授权的前提下不断提高自己的技能。