ãPHPã®ã»ãã¥ãªãã£ããšããæ¬ïŒããŒã1ïŒ
ãPHPã®ã»ãã¥ãªãã£ããšããæ¬ïŒããŒã2ïŒ
ãPHPã®ã»ãã¥ãªãã£ããšããæ¬ïŒããŒã3ïŒ
ãPHPã®ã»ãã¥ãªãã£ããšããæ¬ïŒããŒã4ïŒ
PHPã®ã©ã³ãã ãªå€ã¯ã©ãã«ã§ããããŸãã ãã¹ãŠã®ãã¬ãŒã ã¯ãŒã¯ãå€ãã®ã©ã€ãã©ãªã ããªãã¯ãããããããŒã¯ã³ãšãœã«ããçæããããã«ããŸãé¢æ°ãžã®å
¥åãšããŠã©ã³ãã ãªå€ã䜿çšããäžé£ã®ã³ãŒããæžããã§ãããã ãŸããã©ã³ãã ãªå€ã¯ãããŸããŸãªåé¡ã®è§£æ±ºã«éèŠãªåœ¹å²ãæãããŸãã
- ããŒã«ãŸãã¯æ¢ç¥ã®ãªãã·ã§ã³ã®ç¯å²ãããªãã·ã§ã³ãã©ã³ãã ã«éžæããŸãã
- æå·åã®åæåãã¯ãã«ãçæããŸãã
- èš±å¯æã«äºæž¬äžèœãªããŒã¯ã³ãŸãã¯1åéãã®å€ãçæããããã
- ã»ãã·ã§ã³IDãªã©ã®äžæã®èå¥åãçæããããã
ããããã¹ãŠã®å Žåã«ãç¹åŸŽçãªè匱æ§ããããŸãã æ»æè
ãä¹±æ°ãžã§ãã¬ãŒã¿ãŒïŒRNGãä¹±æ°ãžã§ãã¬ãŒã¿ãŒïŒãŸãã¯ç䌌乱æ°ãžã§ãã¬ãŒã¿ãŒïŒPRNGãæ¬äŒŒä¹±æ°ãžã§ãã¬ãŒã¿ãŒïŒã®åºåãæšæž¬ãŸãã¯äºæž¬ããå Žåãæ»æè
ã¯ãããŒã¯ã³ããœã«ããã¯ã³ã¿ã€ã å€ãããã³æå·ååæåãã¯ãã«ã䜿çšããŠäœæã§ããŸããã®ãžã§ãã¬ãŒã¿ã ãããã£ãŠãé«å質ã®ã©ã³ãã å€ãã€ãŸãäºæž¬ãéåžžã«å°é£ãªã©ã³ãã å€ãçæããããšã¯éåžžã«éèŠã§ãã ãããªãå Žåã§ãããã¹ã¯ãŒããªã»ããããŒã¯ã³ãCSRFããŒã¯ã³ãAPIããŒãã¯ã³ã¿ã€ã å€ãèªèšŒããŒã¯ã³ã®äºæž¬å¯èœæ§ãèš±å¯ããªãã§ãã ããïŒ
PHPã§ã¯ãããã«2ã€ã®æœåšçãªè匱æ§ãã©ã³ãã ãªå€ã«é¢é£ä»ããããŠããŸãã
- æ
å ±é瀺
- ãšã³ããããŒã®äžè¶³ïŒäžååãªãšã³ããããŒïŒã
ããã«é¢é£ããŠããæ
å ±ã®é瀺ããšã¯ãæ¬äŒŒä¹±æ°ãžã§ãã¬ãŒã¿ã®å
éšç¶æ
ã®æŒæŽ©ãã€ãŸããã®åæå€ïŒã·ãŒãå€ïŒãæããŸãã ãã®ãããªãªãŒã¯ã¯ãå°æ¥ã®PRNGåºåã®äºæž¬ã倧å¹
ã«ä¿é²ã§ããŸãã
ããšã³ããããŒã®æ¬ åŠãã¯ãPRNGãŸãã¯ãã®åºåã®åæå
éšç¶æ
ïŒã·ãŒãïŒã®å€åæ§ãéåžžã«å°ãããããå¯èœãªå€ã®ç¯å²å
šäœãæ¯èŒçç°¡åã«ãã«ãŒããã©ãŒã¹ã§ãœãŒããããç¶æ³ãè¡šããŸãã PHPããã°ã©ãã«ãšã£ãŠã¯ããŸãè¯ããã¥ãŒã¹ã§ã¯ãããŸããã
æ»æã·ããªãªã®äŸã䜿çšããŠãäž¡æ¹ã®è匱æ§ã詳现ã«èª¿ã¹ãŸãã ããããæåã«ãPHPã§ã®ããã°ã©ãã³ã°ã«é¢ããŠå®éã«ã©ã³ãã ãªå€ãäœã§ããããç解ããŸãããã
ã©ã³ãã å€ã¯äœãããŸããïŒ
ã©ã³ãã å€æ°ã®ç®çã«é¢ããæ··ä¹±ã¯ãäžè¬çãªèª€è§£ã«ãã£ãŠæªåããŠããŸãã æå·çã«æ°žç¶çãªã©ã³ãã å€ãšãä»ã®çšéãã®ãããŸããªãäžæã®ãæå³ãšã®éããèããããšã¯ééããããŸããã äž»ãªå°è±¡ã¯ãæå·åã§äœ¿çšãããã©ã³ãã ãªå€ã«ã¯é«å質ã®ã©ã³ãã æ§ïŒãŸãã¯ããããé«ããšã³ããããŒïŒãå¿
èŠã§ãããä»ã®ã¢ããªã±ãŒã·ã§ã³ã®å€ã§ã¯ãšã³ããããŒãå°ãªããŠæžããšããããšã§ãã ãã®å°è±¡ã¯ééã£ãŠãããéå¹æã§ãã äºæž¬äžå¯èœãªã©ã³ãã å€ãšäºçŽ°ãªã¿ã¹ã¯ã«å¿
èŠãªå€ãšã®æ¬åœã®éãã¯ãåŸè
ã®äºæž¬å¯èœæ§ãæ害ãªçµæã䌎ããªãããšã ãã§ãã ããã¯éåžžãæå·åãåé¡ã®èæ
®ããé€å€ããŸãã èšãæããã°ãèªæã§ãªãã¿ã¹ã¯ã§ã©ã³ãã ãªå€ã䜿çšããå Žåããã匷åãªRNGãèªåçã«éžæããå¿
èŠããããŸãã
ã©ã³ãã å€ã®åŒ·åºŠã¯ãããããçæããããã«è²»ãããããšã³ããããŒã«ãã£ãŠæ±ºãŸããŸãã ãšã³ããããŒã¯ããããããã§è¡šãããäžç¢ºå®æ§ã®å°ºåºŠã§ãã ããšãã°ããã€ããªãããã䜿çšããå Žåããã®å€ã¯0ãŸãã¯1ã«ãªããŸããæ»æè
ãæ£ç¢ºãªå€ãç¥ããªãå Žåã2ãããã®ãšã³ããããŒïŒã€ãŸããã³ã€ã³ãæããïŒããããŸãã æ»æè
ãå€ãåžžã«1ã§ããããšãç¥ã£ãŠããå Žåãäºæž¬å¯èœæ§ã¯äžç¢ºå®æ§ã®å矩èªã§ããããã0ãããã®ãšã³ããããŒããããŸãã ãŸãããããæ°ã¯0ã2ã®ç¯å²ã«ãªããŸããããšãã°ã99ïŒ
ã®ãã€ããªãããã1ã®å Žåããšã³ããããŒã¯0ããããã«è¶
ããå¯èœæ§ããããŸãã
PHPã§ã¯ããããããæ確ã«èŠãããšãã§ããŸãã mt_rand()
é¢æ°ã¯ã©ã³ãã ãªå€ãçæããŸã;ãããã¯åžžã«æ°åã§ãã æåãç¹æ®æåããŸãã¯ãã®ä»ã®æå³ã¯çæããŸããã ããã¯ãæ»æè
ããã€ãããšã«åœãŠæšéãã¯ããã«å°ãªãããšãã€ãŸããšã³ããããŒãäœãããšãæå³ããŸãã Linuxã®source /dev/random
ãããã€ããèªã¿åãããšã§mt_rand()
ã眮ãæãããšãå®éã«ã©ã³ãã ãªãã€ããåŸãããŸããã·ã¹ãã ããã€ã¹ãã©ã€ããŒããã®ä»ã®ãœãŒã¹ã«ãã£ãŠçæããããã€ãºã«åºã¥ããŠçæãããŸãã æããã«ããã®ãªãã·ã§ã³ã¯ãšã³ããããŒã®ãããã倧å¹
ã«å¢ãããããã¯ããã«åªããŠããŸãã
mt_rand()
ã®æãŸãããªãããšã¯ããã®ãžã§ãã¬ãŒã¿ãŒãçã®ä¹±æ°ã§ã¯ãªããæ¬äŒŒä¹±æ°ããŸãã¯æ±ºå®è«çã©ã³ãã ããããžã§ãã¬ãŒã¿ãŒïŒæ±ºå®è«çã©ã³ãã ããããžã§ãã¬ãŒã¿ãŒãDRBGïŒãšãåŒã°ãããšããäºå®ã«ãã£ãŠã瀺ãããŸãã Mersenne TwisterãšåŒã°ããã¢ã«ãŽãªãºã ãå®è£
ããŸãããã®ã¢ã«ãŽãªãºã ã¯ãçµæãçã®ä¹±æ°ãžã§ãã¬ãŒã¿ãŒã®çµæã«è¿ããªãããã«åæ£ãããæ°å€ãçæããŸãã mt_rand()
ã¯ã1ã€ã®ã©ã³ãã å€ã®ã¿ã䜿çšããŸããåæå€ïŒã·ãŒãïŒã«åºã¥ããŠãåºå®ã¢ã«ãŽãªãºã ã¯æ¬äŒŒã©ã³ãã å€ãçæããŸãã
ãã®äŸãèŠãŠãã ãããããªãã¯ãããèªåã§ãã¹ãããããšãã§ããŸãïŒ
mt_srand(1361152757.2); for ($i=1; $i < 25; $i++) { echo mt_rand(), PHP_EOL; }
ããã¯ãMersenne vortex PHPé¢æ°ãäºåå®çŸ©æžã¿ã®åæå€ãåãåã£ãåŸã«å®è¡ãããåçŽãªã«ãŒãã§ãã ããã¯ã mt_srand()
ããã¥ã¡ã³ãã§äŸãšããŠåŒçšãããŠããé¢æ°ã®åºåã§ååŸãããçŸåšã®ç§ãšãã€ã¯ãç§ã䜿çšããŠããŸãã äžèšã®ã³ãŒããå®è¡ãããšã25åã®æ¬äŒŒä¹±æ°ã衚瀺ãããŸãã ã©ã³ãã ã«èŠããŸãããå¶ç¶ã§ã¯ãªãããã¹ãŠãæ£åžžã§ãã ã³ãŒããå床å®è¡ããŸãã äœãæ°ã¥ããããšããããŸããïŒ ã€ãŸããåãçªå·ã衚瀺ãããŸãã 3åç®ã4åç®ã5åç®ãå®è¡ããŸãã PHPã®å€ãããŒãžã§ã³ã§ã¯ãçµæãç°ãªãå ŽåããããŸãããããã¯åé¡ã®å Žåã«ã¯åœãŠã¯ãŸããŸãããããã¯ãPHPã®ãã¹ãŠã®ææ°ããŒãžã§ã³ã§äžè¬çãªããã§ãã
æ»æè
ããã®ãããªPRNGã®åæå€ãåãåããšã mt_rand()
ãã¹ãŠã®åºåãäºæž¬ã§ããŸãã ãããã£ãŠãåæå€ã®ä¿è·ã¯æéèŠäºé
ã§ãã çŽå€±ãããšãã©ã³ãã ãªå€ãçæããæš©å©ããªããªããŸã...
次ã®2ã€ã®æ¹æ³ã®ããããã§åæå€ãçæã§ããŸãã
mt_srand()
é¢æ°ã䜿çšããŠæåã§ãmt_srand()
ãç¡èŠããPHPã«èªåçã«çæãããŸãã
2çªç®ã®ãªãã·ã§ã³ãæãŸããã§ãããä»æ¥ã®ã¬ã¬ã·ãŒã¢ããªã±ãŒã·ã§ã³ã¯ãææ°ããŒãžã§ã³ã®PHPã«ç§»æ€ããåŸã§ããå€ãã®å Žåmt_srand()
䜿çšãç¶æ¿ããŸãã
ããã«ãããæ»æè
ãåæå€ïŒã·ãŒãå埩æ»ææ»æïŒã埩å
ãããªã¹ã¯ãé«ãŸããå°æ¥ã®å€ãäºæž¬ããã®ã«ååãªæ
å ±ãåŸãããŸãã ãã®çµæããã®ãããªãªãŒã¯åŸã®ã¢ããªã±ãŒã·ã§ã³ã¯ãæ
å ±æŒããæ»æã«å¯ŸããŠè匱ã«ãªããŸãã ããã¯ãæããã«ååçãªæ§è³ªã«ãããããããæ¬åœã®è匱æ§ã§ãã ããŒã«ã«ã·ã¹ãã ã«é¢ããæ
å ±ãæŒããããšã¯ããã®åŸã®æ»æã§æ»æè
ãå©ããããšãã§ããããã¯å€å±€é²åŸ¡ã®ååã«éåããŸãã
PHPã®ã©ã³ãã å€
PHPã¯3ã€ã®PRNGã䜿çšããŸããæ»æè
ãã¢ã«ãŽãªãºã ã§äœ¿çšãããåæå€ã«ã¢ã¯ã»ã¹ãããšãæ»æã®çµæãäºæž¬ã§ããŸãã
- ç·åœ¢ååãžã§ãã¬ãŒã¿ãŒïŒLCGïŒã
lcg_value()
- ã¡ã«ã»ã³ãã»ã¯ãŒã«ãŠã£ã³ãã
mt_rand()
- ããŒã«ã«ã§ãµããŒããããŠãã
rand()
Cé¢æ°ã
ãŸãããããã®ãžã§ãã¬ãŒã¿ãŒã¯ã array_rand()
ãuniqid()
ãªã©ã®é¢æ°ã®å
éšããŒãºã«äœ¿çšãããŸãã ããã¯ãæ»æè
ãå¿
èŠãªãã¹ãŠã®åæå€ãååŸããå ŽåãPHPèšèªã®å
éšPRNGã䜿çšããŠããããããã³ä»ã®æ©èœã®åºåãäºæž¬ã§ããããšãæå³ããŸãã ããã¯ããžã§ãã¬ãŒã¿ãŒãžã®å€æ°ã®åŒã³åºãã®å©ããåããŠæ»æè
ãæ··ä¹±ãããããšã«ãã£ãŠä¿è·ãæ¹åããããšãã§ããªãããšãæå³ããŸãã ããã¯ãç¹ã«ãªãŒãã³ãœãŒã¹ã¢ããªã±ãŒã·ã§ã³ã«åœãŠã¯ãŸããŸãã æ»æè
ã¯ãæ¢ç¥ã®åæå€ã®ãã¹ãŠã®åºåããŒã¿ãäºæž¬ã§ããŸãã
éèªæãªã¿ã¹ã¯ã«å¯ŸããŠçæãããã©ã³ãã å€ã®å質ãåäžãããããã«ãPHPã¯ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãã£ãŠæäŸãããå€éšãšã³ããããŒã®ãœãŒã¹ãå¿
èŠãšããŸãã Linuxã¯éåžž/dev/urandom
ã䜿çšãopenssl_pseudo_random_bytes()
mcrypt_create_iv()
ãŸãã¯mcrypt_create_iv()
é¢æ°ã䜿çšããŠãçŽæ¥èªã¿åãããéæ¥çã«ã¢ã¯ã»ã¹ã§ããŸãã ã©ã¡ããWindowsã§æå·åŠçã«å®å
šãªæ¬äŒŒä¹±æ°ãžã§ãã¬ãŒã¿ãŒïŒCSPRNGïŒã䜿çšã§ããŸãããPHPã§ã¯ããããã®é¢æ°ã«ãã£ãŠæäŸãããæ¡åŒµæ©èœãªãã«ãã®ãžã§ãã¬ãŒã¿ãŒããããŒã¿ãåä¿¡ããããã®ãŠãŒã¶ãŒç©ºéã«çŽæ¥çãªæ¹æ³ã¯ãããŸããã ã€ãŸãããµãŒããŒããŒãžã§ã³ã®PHPã§OpenSSLãŸãã¯Mcryptæ¡åŒµæ©èœãæå¹ã«ãªã£ãŠããããšã確èªããŠãã ããã
/dev/urandom
ã¯PRNGã§ãããå€ãã®å Žåãéåžžã«ãšã³ããããŒã®é«ããœãŒã¹/dev/random
ããæ°ããåæå€ãååŸããŸãã ããã«ãããæ»æè
ã«ãšã£ãŠã¯é¢çœããªãã¿ãŒã²ããã«ãªããŸãã ããããã³ã°ãªãœãŒã¹ã§ããããã /dev/random
ããçŽæ¥èªã¿åããªãããã«ããŸãã 圌ããšã³ããããŒã䜿ãæãããšãã·ã¹ãã ç°å¢ããåã³ååãªãšã³ããããŒãåŸããããŸã§ããã¹ãŠã®æž¬å®å€ããããã¯ãããŸãã æãéèŠãªã¿ã¹ã¯ã«ã¯ã /dev/random
䜿çšããå¿
èŠããããŸãã
ããã¯ãã¹ãŠç§ãã¡ãã«ãŒã«ã«å°ããŸãïŒ
, , openssl_pseudo_random_bytes(). /dev/urandom. , .
ãã®ã«ãŒã«ã®åºæ¬çãªå®è£
ã¯ãSecurityMultiToolãªãã¡ã¬ã³ã¹ã©ã€ãã©ãªã«ãããŸãã ãã€ãã®ããã«ãPHPå
éšã§ã¯ãPHPã³ã¢ã«å®å
šãªãœãªã¥ãŒã·ã§ã³ãçŽæ¥å«ããã®ã§ã¯ãªããããã°ã©ãã®ç掻ãè€éã«ããããšã奜ã¿ãŸãã
ååãªçè«ã§ãäžèšã§æŠè£
ããã¢ããªã±ãŒã·ã§ã³ãæ»æããæ¹æ³ãèŠãŠã¿ãŸãããã
PHPã®ä¹±æ°ãžã§ãã¬ãŒã¿ãŒãžã®æ»æ
ããã€ãã®çç±ã«ãããPHPã¯PRNGã䜿çšããŠéèŠãªã¿ã¹ã¯ã解決ããŸãã
openssl_pseudo_random_bytes()
é¢æ°ã¯PHP 5.3ã§ã®ã¿å©çšå¯èœã§ããã Windowsã§ã¯ãããŒãžã§ã³5.3.4ããªãªãŒã¹ããããŸã§ããã¯ã®åé¡ãçºçããŠããŸããã ãŸããPHP 5.3ã§ã¯ãWindowsã®mcrypt_create_iv()
é¢æ°ãMCRYPT_DEV_URANDOMãœãŒã¹ã®ãµããŒããéå§ããŸããã ãã以åã¯ãWindowsã§ã¯MCRYPT_RANDã®ã¿ããµããŒããããŠããŸãããå®éãå
éšã®ããŒãºã®ããã«rand()
䜿çšããã®ãšåãã·ã¹ãã PRNGã§ãã ã芧ã®ãšãããPHP 5.3ã®ç»å Žä»¥åã¯å€ãã®ã®ã£ããããã£ãããã以åã®ããŒãžã§ã³ã§äœæãããå€ãã®ã¬ã¬ã·ãŒã¢ããªã±ãŒã·ã§ã³ã¯ããã匷åãªPRNGã«åãæ¿ããããªãã£ãå¯èœæ§ããããŸãã
Opensslããã³Mcryptæ¡åŒµã®éžæã¯ãŠãŒã¶ãŒæ¬¡ç¬¬ã§ãã PHP 5.3ãæèŒãããµãŒããŒã§ãå¯çšæ§ã«äŸåã§ããªããããã¢ããªã±ãŒã·ã§ã³ã¯ãå€ãã®å ŽåãPHPã«çµã¿èŸŒãŸããPRNGãéèªæãªã©ã³ãã å€ãçæããããã®ãã©ãŒã«ããã¯ãšããŠäœ¿çšããŸãã
ãã ããã©ã¡ãã®å Žåããäœãšã³ããããŒã®åæå€ãæã€PRNGã䜿çšããŠçæãããã©ã³ãã ãªå€ãé©çšããéèŠãªã¿ã¹ã¯ããããŸãã ããã«ãããåæå埩æ»æã«å¯ŸããŠè匱ã«ãªããŸãã ç°¡åãªäŸãèŠãŠã¿ãŸãããã
次ã®ã³ãŒãã䜿çšããŠã¢ããªã±ãŒã·ã§ã³å
šäœã®ããŸããŸãªã¿ã¹ã¯ã§äœ¿çšãããããŒã¯ã³ãçæããã¢ããªã±ãŒã·ã§ã³ããªã³ã©ã€ã³ã§èŠã€ãããšæ³åããŠãã ããã
$token = hash('sha512', mt_rand());
ããŒã¯ã³ãçæããããè€éãªæ段ããããŸãããããã¯è¯ããªãã·ã§ã³ã§ãã ããã§ã¯ãSHA512ã§ããã·ã¥åmt_rand()
åŒã³åºãã1ã€ã ãmt_rand()
ãŸãã å®éã«ã¯ãããã°ã©ããŒãPHPã®ã©ã³ãã å€é¢æ°ããããªãã©ã³ãã ãã§ãããšå€æããå Žåããããããæå·åããšããèšèãèããããŸã§åçŽåãããã¢ãããŒããéžæããã§ãããã ããšãã°ãæå·åãããŠããªãå Žåã«ã¯ãã¢ã¯ã»ã¹ããŒã¯ã³ãCSRFããŒã¯ã³ãã¯ã³ã¿ã€ã APIå€ãããã³ãã¹ã¯ãŒããªã»ããããŒã¯ã³ãå«ãŸããŸãã ç¶è¡ããåã«ããã®ã¢ããªã±ãŒã·ã§ã³ã®è匱æ§ã®è©³çŽ°ã説æããŸããããã«ãããäžè¬ã«ã¢ããªã±ãŒã·ã§ã³ãè匱ã«ãªãåå ãããããç解ã§ããŸãã
è匱ãªã¢ããªã±ãŒã·ã§ã³ã®ç¹æ§
ããã¯å®å
šãªãªã¹ãã§ã¯ãããŸããã å®éã«ã¯ãæ©èœã®ãªã¹ãã¯ç°ãªãå ŽåããããŸãïŒ
1. ãµãŒããŒã¯mod_phpã䜿çšããŸãã ããã«ãããKeepAliveã䜿çšãããšãåãPHPããã»ã¹ã§è€æ°ã®ãªã¯ãšã¹ããåŠçã§ããŸãã
PHPã®ä¹±æ°ãžã§ãã¬ãŒã¿ãŒã¯ããã»ã¹ããšã«åæå€ãåãåããããããã¯éèŠã§ãã ããã»ã¹ã«å¯ŸããŠ2ã€ä»¥äžã®èŠæ±ãè¡ãããšãã§ããå Žåãåãåæå€ã䜿çšããŸãã æ»æã®æ¬è³ªã¯ã1ã€ã®ããŒã¯ã³ã®é瀺ãé©çšããŠãSAMEåæå€ã«åºã¥ããŠçæãããå¥ã®ããŒã¯ã³ãäºæž¬ããããã«å¿
èŠãªåæå€ãæœåºããããšã§ãïŒã€ãŸããåãããã»ã¹ã§ïŒã mod_phpã¯è€æ°ã®ã¯ãšãªã䜿çšããŠé¢é£ããã©ã³ãã ãªå€ãååŸããã®ã«çæ³çã§ããããã1ã€ã®ã¯ãšãªã§mt_rand()
é¢é£ããè€æ°ã®å€ãæœåºã§ããå ŽåããããŸãã ããã«ãããmod_phpã®èŠä»¶ãåé·ã«ãªããŸãã ããšãã°ã mt_rand()
åæå€ã®çæã«äœ¿çšããããšã³ããããŒã®äžéšã¯ãåãã¯ãšãªã®ã»ãã·ã§ã³IDãŸãã¯åºåå€ãä»ããŠãªãŒã¯ããå¯èœæ§ããããŸãã
2.ãµãŒããŒã¯ãmt_randïŒïŒããŒã¯ã³ã«åºã¥ããŠçæãããCSRFããŒã¯ã³ããã¹ã¯ãŒããªã»ããããŒã¯ã³ããŸãã¯ã¢ã«ãŠã³ã確èªããŒã¯ã³ã衚瀺ããŸãã
åæå€ãæœåºããã«ã¯ãPHPã®ãžã§ãã¬ãŒã¿ãŒã«ãã£ãŠçæãããæ°å€ãçŽæ¥ç¢ºèªããå¿
èŠããããŸãã ãããŠããããã©ã®ããã«äœ¿çšããããã¯é¢ä¿ãããŸããã mt_rand()
åºåãããã·ã¥åãããCSRFãã¢ã«ãŠã³ã確èªããŒã¯ã³ãªã©ãå©çšå¯èœãªä»»æã®å€ããæœåºã§ããŸãã ã©ã³ãã ãªå€ãåºåã§ã®ç°ãªãåäœã決å®ããéæ¥çãªãœãŒã¹ã§ãããé©åã§ãããããã«ãããã®å€ãæããã«ãªããŸãã äž»ãªå¶éã¯ãäºæž¬ããããšããŠãã2çªç®ã®ããŒã¯ã³ãçæããã®ãšåãããã»ã¹ããã®ãã®ã§ãªããã°ãªããªããšããããšã§ãã ããããæ
å ±æŒãããã®è匱æ§ã§ãã ããã«ãããããã«ãPRNGã®åºåæŒãã¯éåžžã«å±éºã§ãã è匱æ§ã¯åäžã®ã¢ããªã±ãŒã·ã§ã³ã«éå®ãããªãããšã«æ³šæããŠãã ããïŒäž¡æ¹ãåãPHPããã»ã¹ã䜿çšããå ŽåããµãŒããŒäžã®1ã€ã®ã¢ããªã±ãŒã·ã§ã³ã§PRNGåºåãèªã¿åããããã䜿çšããŠåããµãŒããŒäžã®å¥ã®ã¢ããªã±ãŒã·ã§ã³ã®åºåã決å®ã§ããŸãã
3.æ¢ç¥ã®åŒ±ãããŒã¯ã³çæã¢ã«ãŽãªãºã
ããªãã¯ãããèšç®ããããšãã§ããŸãïŒ
- ãªãŒãã³ãœãŒã¹ã¢ããªã±ãŒã·ã§ã³ã®ãœãŒã¹ã³ãŒããæãäžãã
- å人ã®ãœãŒã¹ã³ãŒãã«ã¢ã¯ã»ã¹ã§ããåŸæ¥å¡ã«è³briãèŽãã
- å
éçšè
ã«å¯Ÿããgrã¿ãæ±ããŠããå
åŸæ¥å¡ãèŠã€ãã
- ãŸãã¯ãã©ã®ãããªçš®é¡ã®ã¢ã«ãŽãªãºã ãååšããå¯èœæ§ãããããä»®å®ããŸãã
äžéšã®ããŒã¯ã³çææ¹æ³ã¯ããæçœã§ãããäžéšã¯ããäžè¬çã§ãã æ¬åœã«åŒ±ãçæããŒã«ã¯ãPHPä¹±æ°ãžã§ãã¬ãŒã¿ãŒã®1ã€ïŒããšãã°mt_rand()
ïŒã匱ããšã³ããããŒïŒæªå®çŸ©ããŒã¿ã®ä»ã®ãœãŒã¹ã¯ãããŸããïŒãããã³/ãŸãã¯åŒ±ãããã·ã¥ïŒããšãã°MD5ãŸãã¯ããã·ã¥ãªãïŒã®äœ¿çšã«ãã£ãŠåºå¥ãããŸãã äžèšã®ã³ãŒãäŸã«ã¯ã匱ãçæã¡ãœããã®å
åããããŸãã ãŸããSHA512ããã·ã¥ã䜿çšããŠããã¹ãã³ã°ãåžžã«äžååãªãœãªã¥ãŒã·ã§ã³ã§ããããšã瀺ããŸããã SHA512ã¯åŒ±ãããã·ã¥ã§ããSHA512ã¯è¿
éã«èšç®ããããããæ»æè
ã¯ããããCPUãŸãã¯GPUã§å
¥åããŒã¿ãéåžžã«é«éã§ãã«ãŒããã©ãŒã¹ã§ããŸãã ãŸããã ãŒã¢ã®æ³åãæå¹ã§ããããšãå¿ããªãã§ãã ãããã€ãŸãããã«ãŒããã©ãŒã¹ã®é床ã¯ãCPU / GPUã®æ°äžä»£ããšã«å¢å ããããšãæå³ããŸãã ãããã£ãŠããã¹ã¯ãŒãã¯ãããã»ããµã®ããã©ãŒãã³ã¹ãã ãŒã¢ã®æ³åã«é¢ä¿ãªããã¯ã©ããã³ã°çµæã«åºå®æéãå¿
èŠãªããŒã«ã䜿çšããŠããã·ã¥åããå¿
èŠããããŸãã
æ»æ
æ»æã¯éåžžã«ç°¡åã§ãã PHPããã»ã¹ãžã®æ¥ç¶ã®äžç°ãšããŠãã¯ã€ãã¯ã»ãã·ã§ã³ãå®è¡ãã2ã€ã®åå¥ã®HTTPãªã¯ãšã¹ãïŒãªã¯ãšã¹ãAãšãªã¯ãšã¹ãBïŒãéä¿¡ããŸãã ã»ãã·ã§ã³ã¯ã2çªç®ã®èŠæ±ãåä¿¡ããããŸã§ãµãŒããŒã«ãã£ãŠä¿æãããŸãã ãªã¯ãšã¹ãAã®ç®çã¯ãCSRFããã¹ã¯ãŒããªã»ããããŒã¯ã³ïŒã¡ãŒã«ã§æ»æè
ã«éä¿¡ïŒãªã©ã®å©çšå¯èœãªããŒã¯ã³ãååŸããããšã§ãã ä»»æã®IDã®ãªã¯ãšã¹ããªã©ã§äœ¿çšãããã€ã³ã©ã€ã³ããŒã¯ã¢ãããªã©ãä»ã®æ©èœã«ã€ããŠãå¿ããªãã§ãã ãããåæå€ãåŸããããŸã§ãå
ã®ããŒã¯ã³ãèŠãããŸãã ããã¯ãã¹ãŠãåæå€ã埩å
ããæ»æã®äžéšã§ããåæå€ã®ãšã³ããããŒãéåžžã«å°ããããããã«ãŒããã©ãŒã¹ãŸãã¯äºåã«èšç®ãããã¬ã€ã³ããŒããŒãã«ãæ€çŽ¢ã§ããŸã ã
ãªã¯ãšã¹ãBã¯ãããèå³æ·±ãåé¡ã解決ããŸãã ããŒã«ã«ç®¡çè
ã®ãã¹ã¯ãŒãããªã»ãããããªã¯ãšã¹ããäœæããŸãããã ããã«ãããããŒã¯ã³ã®çæãéå§ãããŸãïŒäž¡æ¹ã®èŠæ±ãåãPHPããã»ã¹ã«æ£åžžã«éä¿¡ãããå ŽåãèŠæ±Aã䜿çšããŠåŒãåºããåãåæå€ã«åºã¥ãä¹±æ°ã䜿çšããŸãïŒã ãã®ããŒã¯ã³ã¯ã管çè
ãã¡ãŒã«ã§éä¿¡ããããã¹ã¯ãŒããªã»ãããªã³ã¯ã䜿çšããç¬éãèŠè¶ããŠãããŒã¿ããŒã¹ã«ä¿åãããŸãã ãªã¯ãšã¹ãAããããŒã¯ã³ã®åæå€ãæœåºã§ããå Žåããªã¯ãšã¹ãBããããŒã¯ã³ãã©ã®ããã«çæãããããç¥ã£ãŠããã¹ã¯ãŒããªã»ããããŒã¯ã³ãäºæž¬ããŸãã ãã®ããã管çè
ãæçŽãèªãåã«ãªã»ãããªã³ã¯ããã©ãããšãã§ããŸãïŒ
ã€ãã³ãã®ã·ãŒã±ã³ã¹ã¯æ¬¡ã®ãšããã§ãã
- ã¯ãšãªAã䜿çšããŠãããŒã¯ã³ãååŸãããªããŒã¹ãšã³ãžãã¢ãªã³ã°ããŠåæå€ãèšç®ããŸãã
- ã¯ãšãªBã䜿çšããŠãåãåæå€ã«åºã¥ããŠçæãããããŒã¯ã³ãååŸããŸãã ãã®ããŒã¯ã³ã¯ãå°æ¥ã®ãã¹ã¯ãŒããªã»ããã®ããã«ã¢ããªã±ãŒã·ã§ã³ããŒã¿ããŒã¹ã«ä¿åãããŸãã
- SHA512ããã·ã¥ã解èªããŠããµãŒããŒãçæããä¹±æ°ãååŸããŸãã
- åä¿¡ãããã«ãŒããã©ãŒã¹ã©ã³ãã å€ã䜿çšããŠãããã䜿çšããŠçæãããåæå€ã
- åæå€ã䜿çšããŠäžé£ã®ã©ã³ãã ãªå€ãèšç®ããŸãããããã¯ãããããã¹ã¯ãŒããªã»ããããŒã¯ã³ã®æ ¹åºã«ããå¯èœæ§ããããŸãã
- ãã®ããŒã¯ã³ã䜿çšããŠã管çè
ãã¹ã¯ãŒãããªã»ããããŸãã
- 管çè
ã¢ã«ãŠã³ãã«ã¢ã¯ã»ã¹ããŠã楜ããã§å©çãåŸãŸãã ãŸããå°ãªããšã楜ããã§ãã ããã
ãããã³ã°ããŸããã...
ãããã³ã°ã¢ããªã±ãŒã·ã§ã³ããã¯
ã¹ããã1.ãªã¯ãšã¹ãAãå®è¡ããŠããŒã¯ã³ãæœåºããŸã
ã¿ãŒã²ããããŒã¯ã³ãšãã¹ã¯ãŒããªã»ããããŒã¯ã³ã¯mt_rand()
åºåã«äŸåãããšæ³å®ããŠããŸãã ãããã£ãŠããããéžæããå¿
èŠããããŸãã æ³åäžã®ã·ããªãªã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã¹ãŠã®ããŒã¯ã³ã¯åãæ¹æ³ã§çæããããããCSRFããŒã¯ã³ãåçŽã«æœåºããå°æ¥ã®ããã«ä¿åã§ããŸãã
æé 2.èŠæ±Bãå®è¡ããŠã管çè
ã¢ã«ãŠã³ãçšã«çæããããã¹ã¯ãŒããªã»ããããŒã¯ã³ãååŸããŸã
ãã®ãªã¯ãšã¹ãã¯ããã¹ã¯ãŒããªã»ãããã©ãŒã ã®ç°¡åãªéä¿¡ã§ãã ããŒã¯ã³ã¯ããŒã¿ããŒã¹ã«ä¿åãããã¡ãŒã«ã§ãŠãŒã¶ãŒã«éä¿¡ãããŸãã ãã®ããŒã¯ã³ãæ£ããèšç®ããå¿
èŠããããŸãã ãµãŒããŒã®ç¹æ§ãæ£ç¢ºãªå Žåãã¯ãšãªBã¯ã¯ãšãªAãšåãPHPããã»ã¹ã䜿çšããŸãããããã£ãŠãã©ã¡ãã®å Žåãã mt_rand()
åŒã³åºãã¯åãåæå€ã䜿çšããŸãã ã¯ãšãªAã䜿çšããŠããªã»ãããã©ãŒã ã®CSRFããŒã¯ã³ããã£ããã£ããæé ãå¹çåããããã®éä¿¡ãæå¹ã«ããããšãã§ããŸãïŒäžéã©ãŠã³ãããªãããé€ãïŒã
ã¹ããã3.èŠæ±Aã§åä¿¡ããããŒã¯ã³ã®SHA512ããã·ã¥ãããã¯ãã
SHA512ã¯ããã°ã©ãã«aæ¬ã®å¿µãæ±ãããŸããSHA -2ã¢ã«ãŽãªãºã ãã¡ããªå
šäœã§æ倧ã®æ°ãæã£ãŠããŸã ã ãã ãã被害è
ãéžæããããŒã¯ã³çææ¹æ³ã«ã¯1ã€ã®åé¡ããããŸã-ã©ã³ãã ãªå€ã¯æ°åã«ãã£ãŠã®ã¿å¶éãããŸãïŒã€ãŸããäžç¢ºå®æ§ãŸãã¯ãšã³ããããŒã®çšåºŠã¯ç¡èŠã§ããŸãïŒã mt_getrandmax()
åºåã確èªãããšã mt_rand()
ãçæã§ããæ倧ã®ä¹±æ°ã¯2 mt_rand()
åã§ãããäºçŽ°ãªããšã§ãã ãã®éãããæ°ã®æ©èœã«ãããSHA512ã¯ãã«ãŒããã©ãŒã¹ã«å¯ŸããŠè匱ã«ãªããŸãã
ãã ç§ã®èšèãåãå
¥ããªãã§ãã ããã ææ°äžä»£ã®ãã£ã¹ã¯ãªãŒãã°ã©ãã£ãã¯ã«ãŒãããæã¡ã®å Žåã¯ã次ã®æ¹æ³ããè©Šããã ããã åäžã®ããã·ã¥ãæ¢ããŠããã®ã§ããã«ãŒããã©ãŒã¹çšã®çŽ æŽãããããŒã«-hashcat-liteã䜿çšããããšã«ããŸããã ããã¯hashcatã®æéããŒãžã§ã³ã®1ã€ã§ãããWindowsãå«ããã¹ãŠã®äž»èŠãªãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§äœ¿çšã§ããŸãã
ãã®ã³ãŒãã䜿çšããŠããŒã¯ã³ãçæããŸãã
$rand = mt_rand(); echo "Random Number: ", $rand, PHP_EOL; $token = hash('sha512', $rand); echo "Token: ", $token, PHP_EOL;
ãã®ã³ãŒãã¯ããªã¯ãšã¹ãAããããŒã¯ã³ãåçŸãïŒå¿
èŠãªä¹±æ°ãå«ãŸããŠãããSHA512ããã·ã¥ã«é ãããŠããŸãïŒãhashcatãå®è¡ããŸãã
./oclHashcat-lite64 -m1700 --pw-min=1 --pw-max=10 -1?d -o ./seed.txt <SHA512 Hash> ?d?d?d?d?d?d?d?d?d?d
ããããã¹ãŠã®ãªãã·ã§ã³ã®æå³ã¯æ¬¡ã®ãšããã§ãã
- -m1700ïŒããã·ã¥ã¢ã«ãŽãªãºã ãå®çŸ©ããŸãã1700ã¯SHA512ãæå³ããŸãã
- --pw-min = 1ïŒããã·ã¥å€ã®æå°å
¥åé·ãå®çŸ©ããŸãã
- --pw-max = 10ïŒããã·ã¥å€ã®æ倧å
¥åé·ãå®çŸ©ããŸãïŒ
mt_rand()
å Žåã¯10ïŒã - -1ïŒDïŒæ°åïŒ0ã9ïŒã®ã¿ã®ã«ã¹ã¿ã èŸæžãå¿
èŠã§ãããšå€æããŸãã
- -o ./seed.txtïŒçµæãèšé²ããããã®ãã¡ã€ã«ã ç»é¢ã«ã¯äœã衚瀺ãããªãã®ã§ãå¿
ããã®ãã©ã¡ãŒã¿ãŒãèšå®ããŠãã ããïŒ
- ïŒdïŒdïŒdïŒdïŒdïŒdïŒdïŒdïŒdïŒdïŒdïŒäœ¿çšããã圢åŒãå®çŸ©ãããã¹ã¯ïŒæ倧10æ¡ãŸã§ã®ãã¹ãŠã®æ°åïŒã
ãã¹ãŠãæ£åžžã«æ©èœããGPUã溶ããªãå ŽåãHashcatã¯æ°åã§ããã·ã¥åãããä¹±æ°ãèšç®ããŸãã ã¯ããåã åã«ããšã³ããããŒã®ä»çµã¿ã«ã€ããŠèª¬æããŸããã èªåã§èŠãŠãã ããã mt_rand()
é¢æ°ã®æ©èœmt_rand()
éåžžã«å°ãªãããããã¹ãŠã®å€ã®SHA512ããã·ã¥ãå®éã«éåžžã«çæéã§èšç®ã§ããŸãã ãããã£ãŠã mt_rand()
åºåãããã·ã¥ããããšã¯ç¡æå³mt_rand()
ã
ã¹ããã4.æ°ãã«ã¯ã©ãã¯ãããä¹±æ°ã䜿çšããŠåæå€ã埩å
ãã
äžã§èŠãããã«ãSHA512ããçæãããmt_rand()
å€ãæœåºããã®ã«æ°åããããŸãã ã©ã³ãã ãªå€ã§æŠè£
ããŠããã«ãŒããã©ãŒã¹çšã®å¥ã®ããŒã«php_mt_seedãå®è¡ã§ããŸãã ãã®å°ããªãŠãŒãã£ãªãã£ã¯mt_rand()
åºåãmt_rand()
ãããã«ãŒããã©ãŒã¹ãåæå€ãèšç®ããåŸãããã«åºã¥ããŠåæãããå€ãçæã§ããŸãã çŸåšã®ããŒãžã§ã³ãããŠã³ããŒãããã³ã³ãã€ã«ããŠå®è¡ããŸãã ã³ã³ãã€ã«ã§åé¡ãçºçããå Žåã¯ãå€ãããŒãžã§ã³ãè©ŠããŠãã ããïŒæ°ããä»®æ³ç°å¢ã§åé¡ãçºçããŸããïŒã
./php_mt_seed <RANDOM NUMBER>
CPUã§å®è¡ããããããSHA512ããããã³ã°ãããããå°ãæéããããå ŽåããããŸãã é©åãªããã»ããµã§ã¯ããŠãŒãã£ãªãã£ã¯æ°åã§åæå€ã®å¯èœãªç¯å²å
šäœãèŠã€ããŸãã â (. . , ). : , PHP . , , , .
, , . mt_rand()
, , (, mt_rand()
). , , . , mt_rand()
Python.
5.
, mt_rand()
. , :
function predict($seed) { mt_srand($seed); mt_rand(); $token = hash('sha512', mt_rand()); return $token; }
.
6 7. !
URL, , . , , HTML ( ). XSS- , « » (Man-In-The-Browser). , ? , , , , . â , , .
mt_rand()
. , mt_rand()
, , « ».
, . , , mt_rand()
- , , , «» , . , . mt_rand()
â , ?
. mt_rand()
( ) . , mt_rand()
. â , mt_rand()
, .
. , , , , .
, PRNG, PHP, (. . ). :
$token = hash('sha512', uniqid(mt_rand()));
. , PHP- uniqid()
. :
-.
, â . - , mt_rand()
, mt_rand()
- . uniqid()
â . . . .
, «», . . . 1 000 000 . 1 , (, HTTP Date ), . , uniqid()
-:
gettimeofday((struct timeval *) &tv, (struct timezone *) NULL); sec = (int) tv.tv_sec; usec = (int) (tv.tv_usec % 0x100000); if (more_entropy) { spprintf(&uniqid, 0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg(TSRMLS_C) * 10); } else { spprintf(&uniqid, 0, "%s%08x%05x", prefix, sec, usec); } RETURN_STRING(uniqid, 0);
, PHP:
function unique_id($prefix = '', $more_entropy = false) { list($usec, $sec) = explode(' ', microtime()); $usec *= 1000000; if(true === $more_entropy) { return sprintf('%s%08x%05x%.8F', $prefix, $sec, $usec, lcg_value()*10); } else { return sprintf('%s%08x%05x', $prefix, $sec, $usec); } }
, uniqid()
13 . 8 â Unix ( ), . 5 â . , uniqid()
, uniqid()
:
$id = uniqid(); $time = str_split($id, 8); $sec = hexdec('0x' . $time[0]); $usec = hexdec('0x' . $time[1]); echo 'Seconds: ', $sec, PHP_EOL, 'Microseconds: ', $usec, PHP_EOL;
-. , :
echo uniqid(), PHP_EOL;
, , uniqid()
â . , uniqid()
. , , 1 000 000 . , . uniqid()
:
$token = hash('sha512', uniqid(mt_rand()));
, , mt_rand()
uniqid()
, SHA512-, . uniqid()
, , HTTP Date. . , !
<?phpphp echo PHP_EOL; mt_srand(1361723136.7); $token = hash('sha512', uniqid(mt_rand())); $httpDateSeconds = time(); $bruteForcedSeed = 1361723136.7; mt_srand($bruteForcedSeed); $prefix = mt_rand(); for ($j=$httpDateSeconds; $j < $httpDateSeconds+2; $j++) { for ($i=0; $i < 1000000; $i++) { $guess = hash('sha512', sprintf('%s%8x%5x', $prefix, $j, $i)); if ($token == $guess) { echo PHP_EOL, 'Actual Token: ', $token, PHP_EOL, 'Forced Token: ', $guess, PHP_EOL; exit(0); } if (($i % 20000) == 0) { echo '~'; } } }
?
, uniqid() TRUE:
$token = hash('sha512', uniqid(mt_rand(), true));
-, php_combined_lcg()
. lcg_value()
, PHP- uniqid()
. , , , . , . mt_rand()
, PHP- .
static void lcg_seed(TSRMLS_D) { struct timeval tv; if (gettimeofday(&tv, NULL) == 0) { LCG(s1) = tv.tv_sec ^ (tv.tv_usec<<11); } else { LCG(s1) = 1; } #ifdef ZTS LCG(s2) = (long) tsrm_thread_id(); #else LCG(s2) = (long) getpid(); #endif if (gettimeofday(&tv, NULL) == 0) { LCG(s2) ^= (tv.tv_usec<<11); } LCG(seeded) = 1; }
- , . .
gettimeofday()
Unix Epoch ( ). , , microsecond()
, . ID , Linux 32 768. , 4 , /proc/sys/kernel/pid_max
, .
, , LCG, . , mt_rand()
? , .
#ifdef PHP_WIN32 #define GENERATE_SEED() (((long) (time(0) * GetCurrentProcessId())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C)))) #else #define GENERATE_SEED() (((long) (time(0) * getpid())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C)))) #endif
, PHP . . , , : , ( 0 + - gettimeofday())
. gettimeofday()
, ( PHP ). , mt_rand()
, .
php_combined_lcg()
. lcg_value()
, PHP-. , . â , .
...
, . , php_combined_lcg()
, â , . lcg_value()
, mt_rand()
, PRNG, PHP. lcg_value()
, . LCG ( mt_srand()
, , - -). , : PHP.
spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);
(pre-hash) ID , IP, , ⊠php_combined_lcg()
. ( 1 ID 2 php_combined_lcg()
, ), . , .
, , , PHP session.entropy_file session.entropy_length. ID , ( ) php_combined_lcg()
LCG-. PHP 5.3 , , , . , ID LCG.
Windows- , LCG-.
, LCG , mt_rand()
, mt_rand()
.
uniqid()
?
$token = hash('sha512', uniqid(mt_rand(), true));
. ( !). ID , ID.
, ? uniqid()
, LCG, . , ID , , , ( !).
PHP . API PRNG- , . openssl mcrypt. , , , .
, , , . , mt_rand()
, , . , , RandomLib . .
. , . . : , ; , . â .
RandomLib , . , mt_rand()
, uniqid()
lcg_value()
, PID, , - , $_ENV, posix_times() . . , RandomLib. , - (. . , - hash()
).
$factory = new \RandomLib\Factory; $generator = $factory->getMediumStrengthGenerator(); $token = hash('sha512', $generator->generate(32));
, OpenSSL Mcrypt (footprint) RandomLib RandomLib , PRNG- SecurityMultiToo l.