題:
除以零是否是安全漏洞?
Gwangmu Lee
2019-03-04 07:15:23 UTC
view on stackexchange narkive permalink

儘管有時將軟件錯誤和漏洞視為同一個概念,但它們之間至少必須有一個不同的方面,我認為最突出的一個是可利用性(後者俱有

我很好奇的是,即使看到很多案例都將除零錯誤報告為軟件問題,我仍然很難提出任何攻擊(除了DoS)使用除零錯誤。我知道並不是所有類型的Bug都會在安全性方面對系統產生相同的影響,但是是否有任何攻擊方法使用除以零的Bug來實現不同於DoS的功能,例如特權升級?

我對多年前的CVE記憶猶新,其核心是除以零,但它是一個遠程根任意代碼錯誤。“大概”有點像約翰·德特斯(John Deters)所描述的,但我記得不夠多,敢冒險給出答案。
我假設您是在談論*整數*除以零?因為IEEE 754浮點除以零是明確定義的,因此應該沒有問題(但是在John Deters的回答方案中適用的部分內容也將在此處適用)。
從這個問題中我得到的另一個結論是,代碼審查應確保在每次除法運算之前都要對分母進行審查。分母為零表示需要研究某種錯誤。
我在一個項目中,我們不得不向用戶報告用戶可控制的零除,這是美國政府的一個重大安全漏洞。用戶可以製作會引起mod 0操作(導致被0除)的數據包。被殺死的是一個入侵防禦系統。因此,您可以在開始攻擊之前用狡猾的包裝將其關閉。當然,這是一個非常奇怪且具體的示例。
@Rob哦,這很有趣。我從沒想過DoS直截了當地打開其他漏洞的情況。
由於類似這樣的事情,有[屏保崩潰](https://www.jwz.org/blog/2015/04/i-told-you-so-again/)的幾種情況,使系統處於解鎖狀態且不受保護
-1
十三 答案:
John Deters
2019-03-04 10:09:31 UTC
view on stackexchange narkive permalink

問題在於將調用異常處理程序來處理除零。通常,攻擊者知道異常處理程序沒有經過常規代碼流的良好測試。您的主要邏輯流程可能很健全且經過了全面測試,但是異常處理程序可以由其範圍內代碼中任何地方發生的中斷觸發。

  int myFunction(int a,int b,SomeState state){state(UNINITIALIZED);嘗試{state.something(a / b);狀態(正常); } catch(){state.something(b / a);狀態(INVERTED); } return retval;}  

這種可怕的偽代碼說明了一種可以利用此缺陷的方式。假設未初始化的狀態易受攻擊。如果調用此例程,則狀態將首先未初始化。如果b為零,它將捕獲異常並嘗試執行其他邏輯。但是,如果a和b都為零,則會再次拋出該狀態,而未初始化狀態。

除以零本身不是漏洞,而是可能被利用的不良代碼。

評論不作進一步討論;此對話已[移至聊天](https://chat.stackexchange.com/rooms/90763/discussion-on-answer-by-john-deters-is-divide-by-zero-a-security-vulnerability)。
Foon
2019-03-04 20:33:24 UTC
view on stackexchange narkive permalink

要添加另一個人為的但基於真實示例的

許多(很多)月球前,我的高中正在運行Novell Netware並對其進行了配置,以使學生無法直接運行dos提示符(如果您例如需要格式化軟盤,這將很煩人。但是,發現如果您輸入的密碼超過X個字符(即僅按住一個鍵一段時間),這將使Netware崩潰並使系統退回到... dos提示符。這很可能是緩衝區溢出,但是原理是一樣的:如果您要處理的系統(尤其是嵌入式系統)通過將您置於維護模式來處理至少一些意外崩潰,則存在安全隱患

帶回美好的回憶...
有一天,我將要講述有關利用某些Apple] [公告牌軟件中的類似缺陷的完整故事。該軟件最初是為整數BASIC編寫的,但無需過多考慮即可移植到浮點BASIC。您只要在任何整數輸入提示下輸入“ 99e999”,就可能導致浮點BASIC崩潰並發生溢出。這將使您進入命令提示符,例如,您可以閱讀您無權訪問的私人電子郵件或論壇。
Josiah
2019-03-04 14:24:40 UTC
view on stackexchange narkive permalink

正如其他答案所暗示的那樣,它完全取決於整個系統。這不僅是代碼,還包括平台,語言和編譯器。

例如,在c ++中,整數除以零是未定義的行為。關於該特定語言的規則之一是編譯器可能會假定未定義的行為將永遠不會發生,並且允許這樣做。

任何事情都包括崩潰,並顯示一條錯誤消息並進行清理,崩潰而不顯示錯誤消息,並使所有內容保持怪異狀態,或者最可怕的嘗試就是好像什麼都沒發生一樣繼續前進。

現在,實際上,大多數優秀的現代編譯器在遇到類似問題時都會嘗試使它們崩潰,但是這應該清楚說明為什麼假設它是一個漏洞。如果您只是使用不同的編譯器或不同的設置來構建代碼,甚至不更改代碼,該程序的工作可能會從徹底崩潰到清除數據庫。

最後一段取決於一個人對“好”的定義。有人會認為編譯器可以優化`if(x!= 0)launch_nuclear_missiles();。通過使函數調用無條件優於無條件調用來返回1 / x;`。我要說的是,高質量的編譯器*被設計為適合涉及不可靠輸入的任務*應該崩潰或不做任何響應以除以零(如果代碼計算`z = y / x;`但從不使用`z`,則完全不應視作完全忽略`x'的編譯器,不應將其視為劣於如果為零的陷阱),但是...
...對於永遠不會涉及不可靠輸入的任務,較寬鬆的語義可能是合理的。
@supercat我認為這需要保證`launch_nuclear_missles`總是返回。
@SolomonUcko:為什麼?如果x為零,則無論該函數是否被調用返回都會被零除。如果x不為零,則該函數可以在不調用UB的情況下返回。
@supercat糟糕,沒關係。缺少花括號和所有內容都在同一行的事實一直讓我感到震驚。
@supercat:“我想說,設計為適合涉及不可靠輸入的任務的高質量編譯器應該崩潰或不響應零除”。編譯器的輸入是程序文本。輸出是一個可執行程序。生成的可執行文件的不可信輸入無法花費時間使編譯器崩潰。至於“什麼也不做”,那通常不能解決問題。在`double x = y / 0`中,省略初始化將使`x`未初始化,從而導致稍後的UB。
@MSalters:在大多數平台上,除非實現無法引起其他行為,否則嘗試加載類型為double的不確定值的嘗試將加載任意值或觸發陷阱,該陷阱的默認行為將導致程序異常終止。同樣,對於大多數形式的UB,除了(IIRC)附件L中被描述為“關鍵的未定義行為”的UB外。儘管附件L的編寫過於精確,以至於沒有真正的含義(要有意義,它應該定義一個行為模型,然後指定非-關鍵UB可能以以下任何方式表現...
...與該模型一致)的概念是,實現應將UB視為逃避責任的藉口*即使底層平台允許實現以較低的成本(在人為場景中通常為零)提供實現的行為保證。C之所以被稱為快速語言,是因為如果在某些特定平台上無需檢查機器代碼中的某些條件就可以滿足程序的要求,那麼程序員和編譯器都不需要進行此類檢查。如果程序員必須包括此類檢查...
...即使在環境自然行為不滿足要求的情況下,也將迫使程序員編寫無法充分利用平台行為來有效處理的代碼。
Jefrey Sobreira Santos
2019-03-05 04:53:16 UTC
view on stackexchange narkive permalink

連同配置錯誤的Web服務器,當導致零除(內部路徑洩漏)時,PHP環境可能會顯示腳本的物理路徑:

  <?php $ denominator = $ _GET ['number']; echo 1 / $ denominator;  

訪問script.php?number = 0,我們可以看到:

警告:在第3行的/var/www/html/script.php中除以零。

可能值得添加的是,您有時可能會使用它來獲取更多詳細錯誤:(“選擇密碼錯誤,登錄名= 1/0時密碼附近Select *”)“詳細錯誤”是一種錯誤配置,但這是一種廉價的處理方法利用它。
那將是配置非常差的PHP安裝。並不是說這樣的安裝不存在。缺省情況下,display_errors長時間未開啟。
Tom
2019-03-04 14:54:38 UTC
view on stackexchange narkive permalink

雖然我有時在講習班和講座中說,軟件中的所有安全問題本質上都是bug,但反之並不能自動成立。

但是,我不會將可利用性作為論據。僅僅因為您和我無法找出一種利用方法,並不意味著一個更狡猾的人就不會有一天。我們將必須提供正式證明,該證明不可利用。

因此,請回答您的問題:除以零的可能是漏洞或漏洞的一部分。 通常會導致異常,從而終止軟件。對於攻擊者而言,這本身可能就是重要的信息(他現在知道某個變量為零)。

僅被零除不太可能構成安全漏洞,但是在更大的背景下,這可能是問題的一部分。

因此,要結束循環,您應始終認真對待所有錯誤。如果您不確定(例如您的部門使用了您無法控制的變量),則需要捕獲並處理它,無論是否安全。 “是的,這是一個錯誤,但我不知道如何利用它”不是一種注重安全性的心態。

“軟件中的所有安全問題本質上都是錯誤”,其中一些是PEBCAK = P
-1
duskwuff -inactive-
2019-03-04 08:26:15 UTC
view on stackexchange narkive permalink

被零除並不是天生的安全漏洞。

但是,如果您可以使應用服務器崩潰並被零除以使其保持脫機狀態,則可能構成拒絕服務漏洞。

問題中已經提到了這一點。
@JAD:似乎有兩個與拒絕攻擊有關的類。一種是提供單個輸入,以使服務器狀態持續受到破壞。二,提供重複輸入,使服務器反复崩潰。這個答案似乎涵蓋了第一種情況(_stay offline_),而問題似乎涵蓋了第二種情況。但是它們絕對是相關的。
在這方面,@jad,的標題和問題不一致。應該可能會更改標題。
基本上,程序中任何可能導致崩潰的錯誤都可能是安全漏洞,而無法防止被零除是此類錯誤的常見現象,但是該原因與其他崩潰原因之間沒有固有的區別。例如,數組越界錯誤同樣危險。
securityOrange
2019-03-04 07:22:09 UTC
view on stackexchange narkive permalink

我認為最終您的答案將歸結為各個系統。系統如何處理試圖除以0的情況?如果情況優美,那麼您的攻擊選擇將有限或不存在。

基本上,沒有標準的攻擊可以發生-我仍然知道-但是計算機總是可以嚴重地處理錯誤。錯誤的處理是許多漏洞的根源。

我對Intel Pentium II CPU的處理方式絕對不滿意。
除零錯誤將出現在應用程序中。如果它降低到CPU級別,則說明您已經遇到問題了。
我知道。當他們從P1 CPU切換到P2 CPU時,英特爾遇到了這個問題。
supercat
2019-03-04 23:20:57 UTC
view on stackexchange narkive permalink

如果程序僅接收可信賴的數據,並且如果在收到惡意製作的數據時它不必滿足任何行為要求,則可能會產生比某些行為更有效的代碼。

由於某些任務只涉及處理可信賴的數據,而另一些任務涉及處理來自不可信賴的數據源的數據,因此C標准允許僅針對前一個任務的實現才能完成

不幸的是,對於那些適合後者的優化,以及適合於後者任務的那些優化,它們提供的保證會不必要地阻礙優化,這些優化在處理前者時可能會有用。

不幸的是,標準沒有提供任何手段來使實現能夠表明它們將提供超出標準規定的行為保證的種類。在編寫C89時,作者期望“市場”比標準的作者能做得更好,因為在標準不加任何規定的情況下,至少通過某種方式可以預測地確定哪種實現應支持哪些“流行擴展”。

給出類似如下的內容:

  if(x!= 0)launch_nuclear_missiles();這樣的態度就不會改變,即使它不再適合當今的編譯器市場。 ...,然後可能在另一個函數中z = y / x;  

有些人會看到一個編譯器,該編譯器用無條件調用 launch_nuclear_missiles()優於僅在 x 為非零時僅調用 launch_nuclear_missiles 的代碼,但這種行為僅在處理永遠不涉及不可靠輸入的任務時才適用。 / p>

如果人們知道一個人正在使用的編譯器,那麼這將順理成章地支持通用編譯器過去提供的那種弱行為保證,並且即使編寫了惡意代碼,也有助於編寫可能滿足弱行為約束的程序,精心設計的輸入,然後除以零可能不會帶來安全漏洞。但是,對於那些不適用於涉及不可靠輸入的任務的激進優化編譯器,有必要添加足夠的安全檢查邏輯以抵消諸如“優化”可能提供的任何優勢。

@PeterCordes:如果x不為零,則該函數可以返回而不會導致UB。如果`x`為零,則UB將發生,無論調用該函數會做什麼。
哦,是的,你是對的。@SolomonUcko's參數不會成立,因為`x = 0'會導致`y / x`運行*不*調用可能不返回的函數,因此可以假定未發生。顯然,這段代碼有一個錯誤,但是是的,某些故障模式比其他故障模式更糟糕。C不是安全的語言。
-1
Sergiy Kolodyazhnyy
2019-03-06 09:35:44 UTC
view on stackexchange narkive permalink

但是有沒有一種攻擊方法使用除零錯誤來實現不同於DoS的功能,例如特權升級?

快速搜索在MITRE的CVE數據庫上將顯示大多數被零除會導致拒絕服務,但是一個特殊情況 CVE-2005-0998允許其他操作:

說明用於PHP-Nuke 7.6的Web_Links模塊允許遠程攻擊者通過無效的show參數獲取敏感信息,該參數將觸發除以零的PHP錯誤,從而洩漏服務器的完整路徑名。

這本身不允許特權升級或特定攻擊,但通常來講,敏感信息在製作其他攻擊時可能很有用。換句話說,被零除本身可能只是一個墊腳石。

ANone
2019-03-04 20:26:08 UTC
view on stackexchange narkive permalink

我知道您來自哪裡。就其本身而言,很難看到僅可以使用算術錯誤來導致需要數據輸入的任何事情(例如代碼執行)。

但是,取決於語言,它可能會導致流控制問題或選擇性地崩潰線程等。這種事情可以讓您加重其他問題,或者如果您真的很(不幸)幸運,則直接導致觸發一條導致雙重利用的途徑。請記住,數據輸入和錯誤不一定必須相同。

這有點做作,但是說,例如,您通過將一個副本添加到鍊錶中來移動一個已經在鍊錶中的對象頭部,然後進行迭代,直到找到它並刪除副本為止。如果您這樣做是在線程中並且由於某種原因(例如有人將stats print語句放入錯誤的迭代循環中),則有可能離開列表處於同一個元素的2個副本的狀態不佳的情況。清理完畢後:double free ...

如果您可以控制此新元素的內容,並且可以使stat結果除以

不太可能,但是有可能。

Erroneous
2019-03-06 04:57:49 UTC
view on stackexchange narkive permalink

該問題最好用“為什麼拒絕服務被認為是安全漏洞?”來表達。在x86處理器上運行Linux時,如果處理器將整數除以0(或最小帶符號整數值除以-1,感謝超級貓),則程序將收到SIGFPE信號。在Windows中,這是非法操作。 C / C ++標準將其視為未定義的行為,這意味著您僅通過查看代碼就無法可靠地知道會發生什麼。

通常,與許多但並非全部的拒絕服務漏洞一樣,這會導致在“崩潰”中。以下是程序異常終止時可以利用的一些可能性:

  • 它可以允許另一個程序使用與第一個程序相同的資源(例如端口),並假裝為同一程序
  • 崩潰可能會規避該程序使用的任何可能被利用的清理操作。
  • 如果該程序的退出代碼正在另一個不檢查信號的程序中使用子進程的PID的狀態,可能會認為程序返回了錯誤代碼。例如,在我的Linux機器上,以下2個程序都將 $?(shell腳本中用於表示前一命令的返回代碼的變量)設置為 136 int main(int argc,char ** argv){return 1 /(argc-1); } int main(){返回136; }
  • 崩潰可能導致諸如核心轉儲之類的事情,其中​​可能包含受保護的內存,例如安全密鑰,密碼和可口可樂的配方。

此外,由於優化,編譯器可能會選擇假定除數永遠不會為0,並可能優化您可能未考慮的代碼。這僅適用於C和C ++之類的已編譯語言,這些語言具有未定義的行為(或等效行為),可以被零除。我無法生成使用clang或gcc的其他答案中的示例來執行此操作的優化代碼,但是並沒有阻止它們或其他編譯器在過去或將來執行此操作的地方。

“崩潰”是否表示安全漏洞取決於執行環境。但是,如果使用瘋狂進取的C實現,則即使行為在C不會崩潰的情況下,其行為不受C Standard強制執行的任何操作也可能導致安全漏洞。
@supercat我試圖根據您的評論改善答案
您應該說,如果在Linux上運行的*機器代碼*嘗試將整數除以零(或將-2147483648的32位整數除以-1),則將引發SIGFPE。嘗試執行這種除法的AC程序可能會在SIGFPE可能造成安全漏洞的情況下,而且在C優化器認為程序的輸入將永遠不會除以零的情況下可能會導致編譯器優化安全性僅在發生此類輸入時才有意義的代碼。
AMADANON Inc.
2019-03-05 03:54:57 UTC
view on stackexchange narkive permalink

這裡是一個可能會有所作為的示例。

它是100%人為設計的-但通過理論上的“人為”示例可以識別許多類別的漏洞利用,直到找到具體示例為止。

p>

它是偽代碼。

  try:如果每個登錄用戶的平均CPU使用率太高,請告訴它,我們正在忙。獲取登錄憑據,如果憑據無效,請驗證登錄憑據,如果有例外,請告訴他們取消對該會話的訪問權限,以限制對此用戶的正確訪問:不執行任何操作,使用戶進入 

In在這種情況下,每個登錄用戶的平均cpu可以計算為“總cpu /登錄用戶數”-如果沒有登錄用戶,則得到“除以0”,並且直接跳至“如果有,是一個例外”子句。這包括限制訪問-新會話可能具有與最後一個用戶匹配的訪問權限,或者無限制訪問。

儘管此示例將所有代碼放在一起,但通常您的主代碼會調用某些內容,而調用某些內容否則,相互作用的兩個方面(在這種情況下,是被0除,並且忽略了異常的事實)可能在代碼中相距很遠的部分中運行。

正如許多人所提到的,除以零(僅靠它本身)並不是安全漏洞,或者根本不是漏洞。據我所知,大多數(也許是所有!)編程語言都清楚地記錄了有關零除的情況。我認為幾乎所有有例外的語言都存在被零除的例外情況(我看到機械計算器陷入了無窮循環)。

symcbean
2019-03-06 18:52:58 UTC
view on stackexchange narkive permalink

這裡有一些非常具體的答案。我同意,(未處理的)除以零的問題主要是功能性問題-但這並不意味著它不能被用作安全性問題。確實,將如此多的錯誤應用於錯誤時,可以將“功能性”與“安全性”的分類視為毫無意義。

您無需討論任何安全性問題(DOS)就可以忽略它。您認為超出範圍的內容。最明顯的情況是,觸發錯誤將導致程序實例停止。但是還有更細微的影響-如果它導致將大量數據寫入文件系統(例如核心轉儲),則會通過填充文件系統為第二種類型的DOS提供一條途徑。

杰弗裡(Jefrey)提到了PHP應用程序的公開信息-但是錯誤消息,日誌和核心轉儲為試圖從不以任何語言編寫的程序訪問其信息的人們提供了豐富的選擇依據。程序終止會導致某種響應,然後攻擊者可以選擇自己的方式來觸發特定程序-他們可以控制系統的工作,從而促進攻擊/特權升級。

即使控制系統是手動的,對於系統來說,仍然存在過渡狀態,其中安全行為的定義不太明確,並且密碼短語,密碼和私鑰等資產正在使用中。



該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 4.0許可。
Loading...