SQL注入

    技术2022-05-11  131

    SQL注入

    l         何谓“SQL注入”

    SQL注入(SQL Injection),就是通过网站的漏洞,使用SQL命令(如:DML语句、DDL语句、SQL扩展存储过程等)获得网站正使用的数据库的信息、修改数据库记录、读取服务器的注册表、追加Windows的帐号、修改Windows帐号的权限等。

     

    l         SQL注入的方式

                  现阶段较为流行的SQL注入工具一般是通过GetPost方法进行注入。

     

    l         SQL注入是怎样产生的

    使用Get方式进行注入一般存在于形如:http://xxx.xxx.xxx/abc.asp?id=XX有参数的ASP动态中,有一个动态中可能只有一个参数,有可能有N个参数,有是整型参数,有是字符串型参数,不能一概而之只要是有参数的动态且此网页访问了数据,那就有可能存在SQL注入。如果ASP程序没有安全意,不行必要的字符过滤,存在SQL注入的可能性就非常大。

    #注:字符过滤只是防止注入的一种方法,具体的请参照后面的介绍。

    使用Post方式进行注入,一般存在于表单的提交中,因为在表单的提交中基本上都会编码,所以使用该方式进行注入比较困难,以下着重介绍Get方式的注入,Post方式的注入形同Get方式的注入。

     

    l         如何判断是否存在SQL注入

    Ø         前期准备

    IE「ツール」→「インターネット オプション」→「 詳細設定」→ 「ブラウズ」中的HTTPエラーメッセージを簡易表示する」前的勾去掉。 以获得更多的错误提示信息。

     

    Ø         注入验证

    对字符型参数:

    因为大多数网页中对数据表的操作都是使用串连接的形式实现的,如下:

    strSQL = “select * from TABLE where name=’”&strUsrName&”’ and password=’”& strPasswd & “’”

    所以在检验是否存在注入,常见的方法是在参数后面加个半角的单引号,如:

    http://xxx.xxx.xxx/abc.asp?id=XX’

    当页面被运行后,画面出现以下错误时,认为该网页可以进行注入:

    技術情報 (サポート担当者用)

    ·         エラー タイプMicrosoft OLE DB Provider for SQL Server (0x80040E14)文字列 '' の前で引用符が閉じていません。/test/xxx.asp, line 40

    这说明该页面没有对输入的参数进行有效性检查,即过滤单引号,则可以使用以下方式进行注入:

    1http://xxx.xxx.xxx.xxx/abc.asp?name=aaa’ or 1=1--

    2http://xxx.xxx.xxx.xx/abc.asp?name=aaa’;exec('create table temp ( [name] [char] (10)) ')--

    对于整型参数:

    对于整型参数来讲,上面的方法就不大适用了,因为对于整型参数,SQL代码可能如下:

    strSQL = “select * from TABLE where id=”& strID

    即使程序中对strID参数中的单引号做了过滤,也可使程序产生注入,如下:

    1、  http://xxx.xxx.xxx.xxx/abc.asp?id=1 or 1=1—

    2、  http://xxx.xxx.xxx.xxx/abc.asp?id=1 ;exec('create table temp ( [name] [char] (10)) ')—

     

    其中“--”在SQL中是注释的意思,所以“--”之后的代码均作为注释处理。

    对于上面的字符型和整型参数的第1种情况,条件“or 1=1”会使strSQL语句中的where条件变得无效;而第2种情况,代码会先执行分号之前的strSQL语句,然后执行exec后的SQL语句创建表,通过修改exec后的SQL语句,就可以通过你的数据库链接,进行SQL注入的攻击。

     

    l         SQL注入所产生的安全隐患

    Ø         逃避安全验证

    从理论上说,认证网页中会有如:select * from admin where username='XXX' and password='YYY' 的语句,若在正式运行此句之前,没有进行必要的字符过滤,则很容易实施SQL注入。如在用户名文本框内输入:abc’ or 1=1-- 在密码框内输入:123 则SQL语句变成:select * from admin where username='abc’ or 1=1 and password='123’ 不管用户输入任何用户名与密码,此语句永远都能正确执行,用户轻易骗过系统,获取合法身份。

    Ø         修改数据表的信息

    通过SQL注入的漏洞,能够得到系统中表的相关信息,从而修改表的内容。

    注:得到表的信息的方法可以参见网上提供的攻击方法,这里就不作介绍了。

    Ø         追加Windows帐号/修改帐号权限

    ASP木马只有USER权限,要想获取对系统的完全控制,还要有系统的管理员权限。怎么办?提升权限的方法有很多种:上传木马,修改开机自动运行的.ini文件(它一重启,便死定了)复制CMD.exescripts,人为制造UNICODE漏洞;下载SAM文件,破解并获取OS的所有用户名密码;等等,视系统的具体情况而定,可以采取不同的方法。

    Ø         修改注册表

    利用xp_regread扩展存储过程修改注册表

    另一个有用的内置存储过程是xp_regXXXX类的函数集合(Xp_regaddmultistring, Xp_regdeletekey,Xp_regdeletevalue,Xp_regenumkeys,Xp_regenumvalues, Xp_regread,Xp_regremovemultistring,Xp_regwrite)。

    攻击者可以利用这些函数修改注册表,如读取SAM 值,允许建立空连接,开机自动运行程序等。

    Ø         用其他存储过程去改变服务器

    Xp _servicecontrol过程允许用户启动,停止服务

    Xp_availablemedia 显示机器上有用的驱动器Xp_dirtree 允许获得一个目录树Xp_enumdsn 列举服务器上的ODBC数据源Xp_loginconfig 获取服务器安全信息Xp_makecab 允许用户在服务器上创建一个压缩文件Xp_ntsec_enumdomains 列举服务器可以进入的域Xp_terminate_process 提供进程的进程ID,终止此进程

    攻击者可以利用这些存储过程来得到服务器信息,进而去攻击服务器。

     

    l         SQL注入的防御

    其实SQL注入的方式不论是Post还是Get方式,注入的参数类型也就是字符型和整型两种,对于这两种参数类型的防御,可以分别采取以下措施:

    u       对参数进行判断

    Ø         字符型参数:

               对能够引起SQL注入的字符做替换处理,例如:

               '」→「''

               /」→「//

               %」→「/%

               _」→「/_

    Ø         整型参数

    对整型参数,在取得参数的值后,通过验证参数值的类型的合法化,来避免SQL

    的注入。

    例如:

    通过VBScript的函数IsNumeric来判断整型参数的输入值是否合法;

    或者通过CLng函数进行对输入值进行转换,捕获Err.Number的方式,来判断整型参数的输入值是否合法。

    u       PlaceHolder方式

    <%Set ObjConn = Server.CreateObject("ADODB.Connection")ObjConn.Open "sample","dbuser","dbpass"Set ObjCmd = Server.CreateObject("ADODB.Command")ObjCmd.CommandText= "SELECT * FROM user WHERE userid=? AND password=?"ObjCmd.CommandType = 1ObjCmd.ActiveConnection = ObjConn userid = Request.QueryString("userid")Set ObjUserid = Server.CreateObject("ADODB.Parameter")ObjUserid.Value = useridObjUserid.Size = Len(userid)ObjUserid.Type = 200ObjCmd.Parameters.Append ObjUserid password = Request.QueryString("password")Set ObjPassword = Server.CreateObject("ADODB.Parameter")ObjPassword.Value = passwordObjPassword.Size = Len(password)ObjPassword.Type = 200ObjCmd.Parameters.Append ObjPassword Set ObjRS = ObjCmd.Execute()%>

    使用上面的方法,可以将参数的检查和无害化交由系统进行处理

    l         总结

    SQL注入产生的后果虽然很严重,但只要我们在编码时进行正确的防御就可以了,在Web应用中,无论是采用Post还是Get方式传递SQL的参数,要做到以下几点:

    1.       整型参数要验证类型的合法化

    2.       字符型参数要对特殊字符进行正确的替换

    3.       DB的操作尽量使用placeholder的方式

     

    以上。


    最新回复(0)