六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

一種被出乎意料的構造與整數溢出重現

[摘要]Michael HowardSecure Windows Initiative摘要:Michael Howard 研究了一種常常被忽略的代碼構造,這種構造可能會導致嚴重的緩沖區溢出問題,然后介紹了一種在沒有溢出副作用的情況下執行算術運算的替代方法。談談構造很奇怪,有如此之多的安全指導文檔提示人們注...

Michael Howard
Secure Windows Initiative

摘要:Michael Howard 研究了一種常常被忽略的代碼構造,這種構造可能會導致嚴重的緩沖區溢出問題,然后介紹了一種在沒有溢出副作用的情況下執行算術運算的替代方法。



談談構造
很奇怪,有如此之多的安全指導文檔提示人們注意危險的函數。在 C 和 C++ 中,很少有危險的函數,不過,有一件事是肯定的,有許多危險的開發人員正在使用 C 和 C++。

因此,您可能會問,“Michael,您究竟要討論什么?”

我得承認,我聽膩了一些文檔說的所謂某些函數是危險的,您應該使用更安全的類型來代替它們。例如,“不要使用 strcpy,它是危險的。您應該改用 strncpy,因為它是安全的。”沒有什么比這更遠離實際情況的了。有可能使用 strcpy 的代碼是安全的,而調用 strncpy 的卻是不安全的代碼。

像 strcpy 這樣的函數是有潛在 危險的,因為源數據比目標緩沖區大,并且它來自不受信任的源。如果源數據來自一個受信任的源,并且在復制之前經過了有效性測試,則調用 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);
}

信不信由您,我正好要在某處用到這個例子。有一種常常被忽略的構造可能會導致緩沖區溢出,它不是函數調用。它是這樣的:

while ()
   *d++ = *s++;

此處沒有函數調用,這是 DCOM 中導致出現 Blaster worm 蠕蟲病毒的編碼構造。在 Buffer Overrun In RPC Interface Could Allow Code Execution 中,您可以讀到更多關于此病毒的修復程序的內容。

該代碼如下所示:

HRESULT GetMachineName(WCHAR *pwszPath) {
    WCHAR  wszMachineName[N + 1])
    LPWSTR pwszServerName = wszMachineName;
    while (*pwszPath != L'\\' )
        *pwszServerName++ = *pwszPath++;   
    ...
}

這里的問題在于,while 循環是以源字符串中的一些字符為界的。它沒有為目標緩沖區的大小所限制。換句話說,如果源數據不受信任,就會出現緩沖區溢出。

我編寫了一段簡單的 Perl 腳本來搜索 C 和 C++ 代碼中這些類型的構造。請注意,這段腳本標記的每個實例并不是一個缺陷,您需要確定是否源數據是受信任的。

use strict;
use File::Find;

my $RECURSE = 1;

###################################################
foreach(@ARGV) {
  next if /^-./;
  if ($RECURSE) {
      finddepth(\&processFile,$_);
  } else {
      find(\&processFile,$_);
  }
}
###################################################
sub processFile {
  my $FILE;
  my $filename = $_;
  
  if (!$RECURSE && ($File::Find::topdir ne $File::Find::dir)) {
    $File::Find::prune = 1;
    return;
  }
  
  # Only accept C/C++ and header extensions
  return 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 . " " . $_ . "\n";
  }
}

注這段腳本只查找 *p++ 構造,而不查找 *++p 構造。

假定您發現了一個缺陷,使代碼更安全的一種方法是限制被復制的數據不大于目標緩沖區:

HRESULT GetMachineName(WCHAR *pwszPath) {
    WCHAR  wszMachineName[N + 1])
    LPWSTR pwszServerName = wszMachineName;

    size_t cbMachineName = N;
    while (*pwszPath != L'\\' && --cbMachineName)
        *pwszServerName++ = *pwszPath++;   
    ...
}

最后,對不為目標緩沖區的大小所限制的任何內存復制函數或構造都應該進行嚴格檢查。

返回頁首
關于整數溢出的更多介紹
在前面的文章 Reviewing Code for Integer Manipulation Vulnerabilities 中,我討論了與所謂整數溢出 的簡單數學運算相關的安全性缺陷。

