整數溢出的概念


1、整數及整數溢出

關於整數的概念,應該說我們在上中學的時候就學過了。這里我們需要了解的是:整數分為無符號和有符號兩類,其中有負符號整數最高位為 1,正整數最高位為 0,無符號整數無此限制;此外,常見的整數類型有 8 位(布爾、單字節字符等)、16 位(短整型、Unicode等)、32 位(整型、長整型)以及 64 位(__int64)等等。對於本文來說,了解這些就基本足夠了。

關於整數溢出,簡而言之,就是往存儲整數的內存單位中存放的數據大於該內存單位所能存儲的最大值,從而導致了溢出。歸根到底,造成整數溢出漏洞的根本原因還是編程人員由於自身疏忽而對整數進行了錯誤操作引起的。

2、導致漏洞的幾種整數誤操作

一般說來,主要有三類整數操作可以導致安全性漏洞,下面列出每類的典型例子:

2.1.無符號整數的下溢和上溢

無符號整數的下溢問題是由於無符號整數不能識別負數所導致的。示例代碼如下:

BOOL fun(size_tcbSize)

{

if(cbSize> 1024)

rerurn FALSE;

char *pBuf = new char[cbSize – 1];

//未對 new 的返回直進行檢查

memset(pBuf, 0x90,cbSize – 1);

……

return TRUE;

}

在上面代碼中,在調用 new 分配內存后,程序未對調用結果的正確性進行檢測。如果cbSize 為 0 的話,則 cbSize – 1 為-1。但是 Memset 中第 3 個參數本身是無符號數,因此會將-1 視為正的 0xffffffff,函數執行之后程序當然就只有崩潰了。無符號整數的上溢問題也不難理解,示例代碼如下:

BOOL fun(char *s1,size_t len1, char *s2,size_t len2)

{

if(len1 + len2 + 1 > 1024)

return FALSE;

charpBuf = new char[len1 + len2 + 1];

if(buf == NULL)

return FALSE;

memcpy(buf, s1, len1);

memcpy(buf + len1, s2, len2); //可能造成程序崩潰

……

return TRUE;

}

本例子中代碼看起來沒什么問題,該檢測的地方也都檢測了。但這段代碼卻可能出現整數上溢問題,len1 和 len2 都是無符號整數,如果 len1 = 8,len2 = 0xffffffff,由於加操作的限制,8+0xffffffff+1 產生的結果是 8。也就是說,new 操作只分配 8 字節的內存,而后面卻要進行長達 0xffffffff 的串拷貝工作,結果肯定也是程序崩潰。

2.2.符號的問題

符號問題可以是多種多樣的,但有幾點是應該注意的:有符號整數之間的比較;有符號整數的運算;無符號整數和有符號整數的對比。這里舉一個典型的例子:

intcopy_something(char *buf,intlen)

{

charszBuf[800];

if(len>sizeof(szBuf)) /* [1] */

{

return -1;

}

return memcpy(szBuf,buf,len); /* [2] */

}

上面代碼的問題在於 memcpy 使用無符號整數作為 len 參數,但是在之前的數據邊界檢測使用了有符號整數。假設提供一個負數的 len,這樣可以繞過[1]的檢測,但是這個值同樣被使用在[2]的 memcpy 函數的參數里面,len 可能被轉換成一個非常大的正整數,導致 kbuf緩沖區后面的數據被重寫,進而使得程序崩潰。

2.3.截斷的問題

截斷問題主要發生在大范圍整數(如 32 位)拷貝給小范圍整數(如 16 位)的時候可能產生的。同樣來看一個例子:

BOOL fun(byte *name, DWORD cbBuf)

{

unsigned short cbCalculatedBufSize = cbBuf;

byte *buf = new byte[cbCalculatedBufSize];

if (buf == NULL)

return FALSE;

memcpy(buf, name,cbBuf);

……

return TRUE;

}

如果 cbBuf 是 0x00010020,又會如何呢?cbCalculatedBufSize 只有 0x20,因為只從0x00010020 復制了低 16 位。因此,僅分配了 0x20 個字節,並且 0x00010020字節復制到新分配的目標緩沖區中。如果整數溢出發生,之后的所有相關操作的結果都將發生變化。與緩沖區溢出不同的是,整數溢出發生時不會馬上發生異常,即使程序執行結果與預期的不同,也很不容易發現問題所在。前面提到,整數溢出在很多時候會導致緩沖區溢出漏洞的發生,包括堆棧溢出和堆溢出。但並不是所有由整數溢出導致的緩沖區溢出都是可以利用的。相反,大多數情況是不能利用的,原因就在於其中涉及到諸如近乎 4G這樣的大內存操作,會發生段錯誤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM