Armis研究人員在施耐德電氣(SE)Modicon PLC中發現了一個新漏洞CVE-2021-22779,該漏洞被稱為ModiPwn,影響Modicon M340、M580以及Modicon系列的其他型號PLC。該漏洞繞過了這些PLC中用來防止濫用未記錄的Modbus命令的安全機制,Armis研究人員發現這些命令可用于接管PLC并獲取設備本地代碼執行權限,攻擊者之后利用代碼可更改PLC的操作,同時對管理PLC的工程工作站隱藏其操作。這是一種未經身份驗證的攻擊,只需要對目標PLC進行網絡訪問。
Armis于2020年11月13日通知SE,此后一直與他們合作以了解潛在問題,并努力開發補丁。2021年7月13日,SE發布了包含緩解措施的安全公告,完全修復這些問題的補丁仍在開發中。
在與SE合作的過程中,Armis研究人員發現并報告了兩個額外的尚未被SE解決的身份驗證繞過技術。由于為Modicon PLC使用的UMAS協議提供支持的Modbus協議存在固有缺陷,Armis將繼續與SE和其他供應商合作解決這些問題。
技術綜述
Armis發現的漏洞CVE-2021-22779是一個身份驗證繞過漏洞,可以與過去在UMAS協議中發現卻只能部分緩解的其他漏洞聯系在一起。Armis研究人員發現雖然這些額外的漏洞被歸類為拒絕服務,它們實際上可以導致本地遠程代碼執行。這些漏洞本質上是UMAS協議中未記錄的命令,Armis研究人員發現,SE并沒有從協議中刪除這些命令(可能是由于遺留的依賴關系),而是在它們周圍添加了一個身份驗證機制來降低它們的風險。不幸的是,這種機制被發現是有問題的,根據最新的發現,需要更加徹底的修復才可以解決這些問題。
由于上述原因,以下CVE仍會影響Modicon M340和M580PLC的最新固件版本:
CVE-2021-22779–通過UMAS命令MemoryBlockRead繞過身份驗證漏洞
CVE-2018-7852–通過UMAS命令PrivateMessage(RCE)解除不受信任的指針引用
CVE-2019-6829–通過UMAS命令WritePhysicalAddress(RCE)進行任意內存寫入
CVE-2020-7537–通過UMAS命令ReadPhysicalAddress讀取任意內存(信息泄漏)
其他Modicon型號目前被認為不易受到攻擊。
要完全理解上述發現的技術細節,需要了解Modbus和UMAS協議的一些背景知識。
Modbus
Modbus是在SCADA系統中控制PLC的實際標準。它于1979年由Modicon首次發布。Modbus是很久以前設計的,缺少現代系統所需的功能,例如二進制對象與PLC之間的傳輸。
Modbus可以通過串行通信或IP通信運行。廣泛使用的Modbus IP版本是Modbus/TCP標準。
圖1 Modbus/TCP頭部
Modicon之后在保留的Modbus功能代碼前提下擴展了Modbus,擴展協議稱為UMAS,它在基本Modbus協議的基礎上增加了身份驗證、二進制數據傳輸、固件更新和其他功能。
UMAS預留機制
Modicon PLC(M340、M580以及其他型號)使用UMAS協議。UMAS重新實現了標準Modbus命令和一些Modbus缺少的必要功能。
圖2 UMAS頭部(包括Modbus功能代碼字段)
對PLC的某些更改需要多個相互依賴的命令,為允許此類情況,Modicon實施了預留機制。創建預留機制是為了同步PLC程序的修改——一種針對某些關鍵更改的全局鎖定機制。一旦工程工作站通過UMAS成功預留PLC,它就會收到一個1字節的令牌,用于對PLC進行修改。不修改PLC的UMAS命令不需要此令牌,并且可以在沒有工作站任何身份驗證的情況下執行。由于一次只有一個工作站可以保留PLC,因此該機制可以保護PLC免受可能導致損壞PLC的重復修改。
預留機制的初始版本通過使用功能代碼為0x10的UMAS命令來工作。此命令不需要身份驗證或質詢-響應握手,并且依賴于PLC和工程工作站上SE管理軟件之間的硬編碼共享敏感信息:
圖3 功能代碼0x10
這種機制使用的硬編碼敏感信息可以在未加密的UMAS流量中觀察到,或者通過對Modicon PLC固件進行逆向工程來定位。
隨著時間的推移,各種未記錄的UMAS命令被證明允許遠程代碼執行或其他惡意意圖。SE決定預留增強機制,因此它不僅可以充當鎖定機制,還可以充當身份驗證機制。預留增強機制基于質詢-響應握手,其中對共享口令口令行身份驗證。
在兩種版本的預留機制中,成功預留后會發送一個1字節令牌作為響應,然后該令牌將被添加到需要身份驗證的UMAS命令之前。
圖4 預留成功后的1字節令牌
身份驗證繞過-CVE-2020-7537
在對預留增強機制的算法進行逆向工程后,研究人員意識到是否可以通過未公開的UMAS命令泄露應用程序口令(或其哈希值)。對M340PLC最新固件(當時)的靜態分析,揭示了一個可疑的UMAS命令:
圖5 pu_ReadPhysicalAddress命令
pu_ReadPhysicalAddress命令拷貝從輸入命令所選擇地址的存儲塊,以響應緩沖。除了緩沖區大小的簡單驗證之外,該函數對從內存中讀取的地址沒有限制。本質上,這個未記錄的命令允許泄漏PLC地址空間中的所有內存。
該命令可用于泄漏存儲在PLC內存中的應用程序口令的哈希值,并用于未經身份驗證的攻擊者預留和管理PLC。
此外,諸如此類的內存讀取命令可用于從PLC泄漏可能與其操作相關的敏感信息。由于此命令讀取的地址沒有限制,攻擊者可以濫用此命令通過讀取某些特定于硬件地址來使設備崩潰,這將導致PLC上的驅動程序與硬件不同步。這可能會導致各種邊緣情況,從而導致拒絕服務。當PLC以這種方式崩潰時,它不能很快恢復正常運行,操作員需要按下一個物理按鈕來重新啟動設備。
此漏洞于2020年11月報告給SE,并在2020年12月的安全公告中披露。SE為解決此問題而引入的補丁將ReadPhysicalAddress命令定義為需要保留的命令,利用該機制來抵御這種攻擊。雖然這確實減輕了這種身份驗證繞過,但它并沒有完全解決這個命令中的風險——因為如果使用的項目文件是無口令的,它仍然可能被觸發。
身份驗證繞過-CVE-2021-22779
為了更好地了解預留增強機制的UMAS消息流,可以使用EcoStruxure軟件連接到PLC并分析它創建的流量。當在EcoStruxure軟件中輸入正確的口令時,會按預期生成一些UMAS命令,但是當輸入的口令不正確時,軟件拒絕了口令,而不會與PLC產生任何流量。這就提出了一個問題——EcoStruxure軟件如何在不與PLC通信的情況下知道口令與否?為了回答這個問題,首先應當分析在輸入口令之前工作站發送的UMAS命令。工作站使用的命令之一是MemoryBlockRead命令,它允許從內存中讀取預配置的塊,無需身份驗證(類似于MemoryBlockWrite命令)。與ReadPhysicalAddress命令不同,塊ID將內存訪問限制為某些固定內存地址。
然而,軟件似乎使用這個命令,pre-reservation,從PLC讀取口令的哈希值,并驗證用戶輸入的口令是否正確。毫無疑問,這種機制從根本上是有缺陷的——口令哈希值通過未加密的協議傳遞,可以被任何未經身份驗證的攻擊者讀取,只需執行內存塊讀取命令。
雖然EcoStruxure軟件使用內存讀取命令來驗證口令哈希,但未經身份驗證的攻擊者可以簡單地使用讀取口令哈希完全繞過預留增強的身份驗證機制。
遠程代碼執行RCE
如上所述,過去發現的兩個未記錄的UMAS命令WritePhysicalAddress(功能代碼0x29,CVE-2019-6829)和PrivateMessage(功能代碼0x6D,CVE-2018-7852),會導致拒絕服務。正如將在下面展示的,這兩個命令實際上還可以導致遠程代碼執行。
任意內存寫入
命令WritePhysicalAddress允許任意寫入PLC內存中的任何地址,并在輸入緩沖區中提供數據緩沖區。雖然在最新的固件版本中,在使用應用程序口令時無法訪問此命令,但如果在繞過預留機制后執行降級攻擊(稍后會詳細介紹),它仍然可以觸發。
這個命令可以通過用任意數據改變內存導致拒絕服務,也可以進行遠程代碼執行。攻擊者利用payload改變其控制地址中的內存可能是RCE最簡單的利用途徑。許多可更改的函數指針、堆棧變量或C++vtable指針駐留在內存中,并將執行狀態從其原始狀態轉移。可以通過ROP技術利用這些來訪問攻擊者控制的代碼。Armis研究人員開發了一個類似的漏洞,當時利用URGENT/11的漏洞在2020年12月的白皮書(第20頁)中被證明會影響Modicon PLC。
遠程過程調用RPC
第二個未記錄的命令–PrivateMessage,它通過訪問輸入緩沖區中提供的指針所指向的C++對象,然后從這些解析對象中觸發回調函數來觸發PLC中的內部函數。目前尚不清楚此特定命令的商業用途是什么,但很明顯,當傳遞的指針未指向PLC內存中的有效C++對象時,它會導致拒絕服務。
將此漏洞轉化為RCE只是稍微復雜一點。C++對象的有效結構可以通過MemoryBlockWrite命令上傳到PLC內存中的已知地址,然后可以發送PrivateMessage命令,觸發對攻擊者控制的C++對象vtable指針內函數的調用。與上面詳述的步驟類似,通過控制程序的PC來獲取攻擊者控制的代碼只是通過幾個ROP小工具連接點的問題。
降級攻擊
施耐德電氣對上面提到的兩個未記錄命令的修復是相似的——在使用應用程序口令時完全禁用它們。但是,當它不使用時,這些命令仍然可以訪問,也許是為了保留與使用這些命令的工具的一些遺留兼容性。
但是,通過利用身份驗證繞過漏洞(例如CVE-2021-22779),攻擊者可以通過上傳未配置口令的新項目文件來降低PLC的安全性。一旦這種降級攻擊完成,攻擊者仍然可以使用上面詳述的未記錄的命令來獲得本機代碼執行。
攻擊步驟如下:
1.使用CVE-2021-22779繞過身份驗證并預留PLC;
2.上傳未配置應用程序口令的新項目文件;
3.釋放PLC預留并斷開與設備的連接;
4.用基本預約方式重新連接PLC,無需口令;
5.通過利用可以到達RCE(WritePhysicalAddress或PrivateMessage)的未記錄命令之一來實現代碼執行。
未來研究
正如上面技術深入探討中所詳述的那樣,很明顯UMAS和Modbus中的潛在設計缺陷暫時仍未修復。雖然正在嘗試加強對某些命令的訪問,但這些設計缺陷給開發人員帶來了重大挑戰——這可能會導致未來出現更多漏洞。除了上面詳述的兩個CVE允許完全繞過預留增強機制之外,還存在兩個暫時尚未修補的額外攻擊場景。
Man-on-the-Side身份驗證繞過
如上所述,當成功預留時,PLC會返回一個1字節的令牌。此令牌稍后用于所有需要預留的命令。如果攻擊者位于網絡中,他能夠查看工程工作站和PLC之間的某些數據包,可以借此向PLC注入TCPRST數據包,這將斷開工作站和PLC之間的ModbusTCP連接。此外,PLC會保留預留令牌的狀態以供重復使用,持續幾秒鐘。如果在那個時間范圍內攻擊者連接到PLC,他可以重用令牌,而無需重新進行身份驗證。這可以通過使用觀察到的令牌(在人為場景中)或簡單地強制使用255個可能的值來實現(PLC將拒絕錯誤的令牌,并且不會在多次嘗試時重置令牌)。
盡管可以使用更長的令牌或通過拒絕蠻力嘗試來部分緩解這種攻擊場景,預留機制的潛在威脅依舊是缺乏加密——這允許攻擊者獲取可用于繞過此身份驗證機制的信息。
中間人身份驗證繞過
不幸的是,PLC還可能面臨一種更簡單直接的攻擊——中間人攻擊。例如,使用ARP欺騙,攻擊者可以在工程工作站和Modicon PLC之間充當中間人角色。
使用此位置,攻擊者可以從工作站伏擊預留嘗試,并獲取合法用戶使用的憑據和/或令牌。雖然在當前的預留機制設計中,口令哈希值是通過MemoryBlockRead命令未加密傳遞的,預計將來不會使用該命令,并且不會以明文形式傳遞UMAS\Modbus連接。然而,由于協議目前沒有辦法檢測到中間人攻擊,簡單地將身份驗證數據包轉發到PLC將允許攻擊者獲得預留令牌,他可以濫用該令牌來運行任何未記錄的可用于更改PLC配置或觸發可能導致RCE的命令。
修復這種中間人身份驗證繞過需要工程工作站和PLC之間的安全連接既能夠加密通信又能夠驗證雙方,驗證連接是否通過中間人傳遞。
最后說明
雖然現在端點中的安全通信被認為是一個已解決的問題,但以類似的方式解決它還是對工業控制器構成了挑戰。在傳統端點中,服務使用證書進行身份驗證,并以安全的方式定義信任根。在工業控制器中,不存在允許驗證證書的用戶界面。在沒有這些方法的情況下創建安全通信需要對控制器進行物理訪問,通過控制器可以在外部與網絡交換密鑰。這將帶來部署挑戰,制造商和供應商似乎還沒有準備好邁出這一步。
不幸的是,如果沒有這種對Modicon PLC通信方式的基本改造,上面詳述的安全風險暫時仍與這些控制器相關。
披露時間表:
2020年11月13日——關于影響Modicon PLC的三個未記錄的UMAS命令的初步報告,這些命令可能導致遠程代碼執行和信息泄漏。
2020年11月21日-SE宣稱2個命令已經修補(CVE-2018-7852,CVE-2019-6829),信息泄漏問題之前已向他們披露,預計將于2020年12月披露(CVE-2020-7537)。
2020年11月25日——Armis發現兩個打補丁的命令沒有正確修復,初始報告中提供的PoC腳本顯示這些PLC在最新軟件中仍然存在漏洞;此外,這些漏洞被確定為拒絕服務,而Armis發現它們實際上可以導致遠程代碼執行。
2021年2月9日——SE聲稱這些PLC的補丁僅在PLC項目上設置了應用程序口令時才有效。
2021年2月25日——Armis發現了應用口令機制的各種繞過技術(預留增強繞過、ARP欺騙、中間人,以及弱令牌)
2021年3月26日——Armis提供了PoC腳本,演示了在未經身份驗證的攻擊中繞過預留增強機制。這種攻擊允許攻擊者執行降級攻擊——取消應用程序口令限制,從而允許訪問可能導致本機代碼執行的未記錄的UMAS命令。
2021年3月31日——SE確認預留增強繞過中存在一個額外的漏洞(CVE-2021-22779),并且它也被另外的3rd方披露給他們。補丁預計將于2021年第四季度發布,SE將在2021年7月13日的公告中提供解決方法。由于設計限制,其他繞過技術(通過ARP欺騙和安全令牌的暴力破解的中間人)仍未打補丁。