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

6.2 生成會話令牌過程中的漏洞

很多時候,應(yīng)用程序的安全取決于令牌生成過程中的不可預(yù)知性。由于生成令牌過程中存在漏洞,攻擊者能夠確定發(fā)布給其他用戶的令牌,達(dá)到攻擊會話管理機(jī)制的目的。令牌的種類有“記住我”功能使用的永久令牌、用于一次性訪問受保護(hù)的資源的令牌、發(fā)送到用戶注冊的電子郵件地址的恢復(fù)密碼令牌、隱藏表單字段中用于防止跨站點請求偽造攻擊的令牌、未使用驗證的購物應(yīng)用程序的消費者用于檢索現(xiàn)有訂單的當(dāng)前狀態(tài)的令牌等幾種。

由于當(dāng)前的許多應(yīng)用程序都采用成熟的會話令牌生成機(jī)制,我們可以在這些功能區(qū)域中發(fā)現(xiàn)有關(guān)令牌生成過程中的漏洞。

6.2.1 結(jié)構(gòu)化令牌的組成存在漏洞

含有含義數(shù)據(jù)的令牌通常表現(xiàn)出某種結(jié)構(gòu),也就是說,它們由幾種成分組成,通常以分隔符隔開,攻擊者可分別提取并分析這些成分,以了解它們的功能和生成方法。

結(jié)構(gòu)化令牌的組成成分包括以下幾項。

(1)賬戶用戶名。

(2)應(yīng)用程序用來區(qū)分賬戶的數(shù)字標(biāo)識符。

(3)用戶姓名中的名/姓。

(4)用戶的電子郵件地址。

(5)用戶在應(yīng)用程序中所屬的組或扮演的角色。

(6)日期/時間戳。

(7)一個遞增或可預(yù)測的數(shù)字。

(8)客戶的IP地址。

從應(yīng)用程序中獲取一個令牌,對其進(jìn)行系統(tǒng)化的修改,以確定整個令牌是否有效,或者令牌的某些成分是否被忽略。嘗試以一次一個字節(jié)(或者一次一個位)的方式更改令牌的值,然后重新向應(yīng)用程序提交修改后的令牌,看應(yīng)用程序是否仍然接受這個令牌。如果發(fā)現(xiàn)令牌中的某些部分實際上并無作用,可以將它們排除在深入分析之外,以減輕工作負(fù)擔(dān)。

在不同時間以不同的用戶登錄,記錄服務(wù)器發(fā)布的令牌。如果應(yīng)用程序允許自我注冊,可以選擇自己的用戶名,用一系列存在細(xì)微差別的相似用戶名登錄,如admin、admina、adminb、adminlogin等。如果其他與某一名用戶有關(guān)的數(shù)據(jù)(如電子郵件地址)在登錄階段提交或保存在用戶資料中,對其進(jìn)行與前面類似的系統(tǒng)化修改,并記錄登錄后收到的令牌。

對令牌進(jìn)行分析,查找任何與用戶名和其他用戶可控制的數(shù)據(jù)有關(guān)的內(nèi)容。

分析令牌,查找任何明顯的編碼或模糊處理方案。如果用戶名包含一組相同的字符,在令牌中尋找可能使用XOR模糊處理的對應(yīng)字符序列;在令牌中尋找僅包含十六進(jìn)制字符的字符序列,它表示應(yīng)用程序可能對ASCII字符串進(jìn)行了十六進(jìn)制編碼處理,或者披露其他信息。尋找以等號(=)結(jié)尾的字符序列或僅包含其他有效Base64字符的序列,如a-z、A-Z、0-9、+和/。

如果對會話令牌樣本進(jìn)行逆向工程可獲得任何有意義的結(jié)果,看看是否擁有足夠的信息可猜測出應(yīng)用程序最近向其他用戶發(fā)布的令牌。找到一個依賴會話的應(yīng)用程序頁面(即如果不使用有效會話訪問,就會返回錯誤消息或指向其他位置的重定向頁面),通過Burp Suite Free Edition之類的工具可使猜測出的令牌向該頁面提出大量請求。監(jiān)控頁面被正確加載的所有情況的結(jié)果,這表示會話令牌有效。

6.2.2 令牌含義的可預(yù)測性

一些會話令牌并不包含與某個特殊用戶有關(guān)的任何有意義的數(shù)據(jù),但由于它們包含某種順序或模式,允許攻擊者通過幾個令牌樣本即可推斷出應(yīng)用程序最近發(fā)布的其他有效令牌,因此具有可預(yù)測性。即使推斷過程需要做出大量嘗試,并且成功率極低(如每1000次嘗試得到一個有效令牌),自動攻擊工具也仍然能夠利用這種缺陷在很短的時間內(nèi)確定大量有效令牌。

與定制應(yīng)用程序相比,會話管理的商業(yè)應(yīng)用,如Web服務(wù)器或Web應(yīng)用程序平臺中的令牌可預(yù)測漏洞更容易被發(fā)現(xiàn)。當(dāng)向一個定制會話管理機(jī)制實施遠(yuǎn)程攻擊時,攻擊者所能獲得的已發(fā)布令牌樣本的數(shù)量可能受到服務(wù)器容量、其他用戶的活動、帶寬、網(wǎng)絡(luò)延時等因素的限制。然而,在實驗室環(huán)境中,滲透測試員可以迅速建立數(shù)百萬個令牌樣本,所有樣本都緊密相連,并使用了時間戳,而且可以降低其他用戶造成的干擾。

在最簡單也是最容易受到攻擊的情況下,應(yīng)用程序使用一個簡單的連續(xù)數(shù)字作為會話令牌。這時,攻擊者只需獲得兩個或三個令牌樣本就可以實施攻擊,并立即截獲當(dāng)前有效的所有令牌。

在其他情況下,應(yīng)用程序令牌中可能包含更加復(fù)雜的序列,需要付出一定的努力才能發(fā)現(xiàn)。序列的變化形式可能多種多樣,但是,根據(jù)我們的行業(yè)經(jīng)驗,可預(yù)測的會話令牌通常來自3個方面:隱含序列、時間依賴、生成的數(shù)字隨機(jī)性不強(qiáng)。

(1)隱含序列。

有時,對會話令牌的原始形式進(jìn)行分析可能無法預(yù)測它們,但是對其進(jìn)行適當(dāng)解碼或解譯就可以揭示其中包含的序列。

(2)時間依賴。

一些Web服務(wù)器和應(yīng)用程序使用時間作為令牌值的輸入,通過某種算法生成會話令牌。如果沒有在算法中合并足夠的熵,攻擊者就可能推測出其他用戶的令牌。雖然任何特定的令牌序列本身是完全隨機(jī)的,但是如果組合生成每個令牌的時間信息,也許可以發(fā)現(xiàn)某種可以辨別的模式。一個忙碌的應(yīng)用程序每秒會生成大量的會話,因此實施一次自定義攻擊就可以成功確定其他用戶的大量令牌。

(3)生成的數(shù)字隨機(jī)性不強(qiáng)。

計算機(jī)中的數(shù)據(jù)極少完全隨機(jī),因此如果由于某種原因需要隨機(jī)數(shù)據(jù),一般通過軟件使用各種技巧生成偽隨機(jī)數(shù)字。所使用的一些算法生成看似隨機(jī)并且在可能的數(shù)值范圍內(nèi)平均分布的序列,但有些人只需要少數(shù)幾個樣本,仍然能夠準(zhǔn)確推導(dǎo)出整個序列。

有時,令牌根據(jù)一個偽隨機(jī)數(shù)字發(fā)生器的輸出而生成,因此開發(fā)者決定將發(fā)生器的幾個連續(xù)輸出連接起來建立每個令牌。開發(fā)者認(rèn)為使用這種方法可建立一個更長因而“更強(qiáng)大”的令牌。但是這種策略通常是一種誤解。如果攻擊者能夠獲得發(fā)生器生成的幾個連續(xù)輸出,他們就可以通過它們推斷出發(fā)生器內(nèi)部狀態(tài)的一些信息,因此更容易向前或向后推導(dǎo)發(fā)生器的輸出順序。

