當前位置:
首頁 > 科技 > 一個合格程序猿應該知道的基礎知識—XML注入介紹

一個合格程序猿應該知道的基礎知識—XML注入介紹

(圖片源於網路,侵刪)

ps:竟然有人說我是教小學生的!我就不信小學生能看懂我今天給的東西!

XML,Extensible Markup Language,擴展性標識語言。文件的後綴名為:.xml。就像HTML的作用是顯示數據,XML的作用是傳輸和存儲數據。今天阿姨給你們詳細介紹一下關於XML的知識(敲黑板!文章略長,請仔細閱讀)

1

XML定義

XML由3個部分構成,它們分別是:文檔類型定義(Document Type Definition,DTD),即XML的布局語言;可擴展的樣式語言(Extensible Style Language,XSL),即XML的樣式表語言;以及可擴展鏈接語言(Extensible Link Language,XLL)。

XML:可擴展標記語言,標準通用標記語言的子集,是一種用於標記電子文件使其具有結構性的標記語言。

它被設計用來傳輸和存儲數據(而不是儲存數據),可擴展標記語言是一種很像超文本標記語言的標記語言。設計宗旨是傳輸數據,而不是顯示數據。它的標籤沒有被預定義。你需要自行定義標籤。

它被設計為具有自我描述性,是W3C的推薦標準。是用來傳輸和存儲數據,其焦點是數據的內容。

2


XML作用

XML應用於wed開發的許多方面,最常用的作用就是配置文件和數據讀寫操作。

配置文件

許多應用都將配置數據存儲在各種文件里,比如.INI文件。雖然這樣的文件格式已經使用多年並一直很好用,但是XML還是以更為優秀的方式為應用程序標記配置數據。使用.NET里的類,如XmlDocument和XmlTextReader,將配置數據標記為XML格式,能使其更具可讀性,並能方便地集成到應用系統中去。使用XML配置文件的應用程序能夠方便地處理所需數據,不用象其他應用那樣要經過重新編譯才能修改和維護應用系統。

數據讀寫操作

在真實的世界中,計算機系統和數據使用不兼容的格式來存儲數據。XML 數據以純文本格式進行存儲,因此提供了一種獨立於軟體和硬體的數據存儲方法。這讓創建不同應用程序可以共享的數據變得更加容易通過 XML,可以在不兼容的系統之間輕鬆地交換數據。對開發人員來說,其中一項最費時的挑戰一直是在網際網路上的不兼容系統之間交換數據。由於可以通過各種不兼容的應用程序來讀取數據,以 XML 交換數據降低了這種複雜性。

3


XML格式說明

這裡我們要給對方傳輸一段數據,數據內容是「too young,too simple,sometimes naive」,要將這段話按照屬性拆分為三個數據的話,就是,年齡too young,閱歷too simple,結果sometimes naive。

我們都知道程序不像人,可以體會字面意思,並自動拆分出數據,因此,我們需要幫助程序做拆分,因此出現了各種各樣的數據格式以及拆分方式。比如,可以是這樣的數據為「too young,too simple,sometimes naive」然後按照逗號拆分,第一部分為年齡,第二部分為閱歷,第三部分為結果。

也可以是這樣的數據為「too_young* too_simple*sometimes_naive」從數據開頭開始截取前面十一個字元,去掉號並把下劃線替換為空格作為第一部分,再截取接下來的十一個字元同樣去掉並替換下劃線為空格作為第二部分,最後把剩下的字元同樣去號體會空格作為第三部分。

這兩種方式都可以用來容納數據並能夠被解析,但是不直觀,通用性也不好,而且如果出現超過限定字數的字元串就容納不了,也可能出現數據本身就下劃線字元導致需要做轉義。基於這種情況,出現了xml這種數據格式, 上面的數據用XML表示的話可以是這樣

也可以是這樣

兩種方式都是xml,都很直觀,附帶了對數據的說明,並且具備通用的格式規範可以讓程序做解析。如果用json格式來表示的話,就是下面這樣

其實數據都是一樣的,不同的只是數據的格式而已,同樣的數據,我用xml格式傳給你,你用xml格式解析出三個數據。

4


XML的實體

XML實體分為:參數實體和通用實體兩種。參數實體用在DTD定義中。一般的xml文檔中都使用通用實體。這裡只介紹通用實體。

使用實體之前,必需先聲時,聲明語句位於xml文檔的序言的內部子集中,實體聲明必需使用大寫方式,如: ,ENTITY必需是大寫的。

使用實本時,在實體名稱前面加上 & ,並表在後面加上分號: ;。與HTML中的轉義符類似。在以下xml中:&client;引用了一個實體,&241;引用了一個實體。當xml處理器碰到實體引用時,會使用定義實體時設定的值去代替實體聲時。

如下面的示例,當處理器解析到&client;時, 會使用"Mr.Rufus Xavier Sasperilla"來代替這個&client;在解析後的文本中,是看不到&client;的。

字元實體

字元實體用來代表單個字元。字元實體分為以下三種:

a、預定義字元實體

由XML規範預先定義好了,如 amp 代表&, apos 代表單引號,gt 代表>, 在使用時加上&號,如: & 表示單個字元&, ' 表示單引號。

b、數字字元實體

在前面我們總結實體的作用時,有一條;可以代表無法輸入的字元。這些字元就是使用數字字元實體表示的。我們可以使用某個字元在字符集中的位 置數來表示該字元。 該數字可以使用10進位或16進位的方式表示,在數字前面加上:&# , 比如: ? 16進位的表示:? , 這兩種方式都表示同一個字元。

c、命名字元實體

與數字字元實體類似,只是將數字改為一個更容易記憶的英文標識.

混合內容實體

混合內容實體是xml中使用得最多的實體,它的值不僅限於單個字元,還可以代表不限長度的各種字元塊。混合內容實體分為:內部實體和外部實體

a、內部混合實體

內部混合實體表示該實體在xml文檔內部定義,內部實體常用來代替經常重複的短語,名稱和模板文本。上面的xml示例中,agent實體就是典型。除了agent,clietn, phone 實體都是內部混合實體。

a、外部混合實體

一些實體需要代表大塊的字元,為了便於文件的管理,可以將這些大塊的字元放在其他文件中,這是外部混合實體便發揮作用了。可以在外部文件中定義實體,然後在xml文檔中聲明並使用它。下面是一個例子:

聲明了一個名稱為;「part1"的外部實體,該實體代表的內容處於P1.xml文件中。 part2, part3 也分別代表了 p2.xml, p3.xml 中的內容。

外部混合實體最大的用處是可以將內容太長的xml文檔分成幾個小的xml文檔,便於網路傳輸。

未析實體

未析實體代表不同於xml文檔內容的其他數據,如:二進位數據等等。當xml處理器無法識別該數據時,不會像對待其他實體一樣,去解析它,而是讓它保持原樣。未析實體的定義與外部混合實體的聲明方式類似,只是後面多了個「NDATA」字元和一些數據標識。比如:

5


XML外部實體注入

XXE注入,即XML External Entity,XML外部實體注入。通過 XML 實體,」SYSTEM」關鍵詞導致 XML 解析器可以從本地文件或者遠程 URI 中讀取數據。

所以攻擊者可以通過 XML 實體傳遞自己構造的惡意值,是處理程序解析它。當引用外部實體時,通過構造惡意內容,可導致讀取任意文件、執行系統命令、探測內網埠、攻擊內網網站等危害。下面介紹兩個注入實例:

文件內容和信息泄露

在早前的一個信息泄露的例子中,我們注意到自定義實體可能引用一個外部文件。

這會把文件內容擴展到自定義的&harmless;實體中。由於所有類似的請求都是在本地完成的,這使得該應用有許可權讀取的所有文件內容都可能被泄露。

只要應用的輸出中包含了這個擴展了的實體,攻擊者就可以查看那些文件,包括沒有公開的文件。因這種方式而造成內容泄露的文件是相當有限的,只能是XML文件,和不會造成XML解析錯誤的文件。但是,PHP可以完全忽略這種限制。

PHP允許通過URI訪問PHP wrapper,這是一般文件系統函數,如file_get_contents()、require()、require_once()、file()、和copy()等,接受的協議之一。

PHP wrapper支持一些過濾器,這些過濾器運行在給定的資源上,結果可以通過函數調用返回。在上述例子中,我們對想要讀取的目標文件使用了convert.base-64-encode過濾器。

