hashtable と hashdos
DESCRIPTION
TRANSCRIPT
![Page 1: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/1.jpg)
HashTableと
HashDoS@yuya_takeyama
![Page 2: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/2.jpg)
Forthe
Beginners
![Page 3: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/3.jpg)
Bya
Beginner
![Page 4: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/4.jpg)
アジェンダ
•ハッシュテーブルとは•PHP におけるハッシュテーブル•PHP における HashDoS
![Page 5: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/5.jpg)
ハッシュテーブルとは•Key から Value を検索•連想配列に使われる•基本的には効率的で高速•最悪の場合はとても非効率に
![Page 6: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/6.jpg)
http://www.is.titech.ac.jp/~kishi/classes/java11/java09.html
![Page 7: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/7.jpg)
PHP における ハッシュテーブル
•HashTable 構造体•複数の Bucket 構造体から成る•順番を保持
![Page 8: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/8.jpg)
typedef struct _hashtable { uint nTableSize; uint nTableMask; uint nNumOfElements; ulong nNextFreeElement; Bucket *pInternalPointer; Bucket *pListHead; Bucket *pListTail; Bucket **arBuckets; dtor_func_t pDestructor; zend_bool persistent; unsigned char nApplyCount; zend_bool bApplyProtection;} HashTable;
![Page 9: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/9.jpg)
typedef struct _hashtable { uint nTableSize; uint nTableMask; uint nNumOfElements; ulong nNextFreeElement; Bucket *pInternalPointer; Bucket *pListHead; Bucket *pListTail; Bucket **arBuckets; dtor_func_t pDestructor; zend_bool persistent; unsigned char nApplyCount; zend_bool bApplyProtection;} HashTable;
テーブルのスロット数
![Page 10: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/10.jpg)
typedef struct _hashtable { uint nTableSize; uint nTableMask; uint nNumOfElements; ulong nNextFreeElement; Bucket *pInternalPointer; Bucket *pListHead; Bucket *pListTail; Bucket **arBuckets; dtor_func_t pDestructor; zend_bool persistent; unsigned char nApplyCount; zend_bool bApplyProtection;} HashTable; 要素数
![Page 11: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/11.jpg)
typedef struct _hashtable { uint nTableSize; uint nTableMask; uint nNumOfElements; ulong nNextFreeElement; Bucket *pInternalPointer; Bucket *pListHead; Bucket *pListTail; Bucket **arBuckets; dtor_func_t pDestructor; zend_bool persistent; unsigned char nApplyCount; zend_bool bApplyProtection;} HashTable;
先頭または
末尾の要素
![Page 12: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/12.jpg)
typedef struct _hashtable { uint nTableSize; uint nTableMask; uint nNumOfElements; ulong nNextFreeElement; Bucket *pInternalPointer; Bucket *pListHead; Bucket *pListTail; Bucket **arBuckets; dtor_func_t pDestructor; zend_bool persistent; unsigned char nApplyCount; zend_bool bApplyProtection;} HashTable;
要素の集まり
![Page 13: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/13.jpg)
ドユコト?
![Page 14: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/14.jpg)
可視化しましょう
![Page 15: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/15.jpg)
![Page 16: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/16.jpg)
![Page 17: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/17.jpg)
<?phphashtable_dump(array(1, 2, 3, 4, 5, 6, 7, 8));/*nTableSize: 8nTableMask: 7nNumOfElements: 8nNextFreeElement: 8pListHead: 0pListTail: 7**arBuckets: 0 => [0, NULL] 1 => [1, NULL] 2 => [2, NULL] 3 => [3, NULL] 4 => [4, NULL] 5 => [5, NULL] 6 => [6, NULL] 7 => [7, NULL]*/
テーブルのスロット数
![Page 18: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/18.jpg)
<?phphashtable_dump(array(1, 2, 3, 4, 5, 6, 7, 8));/*nTableSize: 8nTableMask: 7nNumOfElements: 8nNextFreeElement: 8pListHead: 0pListTail: 7**arBuckets: 0 => [0, NULL] 1 => [1, NULL] 2 => [2, NULL] 3 => [3, NULL] 4 => [4, NULL] 5 => [5, NULL] 6 => [6, NULL] 7 => [7, NULL]*/ 要素数
![Page 19: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/19.jpg)
<?phphashtable_dump(array(1, 2, 3, 4, 5, 6, 7, 8));/*nTableSize: 8nTableMask: 7nNumOfElements: 8nNextFreeElement: 8pListHead: 0pListTail: 7**arBuckets: 0 => [0, NULL] 1 => [1, NULL] 2 => [2, NULL] 3 => [3, NULL] 4 => [4, NULL] 5 => [5, NULL] 6 => [6, NULL] 7 => [7, NULL]*/
先頭または
末尾の要素
![Page 20: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/20.jpg)
<?phphashtable_dump(array(1, 2, 3, 4, 5, 6, 7, 8));/*nTableSize: 8nTableMask: 7nNumOfElements: 8nNextFreeElement: 8pListHead: 0pListTail: 7**arBuckets: 0 => [0, NULL] 1 => [1, NULL] 2 => [2, NULL] 3 => [3, NULL] 4 => [4, NULL] 5 => [5, NULL] 6 => [6, NULL] 7 => [7, NULL]*/
要素の集まり
![Page 21: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/21.jpg)
Bucket 構造体
•値の入れ物•配列内の一要素を表現•二重の双方向リスト
![Page 22: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/22.jpg)
typedef struct bucket { ulong h; uint nKeyLength; void *pData; void *pDataPtr; struct bucket *pListNext; struct bucket *pListLast; struct bucket *pNext; struct bucket *pLast; const char *arKey;} Bucket;
キーの数値または
キー文字列のハッシュ値ここあんまり自信無いです...
![Page 23: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/23.jpg)
typedef struct bucket { ulong h; uint nKeyLength; void *pData; void *pDataPtr; struct bucket *pListNext; struct bucket *pListLast; struct bucket *pNext; struct bucket *pLast; const char *arKey;} Bucket; キー文字列
![Page 24: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/24.jpg)
typedef struct bucket { ulong h; uint nKeyLength; void *pData; void *pDataPtr; struct bucket *pListNext; struct bucket *pListLast; struct bucket *pNext; struct bucket *pLast; const char *arKey;} Bucket; 値まだよく読めてないです...
![Page 25: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/25.jpg)
typedef struct bucket { ulong h; uint nKeyLength; void *pData; void *pDataPtr; struct bucket *pListNext; struct bucket *pListLast; struct bucket *pNext; struct bucket *pLast; const char *arKey;} Bucket;
ハッシュテーブル内の前後の要素
![Page 26: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/26.jpg)
typedef struct bucket { ulong h; uint nKeyLength; void *pData; void *pDataPtr; struct bucket *pListNext; struct bucket *pListLast; struct bucket *pNext; struct bucket *pLast; const char *arKey;} Bucket;
スロット内の前後の要素
![Page 27: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/27.jpg)
二重の双方向リスト
•ハッシュテーブル内のリスト-> 配列の走査に使う
•スロット内のリスト-> ハッシュ値の衝突時に連結
![Page 28: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/28.jpg)
https://www.codeblog.org/blog/moriyoshi/20060824.html
![Page 29: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/29.jpg)
p = ht->pListHead;while (p != NULL) { // p にごにょごにょする p = p->pListNext;}
リスト全体の走査
![Page 30: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/30.jpg)
h = ハッシュ値の計算(arKey, nLength);
// スロット番号の算出nIndex = h & ht->nTableMask;
p = ht->arBuckets[nIndex];while (p != NULL) { if (キーが等しければ) {
*pData = p->pData; return SUCCESS; } p = p->pNext;}return FAILURE;
キーによる探索
![Page 31: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/31.jpg)
PHPにおけるHashDoS
![Page 32: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/32.jpg)
テキスト
http://blog.tokumaru.org/2011/12/webdoshashdos.html
![Page 33: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/33.jpg)
HashDoS とは
•ハッシュ値の衝突する連想配列を作る•Web アプリに入力として与える
•非効率な挿入・検索が起こる•効率よく DoS アタックができる
![Page 34: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/34.jpg)
<?phphashtable_dump(array(0 => 1, 8 => 2, 16 => 3, 24 => 4, 32 => 5, 40 => 6, 48 => 7, 56 => 8));/*nTableSize: 8nTableMask: 7nNumOfElements: 8nNextFreeElement: 57pListHead: 0pListTail: 56**arBuckets: 0 => [56, 48, 40, 32, 24, 16, 8, 0, NULL] 1 => [NULL] 2 => [NULL] 3 => [NULL] 4 => [NULL] 5 => [NULL] 6 => [NULL] 7 => [NULL]*/
全ての要素が同じスロットに
![Page 35: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/35.jpg)
<?phphashtable_dump(array(0 => 1, 8 => 2, 16 => 3, 24 => 4, 32 => 5, 40 => 6, 48 => 7, 56 => 8));/*nTableSize: 8nTableMask: 7nNumOfElements: 8nNextFreeElement: 57pListHead: 0pListTail: 56**arBuckets: 0 => [56, 48, 40, 32, 24, 16, 8, 0, NULL] 1 => [NULL] 2 => [NULL] 3 => [NULL] 4 => [NULL] 5 => [NULL] 6 => [NULL] 7 => [NULL]*/
全ての要素が同じスロットに
非効率な探索
![Page 36: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/36.jpg)
HashDoS への対策•入力による HashTable の生成を制限する (max_input_vars とか)
•根本的解決では無いが, 現実的なリスクを軽減できる
•続きは徳丸さんのブログで
![Page 37: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/37.jpg)
根本的な解決の事例
•Perl (5.8.1 以降)•Ruby (1.8.7-p356 より後)•ハッシュ値の予測を困難にする? まだよく調べてません...
![Page 38: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/38.jpg)
まとめ•PHP の HashTable は HashDoS に対して脆弱である
•運用でカバーしましょう•詳しくは徳丸さんのブログで
![Page 39: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/39.jpg)
ご清聴ありがとうございました
![Page 40: HashTable と HashDos](https://reader034.vdocuments.net/reader034/viewer/2022051611/54b515104a7959fd6d8b48f7/html5/thumbnails/40.jpg)
参考資料• アルゴリズムとデータ構造編 第14章 ハッシュ探索①(チェイン法)
http://www.geocities.jp/ky_webid/algorithm/014.html
• PHPソースコードリーディング入門(とっかかり編)http://d.hatena.ne.jp/anatoo/20111031/1319991834
• Webアプリケーションに対する広範なDoS攻撃手法(hashdos)の影響と対策http://blog.tokumaru.org/2011/12/webdoshashdos.html
• Zend_Hash_Del_Key_Or_Index Vulnerabilityhttp://www.hardened-php.net/hphp/zend_hash_del_key_or_index_vulnerability.html
• ハッシュテーブルの実装https://www.codeblog.org/blog/moriyoshi/20060824.html
• PHP のコア: Zend Engine ハッカーの手引きhttp://www.php.net/manual/ja/internals2.php
• PHP Extensions: Understanding and working with hash API Part 1http://zendguru.wordpress.com/2009/05/10/php-extensions-understanding-and-working-with-hash-api-part-1/