SQL注入漏洞
免责声明本文仅用于网络安全学习与研究所有漏洞测试必须在得到明确授权的情况下进行。未经授权的渗透测试行为是违法的请遵守法律法规。一、什么是SQL注入一句话讲明白SQL注入 用户传的参数没经过严格检查直接拼接到SQL语句里导致坏人可以篡改SQL命令打个比方• 正常情况你去银行取钱柜员问你取多少你说取1000柜员照办• SQL注入坏人说取1000顺便把所有人的钱都转到我账户柜员没检查直接执行了就这么简单核心就是用户输入的东西被当成了SQL命令执行。二、SQL注入有什么危害危害等级具体危害大白话解释⭐⭐⭐泄露数据库数据把用户账号、密码、订单全偷了⭐⭐⭐⭐破坏数据库删库跑路数据全没了⭐⭐⭐⭐⭐控制服务器直接拿下服务器想干嘛干嘛所以SQL注入被评为Web漏洞之王不是没有道理的三、怎么学习SQL注入学习SQL注入按这个顺序来1.漏洞产生的原因原理—— 先搞懂为什么会有这个漏洞2.危害—— 知道它能干什么3.怎么挖掘—— 黑盒测试、白盒测试4.怎么利用—— 拿到漏洞后怎么搞数据5.怎么修复—— 开发怎么防6.怎么绕过拦截—— 进阶技巧四、怎么发现SQL注入漏洞方法一代码审计白盒测试白盒就是能看到源代码找起来最准。三步走步骤做什么通过条件第1步定位SQL语句找有没有可控变量有第2步看变量有没有被过滤没有第3步看变量是不是从前端传来的是三个条件都满足 一定有SQL注入就这么简单白盒测试找SQL注入就看这三点。方法二漏洞挖掘黑盒测试黑盒就是看不到源码只能靠猜和试。两种方式1.扫描器扫—— 用工具扫所有参数快但不准2.手工测—— 手动测试和数据库有交互的参数慢但准怎么判断哪些参数可能有注入很简单凡是跟数据查询有关的功能都可能有注入• 成绩查询有• 商品搜索有• 用户登录有• 订单查询有只要是需要查数据库的地方都有可能五、6种测试闭合的方法重点找到可疑参数后怎么确认有没有SQL注入用下面6种方法方法一⭐引号测试闭合原理加个引号看会不会报错。正常 ?id1 测试 ?id1 单引号 ?id1 双引号判断方法• 加单引号报错加双引号不报错 →单引号闭合可能有注入• 加双引号报错加单引号不报错 →双引号闭合可能有注入举个例子假设后端SQL是这样的SELECT name, score FROM students WHERE student_id $student_id limit 0,1;传id1后SQL变成SELECT name, score FROM students WHERE student_id 1 limit 0,1;看到没多了一个单引号语法错了就报错了为什么报错就可能有注入因为报错说明你的输入真的被拼到SQL里了如果输入被过滤了就不会报错。方法二⭐and测试前提你得知道一个正确的值正常 ?id20210101 正常显示 测试正常 ?id20210101 and 11# 还是正常显示 测试异常 ?id20210101 and 12# 不显示了原理•and 11两边都是真所以SQL正常执行页面正常显示•and 12一边真一边假所以SQL查不到数据页面不显示如果加不加and 11页面都一样说明很可能有SQL注入#是MySQL的注释符意思是后面的内容都不算了方法三⭐or测试适用场景不知道正确值的时候用测试 ?id-1 or 11#原理•-1是个不存在的值正常查不到•or 11是永远成立的条件• 加在一起就变成了查id-1的或者11的因为11永远成立所以能查到所有数据⚠ 慎用or测试可能会查出整张表的数据影响比较大尽量用and测试。方法四⭐不加注释符闭合测试有些情况注释符被过滤了怎么办不用注释符也行正确值测试 ?id1 and 11 错误值测试 ?id-1 or 11原理用单引号自己闭合就不用注释符了。假设原SQL是SELECT * FROM users WHERE id $id传id1 and 11后SELECT * FROM users WHERE id 1 and 11看到没两边的单引号都对上了完美闭合MySQL的注释符有两种#和--注意--后面有个空格方法五⭐sleep测试盲注用适用场景页面不报错也不显示啥都看不到的时候测试 ?id1 and sleep(5)#原理•sleep(5)意思是睡5秒钟• 如果页面延迟了5秒才加载出来说明有注入• 如果页面秒开说明没有注入这个方法很管用因为不需要看页面内容只需要看加载时间就行。方法六⭐order by测试测试 ?id1 order by 999#原理•order by 999意思是按第999列排序• 一般的表哪有999列啊所以肯定报错• 一报错就说明闭合方式是对的可能有注入六、SQL注入怎么利用联合查询注入确认有注入后怎么拿数据最经典的就是联合查询注入。联合查询union query 把两个SELECT语句的结果拼在一起一起显示出来打个比方• 正常查询查学生成绩• 注入查询查学生成绩 查管理员密码• 联合起来两个结果一起显示在页面上前置知识information_schemaMySQL里有个很重要的数据库叫information_schema它里面存了所有数据库的元信息。表名存了什么作用schemata所有数据库名查有哪些数据库tables所有表的信息查某个库里有哪些表columns所有列的信息查某个表里有哪些字段这个库是SQL注入的字典拿数据全靠它七、联合查询注入四步走第1步判断查询结果的列数用 order by 猜?id-1 order by 999# 报错说明没有999列 ?id-1 order by 1# 正常说明至少有1列 ?id-1 order by 2# 正常说明至少有2列 ?id-1 order by 3# 报错说明没有3列结论查询结果有2列小技巧用-1而不是正常值是因为正常值会返回数据把我们注入的结果挤掉。用-1不存在的值原查询查不到东西就只会显示我们注入的内容。第2步判断回显位知道有几列后用 union select 看哪一列会显示在页面上?id-1 union select 1,2#如果页面显示了1和2说明两列都会显示。如果只显示了2说明只有第2列是回显位。回显位 数据会显示在页面上的位置我们把要查的数据放这里就行。第3步用函数获取基础信息把回显位替换成MySQL函数获取数据库的基本信息函数作用示例version()获取MySQL版本5.7.26user()获取MySQL用户名rootlocalhostdatabase()获取当前数据库名test_dbbasedir获取MySQL安装路径/usr/local/mysql示例?id-1 union select version(),2#SRC挖洞提示如果是挖SRC漏洞到这一步就可以了能证明有注入就行不用往下拖库。第4步获取数据重头戏来了怎么把数据库里的数据全拖出来第一步获取所有数据库名?id-1 union select schema_name,2 from information_schema.schemata#information_schema.schemata表里存了所有数据库的名字。⚠ 常见问题显示不完整怎么办有时候数据库太多页面显示不全两种解决方法解决方法1group_concat 聚合函数?id-1 union select group_concat(schema_name),2 from information_schema.schemata#group_concat()的作用把多行数据合并成一行用逗号隔开。这样一整行就能显示所有数据库名了。解决方法2limit 分页?id-1 union select schema_name,2 from information_schema.schemata limit 0,1# 第1个 ?id-1 union select schema_name,2 from information_schema.schemata limit 1,1# 第2个 ?id-1 union select schema_name,2 from information_schema.schemata limit 2,1# 第3个limit 2,1的意思从第2行开始不包括第2行取1条结果。也就是取第3条。注意MySQL是从0开始数的第1条是0第2条是1以此类推。八、获取表名和字段名拿到数据库名后继续拿表名和字段名。获取表名?id-1 union select group_concat(table_name),2 from information_schema.tables where table_schema数据库名#获取字段名?id-1 union select group_concat(column_name),2 from information_schema.columns where table_name表名#获取具体数据?id-1 union select username,password from 表名#九、Linux环境补充文件上传与解压课程里还提到怎么把Windows的文件传到Linux里并解压# 解压zip文件 unzip 文件名.zip十、总结速查表SQL注入判断方法方法适用场景原理引号测试快速判断加引号看会不会报错and测试有正确值and 11正常, and 12异常or测试无正确值or 11 返回所有数据无注释闭合注释符被过滤用引号自己闭合sleep测试盲注无回显看页面延迟时间order by测试通用大数字排序会报错联合查询步骤步骤做什么示例1猜列数order by N2找回显位union select 1,2,33拿基础信息version()、user()、database()4拿数据库名information_schema.schemata5拿表名information_schema.tables6拿字段名information_schema.columns7拿数据select 字段 from 表最后说几句SQL注入的核心就一句话用户输入的参数被直接拼到SQL里了。学习建议1.先搞懂原理别上来就背payload2.多在靶场里练比如sqli-labs3.理解每一步为什么这么做而不是死记硬背4.挖到SRC漏洞点到为止别拖库记住技术是把双刃剑用在正途上是保护网络安全用在歪路上就是违法犯罪学习路线提醒这是SQL注入的第一篇讲的是最基础的显错注入联合查询。后面还有报错注入、盲注、堆叠注入等等一步一步来先把基础打牢