圖6-5表示正在使用Burp Suite Free Edition軟件循環(huán)訪問一個會話令牌,以查找會話仍處于活動狀態(tài)可被劫持的令牌值。這時,服務(wù)器響應(yīng)的長度是發(fā)現(xiàn)有效會話的可靠指標(biāo)。

圖6-5 循環(huán)訪問一個會話令牌

1 單擊Burp Suite Free Edition軟件的“intruder”按鈕。

2 在彈出的選項中單擊“Options”按鈕。

3 單擊顯示窗口右上方的“Start attack”按鈕,軟件開始循環(huán)訪問一個會話令牌。

6.2.3 對令牌的算法存在漏洞

當(dāng)用戶登錄時,系統(tǒng)創(chuàng)建一個訪問令牌,里面包含登錄進(jìn)程返回的Session ID和由本地安全策略分配給用戶和用戶的安全組的特權(quán)列表以該用戶身份運行的所有進(jìn)程都擁有該令牌的一個拷貝。系統(tǒng)使用令牌控制用戶可以訪問哪些安全對象,并控制用戶執(zhí)行相關(guān)系統(tǒng)操作的能力。對令牌的算法漏洞可能存在于以下4個方面。

1.沒有采用強(qiáng)算法生成Session ID

會話ID必須具有隨機(jī)性和不可預(yù)測性。一般來說,會話ID的長度至少為128位。下面就以常見的應(yīng)用服務(wù)器Tomcat來說明如何配置會話ID的長度和生成算法。

首先找到{TOMCAT_HOME}\conf\context.xml,然后加入下面一段代碼:

<Manager sessionIdLength="20"
            secureRandomAlgorithm="SHA1PRNG"
            secureRandomClass="java.security.SecureRandom"
    />

定義會話ID的長度,如果這里不聲明的話,默認(rèn)是16字節(jié)??赡苡凶x者會納悶,怎么平時我看到的會話ID都是很長的呀?我們就以這里的20個字節(jié)來講,在瀏覽器發(fā)送請求時會發(fā)現(xiàn)這樣的會話ID:

JSESSIONID=90503B6BE403D4AB6164A311E167CF1F6F3F2BD0

仔細(xì)觀察會發(fā)現(xiàn)ID的長度為40,因為這里顯示的是十六進(jìn)制,每兩個字符代表一個字節(jié)。

定義隨機(jī)數(shù)算法,默認(rèn)的是SHA1PRNG,你也可以換成自己的算法。

定義隨機(jī)數(shù)類,默認(rèn)的是java.security.SecureRandom,我們也可以繼承這個類來實現(xiàn)自己的算法。但有一點要注意,在實現(xiàn)自己的隨機(jī)數(shù)算法時,一定要保證生成的Session ID不能有重復(fù),這里我們參考一下Tomcat實現(xiàn)的機(jī)制。

/**
        * Generate and return a new session identifier.
        */
        protected StringgenerateSessionId() {
  String result = null;
            do {
                if (result ! = null) {
                    duplicates++;
                }
                result = sessionIdGenerator.generateSessionId();
            } while (sessions.containsKey(result));
            return result;
        }

由此可見,Tomcat不會產(chǎn)生兩個相同的會話ID。

2.沒有使用“軟硬兼施,會話過期”機(jī)制

會話過期是應(yīng)用程序的一項重要的安全控制,它定義了用戶在多長時間段內(nèi)不用重新登錄而仍然維持一個登錄狀態(tài)。一般來說,有兩種會話過期:軟會話過期(Soft Session Timeout)和硬會話過期(Hard Session Timeout)。

(1)軟會話過期。

軟會話過期指的是用戶在一定的時間內(nèi)與應(yīng)用系統(tǒng)沒有交互,則會話過期。例如,一個用戶登錄了一個應(yīng)用系統(tǒng),他臨時離開了計算機(jī)40分鐘,而應(yīng)用系統(tǒng)設(shè)置的會話過期時間為30分鐘,這時用戶回到計算機(jī)前再做任何操作,系統(tǒng)都會重定向為登錄頁面讓用戶重新輸入用戶名和密碼。

那么,軟會話過期有什么用呢?我們知道在CSRF攻擊中一個最基本的假設(shè)就是合法用戶處在一個登錄狀態(tài)中,如果我們設(shè)置了一個合理的且較低的會話過期時間,就提高了實施CSRF攻擊的難度,從而保護(hù)了系統(tǒng)。

