Pikachu靶场实战:从数字型到宽字节的SQL注入全解析
1. Pikachu靶场与SQL注入实战入门第一次接触Pikachu靶场时我就被它丰富的漏洞场景吸引了。这个专门为网络安全学习设计的靶场把各种SQL注入漏洞都做成了闯关游戏特别适合新手入门。你可能听说过SQL注入但真正动手时总会遇到各种问题比如不知道从哪里下手、payload构造不对、或者根本看不出注入点在哪里。我在Pikachu靶场里摸爬滚打了好几个月今天就把这些实战经验完整分享给你。SQL注入的本质就是通过构造特殊输入让数据库执行我们预设的恶意SQL语句。想象一下你家的门锁数据库本来只认钥匙正常查询但有人用铁丝恶意payload也能撬开这就是注入攻击。Pikachu靶场把这种攻击分成了10种典型场景从最简单的数字型注入到复杂的宽字节注入难度循序渐进。在开始实战前你需要准备好三样工具浏览器推荐Chrome、Burp Suite抓包工具、以及一个能运行Pikachu靶场的PHP环境比如XAMPP。靶场安装很简单把下载的源码放到网站根目录访问setup.php初始化数据库就行。我遇到过新手常犯的错误是数据库配置不对如果连接失败记得检查config.inc.php里的数据库账号密码是否匹配。2. 数字型注入最基础的突破口数字型注入就像黑客的Hello World我在第一次尝试时就成功拿到了数据库权限。在Pikachu靶场的数字型注入关卡页面只有一个简单的用户ID输入框。关键点在于这里的参数没有用引号包裹直接拼接到SQL语句中。实战步骤是这样的先输入1看看正常返回页面显示用户kobe的信息输入1 and 11和1 and 12测试前者正常返回后者无结果确认存在注入用1 order by 2测试列数当order by 3时报错说明只有2列构造union查询获取数据-1 union select 1,database()# # 获取数据库名 -1 union select 1,group_concat(table_name) from information_schema.tables where table_schemapikachu# # 获取所有表名这里有个实用技巧用-1让原查询不返回结果这样页面就只显示我们union注入的内容。我第一次练习时总忘记加-1结果页面数据混在一起很难辨认。获取到users表后继续爆字段和密码-1 union select group_concat(username),group_concat(password) from users#密码虽然是MD5加密的但用在线网站就能解密。整个过程就像拼图游戏一步步获取数据库的完整信息。数字型注入的防御也很简单——使用预编译语句或者至少要把输入参数强制转换为整数。3. 字符型注入单引号的攻防战字符型注入比数字型多了一道门禁——单引号。在Pikachu的字符型注入关卡输入用户名时会用单引号包裹。我刚开始总构造不对payload后来发现关键在于闭合引号。具体操作流程输入kobe and 11测试页面正常说明存在注入测试列数kobe order by 3#报错确认2列获取数据时要注意引号闭合admin union select database(),2# # 获取数据库名 admin union select 1,group_concat(column_name) from information_schema.columns where table_nameusers# # 获取字段这里有个易错点如果原查询后面还有SQL代码记得用#或--注释掉。我有次测试时payload总是报错后来发现是漏了注释符。字符型注入的防御方法是参数化查询或者至少对单引号进行转义。搜索型注入是字符型的变种区别在于SQL语句中使用了LIKE模糊匹配。在Pikachu靶场里这类注入需要用%来闭合k% union select database(),2,3# # %闭合前面的模糊匹配4. 进阶注入技术实战4.1 HTTP头注入隐藏在请求头中的漏洞这个漏洞让我大开眼界——原来不只是表单能注入HTTP头也行在Pikachu的HTTP头注入关卡登录后页面会显示User-Agent信息。通过Burp Suite抓包在User-Agent字段插入payload and updatexml(1,concat(0x7e,database()),1) and updatexml是MySQL的报错注入函数0x7e是波浪号~的十六进制用来分隔报错信息。这个payload会让数据库返回错误信息其中包含我们想要的数据库名。同样的方法可以获取表名、字段名 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schemadatabase()))),1) and 4.2 盲注没有回显的猜谜游戏布尔盲注是最考验耐心的就像蒙着眼睛玩扫雷。在Pikachu的布尔盲注关卡页面不会显示错误信息只能通过返回结果的真假来判断。我花了整整一个下午才搞明白怎么系统性地猜解数据。以猜解数据库名为例先猜长度kobe and length(database())7#返回正常说明长度正确逐个字母猜解kobe and substr(database(),1,1)p# # 第一个字母 kobe and ascii(substr(database(),2,1))105# # 第二个字母的ASCII码时间盲注更麻烦要通过页面响应时间来判断。payload类似这样kobe and if(ascii(substr(database(),1,1))105,sleep(3),0)# # 如果第一个字母是i就延迟3秒4.3 宽字节注入编码引发的血案这是最让我头疼的一种注入涉及到GBK编码特性。原理是当MySQL使用GBK编码时%df%5c会被当作一个汉字運从而吃掉转义的反斜杠。在Pikachu的宽字节注入关卡构造这样的payload1%df union select 1,2# # %df和转义的反斜杠组合成汉字实际测试时要注意确保数据库连接使用GBK编码在输入后通过Burp Suite修改参数直接输入可能会被URL编码后续步骤和普通字符型注入类似只是多了%df前缀5. 防御之道从攻击者角度思考安全经过这些注入实战我深刻体会到安全是攻防双方的博弈。有效的防御需要理解攻击手法这里分享几个关键点预编译语句是终极解决方案它能彻底分隔代码和数据。我在项目中用PDO实现$stmt $pdo-prepare(SELECT * FROM users WHERE id ?); $stmt-execute([$input]);最小权限原则数据库账户只给必要权限比如查询账号禁用DROP权限输入验证数字型参数强制类型转换字符串参数过滤特殊字符错误处理生产环境要关闭错误回显避免泄露数据库结构WAF防护对于遗留系统可以用ModSecurity等WAF做基础防护在Pikachu靶场的实战中我经常故意写些有漏洞的代码然后自己尝试攻击。这种自己打自己的方式能最直观地理解漏洞成因。比如发现搜索功能有注入时回去看源码发现是直接拼接LIKE语句$sql SELECT * FROM users WHERE username LIKE %$input%; // 危险写法改成参数化查询后注入就彻底防住了。安全开发不是添加功能而是培养一种思维方式——永远假设输入是恶意的。