官术网_书友最值得收藏!

2.2 欺騙是如何進(jìn)行的

簡單說來,SQL注入(SQL Injection)攻擊,就是攻擊者通過往SQL的query中插入一系列的SQL語句,來操作數(shù)據(jù)寫入到應(yīng)用程序中去,從而達(dá)到非法操作數(shù)據(jù)庫或網(wǎng)站程序的目的。但是攻擊者是如何提交自己的SQL欺騙語句的呢?

2.2.1 一個無名小站與一條典型SQL語句

對于一個普通的網(wǎng)站,用戶可以提交數(shù)據(jù)的地方很多,比如頁面登錄框、搜索框、文章發(fā)布、留言板、投票等,甚至一個簡單的網(wǎng)頁鏈接,都可能是用戶數(shù)據(jù)提交的途徑。而這些數(shù)據(jù)提交途徑,往往也會成為攻擊者提交自己欺騙性語句的入口點。這里,我們先來看看攻擊者是如何提交欺騙性的SQL攻擊語句的。

在Internet網(wǎng)上一個不知名小站,很不幸被攻擊者所選中,作為攻擊目標(biāo)。在這個網(wǎng)站上,有一個小鎮(zhèn)的簡介文章,單擊打開這個文章的鏈接,可以看到小鎮(zhèn)的介紹信息(見圖2)。

這是一個很普通的網(wǎng)頁文章,但是卻會成為攻擊者提交欺騙性SQL語句的入口。看看文章的鏈接是這樣的:

            http://www.***.cn/gkml1/dwgk.asp? name=永寧鎮(zhèn)

表面上看來,這只是一個鏈接地址而已,而事實上,這是一個典型的用戶向數(shù)據(jù)庫提交數(shù)據(jù)的例子。這個鏈接對應(yīng)的SQL操作指令,可以猜測其語句格式如下:

            Select name, article, address from gkml where name=’永寧鎮(zhèn)’

這是一條典型的SQL語句,表示從名為“gkml”的數(shù)據(jù)庫中,查詢“name”字段為“永寧鎮(zhèn)”的記錄,并顯示該記錄中的“name”、“article”及“address”等數(shù)據(jù)。正是這些查詢顯示的數(shù)據(jù)信息,構(gòu)成了最終顯示的頁面結(jié)果。

圖2 小鎮(zhèn)信息介紹

這樣一條經(jīng)典的語句,是如何被攻擊者所利用的呢?在上面的語句中,“永寧鎮(zhèn)”就是用戶提交的數(shù)據(jù),而攻擊者時時可以通過修改這個數(shù)據(jù)進(jìn)行攻擊,在這個查詢中注入一些SQL語句或字符,從而改變原來的整條SQL語句。例如,攻擊者可能會修改文章的鏈接為:

            http://www.***.cn/gkml1/dwgk.asp? name=永寧’鎮(zhèn)

那么,攻擊者就完成了一次修改后的數(shù)據(jù)提交,提交的數(shù)據(jù)是“永寧’鎮(zhèn)”,這個數(shù)據(jù)被作為“name”字段的值,進(jìn)入原來的SQL語句中,從而改變了原來的SQL語句,變成如下:

            Select name, article, address from gkml where name=’永寧’鎮(zhèn)’

當(dāng)數(shù)據(jù)庫試圖去執(zhí)行這個查詢時,它將返回類似如下的錯誤(見圖3):

            Microsoft OLE DB Provider for SQL Server 錯誤 '80040e14'
            第 1 行: ’鎮(zhèn)’ 附近有語法錯誤。
            /gkml1/dwgk.asp,行 42

造成這種結(jié)果的原因是插入了單引號“' ”,作為定界符的單引號,改變了SQL語句的構(gòu)成。數(shù)據(jù)庫管理系統(tǒng)嘗試去執(zhí)行如下語句:

            Select name, article, address from gkml where name=’永寧’鎮(zhèn)’

圖3 修改提交數(shù)據(jù)出錯

由于其中有一個不閉合的單引號,這是不符合SQL語句規(guī)范的,因此執(zhí)行失敗,返回了錯誤信息。