通常有3種辦法來設(shè)定軟會話過期,其級別由高到低依次為:Tomcat級別> Web應(yīng)用級別>Servlet運行時context級別,這時低級別的設(shè)定會覆蓋高級別的設(shè)定。

①Tomcat級別的設(shè)定。

若需要設(shè)定30分鐘的會話過期,可以在{TOMCAT_HOME}\conf\web.xml中進(jìn)行如下設(shè)定:

<session-confi g>
            <session-timeout>30</session-timeout><! -- set in minutes -->
    </session-confi g>

②Web應(yīng)用級別的設(shè)定。

若需要設(shè)定15分鐘的會話過期,可以在{TOMCAT_HOME}\webapps\ {APP_NAME}\WEB-INF\web.xml中進(jìn)行如下設(shè)定:

<session-confi g>
          <session-timeout>15</session-timeout><! -- set in minutes -->
    </session-confi g>

③在程序代碼中進(jìn)行設(shè)定。

若需要在程序中設(shè)定5分鐘的會話過期,可以用下面一行代碼來實現(xiàn):

httpSession.setMaxInactiveInterval(5*60); // set in seconds

如果我們按照上面的步驟進(jìn)行了會話過期設(shè)置,那么最后真正起作用的是在程序中進(jìn)行設(shè)定的5分鐘。

(2)硬會話過期。

硬會話過期指的是用戶登錄到系統(tǒng)中經(jīng)過一定的時間后,不管用戶做什么,該會話都會過期。例如,網(wǎng)絡(luò)游戲防沉迷系統(tǒng),如果未成年人的累計在線時間已滿5小時,則累計在線時間清零。這與我們所說的硬會話過期很相似,只不過這里不是在線時間清零,而是強(qiáng)制用戶退出并重新登錄。

硬會話過期主要用來防止永久地對一個賬號劫持。例如,一個攻擊者通過XSS得到了受害者的Session,并用它冒充受害者進(jìn)行登錄,如果我們設(shè)定了硬會話過期,則經(jīng)過了一段時間之后,系統(tǒng)會強(qiáng)制用戶重新進(jìn)行認(rèn)證。

沒有專門的API或者配置來設(shè)定硬會話過期,但我們可以通過在Web filter中輸入自己的代碼來實現(xiàn)這個功能?;舅悸啡缦拢簩γ總€用戶登錄成功后記錄下此時的時間,并且把這個時間與他們的Session ID綁定起來,如果用同一個Session ID發(fā)送的請求的時間減去這個Session ID剛登錄成功的時間大于我們設(shè)定的會話過期時間,則使這個會話無效,并重定向到登錄頁面。

3.沒有使用Cookies保護(hù)機(jī)制

Cookies有兩個很重要的屬性:secure和HttpOnly,設(shè)置好這兩個屬性對于保護(hù)你的Cookies至關(guān)重要。

(1)Secure屬性。

聲明了Secure屬性,則說明當(dāng)前這個Cookies只會在HTTPS的鏈接中進(jìn)行傳遞,這樣就使攻擊者無法很容易地通過分析網(wǎng)絡(luò)流量來獲得會話ID,從而有效地防止中間人攻擊(Man-in-the-Middle)。

一個好消息是,Tomcat 7支持了Servlet 3.0,所以我們可以在web.xml設(shè)定上面的兩個屬性。

<session-confi g>
    <cookies-confi g>
            <secure>true</secure>
            </cookies-confi g>
            <cookies-confi g>
            <http-only>true</http-only>
            </cookies-confi g>
    </session-confi g>

需要注意的是,Tomcat 6以前的版本不支持,Tomcat 6支持的是Servlet 2.5。

(2)HttpOnly屬性。

