緩沖區溢出:
前提:
一般發生在C這種需手工管理內存的語言編寫的程序中
原理:
進程分控制層面和數據層面兩個部分,每個部分各占一部分內存。
當程序沒有對數據層面內存大小做限制時,輸入一個超過數據內存大小的數據就會發生數據層面的數據把控制層面內存覆蓋的情況,此時如果在數據尾部加上一些操作系統指令就會把該指令加載到控制層面
內存(即寄存器)當中去,當CPU執行下一個控制層面內存里的內容時就會加載該惡意指令。 (注:寄存器中的EIP為CPU要執行的下一條指令的內存地址)
思路:
對存在緩沖區溢出程序輸入1000個A,假如第900至904個A溢出到了寄存器中的EIP(CPU要執行的下一條指令的內存地址,注意EIP存儲的是一個16進制的內存地址。它本屬於控制層面的內存空間),那也就意味着只要將第900到904位置的數值替換為一個存放有shellcode的內存地址就可以拿下該主機。
然后測試發現從第905個位置往后的數據都放入寄存器ESP中,那么也就意味着可以將第905個位置往后的數據替換為shellcode,再將900到904位置的數據替換為ESP的內存地址。
注意:但是由於目標程序每次啟動占用內存位置的不同,ESP的內存地址也就每次都不同,所以EIP想要直接指定ESP內存地址基本不可能。
解決方法:找一個每次占用內存地址都一樣且擁有“JMP ESP”的系統進程,將EIP指向這個進程中“JMP ESP”的內存地址,然后再跳到ESP。通過這種間接跳轉的方式最終跳到ESP。
思考:
1、為什么數據層面內存中的系統指令不會被執行
(猜:應該是軟件對數據層面做了限制,規定數據層面的內容只能當數據使用。如果沒有該規定則該程序此處就是命令注入或者SQL注入漏洞了。也就是說緩沖區溢出是在沒有命令注入漏洞的基礎上更深一步的漏洞)
2、為什么數據內存占滿后剩下的數據會寫入寄存器中的EIP和ESP中?
(猜:寄存器中的數據存放是有嚴格順序的,每次都是EIP、ESP、數據內存這樣循環執行。所以可以推測只要是緩沖區溢出問題就都會先溢出到EIP和ESP內)