如果攻擊者再提交特別的參數(shù),例如:“永寧鎮(zhèn)’; drop table authors-”,那么原來的SQL語句,就變成了如下形式:

            Select name, article, address from gkml where name=’永寧鎮(zhèn)’ ; dro
            p table authors--

可以看到,原來的一條SQL語句,現(xiàn)在經(jīng)過攻擊者精心提交的數(shù)據(jù),被修改成了兩條SQL語句。數(shù)據(jù)庫會在執(zhí)行了正常的查詢之后,又執(zhí)行攻擊者添加的另一條語句:

            drop table authors--

這條SQL語句執(zhí)行的結(jié)果是,將數(shù)據(jù)庫中名為“authors”的表刪除。造成這種結(jié)果的原因,我們后面會詳細(xì)進(jìn)行講解。此外,攻擊者還可以猜解數(shù)據(jù)庫中的用戶名和密碼等。

從上面的小例子可以看出,SQL注入式攻擊主要就是通過非法修改提交SQL查詢語句,達(dá)到猜解或破壞數(shù)據(jù)庫的目的。而網(wǎng)站給攻擊者所利用的數(shù)據(jù)提交入口,也是非常多的。

2.2.2 創(chuàng)建SQL注入檢測的數(shù)據(jù)庫平臺

當(dāng)然,并非任意一個網(wǎng)站,都可以被攻擊者成功地進(jìn)行入侵破壞,這往往取決于網(wǎng)站是否存在著SQL注入漏洞。在上面的例子中,也許攻擊所產(chǎn)生的效果并不是那么直觀,那么下面我們就來自己打造一個SQL注入攻擊的簡單實例。相信這個例子,可以讓讀者更加清楚地看到SQL注入攻擊的危害。

首先,需要搭建一個SQL注入攻擊的目標(biāo)——數(shù)據(jù)庫。這里我們簡單地打造一個MS SQL數(shù)據(jù)庫作為攻擊目標(biāo)。

常見的數(shù)據(jù)庫非常多,在本書后面的章節(jié)中,讀者將會經(jīng)常碰到幾種最常見的數(shù)據(jù)庫,如Access數(shù)據(jù)庫、MS SQL、MySQL數(shù)據(jù)庫等。對于這幾種數(shù)據(jù)庫的創(chuàng)建及安裝與配置,都是必須了解熟悉的,可以為后面進(jìn)行網(wǎng)站數(shù)據(jù)庫入侵檢測打下基礎(chǔ)。由于本書不是專門的數(shù)據(jù)庫著作,因此沒有將數(shù)據(jù)庫的安裝、創(chuàng)建及配置等作為獨立的章節(jié)列出,而是融合到相關(guān)的入侵章節(jié)中進(jìn)行介紹。在介紹到相關(guān)的數(shù)據(jù)庫知識時,也希望讀者們用心學(xué)習(xí)。

MS SQL數(shù)據(jù)庫管理系統(tǒng)目前最新版本為MS SQL 2005,不過,目前應(yīng)用最廣泛的還是SQL 2000版本。在Windows 2000中安裝SQL 2000版本是比較簡單的,但是在Windows XP系統(tǒng)中安裝SQL 2000企業(yè)版本時,會提示版本類型檢測不正確,要求安裝Windows Server版本。這里主要講一下如何在Windows XP系統(tǒng)中安裝SQL 2000企業(yè)版本。

首先,在SQL 2000服務(wù)器安裝光盤中,打開MSDE目錄,雙擊“setup.exe”程序,即可進(jìn)行服務(wù)器商的安裝(圖4)。安裝過程很簡單,按照安裝向?qū)В苯訂螕簟鞠乱徊健堪粹o即可。如果在安裝過程中,出現(xiàn)“指定的實例名稱無效”的錯誤提示(圖5),則可刪除“C:\Program Files\Microsoft SQL Server”目錄下的所有文件,重新運行安裝程序即可。

重啟系統(tǒng)后,就可以看到SQL服務(wù)的圖標(biāo)出現(xiàn)了。再通過SQL服務(wù)器版的安裝光盤,雙擊光盤根目錄下的“autorun.exe”工具,直接安裝客戶端工具。根據(jù)提示安裝,在自檢過程中會提示系統(tǒng)不是Server版,只安裝客戶端工具。

然后要求選擇安裝路徑,選擇“本地計算機(jī)”(圖6),單擊【下一步】按鈕,選擇“創(chuàng)建新的SQL Sever實例,或安裝‘客戶端工具’”(圖7)單選按鈕。然后設(shè)置姓名及單位,并選擇接受協(xié)議,再選擇“僅客戶端工具”單選按鈕(圖8)。

圖4 直接安裝服務(wù)端程序

圖5 安裝出錯信息

圖6 選擇安裝路徑

圖7 創(chuàng)建新的SQL Sever實例

圖8 安裝客戶端工具

然后要求選擇安裝組件(圖9),單擊【下一步】按鈕后完成文件的安裝復(fù)制。完成文件安裝復(fù)制后,在“運行”中輸入“regedit”命令,打開注冊表編輯器。找到[HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\MSSQLServer\MSSQLServer],這個項里面有一個鍵值LoginMode,默認(rèn)值是1,現(xiàn)在將值改為2,重啟計算機(jī)。然后重啟系統(tǒng)即可(圖10)。

圖9 選擇安裝組件

圖10 修改注冊表驗證值

重啟系統(tǒng)后,單擊【開始】→【所有程序】→【Microsoft SQL Server】→【企業(yè)管理器】菜單命令,打開企業(yè)管理器工具。依次單擊左側(cè)欄中的“Microsoft SQL Servers”→“SQL Server組”,雙擊右邊窗口中的“Local”服務(wù)器,即可連接SQL Server了(圖11)。

圖11 使用企業(yè)管理器連接SQL Server

對于SQL Server配置,最重要的是連接的用戶密碼的修改。默認(rèn)安裝的SA用戶為空密碼,需要手工進(jìn)行修改設(shè)置。在“SQL Server企業(yè)管理器”下展開“安全性”→“登錄”,雙擊右邊窗口中的“sa”用戶(圖12),打開用戶設(shè)置對話框。在“密碼”框中,輸入新密碼,單擊【確定】按鈕,即可配置新密碼(圖13)。在“服務(wù)器角色”和“數(shù)據(jù)庫訪問”選項頁中,還可以設(shè)置數(shù)據(jù)庫訪問權(quán)限及其他詳細(xì)用戶設(shè)置。

圖12 設(shè)置sa用戶

圖13 修改sa密碼

MS SQL數(shù)據(jù)庫服務(wù)器建立成功后,已經(jīng)內(nèi)置默認(rèn)了幾個數(shù)據(jù)庫及表。SQL Server 2000服務(wù)器安裝完畢后,默認(rèn)會建立6個數(shù)據(jù)庫:master、model、msdb、tempdb、pubs和Northwind。MS SQL數(shù)據(jù)庫及表的建立主要通過SQL語句執(zhí)行操作,這里使用MS SQL內(nèi)置的“SQL查詢分析器”來執(zhí)行SQL語句。

在默認(rèn)的幾個數(shù)據(jù)庫中,pubs和Northwind數(shù)據(jù)庫為用戶數(shù)據(jù)庫,存儲的是實例數(shù)據(jù),供DBA和開發(fā)人員練習(xí)使用。其余的4個數(shù)據(jù)庫為系統(tǒng)數(shù)據(jù)庫,用于SQL Server 2000服務(wù)器的系統(tǒng)管理使用。

master數(shù)據(jù)庫是SQL Server 2000中最重要的數(shù)據(jù)庫,存儲的是SQL Server 2000的系統(tǒng)信息,包括磁盤空間、文件分配和使用、系統(tǒng)級的配置參數(shù)、所有的登錄賬戶信息、初始化信息和其他數(shù)據(jù)庫的信息等。由于master數(shù)據(jù)庫對SQL Server 2000十分重要,所以禁止用戶的直接訪問,并確保在修改之前有完整的備份。這幾個默認(rèn)的數(shù)據(jù)庫,我們在以后的入侵中會經(jīng)常使用到,尤其是默認(rèn)的master庫。

單擊【開始】→【所有程序】→【Microsoft SQL Server】→【查詢分析器】菜單命令,打開“SQL查詢分析器”。首先,輸入服務(wù)器連接賬號及密碼(圖14),單擊【確定】按鈕后連接上SQL Server。在中間窗口上方,就可以輸入SQL語句,單擊工具欄上的【執(zhí)行】按鈕,即可執(zhí)行SQL語句(圖15)。

圖14 SQL查詢分析器登錄

圖15 SQL語句執(zhí)行窗口

在SQL查詢分析器窗口中,依次執(zhí)行如下語句(圖16):

        Create database users
        use users
        CREATE TABLE USERS(USERNAME VARCHAR(20), PASSWORD VARCHAR(20))
        Insert into users values(' admin' ,123456)

圖16 執(zhí)行SQL語句

執(zhí)行后可建立一個名為“users”的數(shù)據(jù)庫,并在此數(shù)據(jù)庫中建立名為“users”的表。“users”表包含兩個字段,一個是“username”,另一個是“password”。并在“users”表中插入了一條數(shù)據(jù):“username=admin, password=123456”,也就是說,用戶名為“admin”,登錄密碼為“123456”。

2.2.3 搭建一個SQL注入漏洞站點

下面,我們來通過一個簡單的ASP登錄頁面實例,分析SQL注入攻擊的原理。此ASP頁面功能用于提交用戶輸入的用戶名及密碼,并查詢數(shù)據(jù)庫中的用戶名與密碼,如果相符,則顯示登錄成功的提示;否則,提示登錄失敗。

我們已經(jīng)建立了一個用于用戶登錄的數(shù)據(jù)庫及表、字段和值,該數(shù)據(jù)庫名為“users”,用戶名為“admin”,登錄密碼為“123456”。用記事本編寫一個提交表單頁的代碼,讓用戶輸入用戶名和密碼,代碼如下(源代碼見隨書光盤\Sample\ch2\1.2.3 SQL注入簡單實例.rar):

            <HTML>
            <HEAD>
            <TITLE>Login Page</TITLE>
            </HEAD>
            <BODY bgcolor='000000' text=' cccccc' >
            <FONT Face=' tahoma' color=' cccccc' >
            <CENTER><H1>Login</H1>
            <FORM action=' login.asp' method=post>
            <TABLE>
            <TR><TD>用戶名:</TD><TD><INPUT type=text name=username size=6
            2 width=50></TD></TR>
            <TR><TD>密   碼:</TD><TD><INPUT type=password name=password s
            ize=70 withd=50></TD></TR>
            </TABLE>
            <INPUT type=submit value=’登錄’><INPUT type=reset value=’重新
            登錄’>
            </FORM>
            </Font>
            </BODY>
            </HTML>