最近,作為正在進行的可信賴計算工程系列 (Trustworthy Computing Engineering Series) 的一部分,我給 Microsoft 的工程師做了一次關于整數溢出的講座。在講座中,我概述了如何發現整數溢出以及如何修復整數溢出。讓我感到吃驚的是,我接收到的許多電子郵件都說我的補救方法很好,但是充滿危險。請允許我做一些解釋。

在該專欄中,我提到過的代碼如下所示:

if (A + B > MAX) return -1;

應該改成這樣:

if (A + B >= A && A + B < MAX) {
   // cool!
}

三年前就有人指出,一些人會看到這段代碼,但是不知道它有什么用,從而可能刪除 A+B >= A 部分,因為它看起來純屬多余,而現在,整數溢出又重新出現在您面前。不會吧!

作為回應,我寫了下面的頭文件,它的意圖再明白不過了。是的,它看起來像亂碼,但這段亂碼卻是 x86 匯編語言。我之所以使用匯編語言,是因為它可以使我直接訪問 jc 操作數,即按進位轉移 (jump-on-carry)。換句話說,它檢測數學運算是否會導致溢出。

#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 j1
      mov         al,1
      jmp         short j2
j1:

#ifdef _DEBUG
      int         3
#endif
      xor         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 j1
      mov         al,1
      jmp         short j2
j1:

#ifdef _DEBUG
      int         3
#endif
      xor         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_

請查看這個文件,它包括解釋這些函數的簡單文檔。

返回頁首
發現安全漏洞
雖然花了一點時間,但是許多人都找到了漏洞。當通過比較字符串來做出安全決策時,這種比較就應該是區域性不變的比較或字節方式的比較。在這個例子中,我編寫的代碼可能允許訪問土耳其語的敏感數據,因為在土耳其語中,字母“I”有四個實例,兩個小寫字母,兩個大寫字母。您可以在 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemstringclasscomparetopic5.asp 上閱讀這方面的內容。

現在,讓我們轉到本月的錯誤。這段代碼有什么問題?

void func(char *p) {
   char buf[10+1];
   memset(buf,0,sizeof(buf));
   
   // limit string to 10 chars
   sprintf(buf,"%10s",p);
   printf("Hello, %s\n",buf);
}

返回頁首
一個小智力游戲
這個智力游戲實際上與安全性毫無關系,但是當我想到人們為整數溢出檢測代碼所困擾時,我就把它從我記憶的深處拉了出來。這段代碼有什么用呢?

int a = 0x42;
int b = 0x69;

a ^= b;
b ^= a;
a ^= b;

這個游戲的規則非常簡單,您無法編譯或解釋這段代碼。試著僅僅通過觀察來確定它有什么用。

Michael Howard 是 Microsoft Secure Windows Initiative 組的高級安全程序經理,是 Writing Secure Code 的合著者之一,該書的第二版現已發行。他還是 Designing Secure Web-based Applications for Windows 2000 的主要作者。他致力于確保人們所設計、構建、測試和記錄的系統符合安全要求。他最喜歡的一句話是“一人之工具,他人之兇器。”


主站蜘蛛池模板: 天天射视频 | 青青青国产色视频在线观看 | 中文字幕第二区 | 手机看片日韩国产一区二区 | 亚洲五月婷| 亚洲福利区 | 欧美伊人久久久久久久久影院 | 污污小视频在线观看 | 青娱乐国产在线 | 视频在线观看h | 亚洲成a | 欧美香蕉视频在线观看 | 亚洲精品在线看 | 四虎影院免费观看视频 | 欧美在线视频免费看 | 四虎国产永久在线精品免费观看 | 五月天婷婷免费观看视频在线 | 亚洲最大免费视频网 | 亚洲天堂婷婷 | 日本高清不卡在线 | 手机看片久久国产免费不卡 | 日韩欧美国产一区二区三区 | 素人天堂 | 日本在线视频二区 | 五月婷婷 六月丁香 | 日韩免费高清 | 视频一区二区不卡 | 欧美无遮挡国产欧美另类 | 亚洲图区综合网 | 亚洲成a人伦理 | 午夜伊人 | 亚洲欧美香蕉在线日韩精选 | 伊人色影院 | 午夜黄大色黄大片美女图片 | 亚欧精品一区二区三区四区 | 四虎影院成人在线观看 | 色吊丝国产永久免费网址 | 亚洲视频在线看 | 在线免费观看a视频 | 人人鲁免费播放视频人人香蕉 | 伊人www|