一种被忽视的构造和整数溢出重现
Michael Howard
Secure Windows Initiative
摘要:Michael Howard 研究了一種常常被忽略的代碼構(gòu)造,這種構(gòu)造可能會(huì)導(dǎo)致嚴(yán)重的緩沖區(qū)溢出問題,然后介紹了一種在沒有溢出副作用的情況下執(zhí)行算術(shù)運(yùn)算的替代方法。
談?wù)剺?gòu)造
很奇怪,有如此之多的安全指導(dǎo)文檔提示人們注意危險(xiǎn)的函數(shù)。在 C 和 C++ 中,很少有危險(xiǎn)的函數(shù),不過,有一件事是肯定的,有許多危險(xiǎn)的開發(fā)人員正在使用 C 和 C++。
因此,您可能會(huì)問,“Michael,您究竟要討論什么?”
我得承認(rèn),我聽膩了一些文檔說的所謂某些函數(shù)是危險(xiǎn)的,您應(yīng)該使用更安全的類型來代替它們。例如,“不要使用 strcpy,它是危險(xiǎn)的。您應(yīng)該改用 strncpy,因?yàn)樗前踩摹!睕]有什么比這更遠(yuǎn)離實(shí)際情況的了。有可能使用 strcpy 的代碼是安全的,而調(diào)用 strncpy 的卻是不安全的代碼。
像 strcpy 這樣的函數(shù)是有潛在 危險(xiǎn)的,因?yàn)樵磾?shù)據(jù)比目標(biāo)緩沖區(qū)大,并且它來自不受信任的源。如果源數(shù)據(jù)來自一個(gè)受信任的源,并且在復(fù)制之前經(jīng)過了有效性測試,則調(diào)用 strcpy 就是安全的:
void func(char *p) {const int MAX = 10;char buf[MAX + 1];memset(buf,0,sizeof(buf));if (p && strlen(p) <= MAX) strcpy(buf,p); }信不信由您,我正好要在某處用到這個(gè)例子。有一種常常被忽略的構(gòu)造可能會(huì)導(dǎo)致緩沖區(qū)溢出,它不是函數(shù)調(diào)用。它是這樣的:
while () *d++ = *s++;此處沒有函數(shù)調(diào)用,這是 DCOM 中導(dǎo)致出現(xiàn) Blaster worm 蠕蟲病毒的編碼構(gòu)造。在 Buffer Overrun In RPC Interface Could Allow Code Execution 中,您可以讀到更多關(guān)于此病毒的修復(fù)程序的內(nèi)容。
該代碼如下所示:
HRESULT GetMachineName(WCHAR *pwszPath) {WCHAR wszMachineName[N + 1]) LPWSTR pwszServerName = wszMachineName;while (*pwszPath != L'//' )*pwszServerName++ = *pwszPath++; ... }這里的問題在于,while 循環(huán)是以源字符串中的一些字符為界的。它沒有為目標(biāo)緩沖區(qū)的大小所限制。換句話說,如果源數(shù)據(jù)不受信任,就會(huì)出現(xiàn)緩沖區(qū)溢出。
我編寫了一段簡單的 Perl 腳本來搜索 C 和 C++ 代碼中這些類型的構(gòu)造。請注意,這段腳本標(biāo)記的每個(gè)實(shí)例并不是一個(gè)缺陷,您需要確定是否源數(shù)據(jù)是受信任的。
use strict; use File::Find;my $RECURSE = 1;################################################### foreach(@ARGV) {next if /^-./;if ($RECURSE) {finddepth(/&processFile,Michael Howard
Secure Windows Initiative
摘要:Michael Howard 研究了一種常常被忽略的代碼構(gòu)造,這種構(gòu)造可能會(huì)導(dǎo)致嚴(yán)重的緩沖區(qū)溢出問題,然后介紹了一種在沒有溢出副作用的情況下執(zhí)行算術(shù)運(yùn)算的替代方法。
談?wù)剺?gòu)造
很奇怪,有如此之多的安全指導(dǎo)文檔提示人們注意危險(xiǎn)的函數(shù)。在 C 和 C++ 中,很少有危險(xiǎn)的函數(shù),不過,有一件事是肯定的,有許多危險(xiǎn)的開發(fā)人員正在使用 C 和 C++。
因此,您可能會(huì)問,“Michael,您究竟要討論什么?”
我得承認(rèn),我聽膩了一些文檔說的所謂某些函數(shù)是危險(xiǎn)的,您應(yīng)該使用更安全的類型來代替它們。例如,“不要使用 strcpy,它是危險(xiǎn)的。您應(yīng)該改用 strncpy,因?yàn)樗前踩摹!睕]有什么比這更遠(yuǎn)離實(shí)際情況的了。有可能使用 strcpy 的代碼是安全的,而調(diào)用 strncpy 的卻是不安全的代碼。
像 strcpy 這樣的函數(shù)是有潛在 危險(xiǎn)的,因?yàn)樵磾?shù)據(jù)比目標(biāo)緩沖區(qū)大,并且它來自不受信任的源。如果源數(shù)據(jù)來自一個(gè)受信任的源,并且在復(fù)制之前經(jīng)過了有效性測試,則調(diào)用 strcpy 就是安全的:
void func(char *p) {const int MAX = 10;char buf[MAX + 1];memset(buf,0,sizeof(buf));if (p && strlen(p) <= MAX) strcpy(buf,p); }信不信由您,我正好要在某處用到這個(gè)例子。有一種常常被忽略的構(gòu)造可能會(huì)導(dǎo)致緩沖區(qū)溢出,它不是函數(shù)調(diào)用。它是這樣的:
while () *d++ = *s++;此處沒有函數(shù)調(diào)用,這是 DCOM 中導(dǎo)致出現(xiàn) Blaster worm 蠕蟲病毒的編碼構(gòu)造。在 Buffer Overrun In RPC Interface Could Allow Code Execution 中,您可以讀到更多關(guān)于此病毒的修復(fù)程序的內(nèi)容。
該代碼如下所示:
HRESULT GetMachineName(WCHAR *pwszPath) {WCHAR wszMachineName[N + 1]) LPWSTR pwszServerName = wszMachineName;while (*pwszPath != L'//' )*pwszServerName++ = *pwszPath++; ... }這里的問題在于,while 循環(huán)是以源字符串中的一些字符為界的。它沒有為目標(biāo)緩沖區(qū)的大小所限制。換句話說,如果源數(shù)據(jù)不受信任,就會(huì)出現(xiàn)緩沖區(qū)溢出。
我編寫了一段簡單的 Perl 腳本來搜索 C 和 C++ 代碼中這些類型的構(gòu)造。請注意,這段腳本標(biāo)記的每個(gè)實(shí)例并不是一個(gè)缺陷,您需要確定是否源數(shù)據(jù)是受信任的。
___FCKpd___3注這段腳本只查找 *p++ 構(gòu)造,而不查找 *++p 構(gòu)造。
假定您發(fā)現(xiàn)了一個(gè)缺陷,使代碼更安全的一種方法是限制被復(fù)制的數(shù)據(jù)不大于目標(biāo)緩沖區(qū):
HRESULT GetMachineName(WCHAR *pwszPath) {WCHAR wszMachineName[N + 1]) LPWSTR pwszServerName = wszMachineName;size_t cbMachineName = N;while (*pwszPath != L'//' && --cbMachineName)*pwszServerName++ = *pwszPath++; ... }最后,對不為目標(biāo)緩沖區(qū)的大小所限制的任何內(nèi)存復(fù)制函數(shù)或構(gòu)造都應(yīng)該進(jìn)行嚴(yán)格檢查。
返回頁首關(guān)于整數(shù)溢出的更多介紹
在前面的文章 Reviewing Code for Integer Manipulation Vulnerabilities 中,我討論了與所謂整數(shù)溢出 的簡單數(shù)學(xué)運(yùn)算相關(guān)的安全性缺陷。
最近,作為正在進(jìn)行的可信賴計(jì)算工程系列 (Trustworthy Computing Engineering Series) 的一部分,我給 Microsoft 的工程師做了一次關(guān)于整數(shù)溢出的講座。在講座中,我概述了如何發(fā)現(xiàn)整數(shù)溢出以及如何修復(fù)整數(shù)溢出。讓我感到吃驚的是,我接收到的許多電子郵件都說我的補(bǔ)救方法很好,但是充滿危險(xiǎn)。請?jiān)试S我做一些解釋。
在該專欄中,我提到過的代碼如下所示:
if (A + B > MAX) return -1;應(yīng)該改成這樣:
if (A + B >= A && A + B < MAX) {// cool! }三年前就有人指出,一些人會(huì)看到這段代碼,但是不知道它有什么用,從而可能刪除 A+B >= A 部分,因?yàn)樗雌饋砑儗俣嘤?#xff0c;而現(xiàn)在,整數(shù)溢出又重新出現(xiàn)在您面前。不會(huì)吧!
作為回應(yīng),我寫了下面的頭文件,它的意圖再明白不過了。是的,它看起來像亂碼,但這段亂碼卻是 x86 匯編語言。我之所以使用匯編語言,是因?yàn)樗梢允刮抑苯釉L問 jc 操作數(shù),即按進(jìn)位轉(zhuǎn)移 (jump-on-carry)。換句話說,它檢測數(shù)學(xué)運(yùn)算是否會(huì)導(dǎo)致溢出。
#ifndef _INC_INTOVERFLOW_ #define _INC_INTOVERFLOW_#ifdef _X86_inline bool UAdd(size_t a, size_t b, size_t *r) {__asm {mov eax,dword ptr [a] add eax,dword ptr [b] mov ecx,dword ptr [r] mov dword ptr [ecx],eax jc short j1mov al,1 jmp short j2 j1:#ifdef _DEBUGint 3 #endifxor al,al j2:}; }inline bool UMul(size_t a, size_t b, size_t *r) {__asm {mov eax,dword ptr [a] mul dword ptr [b] mov ecx,dword ptr [r] mov dword ptr [ecx],eax jc short j1mov al,1 jmp short j2 j1:#ifdef _DEBUGint 3 #endifxor al,al j2:}; }inline bool UMulAdd(size_t mul1, size_t mul2, size_t add, size_t *r) {size_t t = 0;if (UMul(mul1,mul2,&t))return UAdd(t,add,r);return false; }#else # error "This code compiles only on 32-bit x86 #endif // _X86_#endif // _INC_INTOVERFLOW_請查看這個(gè)文件,它包括解釋這些函數(shù)的簡單文檔。
返回頁首發(fā)現(xiàn)安全漏洞
雖然花了一點(diǎn)時(shí)間,但是許多人都找到了漏洞。當(dāng)通過比較字符串來做出安全決策時(shí),這種比較就應(yīng)該是區(qū)域性不變的比較或字節(jié)方式的比較。在這個(gè)例子中,我編寫的代碼可能允許訪問土耳其語的敏感數(shù)據(jù),因?yàn)樵谕炼湔Z中,字母“I”有四個(gè)實(shí)例,兩個(gè)小寫字母,兩個(gè)大寫字母。您可以在 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemstringclasscomparetopic5.asp 上閱讀這方面的內(nèi)容。
現(xiàn)在,讓我們轉(zhuǎn)到本月的錯(cuò)誤。這段代碼有什么問題?
void func(char *p) {char buf[10+1];memset(buf,0,sizeof(buf));// limit string to 10 charssprintf(buf,"%10s",p);printf("Hello, %s/n",buf); } 返回頁首一個(gè)小智力游戲
這個(gè)智力游戲?qū)嶋H上與安全性毫無關(guān)系,但是當(dāng)我想到人們?yōu)檎麛?shù)溢出檢測代碼所困擾時(shí),我就把它從我記憶的深處拉了出來。這段代碼有什么用呢?
int a = 0x42; int b = 0x69; a ^= b; b ^= a; a ^= b;這個(gè)游戲的規(guī)則非常簡單,您無法編譯或解釋這段代碼。試著僅僅通過觀察來確定它有什么用。
Michael Howard 是 Microsoft Secure Windows Initiative 組的高級安全程序經(jīng)理,是 Writing Secure Code 的合著者之一,該書的第二版現(xiàn)已發(fā)行。他還是 Designing Secure Web-based Applications for Windows 2000 的主要作者。他致力于確保人們所設(shè)計(jì)、構(gòu)建、測試和記錄的系統(tǒng)符合安全要求。他最喜歡的一句話是“一人之工具,他人之兇器。”
轉(zhuǎn)到原英文頁面
);} else {find(/&processFile,Michael Howard
Secure Windows Initiative
摘要:Michael Howard 研究了一種常常被忽略的代碼構(gòu)造,這種構(gòu)造可能會(huì)導(dǎo)致嚴(yán)重的緩沖區(qū)溢出問題,然后介紹了一種在沒有溢出副作用的情況下執(zhí)行算術(shù)運(yùn)算的替代方法。
談?wù)剺?gòu)造
很奇怪,有如此之多的安全指導(dǎo)文檔提示人們注意危險(xiǎn)的函數(shù)。在 C 和 C++ 中,很少有危險(xiǎn)的函數(shù),不過,有一件事是肯定的,有許多危險(xiǎn)的開發(fā)人員正在使用 C 和 C++。
因此,您可能會(huì)問,“Michael,您究竟要討論什么?”
我得承認(rèn),我聽膩了一些文檔說的所謂某些函數(shù)是危險(xiǎn)的,您應(yīng)該使用更安全的類型來代替它們。例如,“不要使用 strcpy,它是危險(xiǎn)的。您應(yīng)該改用 strncpy,因?yàn)樗前踩摹!睕]有什么比這更遠(yuǎn)離實(shí)際情況的了。有可能使用 strcpy 的代碼是安全的,而調(diào)用 strncpy 的卻是不安全的代碼。
像 strcpy 這樣的函數(shù)是有潛在 危險(xiǎn)的,因?yàn)樵磾?shù)據(jù)比目標(biāo)緩沖區(qū)大,并且它來自不受信任的源。如果源數(shù)據(jù)來自一個(gè)受信任的源,并且在復(fù)制之前經(jīng)過了有效性測試,則調(diào)用 strcpy 就是安全的:
void func(char *p) {const int MAX = 10;char buf[MAX + 1];memset(buf,0,sizeof(buf));if (p && strlen(p) <= MAX) strcpy(buf,p); }信不信由您,我正好要在某處用到這個(gè)例子。有一種常常被忽略的構(gòu)造可能會(huì)導(dǎo)致緩沖區(qū)溢出,它不是函數(shù)調(diào)用。它是這樣的:
while () *d++ = *s++;此處沒有函數(shù)調(diào)用,這是 DCOM 中導(dǎo)致出現(xiàn) Blaster worm 蠕蟲病毒的編碼構(gòu)造。在 Buffer Overrun In RPC Interface Could Allow Code Execution 中,您可以讀到更多關(guān)于此病毒的修復(fù)程序的內(nèi)容。
該代碼如下所示:
HRESULT GetMachineName(WCHAR *pwszPath) {WCHAR wszMachineName[N + 1]) LPWSTR pwszServerName = wszMachineName;while (*pwszPath != L'//' )*pwszServerName++ = *pwszPath++; ... }這里的問題在于,while 循環(huán)是以源字符串中的一些字符為界的。它沒有為目標(biāo)緩沖區(qū)的大小所限制。換句話說,如果源數(shù)據(jù)不受信任,就會(huì)出現(xiàn)緩沖區(qū)溢出。
我編寫了一段簡單的 Perl 腳本來搜索 C 和 C++ 代碼中這些類型的構(gòu)造。請注意,這段腳本標(biāo)記的每個(gè)實(shí)例并不是一個(gè)缺陷,您需要確定是否源數(shù)據(jù)是受信任的。
___FCKpd___3注這段腳本只查找 *p++ 構(gòu)造,而不查找 *++p 構(gòu)造。
假定您發(fā)現(xiàn)了一個(gè)缺陷,使代碼更安全的一種方法是限制被復(fù)制的數(shù)據(jù)不大于目標(biāo)緩沖區(qū):
___FCKpd___4最后,對不為目標(biāo)緩沖區(qū)的大小所限制的任何內(nèi)存復(fù)制函數(shù)或構(gòu)造都應(yīng)該進(jìn)行嚴(yán)格檢查。
返回頁首關(guān)于整數(shù)溢出的更多介紹
在前面的文章 Reviewing Code for Integer Manipulation Vulnerabilities 中,我討論了與所謂整數(shù)溢出 的簡單數(shù)學(xué)運(yùn)算相關(guān)的安全性缺陷。
最近,作為正在進(jìn)行的可信賴計(jì)算工程系列 (Trustworthy Computing Engineering Series) 的一部分,我給 Microsoft 的工程師做了一次關(guān)于整數(shù)溢出的講座。在講座中,我概述了如何發(fā)現(xiàn)整數(shù)溢出以及如何修復(fù)整數(shù)溢出。讓我感到吃驚的是,我接收到的許多電子郵件都說我的補(bǔ)救方法很好,但是充滿危險(xiǎn)。請?jiān)试S我做一些解釋。
在該專欄中,我提到過的代碼如下所示:
___FCKpd___5應(yīng)該改成這樣:
___FCKpd___6三年前就有人指出,一些人會(huì)看到這段代碼,但是不知道它有什么用,從而可能刪除 A+B >= A 部分,因?yàn)樗雌饋砑儗俣嘤?#xff0c;而現(xiàn)在,整數(shù)溢出又重新出現(xiàn)在您面前。不會(huì)吧!
作為回應(yīng),我寫了下面的頭文件,它的意圖再明白不過了。是的,它看起來像亂碼,但這段亂碼卻是 x86 匯編語言。我之所以使用匯編語言,是因?yàn)樗梢允刮抑苯釉L問 jc 操作數(shù),即按進(jìn)位轉(zhuǎn)移 (jump-on-carry)。換句話說,它檢測數(shù)學(xué)運(yùn)算是否會(huì)導(dǎo)致溢出。
___FCKpd___7請查看這個(gè)文件,它包括解釋這些函數(shù)的簡單文檔。
返回頁首發(fā)現(xiàn)安全漏洞
雖然花了一點(diǎn)時(shí)間,但是許多人都找到了漏洞。當(dāng)通過比較字符串來做出安全決策時(shí),這種比較就應(yīng)該是區(qū)域性不變的比較或字節(jié)方式的比較。在這個(gè)例子中,我編寫的代碼可能允許訪問土耳其語的敏感數(shù)據(jù),因?yàn)樵谕炼湔Z中,字母“I”有四個(gè)實(shí)例,兩個(gè)小寫字母,兩個(gè)大寫字母。您可以在 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemstringclasscomparetopic5.asp 上閱讀這方面的內(nèi)容。
現(xiàn)在,讓我們轉(zhuǎn)到本月的錯(cuò)誤。這段代碼有什么問題?
___FCKpd___8返回頁首一個(gè)小智力游戲
這個(gè)智力游戲?qū)嶋H上與安全性毫無關(guān)系,但是當(dāng)我想到人們?yōu)檎麛?shù)溢出檢測代碼所困擾時(shí),我就把它從我記憶的深處拉了出來。這段代碼有什么用呢?
___FCKpd___9 ___FCKpd___10這個(gè)游戲的規(guī)則非常簡單,您無法編譯或解釋這段代碼。試著僅僅通過觀察來確定它有什么用。
Michael Howard 是 Microsoft Secure Windows Initiative 組的高級安全程序經(jīng)理,是 Writing Secure Code 的合著者之一,該書的第二版現(xiàn)已發(fā)行。他還是 Designing Secure Web-based Applications for Windows 2000 的主要作者。他致力于確保人們所設(shè)計(jì)、構(gòu)建、測試和記錄的系統(tǒng)符合安全要求。他最喜歡的一句話是“一人之工具,他人之兇器。”
轉(zhuǎn)到原英文頁面
);} } ################################################### sub processFile {my $FILE;my $filename =Michael Howard
Secure Windows Initiative
摘要:Michael Howard 研究了一種常常被忽略的代碼構(gòu)造,這種構(gòu)造可能會(huì)導(dǎo)致嚴(yán)重的緩沖區(qū)溢出問題,然后介紹了一種在沒有溢出副作用的情況下執(zhí)行算術(shù)運(yùn)算的替代方法。
談?wù)剺?gòu)造
很奇怪,有如此之多的安全指導(dǎo)文檔提示人們注意危險(xiǎn)的函數(shù)。在 C 和 C++ 中,很少有危險(xiǎn)的函數(shù),不過,有一件事是肯定的,有許多危險(xiǎn)的開發(fā)人員正在使用 C 和 C++。
因此,您可能會(huì)問,“Michael,您究竟要討論什么?”
我得承認(rèn),我聽膩了一些文檔說的所謂某些函數(shù)是危險(xiǎn)的,您應(yīng)該使用更安全的類型來代替它們。例如,“不要使用 strcpy,它是危險(xiǎn)的。您應(yīng)該改用 strncpy,因?yàn)樗前踩摹!睕]有什么比這更遠(yuǎn)離實(shí)際情況的了。有可能使用 strcpy 的代碼是安全的,而調(diào)用 strncpy 的卻是不安全的代碼。
像 strcpy 這樣的函數(shù)是有潛在 危險(xiǎn)的,因?yàn)樵磾?shù)據(jù)比目標(biāo)緩沖區(qū)大,并且它來自不受信任的源。如果源數(shù)據(jù)來自一個(gè)受信任的源,并且在復(fù)制之前經(jīng)過了有效性測試,則調(diào)用 strcpy 就是安全的:
void func(char *p) {const int MAX = 10;char buf[MAX + 1];memset(buf,0,sizeof(buf));if (p && strlen(p) <= MAX) strcpy(buf,p); }信不信由您,我正好要在某處用到這個(gè)例子。有一種常常被忽略的構(gòu)造可能會(huì)導(dǎo)致緩沖區(qū)溢出,它不是函數(shù)調(diào)用。它是這樣的:
while () *d++ = *s++;此處沒有函數(shù)調(diào)用,這是 DCOM 中導(dǎo)致出現(xiàn) Blaster worm 蠕蟲病毒的編碼構(gòu)造。在 Buffer Overrun In RPC Interface Could Allow Code Execution 中,您可以讀到更多關(guān)于此病毒的修復(fù)程序的內(nèi)容。
該代碼如下所示:
HRESULT GetMachineName(WCHAR *pwszPath) {WCHAR wszMachineName[N + 1]) LPWSTR pwszServerName = wszMachineName;while (*pwszPath != L'//' )*pwszServerName++ = *pwszPath++; ... }這里的問題在于,while 循環(huán)是以源字符串中的一些字符為界的。它沒有為目標(biāo)緩沖區(qū)的大小所限制。換句話說,如果源數(shù)據(jù)不受信任,就會(huì)出現(xiàn)緩沖區(qū)溢出。
我編寫了一段簡單的 Perl 腳本來搜索 C 和 C++ 代碼中這些類型的構(gòu)造。請注意,這段腳本標(biāo)記的每個(gè)實(shí)例并不是一個(gè)缺陷,您需要確定是否源數(shù)據(jù)是受信任的。
___FCKpd___3注這段腳本只查找 *p++ 構(gòu)造,而不查找 *++p 構(gòu)造。
假定您發(fā)現(xiàn)了一個(gè)缺陷,使代碼更安全的一種方法是限制被復(fù)制的數(shù)據(jù)不大于目標(biāo)緩沖區(qū):
___FCKpd___4最后,對不為目標(biāo)緩沖區(qū)的大小所限制的任何內(nèi)存復(fù)制函數(shù)或構(gòu)造都應(yīng)該進(jìn)行嚴(yán)格檢查。
返回頁首關(guān)于整數(shù)溢出的更多介紹
在前面的文章 Reviewing Code for Integer Manipulation Vulnerabilities 中,我討論了與所謂整數(shù)溢出 的簡單數(shù)學(xué)運(yùn)算相關(guān)的安全性缺陷。
最近,作為正在進(jìn)行的可信賴計(jì)算工程系列 (Trustworthy Computing Engineering Series) 的一部分,我給 Microsoft 的工程師做了一次關(guān)于整數(shù)溢出的講座。在講座中,我概述了如何發(fā)現(xiàn)整數(shù)溢出以及如何修復(fù)整數(shù)溢出。讓我感到吃驚的是,我接收到的許多電子郵件都說我的補(bǔ)救方法很好,但是充滿危險(xiǎn)。請?jiān)试S我做一些解釋。
在該專欄中,我提到過的代碼如下所示:
___FCKpd___5應(yīng)該改成這樣:
___FCKpd___6三年前就有人指出,一些人會(huì)看到這段代碼,但是不知道它有什么用,從而可能刪除 A+B >= A 部分,因?yàn)樗雌饋砑儗俣嘤?#xff0c;而現(xiàn)在,整數(shù)溢出又重新出現(xiàn)在您面前。不會(huì)吧!
作為回應(yīng),我寫了下面的頭文件,它的意圖再明白不過了。是的,它看起來像亂碼,但這段亂碼卻是 x86 匯編語言。我之所以使用匯編語言,是因?yàn)樗梢允刮抑苯釉L問 jc 操作數(shù),即按進(jìn)位轉(zhuǎn)移 (jump-on-carry)。換句話說,它檢測數(shù)學(xué)運(yùn)算是否會(huì)導(dǎo)致溢出。
___FCKpd___7請查看這個(gè)文件,它包括解釋這些函數(shù)的簡單文檔。
返回頁首發(fā)現(xiàn)安全漏洞
雖然花了一點(diǎn)時(shí)間,但是許多人都找到了漏洞。當(dāng)通過比較字符串來做出安全決策時(shí),這種比較就應(yīng)該是區(qū)域性不變的比較或字節(jié)方式的比較。在這個(gè)例子中,我編寫的代碼可能允許訪問土耳其語的敏感數(shù)據(jù),因?yàn)樵谕炼湔Z中,字母“I”有四個(gè)實(shí)例,兩個(gè)小寫字母,兩個(gè)大寫字母。您可以在 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemstringclasscomparetopic5.asp 上閱讀這方面的內(nèi)容。
現(xiàn)在,讓我們轉(zhuǎn)到本月的錯(cuò)誤。這段代碼有什么問題?
___FCKpd___8返回頁首一個(gè)小智力游戲
這個(gè)智力游戲?qū)嶋H上與安全性毫無關(guān)系,但是當(dāng)我想到人們?yōu)檎麛?shù)溢出檢測代碼所困擾時(shí),我就把它從我記憶的深處拉了出來。這段代碼有什么用呢?
___FCKpd___9 ___FCKpd___10這個(gè)游戲的規(guī)則非常簡單,您無法編譯或解釋這段代碼。試著僅僅通過觀察來確定它有什么用。
Michael Howard 是 Microsoft Secure Windows Initiative 組的高級安全程序經(jīng)理,是 Writing Secure Code 的合著者之一,該書的第二版現(xiàn)已發(fā)行。他還是 Designing Secure Web-based Applications for Windows 2000 的主要作者。他致力于確保人們所設(shè)計(jì)、構(gòu)建、測試和記錄的系統(tǒng)符合安全要求。他最喜歡的一句話是“一人之工具,他人之兇器。”
轉(zhuǎn)到原英文頁面
;if (!$RECURSE && ($File::Find::topdir ne $File::Find::dir)) {$File::Find::prune = 1;return;} # Only accept C/C++ and header extensionsreturn if (!(//.[ch](?:pp|xx)?$/i));warn "$!/n" unless open FILE, "<" . $filename;# reset line number$. = 0;while () {chomp;s/^/s+//;s//s+$//;if (//*/w+/+/+/s{0,}=/s{0,}/*/w+/+/+) {print $filename . " " .Michael Howard
Secure Windows Initiative
摘要:Michael Howard 研究了一種常常被忽略的代碼構(gòu)造,這種構(gòu)造可能會(huì)導(dǎo)致嚴(yán)重的緩沖區(qū)溢出問題,然后介紹了一種在沒有溢出副作用的情況下執(zhí)行算術(shù)運(yùn)算的替代方法。
談?wù)剺?gòu)造
很奇怪,有如此之多的安全指導(dǎo)文檔提示人們注意危險(xiǎn)的函數(shù)。在 C 和 C++ 中,很少有危險(xiǎn)的函數(shù),不過,有一件事是肯定的,有許多危險(xiǎn)的開發(fā)人員正在使用 C 和 C++。
因此,您可能會(huì)問,“Michael,您究竟要討論什么?”
我得承認(rèn),我聽膩了一些文檔說的所謂某些函數(shù)是危險(xiǎn)的,您應(yīng)該使用更安全的類型來代替它們。例如,“不要使用 strcpy,它是危險(xiǎn)的。您應(yīng)該改用 strncpy,因?yàn)樗前踩摹!睕]有什么比這更遠(yuǎn)離實(shí)際情況的了。有可能使用 strcpy 的代碼是安全的,而調(diào)用 strncpy 的卻是不安全的代碼。
像 strcpy 這樣的函數(shù)是有潛在 危險(xiǎn)的,因?yàn)樵磾?shù)據(jù)比目標(biāo)緩沖區(qū)大,并且它來自不受信任的源。如果源數(shù)據(jù)來自一個(gè)受信任的源,并且在復(fù)制之前經(jīng)過了有效性測試,則調(diào)用 strcpy 就是安全的:
void func(char *p) {const int MAX = 10;char buf[MAX + 1];memset(buf,0,sizeof(buf));if (p && strlen(p) <= MAX) strcpy(buf,p); }信不信由您,我正好要在某處用到這個(gè)例子。有一種常常被忽略的構(gòu)造可能會(huì)導(dǎo)致緩沖區(qū)溢出,它不是函數(shù)調(diào)用。它是這樣的:
while () *d++ = *s++;此處沒有函數(shù)調(diào)用,這是 DCOM 中導(dǎo)致出現(xiàn) Blaster worm 蠕蟲病毒的編碼構(gòu)造。在 Buffer Overrun In RPC Interface Could Allow Code Execution 中,您可以讀到更多關(guān)于此病毒的修復(fù)程序的內(nèi)容。
該代碼如下所示:
HRESULT GetMachineName(WCHAR *pwszPath) {WCHAR wszMachineName[N + 1]) LPWSTR pwszServerName = wszMachineName;while (*pwszPath != L'//' )*pwszServerName++ = *pwszPath++; ... }這里的問題在于,while 循環(huán)是以源字符串中的一些字符為界的。它沒有為目標(biāo)緩沖區(qū)的大小所限制。換句話說,如果源數(shù)據(jù)不受信任,就會(huì)出現(xiàn)緩沖區(qū)溢出。
我編寫了一段簡單的 Perl 腳本來搜索 C 和 C++ 代碼中這些類型的構(gòu)造。請注意,這段腳本標(biāo)記的每個(gè)實(shí)例并不是一個(gè)缺陷,您需要確定是否源數(shù)據(jù)是受信任的。
___FCKpd___3注這段腳本只查找 *p++ 構(gòu)造,而不查找 *++p 構(gòu)造。
假定您發(fā)現(xiàn)了一個(gè)缺陷,使代碼更安全的一種方法是限制被復(fù)制的數(shù)據(jù)不大于目標(biāo)緩沖區(qū):
___FCKpd___4最后,對不為目標(biāo)緩沖區(qū)的大小所限制的任何內(nèi)存復(fù)制函數(shù)或構(gòu)造都應(yīng)該進(jìn)行嚴(yán)格檢查。
返回頁首關(guān)于整數(shù)溢出的更多介紹
在前面的文章 Reviewing Code for Integer Manipulation Vulnerabilities 中,我討論了與所謂整數(shù)溢出 的簡單數(shù)學(xué)運(yùn)算相關(guān)的安全性缺陷。
最近,作為正在進(jìn)行的可信賴計(jì)算工程系列 (Trustworthy Computing Engineering Series) 的一部分,我給 Microsoft 的工程師做了一次關(guān)于整數(shù)溢出的講座。在講座中,我概述了如何發(fā)現(xiàn)整數(shù)溢出以及如何修復(fù)整數(shù)溢出。讓我感到吃驚的是,我接收到的許多電子郵件都說我的補(bǔ)救方法很好,但是充滿危險(xiǎn)。請?jiān)试S我做一些解釋。
在該專欄中,我提到過的代碼如下所示:
___FCKpd___5應(yīng)該改成這樣:
___FCKpd___6三年前就有人指出,一些人會(huì)看到這段代碼,但是不知道它有什么用,從而可能刪除 A+B >= A 部分,因?yàn)樗雌饋砑儗俣嘤?#xff0c;而現(xiàn)在,整數(shù)溢出又重新出現(xiàn)在您面前。不會(huì)吧!
作為回應(yīng),我寫了下面的頭文件,它的意圖再明白不過了。是的,它看起來像亂碼,但這段亂碼卻是 x86 匯編語言。我之所以使用匯編語言,是因?yàn)樗梢允刮抑苯釉L問 jc 操作數(shù),即按進(jìn)位轉(zhuǎn)移 (jump-on-carry)。換句話說,它檢測數(shù)學(xué)運(yùn)算是否會(huì)導(dǎo)致溢出。
___FCKpd___7請查看這個(gè)文件,它包括解釋這些函數(shù)的簡單文檔。
返回頁首發(fā)現(xiàn)安全漏洞
雖然花了一點(diǎn)時(shí)間,但是許多人都找到了漏洞。當(dāng)通過比較字符串來做出安全決策時(shí),這種比較就應(yīng)該是區(qū)域性不變的比較或字節(jié)方式的比較。在這個(gè)例子中,我編寫的代碼可能允許訪問土耳其語的敏感數(shù)據(jù),因?yàn)樵谕炼湔Z中,字母“I”有四個(gè)實(shí)例,兩個(gè)小寫字母,兩個(gè)大寫字母。您可以在 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemstringclasscomparetopic5.asp 上閱讀這方面的內(nèi)容。
現(xiàn)在,讓我們轉(zhuǎn)到本月的錯(cuò)誤。這段代碼有什么問題?
___FCKpd___8返回頁首一個(gè)小智力游戲
這個(gè)智力游戲?qū)嶋H上與安全性毫無關(guān)系,但是當(dāng)我想到人們?yōu)檎麛?shù)溢出檢測代碼所困擾時(shí),我就把它從我記憶的深處拉了出來。這段代碼有什么用呢?
___FCKpd___9 ___FCKpd___10這個(gè)游戲的規(guī)則非常簡單,您無法編譯或解釋這段代碼。試著僅僅通過觀察來確定它有什么用。
Michael Howard 是 Microsoft Secure Windows Initiative 組的高級安全程序經(jīng)理,是 Writing Secure Code 的合著者之一,該書的第二版現(xiàn)已發(fā)行。他還是 Designing Secure Web-based Applications for Windows 2000 的主要作者。他致力于確保人們所設(shè)計(jì)、構(gòu)建、測試和記錄的系統(tǒng)符合安全要求。他最喜歡的一句話是“一人之工具,他人之兇器。”
轉(zhuǎn)到原英文頁面
. "/n";} }注這段腳本只查找 *p++ 構(gòu)造,而不查找 *++p 構(gòu)造。
假定您發(fā)現(xiàn)了一個(gè)缺陷,使代碼更安全的一種方法是限制被復(fù)制的數(shù)據(jù)不大于目標(biāo)緩沖區(qū):
___FCKpd___4最后,對不為目標(biāo)緩沖區(qū)的大小所限制的任何內(nèi)存復(fù)制函數(shù)或構(gòu)造都應(yīng)該進(jìn)行嚴(yán)格檢查。
返回頁首關(guān)于整數(shù)溢出的更多介紹
在前面的文章 Reviewing Code for Integer Manipulation Vulnerabilities 中,我討論了與所謂整數(shù)溢出 的簡單數(shù)學(xué)運(yùn)算相關(guān)的安全性缺陷。
最近,作為正在進(jìn)行的可信賴計(jì)算工程系列 (Trustworthy Computing Engineering Series) 的一部分,我給 Microsoft 的工程師做了一次關(guān)于整數(shù)溢出的講座。在講座中,我概述了如何發(fā)現(xiàn)整數(shù)溢出以及如何修復(fù)整數(shù)溢出。讓我感到吃驚的是,我接收到的許多電子郵件都說我的補(bǔ)救方法很好,但是充滿危險(xiǎn)。請?jiān)试S我做一些解釋。
在該專欄中,我提到過的代碼如下所示:
___FCKpd___5應(yīng)該改成這樣:
___FCKpd___6三年前就有人指出,一些人會(huì)看到這段代碼,但是不知道它有什么用,從而可能刪除 A+B >= A 部分,因?yàn)樗雌饋砑儗俣嘤?#xff0c;而現(xiàn)在,整數(shù)溢出又重新出現(xiàn)在您面前。不會(huì)吧!
作為回應(yīng),我寫了下面的頭文件,它的意圖再明白不過了。是的,它看起來像亂碼,但這段亂碼卻是 x86 匯編語言。我之所以使用匯編語言,是因?yàn)樗梢允刮抑苯釉L問 jc 操作數(shù),即按進(jìn)位轉(zhuǎn)移 (jump-on-carry)。換句話說,它檢測數(shù)學(xué)運(yùn)算是否會(huì)導(dǎo)致溢出。
___FCKpd___7請查看這個(gè)文件,它包括解釋這些函數(shù)的簡單文檔。
返回頁首發(fā)現(xiàn)安全漏洞
雖然花了一點(diǎn)時(shí)間,但是許多人都找到了漏洞。當(dāng)通過比較字符串來做出安全決策時(shí),這種比較就應(yīng)該是區(qū)域性不變的比較或字節(jié)方式的比較。在這個(gè)例子中,我編寫的代碼可能允許訪問土耳其語的敏感數(shù)據(jù),因?yàn)樵谕炼湔Z中,字母“I”有四個(gè)實(shí)例,兩個(gè)小寫字母,兩個(gè)大寫字母。您可以在 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemstringclasscomparetopic5.asp 上閱讀這方面的內(nèi)容。
現(xiàn)在,讓我們轉(zhuǎn)到本月的錯(cuò)誤。這段代碼有什么問題?
___FCKpd___8 返回頁首一個(gè)小智力游戲
這個(gè)智力游戲?qū)嶋H上與安全性毫無關(guān)系,但是當(dāng)我想到人們?yōu)檎麛?shù)溢出檢測代碼所困擾時(shí),我就把它從我記憶的深處拉了出來。這段代碼有什么用呢?
___FCKpd___9 ___FCKpd___10這個(gè)游戲的規(guī)則非常簡單,您無法編譯或解釋這段代碼。試著僅僅通過觀察來確定它有什么用。
Michael Howard 是 Microsoft Secure Windows Initiative 組的高級安全程序經(jīng)理,是 Writing Secure Code 的合著者之一,該書的第二版現(xiàn)已發(fā)行。他還是 Designing Secure Web-based Applications for Windows 2000 的主要作者。他致力于確保人們所設(shè)計(jì)、構(gòu)建、測試和記錄的系統(tǒng)符合安全要求。他最喜歡的一句話是“一人之工具,他人之兇器。”
轉(zhuǎn)到原英文頁面
總結(jié)
以上是生活随笔為你收集整理的一种被忽视的构造和整数溢出重现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用MatConvNet进行孪生多分支网
- 下一篇: 深度网络模型裁剪和发布正规化