
笔记:sql注入
SQL注入原理
程序员没有遵循代码与数据分离原则,使用户数据作为代码执行。
SQL注入条件
用户可以控制数据的输入。
原本要运行的代码拼接了用户的输入并运行。
基本流程
sql注入流程图
SQL注入的步骤
1、判断注入类型,数字型还是字符型:
首先,我们需要确定目标是数字型还是字符型注入漏洞,以便我们进一步进行其它注入操作。如下面的php代码片段所示,第一行代码代表数字型的sql拼接,其中的变量在sql查询语句拼接时并没有用引号括起来;第二行代码是字符型,其中的变量使用了引号进行拼接。
数字型
$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
字符型
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
2、猜解sql查询语句中的字段数
在这一步中,尝试去猜测出查询语句中的字段个数,如下注入语句所示,假设为字符型注入,先利用1'实现引号闭环,再利用or 1=1这样可以暴露出表中所有的数据,最后利用order by num#去看是否报错来明确查询语句中的字段数,其中#号用于截断sql查询语句。
1' or 1=1 order by 1 #
1' or 1=1 order by 2 #
或者
1' or 1=1 union select 1, 2, 3 #
原理:
1、当sql查询语句为:
select username,password,uid from tbl_user order by 1;
就按照查询的第一个字段(即username字段)进行排序 ,此时SQL语句不会报错
2、当 order by 2 时,就按照查询的第二个字段(即password字段)进行排序 ,此时SQL语句也不会报错
3、当 order by 4 时,就按照查询的第四个字段进行排序,可是SQL语句中没有查询的第四个字段,查询的字段最多到第三个(即uid),所以SQL语句会报错
4、我们就可以根据页面有没有显示报错来判断查询的字段数有多少个。
3、确定字段的显示顺序
这里我们直接使用union就行,如下
代码所示,这里我们故意扰乱了first_name和last_name的两个位置,查询出来结果中的1,2会指明数据字段在查询语句中的位置。
1' union select 1, 2 #
使用union查询判断回显点
union查询条件:每个子查询检索列数、类型、排序规则必须相同,否则报错
union查询结果:合并显示查询的结果
4、获取当前数据库
通过前面的字段数确定以及显示顺序确定,我们就可以结合union操作来获取数据库中的信息了。如下代码所示,展示了获取数据库名的操作,根据前面已经获取到的字段数以及位置关系,假设有两个字段,那么下面的查询语句将会把数据库的名称放在第二个字段中。
1' union select 1, database() #
6、获取表中的字段名
进一步获取其中的字段名,假设要获取的表为users,如下面的代码和截图所示。information_schema的columns表存储了表中列的信息,也就是表中字段信息,指定table_name表名,即可获取到对应表的字段信息。
1' union select 1, group_concat(column_name) from information_schema.columns where table_name='users' #
报错注入: