国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > PHP > 正文

PHP-5.3.9遠程執行任意代碼漏洞

2024-05-04 21:48:20
字體:
來源:轉載
供稿:網友

還記得我之前說的PHP Hash Collisions Ddos漏洞吧? 最初的時候,開發組給出的修復方案,采用的是如果超過max_input_vars,就報錯(E_ERROR),繼而導致PHP出錯結束,而后來,為了更加輕量級的解決這個問題,我們又改善了一下,變成了如果超過max_input_vars,就發出警告(E_WARNING),并且不再往目的數組添加,但是流程繼續,然后我們發布了5.3.9.

這個新的修復方法初衷是好的,但是卻帶來一個嚴重的問題(5.3.10中已經修復),這個問題最初是由Stefan Esser發現的,請看之前(5.3.9)最終的修復方案(php_register_variable_ex),代碼如下:

  1. while (1) { 
  2.  
  3.      if (zend_symtable_find(symtable1, escaped_index, index_len + 1, (void **) &gpc_element_p) == FAILURE 
  4.  
  5.           || Z_TYPE_PP(gpc_element_p) != IS_ARRAY) { //(3) 
  6.  
  7.           if (zend_hash_num_elements(symtable1) <= PG(max_input_vars)) { // (4) 
  8.  
  9.                if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) { 
  10.  
  11.                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. ...", PG(max_input_vars)); // (1) 
  12.  
  13.                } 
  14.  
  15.                MAKE_STD_ZVAL(gpc_element); 
  16.  
  17.                array_init(gpc_element); 
  18.  
  19.                zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); 
  20.  
  21.           } 
  22.  
  23.           //...... 
  24.  
  25.      } 
  26.  
  27.      //..... 
  28.  
  29.      symtable1 = Z_ARRVAL_PP(gpc_element_p); // (2) 
  30.      //開源代碼Vevb.com 
  31.      goto plain; 
  32.  
  33. }< li> 

注意到,如果此時注冊一個數組變量(在GET中類似于:a[]=2),并且此時這個變量剛好是第max_input_vars個變量的時候,會觸發一個警告(1),此時一切正常.

但是,如果此時還是注冊一個數組變量,但是這個變量已經是第max_input_vars + 1個變量的時候,那么此時gpc_element_p將成為一個未初始化的指針,而因為現在邏輯會繼續走, 也就會走到(2)號位置, 導致解引用了一個未初始化的指針,于是,Boomb~

那么,到目前位置,我們就可以使用這樣的特性來對5.3.9做Ddos了,如果Server開啟了Core Dump的話,這個效果會非常明顯.

然而,這個問題還會導致一個更嚴重的問題:

還是上面的代碼,在最外層有一個循環,這個循環起作用的時刻在注冊類似于a[b]=2的pair對的時候,循環將會執行倆次,第一次插入a[],第二次往a[]中插入b.然后再讓我們注意下(3),如果在目的數組中找不到一個想要的元素,**或者這個元素不為數組**,則也會直接導致流程留到(2),于是問題就出現了.

對于這樣的POST串(默認max_input_vars是1000):

1=1&1=2&..........&999=1&x="我是惡意的string"&x[0]=

會發生什么事情呢?讓我來一步一步描述下:

1.從1到999沒什么問題, 都被正常插入

2.x是1000個元素, 所以觸發警告, 也沒有問題, x被插入

3.x[0]插入的時候,(3)號語句判斷發現不是Arrary于是進入if體,但是此時(4)號語句失敗, 于是流程最終流到了(2)

4.此時,gpc_element_p指向x,也就是那個我們偽造的字符串….現在讓我們看看關鍵的數據結構,zval,代碼如下:

  1. struct _zval_struct { 
  2.  
  3.     /* Variable information */ 
  4.  
  5.     zvalue_value value; /* value */ 
  6.  
  7.     zend_uint refcount__gc; 
  8.  
  9.     zend_uchar type; /* active type */ 
  10.  
  11.     zend_uchar is_ref__gc; 
  12.  
  13. };< li> 

然后看zvalue_value,代碼如下:

  1. typedef union _zvalue_value { 
  2.  
  3.     long lval; /* long value */ 
  4.  
  5.     double dval; /* double value */ 
  6.  
  7.     struct { 
  8.  
  9.         char *val; 
  10.  
  11.         int len; 
  12.  
  13.     } str; 
  14.  
  15.     HashTable *ht; /* hash table value */ 
  16.  
  17.     zend_object_value obj; 
  18.  
  19. } zvalue_value;< li> 

zvalue_value是一個聯合體,于是我們構造的字符串區域的內存,就會被當做一個Hashtable結構體,代碼如下:

  1. typedef struct _hashtable { 
  2.  
  3.     uint nTableSize; 
  4.  
  5.     uint nTableMask; 
  6.  
  7.     uint nNumOfElements; 
  8.  
  9.     ulong nNextFreeElement; 
  10.  
  11.     Bucket *pInternalPointer; /* Used for element traversal */ 
  12.  
  13.     Bucket *pListHead; 
  14.  
  15.     Bucket *pListTail; 
  16.  
  17.     Bucket **arBuckets; 
  18.  
  19.     dtor_func_t pDestructor; //注意這個 
  20.  
  21.     zend_bool persistent; 
  22.  
  23.     unsigned char nApplyCount; 
  24.  
  25.     zend_bool bApplyProtection; 
  26.  
  27. #if ZEND_DEBUG 
  28.  
  29.     int inconsistent; 
  30.  
  31. #endif 
  32.  
  33. } HashTable;< li> 

在Hashtable結構體中,有一個pDestructor,這個指針指向一個函數,當這個Hashtable中有元素要被清除的時候,就會調用它…

也就是說,你可以隨心所欲的設置一個地址(pDestructor),然后讓PHP去調用它(誘使一個元素被刪除).

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 临朐县| 兴海县| 吉林市| 石景山区| 鄢陵县| 双鸭山市| 巍山| 内江市| 凤城市| 竹北市| 武义县| 陕西省| 绥芬河市| 余江县| 农安县| 乐山市| 阿鲁科尔沁旗| 临海市| 错那县| 鹤壁市| 淮阳县| 怀柔区| 田林县| 青龙| 凌海市| 奉化市| 九龙坡区| 利辛县| 鹤山市| 教育| 普洱| 渭源县| 清远市| 岢岚县| 大理市| 古田县| 广汉市| 博爱县| 友谊县| 海宁市| 阿瓦提县|