Git嚴重漏洞,遠端執行程式碼,Mac和Windows通殺!

不得了了,家人們!
就在這幾天,Git爆出了一個嚴重漏洞,編號CVE-2024-32002,一個可以遠端執行程式碼的RCE漏洞!
攻擊者精心準備一個Git專案,只要你嘗試去Clone它,你的電腦就能執行攻擊程式碼淪陷。
比如下面這個GitHub上面的專案:
你可以執行一下下面的命令:
git clone –recursive [email protected]:amalmurali47/git_rce.git
不出意外的話,你的電腦將會彈出計算器程式:
能讓你彈計算器,就能執行其他更危險的操作,比如給你種木馬等等。
Git是我們程式設計師基本離不開的工具,這波漏洞操作,屬實是對程式設計師定向打擊了。
接下來我們來理一理這個漏洞的工作原理是怎麼樣的。
在介紹攻擊原理之前,得先來了解幾個東西。

1、Git 鉤子

在Git裡面有一個HOOK的機制,就是鉤子的意思。不過這個HOOK不是咱們二進位制安全攻擊中的那個HOOK。
Git中的鉤子是一些指令碼,這些指令碼在Git的特定事件發生時自動執行。鉤子允許你在Git操作的不同階段執行自定義操作,如程式碼格式化、測試執行、通知傳送等。
Git 設計 hooks(鉤子)的初衷是為了讓使用者能夠在特定的 Git 事件發生時自動執行自定義指令碼或操作。這些鉤子提供了一種機制,可以在 Git 操作的各個階段插入使用者自定義的邏輯,以便實現更強大的自動化和定製化流程。
Git鉤子分為服務端和客戶端鉤子,在咱們程式設計師使用的Git客戶端中,有下面這幾個鉤子:
  • pre-commit:在提交之前執行。可以用來檢查程式碼格式、執行單元測試等。
  • prepare-commit-msg:在提交資訊編輯器開啟之前執行。可以用來自動生成提交訊息模板。
  • commit-msg:在提交資訊編輯器關閉之後執行。可以用來驗證提交訊息的格式。
  • post-commit:在提交完成之後執行。可以用來發送通知或執行其他後續任務。
  • pre-rebase:在變基操作之前執行。可以用來檢查變基前的狀態。
  • post-checkout:在 git checkout 命令執行之後執行。可以用來設定特定檔案的狀態。
  • post-merge:在合併操作完成之後執行。可以用來重新編譯專案或執行其他合併後的任務。
那這些鉤子指令碼是存放在哪裡的呢?就是在那個神秘的.git目錄下。
大家可以去看一下自己電腦上,不管是從GitHub克隆的專案,還是從公司的git伺服器克隆的專案,你們的程式碼目錄下,都有一個叫.git的資料夾,它的目錄結構大致是下面這樣的:
當我們建立一個新的Git專案時,執行完git init後,git就會為我們建立一個.git目錄。
而我們剛才說的鉤子指令碼,就放在.git/hooks裡面,git預設為我們提供了一些鉤子指令碼的示例。
你可以在這裡面新增一些自己的指令碼程式,這樣當你在執行對應的git命令操作時,對應的指令碼程式就會得到執行。
要注意,.git目錄下的內容,是git程式自己在維護,不會受到Git專案裡的內容的影響。你在上傳程式碼的時候,.git目錄也不會被傳到伺服器上去。
所以,正常情況下,你從伺服器克隆一個專案的時候,只是把專案拉到本地,不用擔心執行惡意的HOOK指令碼,因為.git目錄是你本地的git客戶端程式建立的,除非你手動去把鉤子指令碼放到裡面去,否則裡面是不會有惡意鉤子指令碼的。
但是,我要說但是了,這一次漏洞的操作就很騷,騷在哪裡呢?騷就騷在,它巧妙的利用了一個特性,把攻擊指令碼給寫到.git目錄下面去了!
這是怎麼辦到的呢?這需要了解另一個Git的知識。

2、子模組

子模組是巢狀在一個 Git 倉庫中的另一個 Git 倉庫,可以讓你在一個專案中包含其他專案,比如某個開源專案要依賴於其他的開源專案。
在這種情況下,主專案下面會存在一個.gitmodules檔案,裡面會記錄該專案包含的其他Git專案的資訊。
其中,path指定子模組存放的位置,url指定子模組的Git倉庫地址。
我們在執行git clone克隆專案的時候,如果指定了一個遞迴的引數:--recursive,就會在拉取主專案之後,然後根據這個檔案中的內容,遞迴的去拉取所依賴的其他子模組,然後放到對應的檔案目錄位置。
不僅主專案有一個.git目錄來記錄專案相關的資訊,子模組也有。你去上面這個path目錄下去看,會發現這裡也有一個.git,不過這個.git不是一個資料夾,而是一個檔案,裡面記錄了這個子模組對應的真正的.git目錄的位置。
這個位置一般在主專案.git目錄下的modules資料夾下面。

3、符號連結

接下來了解與這個漏洞相關的第三個知識點:符號連結。
在 Git 中,符號連結(symbolic link,簡稱 symlink)是指向另一個檔案或目錄的特殊型別的檔案。符號連結本身不包含檔案的內容,而是包含指向目標檔案或目錄的路徑。當訪問符號連結時,系統會自動重定向到其指向的目標。
簡單理解的話,這玩意兒有點像快捷方式。

4、漏洞成因

好了,瞭解了上面這些知識背景,接下來,就要說說這個漏洞的成因了。
剛才說過,鉤子指令碼位於.git目錄中,而這個目錄是與專案本身的內容無關的,它的內容是git客戶端在維護,除非你手動放置指令碼程式到hooks目錄中,否則專案中的內容是不會跑到.git目錄中的。
而這次漏洞就採用了一個騷操作:
攻擊者準備一個Git專案,在這個Git專案中,又依賴一個子專案。當採用--recursive引數的時候,遞迴去拉取對應的子專案,放到對應的位置。
就像上面這樣,它指示git,把url中的專案拉下來放到A/modules/x目錄中。
然後騷操作來了:在這個專案下,有一個名字叫a的符號連結,並且讓它指向了.git目錄。
因為Windows和Mac平臺的檔案和目錄名稱是大小寫不敏感,注意這點很重要,導致在放置子模組到A/modules/x的時候,實際上就是放到了.git/modules/x目錄下去了。
Git專案內容寫到.git目錄下了!事情就出在這裡了!.git目錄是git程式的私家花園,被專案內容闖了進來!
你可能會問,一定要大小寫不一樣嗎,我直接在.gitmodules檔案裡面指定讓它寫到小寫的a/modules/x路徑下不行嗎?
還真不行,我試過了,git直接報錯了:
看來,git基本的檢查工作還是做了的,只是疏漏了大小寫不一樣的情況。
繼續我們剛剛的分析,.git目錄這個git程式的私家花園,被人給闖進來了。
而且關鍵是它闖進來的位置是在.git/modules/x下面,前面說過,這個目錄下面,是子模組所屬的.git目錄,然後這個闖進來的傢伙,還按照.git目錄的結構,裡面放置一個hooks資料夾,裡面放上相關的鉤子指令碼,等下git clone完成的時候,就會去執行這裡的指令碼程式了。
克隆完成之後的整個目錄結構變成了這樣:
我用procmon抓了一下執行下面這條克隆命令到彈出計算器程序中間的過程
git clone –recursive [email protected]:amalmurali47/git_rce.git
大家從程序的父子關係樹和程序的命令列引數,就能看到這條攻擊鏈路了:
最後總結一下:
1、攻擊者精心構造了一個Git專案,這個專案依賴一個子專案,並且指定了這個子專案儲存的路徑為A。
2、在這個Git專案下,有一個名為a的符號連結,指向了.git目錄。
3、子專案裡面構造了一個hooks目錄,攻擊指令碼存放在裡面。
4、最後,遞迴克隆專案的時候,因為目錄大小寫不敏感的原因,子專案實際上被寫到了.git目錄下。
5、相關的克隆動作,觸發了post-checkout鉤子的執行,而現在的hooks目錄下,被寫入了攻擊者的惡意鉤子指令碼,於是就執行了這個惡意指令碼。
Windows:
Mac:
以上就是本次漏洞的大致過程了。
本次漏洞受影響的版本有:
  • v2.45.0
  • v2.44.0
  • <=v2.43.3
  • <=v2.42.1
  • v2.41.0
  • <=v2.40.1
  • <=v2.39.3
趕緊來執行git –version看看你的版本有沒有在上面的範圍裡,是的話趕緊升個級吧!
溫馨提示:陌生人發來的Git專案連結,不要隨意去克隆,小心被攻擊哦~

·················END·················


相關文章