大家知道Cookies都是通過document對象獲取的,如果能讓Cookies在瀏覽器中不可見就可以了,那么HttpOnly就是在設(shè)置Cookies時接受這樣一個參數(shù),一旦被設(shè)置,在瀏覽器的document對象中就看不到Cookies了。而在瀏覽網(wǎng)頁時不受任何影響,因為Cookies會被放在瀏覽器頭中發(fā)送出去(包括Ajax的時候),應(yīng)用程序也一般不會在JS里操作這些敏感的Cookies。對于一些敏感的Cookies我們采用HttpOnly,對于一些需要在應(yīng)用程序中用JS操作的Cookies我們就不予設(shè)置,這樣就保障了Cookies信息的安全,也保證了應(yīng)用。

給瀏覽器設(shè)置Cookies的頭如下:

Set-Cookies: =[; =]
    [; expires=][; domain=]
    [; path=][; secure][; HttpOnly]

如果Cookies具有HttpOnly特性且不能通過客戶端腳本訪問,則為true,否則為false;默認(rèn)值為false。

4.沒有提供logout功能

上面介紹的是系統(tǒng)自動按照設(shè)定的時間使會話過期,一個好的應(yīng)用程序應(yīng)該提供一個功能,即用戶可以手動地使當(dāng)前會話過期,這就是我們在幾乎所有網(wǎng)站上都看到的logout按鈕。那么一般的logout需要完成哪些功能呢?下面我們看看ESAPI中是如何實現(xiàn)logout功能的。

Class: org.owasp.esapi.reference.DefaultUser
        public void logout() {
            ESAPI.httpUtilities().killCookies( ESAPI.currentRequest(),
    ESAPI.currentResponse(),
    HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME );
            HttpSession session = ESAPI.currentRequest().getSession
  (false);
            if (session ! = null) {
    removeSession(session);
                session.invalidate();
            }
            ESAPI.httpUtilities().killCookies(ESAPI.currentRequest(),
    ESAPI.currentResponse(),
    "JSESSIONID");
            loggedIn = false;
            logger.info(Logger.SECURITY_SUCCESS, "Logout successful");
            ESAPI.authenticator().setCurrentUser(User.ANONYMOUS);
        }

killCookies的實現(xiàn)代碼如下:

public void killCookies(HttpServletRequest request,
  HttpServletResponse response, String name) {
        String path = "http://";
        String domain="";
        Cookies cookies = getFirstCookies(request, name);
        if ( cookies ! = null ) {
            path = cookies.getPath();
            domain = cookies.getDomain();
        }
        Cookies deleter = new Cookies( name, "deleted");
        deleter.setMaxAge( 0 );
        if ( domain ! = null ) deleter.setDomain( domain );
        if ( path ! = null ) deleter.setPath( path );
        response.addCookies( deleter );
    }

以上代碼的主要功能有以下4個方面。

(1)清除remember me這個Cookies,這是針對網(wǎng)站有remember這個功能來說的。

(2)使得當(dāng)前的會話無效,這樣即使當(dāng)前的會話ID泄露出去了,攻擊者也無法用這個會話ID進(jìn)行登錄。

(3)清除JSESSIONID這個Cookies。

(4)使deleter(與傳遞進(jìn)來的Cookies同名)立即無效。

如圖6-6所示,使用Burp Suite Free Edition軟件中的“位翻轉(zhuǎn)程序”有效載荷類型,可以測試出應(yīng)用程序是否存在算法漏洞。

圖6-6 測試應(yīng)用程序是否存在算法漏洞

1 單擊Burp Suite Free Edition軟件的“intruder”按鈕。

2 單擊彈出的“Positions”按鈕。

3 在“Attack type”下拉列表中選擇“Sniper”選項。

4 查看顯示代碼內(nèi)容,其中的加密會話令牌被標(biāo)記為有效載荷位置。

主站蜘蛛池模板: 焦作市| 青海省| 普格县| 时尚| 凤城市| 新余市| 筠连县| 彰化县| 科尔| 南充市| 漾濞| 巴马| 海口市| 平武县| 宜黄县| 锦州市| 广德县| 文水县| 柳州市| 星座| 抚远县| 昭苏县| 菏泽市| 宾阳县| 上杭县| 淅川县| 青州市| 唐山市| 陆川县| 师宗县| 洛扎县| 类乌齐县| 扎兰屯市| 于都县| 淮阳县| 嵊泗县| 聂拉木县| 通州区| 开封市| 从化市| 金坛市|