SQL注入深度解析:Web攻击原理与渗透实战
摘要
注入攻击本质是未区分用户数据与执行代码,攻击者在输入中插入代码使系统误执行。SQL注
第三章:Web攻击原理(上)——注入与SQL注入
从一句玩笑话开始
小明去网吧上网,吧台小哥让他输入姓名注册。小明在键盘上敲了两个字:“小明”。系统提示注册成功。

第二天,小明又来了。这次他在姓名栏里敲了:“小明’ OR ‘1’=’1”。系统愣了一下,然后弹出一行字:“欢迎回来,管理员。”
这故事听起来像个段子,但背后揭示的是一个真实存在了二十多年、至今仍在不断上演的安全问题——注入攻击。
什么是“注入”?
“注入”这个词,字面意思就是“把东西塞进去”。在Web安全的语境下,它的意思是:攻击者在本该是“数据”的地方,塞进去一段“代码”,让系统误以为这是它自己该执行的指令。
用个通俗的比喻。你去餐厅点餐,菜单上写着:“请选择主食:A.米饭 B.面条”。你在点菜单上写“A”,这是正常情况。但如果你在点菜单上写:“A,顺便把厨房的煤气关了”。如果服务员把你的话原封不动地传给厨师,厨师一看——“关煤气”也是指令,那就真去照做了。
注入的本质就是这样:程序没有区分“用户说的话”和“自己要执行的指令”,把两者混在一起处理了。Web世界里最常见的注入有两种:SQL注入和命令注入。这一章,我们先聊SQL注入。
SQL是什么?为什么网站离不开它?
几乎所有网站背后都有一个数据库。你注册账号,用户名和密码被存进去;你发一条评论,这条评论也被存进去;你搜索商品,数据库把匹配的结果返回来。SQL(结构化查询语言)就是程序和数据库之间沟通的语言。程序告诉数据库:“帮我查一下用户名叫‘张三’的人”,数据库返回结果。
举个例子,当你在登录页面输入用户名zhangwei和密码123456时,程序会拼接出一条SQL指令:查询用户表,找到用户名为“zhangwei”并且密码为“123456”的那条记录。如果找到了,就让他登录。
这个逻辑听起来没问题。问题出在:这个指令是“拼接”出来的,而不是严格区分的。
拼接字符串为什么会出事?
假设程序用下面这种方式拼接SQL指令:查询用户表,找到用户名为“(这里填你输入的用户名)”并且密码为“(这里填你输入的密码)”的那条记录。
如果你老老实实输入zhangwei和123456,拼接出来的指令是正常的。但如果你在用户名那一栏输入的不是一个名字,而是一段SQL代码呢?
试想一下,你在用户名的框里输入:zhangwei' OR '1'='1,密码随便写点什么。程序拼接出来的指令变成了:查询用户表,找到用户名为“zhangwei’ OR ‘1’=’1”并且密码为“随便”的那条记录。
乍一看好像没区别。但“1=1”在SQL的世界里代表什么?代表“永远为真”。这条指令会被数据库解释成:找到用户名为zhangwei 或者 1=1(这个条件永远成立)的那条记录。结果就是:数据库返回了这张表里的第一条用户记录——通常,第一条就是管理员账号。
攻击者不知道任何人的密码,却成功登录了系统。这就是SQL注入最经典的场景——万能密码登录。
用一个表格看懂注入的魔法
你输入的用户名 | 拼接出来的SQL条件 | 结果 |
| 用户名 = zhangwei | 只查到zhangwei本人 |
| 用户名 = zhangwei 或者 1=1 | 查到整张表的第一条 |
| 用户名 = anything 或者 a=a | 查到整张表的第一条 |
| 用户名 = admin(后面的条件被注释掉了) | 直接以admin身份登录 |
最后一个--是SQL里的注释符号。它告诉数据库:“后面的内容不用看了”。所以admin' --的意思是:用户名是admin,不用检查密码。
SQL注入能造成多大的破坏?
万能密码登录只是最入门的玩法。SQL注入能做的事远不止这些。
窃取数据。攻击者可以一点一点地把整个数据库倒出来。用户的手机号、身份证、家庭住址、交易记录——全都可以拿走。历史上著名的数据泄露事件,相当一部分和SQL注入有关。
绕过权限。普通用户的账号可能只有查看权限,管理员账号才有删除权限。通过SQL注入,攻击者可以把自己变成管理员,或者直接冒充任何人的身份。
篡改数据。攻击者可以改掉你的密码让你登录不了,可以把自己的账户余额从100改成100万(如果数据库没有做别的一致性校验),可以在网站上植入恶意代码。
删除数据。最极端的破坏:DROP TABLE命令可以删除整张表,DROP DATABASE可以删除整个数据库。如果攻击者发现数据库的权限配置不当,他可以把你的一切数据删干净。
获取服务器控制权。在某些极端情况下,攻击者可以通过SQL注入在服务器上写入文件,甚至直接拿到服务器的控制权限。到了这一步,这台服务器上的所有东西都归攻击者了。
一个直观的类比
想象一下,你给客服打电话,说:“我要修改我的收货地址。”客服说:“请告诉我您的新地址。”你回答说:“北京市朝阳区某某路123号,顺便把我的余额改成100万。”如果客服傻乎乎地把你的后半句也当作“新地址”去执行了,那就出大事了。
SQL注入就是这个道理:程序把攻击者写的代码当成了“地址”本身。
为什么二十多年了,SQL注入还存在?
SQL注入漏洞第一次被公开讨论是在1998年。二十多年过去了,它仍然每年出现在各大漏洞报告里。原因有几个。
历史代码太多。很多老网站上线于Web安全还没被重视的年代,代码里到处是拼接字符串。这些网站可能再也不会被更新了,但依然在运行着。
开发者安全意识不足。很多新手程序员不知道SQL注入的存在,或者知道但觉得“我的应用这么小,不会有人来攻击的”。黑客可不会这么想,他们有自动化的扫描工具,24小时在扫全网。
修复需要改架构。正确的修复方式是不再拼接SQL,而使用“参数化查询”或预编译语句。这往往意味着要重写一大段数据访问层的代码。在工期压力下,很多团队选择“先上线再说”。
这一章你该记住什么
第一,注入的本质:程序没有区分“数据”和“代码”,把用户输入当成指令来执行了。
第二,SQL注入的原理:攻击者在一段SQL指令中插入自己的SQL代码,改变了指令的原本含义。
第三,万能密码登录:' OR '1'='1 是最经典的SQL注入例子,它让条件永远为真。
第四,SQL注入的危害极大:从窃取数据到删除数据库,从绕过登录到获取服务器权限,都可以做到。
第五,这个漏洞至今仍然普遍存在,不是因为技术难,而是因为历史积压和意识不足。
下一章,我们将继续Web攻击原理的下半场:XSS、CSRF和文件上传漏洞。
来源:互联网
本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。