這意味著,攻擊者通過利用XXE的脆弱性,可以用PHP讀取任何可讀的文件,不論文本格式如何。攻擊者只需用base64將應用輸出解碼,就可以毫無顧忌的分析一大堆非公開文件的內容。

儘管這本身不會直接傷害終端用戶或是應用後台,但是它能讓攻擊者了解目標應用,從而以最小的代價、最低的風險發現應用的其他弱點。

繞過訪問控制

訪問控制可以通過各種方法來實現。由於XXE攻擊是掛在web應用後台的,它無法使用當前用戶會話產生任何影響,但是攻擊者仍然可以藉助從本地伺服器發送請求,來繞過後台訪問控制。我們來看一下下面這個簡單的訪問控制:

這段PHP和無數的類似代碼都用於限制特定PHP文件對本地伺服器的訪問,如 localhost。但是,應用前端的XXE脆弱性,正好為攻擊者提供了繞過訪問控制所需的憑證,因為XML解析器發出的所有HTTP請求都來自localhost。

如果只有本地請求可以查看日誌,攻擊者就可以成功獲取日誌。同樣的思路也適用於只接受本地請求的維護和管理介面。

6


如何抵禦XML外部實體注入

這類攻擊十分「誘人「,但對它的防禦也簡單的出奇。既然DOM、SimpleXML和XMLReader依賴於libxml2,我們可以簡單地利用libxml_disable_entity_loader()函數來禁止外部實體引用。

與此同時,DOCTYPE中預定義的自定義實體卻不會受到影響,因為它們並沒有使用任何需要文件系統操作或發送HTTP請求的外部資源。

在所有涉及通過字元串、文件或者遠程URI來載入XML時,都需要使用這些操作。

當應用程序及其大部分請求都不需要外部實體時,你可以簡單地從全局禁掉外部資源載入。大多數時候,這比找出所有的XML載入實例來逐個操作要更好。記住,許多庫天生自帶XEE脆弱性:

每次需要臨時允許載入外部資源時,載入完後切記再把這裡設為TRUE。例如,在將Docbook XML轉換為HTML時,所使用的XSL樣式就是依賴於外部實體的,這裡需要外部實體,但是是無害的。

但是,libxml2函數絕不是」萬能鑰匙」。我們需要確認,其他用於解析或處理XML的擴展和PHP庫的引用外部實體的功能,都處於關掉狀態。

如果不能通過上述方法來開關外部實體引用,你還可以檢查一下XML文檔是否聲明了DOCTYPE。如果聲明了,同時禁掉了外部實體,則可以簡單地丟棄XML文檔,拒絕可能造成解析器脆弱性的不受信任的XML訪問,同時將這種行為記錄為一次可能的攻擊。

我們需要將這種行為記錄下來,因為除此之外不會有任何系統報錯記錄。可以在日常輸入驗證中進行這項檢查。但是,這種方法並不理想,我們還是強烈建議從源頭上解決外部實體的問題。

同時,值得注意的是,當我們懷疑一段數據有可能是某個攻擊的結果時,最好的方法是丟棄它,而不是繼續使用它。既然它已經表現出了危險,為什麼還要繼續使用它呢?因此,將上述兩個步驟合併起來,我們可以在無法丟棄數據時(例如第三方的庫),通過主動跳過壞數據起到保護作用。

之所以我們更願意完全丟棄這些數據,還因為上文提到過的一個理由:libxml_disable_entity_loader()不會將自定義實體完全禁掉,只有引用外部資源的才會被禁掉。因此這仍有可能導致一個被稱為XML實體擴展的注入攻擊。(未完待續)

以上:就是今天的知識點,大家都看明白了嗎,沒看明白的扣個1,讓阿姨看看誰家孩子這麼bèn~

ps:竟然有人不喜歡玩掃雷,白給你的掃雷外掛不要我就自己私藏嘍~今天還能領,有興趣的去學一學吧!

資料獲取方式還是老規矩

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 安全犀牛 的精彩文章:

懷念那些再也見不到的網站,看了不飆淚算我輸!
越來越囂張的賺錢方法,手機黑卡了解一下?

TAG:安全犀牛 |