將上面的代碼保存為“l(fā)ogin.html”。下面是“l(fā)ogin.asp”的代碼,它是用來控制登錄的:

    <HTML>
    <BODY bgcolor='000000' text=' ffffff' >
    <FONT Face=' tahoma' color=' ffffff' >
    <STYLE>
    p { font-size=20pt ! important}
    font { font-size=20pt ! important}
    h1 { font-size=64pt ! important}
    </STYLE>
    <%@LANGUAGE = JScript %>
    <%
    function trace(str) {
    if(Request.form("debug") == "true")
    Response.write(str);
    }
    function Login(cn) {
    var username;
    var password;
    username = Request.form("username");
    password = Request.form("password");
    var rso = Server.CreateObject("ADODB.Recordset");
    var sql = "select * from users where username = ' " + username
    + "' and password = ' " + password + "' "; trace("query: " + sql
     );
    rso.open(sql, cn);
    if (rso.EOF) {
    rso.close();
    %>
    <FONT Face=' tahoma' color=' cc0000' >
    <H1> <BR>
    <CENTER>登錄失敗</CENTER>
    </H1>
    </BODY>
    </HTML>
    <% Response.end()
    return;
    }
    else {
    Session("username") = "" + rso("username");
    %>
            <FONT Face=' tahoma' color='00cc00' >
            <H1> <CENTER>登錄成功<BR>
            歡迎,<% Response.write(rso("Username")); Response.write( "</B
            ODY></HTML>" ); Response.end()
            return;
            }
            }
            function Main() {
            var username
            var cn = Server.createobject( "ADODB.Connection" );
            cn.connectiontimeout = 20;
            connstr = "Driver={SQL Server}; Server=(local); Database=user
            s; UID=sa; PWD=";
            cn.open(connstr);
            username = new String(Request.form("username"));
            if(username.length > 0) {
            Login(cn);
            }
            cn.close();
            }
            Main();
            %>

建立ASP服務(wù)器,在瀏覽器中打開“l(fā)ogin.html”登錄頁面,要求輸入用戶名和密碼(圖17)。如果輸入正確的用戶名“admin”和密碼“123456”,那么會顯示“登錄成功,歡迎admin”的信息(圖18)。如果用戶名和密碼輸入錯誤,那么則會顯示“登錄失敗”的提示信息(圖19)。

圖17 登錄頁面

圖18 登錄成功

圖19 登錄失敗

2.2.4 第一次SQL注入攻擊測試

上面的這個網(wǎng)頁,表面上看起來沒有任何問題,可以正常地執(zhí)行,輸入正確密碼就可以登錄,密碼錯誤則登錄失敗。但實際上,此網(wǎng)頁代碼中存在著嚴(yán)重的SQL注入漏洞。存在漏洞的代碼,是出現(xiàn)于“l(fā)gin.asp”中產(chǎn)生查詢語句的部分,代碼內(nèi)容如下:

            Var sql="select * from users where username=' "+username+"' an
            d password=' "+password+"' ";

上面的這個SQL查詢語句沒有問題,但是其中的“username”和“password”參數(shù)值是由用戶提交的。程序沒有對用戶提交的值進(jìn)行限制,因此攻擊者可以任意修改構(gòu)造提交的參數(shù)值。假如用戶輸入的信息如下(圖20):

            Username:
            Password:' ; ' drop table users-

圖20 用戶名處輸入SQL注入語句

提交數(shù)據(jù)后,提示登錄失敗,但結(jié)果不僅如此,而是數(shù)據(jù)庫中表users將被刪除,此時再次輸入正確用戶名和密碼后,將提示如下信息(圖21):

圖21 數(shù)據(jù)庫中的表被刪除

            Microsoft OLE DB Provider for ODBC Drivers '80040e37'
            [Microsoft][ODBC SQL Server Driver][SQL Server]對象名 ' users'
            無效。
            \www\asp\login.asp, line 22

也就是說,此時用戶表被刪除后,將拒絕任何用戶登錄。這是因為在上面攻擊提交的數(shù)據(jù)中,“; ”符號表示一個查詢的結(jié)束和另一個查詢的開始;“--”連結(jié)符號,在Transact-SQL中表示忽略“--”之后的語句。通過“--”字符,就可使這個用戶名查詢終止,并且不返回錯誤。也就是說,經(jīng)過用戶精心提交的參數(shù),原來的SQL查詢語句就被修改為如下:

            Var sql="select * from users where username=' ; drop table users-

原來后面的“psssword”驗證部分直接被忽略掉了,而執(zhí)行了“drop table users-”語句,雖然此時用戶無法進(jìn)行登錄,但是導(dǎo)致數(shù)據(jù)庫中的users表被刪除掉。

另外,攻擊者可以只需提交一個已知的用戶名,就可以用任何用戶身份登錄。例如,攻擊者提交如下參數(shù):

            Username:admin
            Password: 'or'1' ='1

即可直接以admin的身份登錄成功。造成這樣的結(jié)果,也是由于SQL注入攻擊漏洞引起的,這里僅是做一個演示,而具體原理將在后面的章節(jié)中進(jìn)行詳細(xì)的解釋。

主站蜘蛛池模板: 渭南市| 古交市| 章丘市| 黎平县| 蚌埠市| 大渡口区| 衡东县| 神池县| 竹山县| 云南省| 阳原县| 静安区| 建平县| 曲沃县| 合作市| 沈阳市| 徐汇区| 克东县| 勃利县| 瑞昌市| 诏安县| 巨野县| 新干县| 宁国市| 龙岩市| 威宁| 临高县| 望城县| 瑞昌市| 东乡县| 东平县| 房产| 建水县| 南漳县| 永春县| 阜新| 麻城市| 河东区| 枣庄市| 防城港市| 宁夏|