|
網(wǎng)絡(luò)技術(shù)是從1990年代中期發(fā)展起來的新技術(shù),它把互聯(lián)網(wǎng)上分散的資源融為有機(jī)整體,實(shí)現(xiàn)資源的全面共享和有機(jī)協(xié)作,使人們能夠透明地使用資源的整體能力并按需獲取信息。資源包括高性能計(jì)算機(jī)、存儲資源、數(shù)據(jù)資源、信息資源、知識資源、專家資源、大型數(shù)據(jù)庫、網(wǎng)絡(luò)、傳感器等。 當(dāng)前的互聯(lián)網(wǎng)只限于信息共享,網(wǎng)絡(luò)則被認(rèn)為是互聯(lián)網(wǎng)發(fā)展的第三階段。 遵守一些簡單的規(guī)則,可以避免這些問題: 不要使用 access(2) 來判定您是否可以做某件事情;通常攻擊者會在調(diào)用 access(2) 后改變該情形,所以,通過調(diào)用 access(2) 獲得的任何數(shù)據(jù)都可能不再是可信任的。換一種方式,將您的程序的特權(quán)設(shè)置得恰好是您想要的特權(quán)(例如,設(shè)置它的有效 id、文件系統(tǒng) id 或者有效 gid,并通過 setgroups 來清除所有不需要的組);然后調(diào)用 open(2) 直接打開或創(chuàng)建您需要的文件。在類 Unix 系統(tǒng)上,open(2) 調(diào)用是原子的(與以前的 NFS 系統(tǒng)版本 1 和版本 2 不同)。 當(dāng)創(chuàng)建一個新文件時(shí),使用 O_CREAT | O_EXCL 模式打開它(確保只有在創(chuàng)建一個新文件時(shí)調(diào)用 O_EXCL 才會成功)。最初只授與非常有限的權(quán)限;至少禁止任意的用戶修改它!通常,這表示您需要使用 umask 和/或打開參數(shù),將初始的訪問權(quán)限局限于用戶,也可以局限于用戶所在的組。不要嘗試在創(chuàng)建完文件后再去減少權(quán)限,因?yàn)檫@樣做會導(dǎo)致競爭條件。在大部分類 Unix 系統(tǒng)上,只在打開文件時(shí)才檢查權(quán)限,所以,攻擊者可以在權(quán)限位(permission bit)允許時(shí)打開文件,并使該文件一直處于打開狀態(tài),不管權(quán)限如何改變。如果您愿意,還可以在以后將權(quán)限修改得更為開放。您還需要為打開失敗做好準(zhǔn)備。如果您絕對需要能打開某個新文件,那么應(yīng)該創(chuàng)建一個循環(huán):(1)創(chuàng)建一個“隨機(jī)”的文件名,(2)使用 O_CREAT | O_EXCL 選項(xiàng)打開文件, (3)成功打開文件后停止循環(huán)。 當(dāng)對文件的元信息進(jìn)行操作時(shí)(比如修改它的所有者、對文件進(jìn)行統(tǒng)計(jì),或者修改它的權(quán)限位),首先要打開該文件,然后對打開的文件進(jìn)行操作。只要有可能,應(yīng)盡量避免使用獲取文件名的操作,而是使用獲取文件描述符的操作。這意味著要使用 fchown( )、fstat( ) 或 fchmod( ) 系統(tǒng)調(diào)用,而不使用取得文件名的函數(shù),比如 chown()、chgrp() 和 chmod()。這樣做將避免文件在您的程序運(yùn)行時(shí)被替換(一種可能的競爭條件)。例如,如果您關(guān)閉一個文件,然后使用 chmod() 來修改其權(quán)限,那么攻擊者很可能在這兩個步驟之間移動或刪除該文件,并創(chuàng)建指向另一個文件(比如 /etc/passwd)的符號鏈接。 如果您的程序需要遍歷文件系統(tǒng)(遞歸地遍歷子目錄),那么要提防攻擊者可能會利用您正在遍歷的目錄結(jié)構(gòu)。這種情形的一個常見的例子是,運(yùn)行您的程序的管理員、系統(tǒng)程序或者有特權(quán)的服務(wù)器正在遍歷的是由普通用戶控制的文件系統(tǒng)部分。GNU 文件實(shí)用程序(fileutils)可以完成遞歸目錄刪除和目錄移動,但是在版本 4.1 之前,當(dāng)遍歷目錄結(jié)構(gòu)時(shí),它只是簡單的遵循“..”這個特殊條目。當(dāng)文件被刪除時(shí),攻擊者可以將一個低層級的目錄移動到更高的層級;fileutils 將會遵循“..”目錄向上到更高層級,可能會一直到文件系統(tǒng)的根。通過在適當(dāng)?shù)臅r(shí)間刪除目錄,攻擊者可以刪除計(jì)算機(jī)中的任何文件。您不應(yīng)該信任“..”或“.”,如果它們是由攻擊者控制的。 如果可以,不要將文件放置在可以由不信任用戶共享的目錄中。如果不是那樣,那么應(yīng)該盡量不使用在用戶間共享的目錄。不要介意創(chuàng)建只能由受信任的特定進(jìn)程訪問的目錄。 考慮避免使用傳統(tǒng)的共享目錄 /tmp 和 /var/tmp。如果您可以只使用一個管道,將數(shù)據(jù)從一個位置發(fā)送到另一個位置,那么您就可以簡化程序,并排除潛在的安全問題。如果您確實(shí)需要創(chuàng)建一個臨時(shí)文件,那么可以考慮將臨時(shí)文件存儲到其他地方。如果您不是在編寫一個有特權(quán)的程序,那么這點(diǎn)尤其需要考慮;如果您的程序沒有特權(quán),那么將臨時(shí)文件放置在用戶目錄內(nèi)部會更安全一些(處理 root 用戶時(shí)要當(dāng)心,它以“/”作為其主目錄)。這樣,即使您沒有“正確地”創(chuàng)建臨時(shí)文件,攻擊者通常也無法引發(fā)問題(因?yàn)楣粽卟荒芾糜脩糁髂夸浀膬?nèi)容)。 但是,無法總是能夠避免使用共享目錄,所以我們需要理解如何處理 /tmp 等共享目錄。這一點(diǎn)非常復(fù)雜,所以它應(yīng)該自己占用一節(jié)! 共享目錄(比如 /tmp) 共享目錄基本概念 如果您可信任的程序?qū)⒁c潛在的非信任用戶共享一個目錄,那么要特別小心。在類 Unix 系統(tǒng)中,最常見的共享目錄是 /tmp 和 /var/tmp,對這些目錄的錯誤使用滋生了很多安全缺陷。最初創(chuàng)建 /tmp 目錄,是將它作為一個創(chuàng)建臨時(shí)文件的方便位置,通常不應(yīng)該與任何其他人共享臨時(shí)文件。不過,該目錄很快它就有了第二個用途 —— 創(chuàng)建用戶間共享對象的標(biāo)準(zhǔn)位置。由于這些標(biāo)準(zhǔn)目錄有多種用途,使得操作系統(tǒng)難以加強(qiáng)訪問控制來防止攻擊;因此,您必須正確地使用它們,以避免受到攻擊。 當(dāng)您使用共享目錄時(shí),確保目錄和文件有適當(dāng)?shù)臋?quán)限。顯然,您需要限制哪些人可以對共享目錄中創(chuàng)建的文件進(jìn)行讀寫操作。但是,在類 Unix 系統(tǒng)中,如果多個用戶都可以向同一目錄添加文件,而且您計(jì)劃通過一個有特權(quán)的程序向該目錄添加文件,那么要確保為該目錄設(shè)置“sticky”位。在一個普通的目錄中(沒有 sticky 位),任何人對它都有寫權(quán)限 —— 包括攻擊者 —— 可以刪除或者重命名文件,導(dǎo)致各種各樣的問題。例如,一個可信任的程序可以在這樣一個目錄下創(chuàng)建一個文件,而一個不受信任的用戶可以刪除或者重命名它。在類 Unix 系統(tǒng)上,需要設(shè)置共享目錄的 “sticky”位;在 sticky 目錄中,文件只能由 root 或者文件的所有者解除鏈接或者重新命名。/tmp 和 /var/tmp 目錄通常實(shí)現(xiàn)為“sticky”目錄,以排除一些問題。 程序有時(shí)會留下一些沒用的臨時(shí)文件,所以,大部分類 Unix 系統(tǒng)會自動刪除特定目錄 /tmp 和 /var/tmp 下的原有臨時(shí)文件(“tmpwatch”程序可以完成這項(xiàng)任務(wù)),一些程序會“自動”刪除它們所使用的特定臨時(shí)目錄下的文件。這聽起來很方便...只可惜攻擊者可能會讓系統(tǒng)特別繁忙,使活動文件成為舊文件。結(jié)果:系統(tǒng)可能會自動刪除正被使用的文件名稱。然后會發(fā)生什么?攻擊者可能會嘗試創(chuàng)建他們自己的相同名稱的文件,或者至少讓系統(tǒng)創(chuàng)建另一個進(jìn)程,并重新使用相同的文件名稱。結(jié)果:混亂。這類問題叫做“tmpwatch”問題。解決這種問題的方法是,一旦自動創(chuàng)建了一個臨時(shí)文件,就必須始終使用打開該文件時(shí)得到的文件描述符或文件流。永遠(yuǎn)不要重新打開文件或者使用任何以文件為參數(shù)的操作 —— 始終使用文件描述符或者相關(guān)的流,否則,tmpwatch 競爭將引發(fā)一些問題。您甚至無法先創(chuàng)建文件、然后關(guān)閉它、然后再重新打開它,即使權(quán)限已經(jīng)限制了誰可以打開該文件。 攻擊 sticky 目錄以及您創(chuàng)建的文件的受限權(quán)限只是第一步。在運(yùn)行安全程序期間,攻擊者可能會嘗試進(jìn)行插入操作。常見的一種攻擊是,當(dāng)您的程序正在運(yùn)行時(shí),在共享目錄中創(chuàng)建和反創(chuàng)建指向其他一些文件的符號鏈接 —— /etc/passwd 或者 /dev/zero 是常見的目標(biāo)。攻擊者的目標(biāo)是,創(chuàng)造這樣一種情形,即讓安全程序判定某個給定的文件名并不存在,然后,攻擊者就可以創(chuàng)建指向另一個文件的符號鏈接,而后安全程序繼續(xù)執(zhí)行某些操作(但是現(xiàn)在,它打開的實(shí)際上是一個意料之外的文件)。重要的文件經(jīng)常會被這樣破壞或更改。這種做法的另一個變種是,創(chuàng)建和反創(chuàng)建攻擊者可以進(jìn)行寫操作的普通文件,這樣,攻擊者有時(shí)就可以控制有特權(quán)的程序創(chuàng)建的“內(nèi)部”文件。 在這些共享目錄中創(chuàng)建文件時(shí),常遇見的一個問題是,您必須確保您計(jì)劃使用的文件名在創(chuàng)建時(shí)并不存在,然后自動創(chuàng)建該文件。在創(chuàng)建該文件“之前”進(jìn)行檢查沒有用,因?yàn)樵谝呀?jīng)進(jìn)行了檢查但還沒有創(chuàng)建該文件之前,另一個進(jìn)程可以使用該文件名創(chuàng)建出這個文件。使用“不可預(yù)知的”或者“惟一的”文件名也沒有用,因?yàn)楣粽呖梢苑磸?fù)猜測該文件名,直到成功為止。所以,您需要執(zhí)行一個或者創(chuàng)建一個新文件或者失敗的操作 —— 不做其他任何事情。類 Unix 系統(tǒng)可以這樣做,但是您需要知道如何要求系統(tǒng)去做。 網(wǎng)絡(luò)的神奇作用吸引著越來越多的用戶加入其中,正因如此,網(wǎng)絡(luò)的承受能力也面臨著越來越嚴(yán)峻的考驗(yàn)―從硬件上、軟件上、所用標(biāo)準(zhǔn)上......,各項(xiàng)技術(shù)都需要適時(shí)應(yīng)勢,對應(yīng)發(fā)展,這正是網(wǎng)絡(luò)迅速走向進(jìn)步的催化劑。 |
溫馨提示:喜歡本站的話,請收藏一下本站!