检测到基于堆栈的缓冲区溢出_检测到堆栈粉碎
檢測到基于堆棧的緩沖區(qū)溢出
我敢打賭,每個Java開發(fā)人員在他們的職業(yè)生涯開始時第一次遇到Java代碼的本機(jī)方法時都會感到驚訝。
我還可以肯定,多年來隨著了解JVM如何通過JNI處理對本機(jī)實現(xiàn)的調(diào)用而使驚奇消失了。
這篇文章是關(guān)于本機(jī)方法的最新經(jīng)驗。 更詳細(xì)地講,使用本機(jī)方法如何導(dǎo)致JVM靜默崩潰,而日志文件中沒有任何合理的跟蹤。 為了向您介紹經(jīng)驗,我創(chuàng)建了一個小測試用例。
它由一個簡單的Java類組成 ,可計算文件的校驗和。 為了實現(xiàn)Awesome Performance(TM),我決定使用本機(jī)實現(xiàn)來實現(xiàn)校驗和計算部分。 該代碼簡單明了,因此正在運(yùn)行。 您只需要克隆存儲庫并啟動它,類似于以下示例:
$ ./gradlew jarWithNatives $ java -jar build/libs/checksum.jar 123.txt Exiting native method with checksum: 1804289383 Got checksum from native method: 1804289383該代碼似乎按預(yù)期工作。 當(dāng)您發(fā)現(xiàn)自己盯著輸出時使用的輸入文件名略有不同(更長),就會暴露出不太直接的部分:
$ java -jar build/libs/checksum.jar 123456789012.txt Exiting native method with checksum: 1804289383 *** stack smashing detected ***: java terminated因此,本機(jī)方法可以很好地完成其執(zhí)行,但是控件沒有返回給Java。 而是,JVM崩潰而沒有崩潰日志。 您應(yīng)該意識到以下事實:我僅在Linux和Mac OS X上測試了示例,并且在Windows上的行為可能有所不同。
根本的問題不是太復(fù)雜,并且可能在C代碼中立即可見:
char dst_filename[MAX_FILE_NAME_LENGTH]; // cut for brevity sprintf(dst_filename, "%s.digested", src_filename);從上面可以明顯看出,緩沖區(qū)只能容納固定數(shù)量的字符。 輸入較長時,剩余字符將被寫到末尾。 實際上,這將導(dǎo)致堆棧崩潰,并為潛在的黑客攻擊或使應(yīng)用程序處于不可預(yù)測的狀態(tài)打開大門。
對于C開發(fā)人員,底層的堆棧保護(hù)器機(jī)制是眾所周知的,但是對于Java開發(fā)人員,可能需要更多說明。 除了使用更安全的snprintf占用緩沖區(qū)長度并且不會超出該長度之外,還可以要求編譯器向堆棧中添加堆棧保護(hù)器或內(nèi)存清理。 可用的安全網(wǎng)因編譯器而異,甚至在同一編譯器的不同版本之間也存在很大差異,但這是一個示例:
gcc -fstack-protector CheckSumCalculator.c -o CheckSumCalculator.so使用適當(dāng)?shù)亩褩1Wo(hù)器編譯代碼后,運(yùn)行時庫或OS的實現(xiàn)在某些情況下可能會檢測到這種情況,并終止程序以防止意外行為。
如下面的示例所示,在未進(jìn)行清理的情況下編譯代碼時,
gcc -fno-stack-protector CheckSumCalculator.c -o CheckSumCalculator.so運(yùn)行此類代碼的結(jié)果可能變得完全不可預(yù)測。 在某些情況下,代碼可能看起來不錯,但是在某些情況下,您可能會遇到緩沖區(qū)溢出。 盡管在此示例中使用snprintf并啟用清除功能肯定會有所幫助,但該錯誤可能比該錯誤更微妙,并且不會自動捕獲。
回到所謂的安全Java世界,這樣的緩沖區(qū)溢出可能會破壞內(nèi)部JVM結(jié)構(gòu),甚至使提供字符串的任何人都可以執(zhí)行任意代碼。 因此,JVM將保護(hù)值添加到內(nèi)存中,如果在本機(jī)方法完成后對這些值進(jìn)行了修改,則立即終止應(yīng)用程序。 為什么在沒有更詳細(xì)的錯誤日志的情況下完成墮胎是一個不同的問題,不在本文的討論范圍之內(nèi)。
我希望這篇文章在面對突然的JVM死亡甚至沒有崩潰日志時能為某人節(jié)省一整夜的時間。 在所有平臺上甚至都沒有出現(xiàn)標(biāo)準(zhǔn)錯誤流中的“ stack smashed”消息,而且可能需要花費大量時間才能確定發(fā)生了什么情況,尤其是在運(yùn)行沒有源代碼的第三方本機(jī)庫的情況下。
翻譯自: https://www.javacodegeeks.com/2015/09/stack-smashing-detected.html
檢測到基于堆棧的緩沖區(qū)溢出
總結(jié)
以上是生活随笔為你收集整理的检测到基于堆栈的缓冲区溢出_检测到堆栈粉碎的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 台湾拼音电脑键盘对照图(台湾键盘图片)
- 下一篇: 双重for_测试双重图案