天天看點

棧溢出筆記1.8 字元串問題

在前面編寫Shellcode的過程中,我們用到的字元串要麼直接使用DB定義,要麼通過PUSH直接壓入棧上(相當于定義局部變量),這樣的話,如果一個Shellcode中的字元串多一點的話,僅字元串就要占用不少空間。而且,在1.7節中,我們在kernel32.dll的導出表中查找函數名稱的時候,有一個字元串比較的過程,要将我們指定的函數名(如LoadLibraryA)與導出表中的函數名比較,這樣一方面我們要儲存需要查找的函數名,另一方面比較字元串占用了比較多的代碼。還有,字元串問題會有前面的NULL位元組的問題。

我們能不能把字元串去掉一些呢?常用的方法是Hash,即将一個字元串算出一個Hash值,然後進行比較,這樣,我們就不需要儲存待查找的函數名,而隻儲存一個Hash值,同樣,比較的代碼也會少一些。當然,效率可能會降低,因為每個字元串都需要算完整的Hash值,而直接比較的話,差别比較大的字元串馬上就可以判斷出來。但在Shellcode中,效率一般不是優先考慮的,優先考慮的是代碼體積,如果能用十幾個位元組能解決問題,就不要用幾十個位元組,因為,有漏洞的程式留給我們可用的空間是有限的,每一個位元組都是寶貴的。而且,代碼量越大,隐蔽性越差,被人發現的機率越大。

那麼需要找一個字元串Hash算法,這個算法至少要保證在一個dll中,所有的函數名算出來的Hash值是唯一的。最常用的是ROR13 Hash算法,這也是Metasploit中使用的算法,它的思想如下:

/*********************************************************/
acc := ;
for c in input_string do    // 對于字元串中的每個字元
acc := ROR(acc, )   // 先将acc循環右移13位
acc := acc+c         // 與目前字元求和
end
/*********************************************************/
           

算法來自:https://www.fireeye.com/blog/threat-research/2012/11/precalculated-string-hashes-reverse-engineering-shellcode.html

這裡隻記錄這樣一個方法,具體實作與上一節大同小異,不過是換掉函數compare_string而已,就不寫代碼了。

實作請看這篇文章:http://www.tophertimzen.com/blog/shellcodeTechniquesCPP/

繼續閱讀