Upgrade to Pro — share decks privately, control downloads, hide ads and more …

知られざるSerialize

 知られざるSerialize

F075c5dfe92334b5031d4da5dc0c9251?s=128

Yuichi Sugiyama

July 31, 2019
Tweet

Transcript

  1. ஌ΒΕ͟ΔSerialize @PHP Study Cybozu Inc, Yuichi Sugiyama

  2. Who am I • ਿࢁ ༞Ұ @oogFranz • αΠϘ΢ζ5೥໨ΤϯδχΞ •

    େاۀ޲͚άϧʔϓ΢ΣΞ Λ࡞ͬͯΔʢPHP 7.2) • ෳۀδϟζϛϡʔδγϟϯ@MASHݭָஂ
  3. serialize(), unserialize()࢖ͬͯ·͔͢ʁ

  4. serialize() όϦϕϯϦ $a = ["hoge", 3, true]; $a[] = &$a;

    echo serialize($a); # a:4:{i:0;s:4:"hoge";i:1;i:3;i:2;b:1;i:3;a:4: {i:0;s:4:"hoge";i:1;i:3;i:2;b:1;i:3;R:5;}} • PHPͷ஋Λ෮ݩՄೳͳจࣈྻʹม׵͢Δɻ • ΫϥεͷΠϯελϯεͰ͋ͬͯ΋ม׵Մೳʂ • DBʹ΋อଘͰ͖Δʂ΍ͬͨͶʂ
  5. serialize() όϦϕϯϦ $a = ["hoge", 3, true]; $a[] = &$a;

    echo serialize($a); # a:4:{i:0;s:4:"hoge";i:1;i:3;i:2;b:1;i:3;a:4: {i:0;s:4:"hoge";i:1;i:3;i:2;b:1;i:3;R:5;}} • PHPͷ஋Λ෮ݩՄೳͳจࣈྻʹม׵͢Δɻ • ΫϥεͷΠϯελϯεͰ͋ͬͯ΋ม׵Մೳʂ • DBʹ΋อଘͰ͖Δʂ΍ͬͨͶʂ
  6. Կ͕໰୊ʁ • serialize() ʹ͸࣮͸ͦΜͳʹ໰୊͸ͳ͍ • ٯؔ਺ͷunserialize()ʹ͍͔ͭ͘ͷ੬ऑੑ͕͋Δ

  7. PHP Object Injection ʢPOIʣ • ҎԼͷ৚͕݅ຬͨ͞Ε͍ͯΔ৔߹ɺ։ൃऀ͕ҙਤ͍ͯ͠ͳ͍
 ίʔυΛ߈ܸऀ͕࣮ߦͰ͖Δɻ • __wakeup(), __destruct()ͳͲͷϚδοΫϝιουʹ


    ෭࡞༻ͷ͋Δίʔυ͕ॻ͔Ε͍ͯΔ • unserialize()ͷҾ਺ʹϢʔβʔ͔Βͷೖྗ͕౉͞ΕΔ
  8. ϚδοΫϝιου • ಛఆͷ৚݅ͰࣗಈͰൃಈ͢Δຐ๏ • serialize()ͷ࣮ߦ࣌ʹϚδοΫϝιουͷ __sleep() ͕
 ͋ͬͨΒࣗಈͰ࣮ߦ͞ΕΔ • unserialize()࣌ʹɺϚδοΫϝιουͷ

    __wakeup() ͕
 ͋ͬͨΒࣗಈͰ࣮ߦ͞ΕΔ
  9. αϯϓϧ class POIExample{ private $filename; public function __destruct() { unlink($this->filename);

    } } unserialize('O:10:"POIExample":1:{s: 20:"POIExamplefilename";s:8:"test.php";}')
  10. αϯϓϧ class POIExample{ private $filename; public function __destruct() { unlink($this->filename);

    } } unserialize('O:10:"POIExample":1:{s: 20:"POIExamplefilename";s:8:"test.php";}') ߈ܸऀ͕೚ҙͷϑΝΠϧͷ࡟আ͕Մೳʂ
  11. POIͷ͕͜͜ා͍ • ࣮ࡍʹunserializeʹ౉͞ΕΔ͜ͱ͕ͳ͍ΫϥεͰ͋ͬͯ΋ɺ
 auto_loadͷ࢓૊Έ͕͋Δͱ࣮ߦ͞Εͯ͠·͏ɻ • privateͷϝϯόม਺ʹ΋೚ҙͷ஋Λ୅ೖՄೳ
 setterΛհ͞ͳ͍ͷͰɺߟྀ͕೉͍͠ɻ • ԾʹsetterͰσΟϨΫτϦτϥόʔαϧΛ๷͍Ͱ͍ͯ΋ແҙຯ

  12. • json_encode(), json_decode()Λ࢖͏ɻ
 ˠΦϒδΣΫτΛγϦΞϥΠζɾσγϦΞϥΠζ͢ΔͷͰͳ͚Ε͹ े෼ɻ • allowed_classesΦϓγϣϯΛ࢖͏
 ˠࢦఆ͞ΕͨΫϥεͷΦϒδΣΫτʹ͔͠
 ɹม׵͞Εͳ͍͜ͱ͕อূ͞ΕΔ POIΛ๷͙ʹ͸ʁ

  13. allowed_classes Φϓγϣϯ $serialized_str = 'O:10:"POIExample":1:{s:20:"POIExamplefilename";s: 8:"test.php";}'; $result = unserialize($serialized_str, ['allowed_classes'

    => false]); var_dump($result); /* object(__PHP_Incomplete_Class)#2 (2) { ["__PHP_Incomplete_Class_Name"]=> string(10) "POIExample" ["filename":"POIExample":private]=> string(8) "test.php" } */ echo serialize($result); // O:10:"POIExample":1:{s:20:"POIExamplefilename";s:8:"test.php";}
  14. allowed_classesͰकΕΔ΋ͷ • ڐՄ͞Ε͍ͯͳ͍ΫϥεΛunserialize()͢Δͱɺ__PHP_Incomplete_Class ʹม׵͞ΕΔ • ͦͷΦϒδΣΫτΛ΋͏Ұ౓serialize͢Δͱ
 ʢͳ͔ͥʣݩʹ໭Δɻ • σϑΥϧτ஋͸ true

    (ΨόΨό)ͳͷͰ໌ࣔతʹࢦఆ͢Δඞཁ͕͋Δ • falseΛࢦఆ͢Ε͹ɺ͋ΒΏΔΫϥεΛڋઈ͢Δ
  15. __PHP_Incomplete_ClassʹͳͬͨΒΤϥʔʹ͍ͨ͠ • ةͳ͍΋ͷ͕౉͖͍ͬͯͯΔͷͰΤϥʔʹ͍ͨ͠ • get_class Λͯ͠ɺ__PHP_Incomplete_Class ͔Λௐ΂Δ • unserialize_callback_func ͸ݺͼग़͞Εͳ͍ͷͰ஫ҙɻ

  16. allowed_classes͕͋Ε͹unserialize࢖ͬ ͯ΋ྑ͍ʁ https://twitter.com/nikita_ppv/status/895571304325062656

  17. allowed_classes͕͋Ε͹unserialize࢖ͬ ͯ΋ྑ͍ʁ https://www.php.net/manual/ja/function.unserialize.php

  18. unserializeͷ੬ऑੑ͸੬ऑੑͱΈͳ͞Εͳ͍ • ϝϞϦपΓͳͲͷෆ۩߹Ͱ͋ͬͯ΋੬ऑੑͱΈͳ͞Εͳ͍
 Մೳੑ͕͋Δ • ΧδϡΞϧʹϝϞϦपΓͷෆ۩߹͕ใࠂ͞Ε͍ͯΔ

  19. serializeͨ͠஋ΛDBʹೖΕΔ͜ͱʹ͍ͭͯ • SQL Ξϯνύλʔϯͷ
 5ষ EAVʢΤϯςΟςΟɾΞτϦϏϡʔτɾόϦϡʔʣ
 ʹͳͬͯΔՄೳੑ͕ߴ͍ɻ

  20. MySQLͱserialize • MySQLͷtextʹγϦΞϥΠζσʔλΛೖΕ͍ͯΔ৔߹ɺ
 จࣈ਺͕Φʔόʔ͢Δͱɺ్தͰ੾ΒΕͯ͠·͍ɺ
 ෮ݩͰ͖ͳ͘ͳΔɻʢStrict SQL Modeʹґଘʣ • MySQL 5.7͔Β͸JSONܕ͕࢖͑ΔΑ͏ʹͳͬͨͷͰɺ


    ಈతεΩʔϚ͕Ͳ͏ͯ͠΋ඞཁͳ৔߹΋JSONܕΛߟ͑ͨํ͕ Αͦ͞͏ɻ
  21. ·ͱΊ • serialize(), unserialize()Λ࢖͍ͬͯͳ͍ͷͳΒɺͦΕ͕Ұ൪ • ΋͠࢖͍ͬͯΔͷͳΒɺPOIΛ๷͙ͨΊɺϢʔβʔೖྗσʔλ͕ೖͬͯ͜ͳ͍͜ͳ͍͜ͱΛ͔֬Ί Α͏ • ՄೳͰ͋Ε͹json_encode, json_decodeʹஔ͖͔͑Α͏

    • ͦΕ΋ແཧͳΒɺallowed_classesΦϓγϣϯͰPOI͸͠ͷ͝͏ • DBʹ͸อଘ͠ͳ͍Α͏ʹ͠·͠ΐ͏ • ϝϞϦपΓͷෆ۩߹΋͋ΔͷͰஔ͖׵͑Λݕ౼͠·͠ΐ͏ɻ