当前位置:首页 > 休闲 > sql注入实验报告 正文

sql注入实验报告

来源:烟消火灭网   作者:休闲   时间:2026-10-17 05:48:32

把单引号塞进登录框,入实整个后台数据库就摊在眼前了。验报这不是入实电影桥段,是验报我上周在本地靶场里亲手复现的东西。一个普通的入实查询框,输入 ' OR '1'='1,验报页面直接跳过了密码校验,入实把我当成了管理员。验报

SQL注入的入实本质,是验报把用户输入当成了代码来执行。后端程序员写查询时偷懒,入实用字符串拼接的验报方式构造SQL语句,比如 "SELECT * FROM users WHERE name='" + input + "'"。入实你输入的验报东西本来该是数据,结果因为那个单引号,入实它跑出了引号的包围圈,变成了SQL语法的一部分。数据库分不清哪部分是程序写的、哪部分是攻击者写的,照单全收。

我搭的环境是DVWA,安全等级调到low。登录框输入 admin' --,注释符把后面的密码判断直接吞掉,一次就进去了。换成 ' OR 1=1 --,更狠,直接返回所有用户记录。页面只显示第一行,但我知道后面还有一堆。这种体验挺奇怪的——你明明在浏览器里操作,却能感觉到数据库在另一端老老实实地执行你拼出来的指令。

手工注入只是开胃菜。真正让我觉得后背发凉的是sqlmap跑起来的时候。指定URL,加个 --dbs 参数,工具自动探测注入点、判断数据库类型、枚举所有库名。几分钟后,information_schema、dvwa、mysql 全列出来了。再 --dump 一下,users表里的用户名和密码哈希直接落到本地文件。密码是MD5,拿去cmd5一查,大部分都能还原成明文。整个流程不需要懂SQL语法,工具全包了。

防御其实不复杂,但很多老系统就是不改。预编译语句(Prepared Statement)是最有效的方案,把SQL模板先发给数据库编译,参数后传,数据库永远不把参数当代码解析。Java里的 PreparedStatement、Python的 cursor.execute("...%s", (param,)) 都是这个思路。另一个常见做法是输入过滤,但黑名单永远有漏网之鱼,宽字节注入、二次注入、堆叠查询,绕过手法层出不穷。白名单校验字段类型更靠谱,比如id参数强制转成整数,非数字直接拒绝。

我在实验里还试了报错注入。输入 ' AND extractvalue(1,concat(0x7e,database())) --,页面直接把库名爆在错误信息里。这种手法在关闭了详细错误显示的站点上没用,但很多开发环境图方便,错误全开着,等于给攻击者递梯子。盲注更磨人,页面不返回数据也不报错,只能靠 AND sleep(5) 这种时间延迟来判断条件真假。一个字符一个字符地猜,脚本跑一晚上才能拖出一张表。效率低,但隐蔽性强,WAF不容易拦。

做完实验我把靶场的等级调回impossible,同样的注入语句全部失效,页面返回空白或报错。对比太明显了。安全等级low和impossible之间隔的不是什么高深技术,就是几行代码写法的区别。很多真实漏洞也是这样,不是攻击者多厉害,是防御方在某个环节省了事。

这次实验最大的收获不是学会了用sqlmap,而是理解了“数据”和“代码”的边界一旦模糊,后果有多严重。数据库本身没有恶意,它只是忠实地执行了收到的指令。问题出在构造指令的那一环。写代码的人多打一个问号、多用一次参数化查询,攻击者就少一条路。

标签:

责任编辑:休闲