脆弱性から学ぶ
Webセキュリティ Part2/study-web-security-from-vulnerability2

022fe97731555344992c588527848cb7?s=47 hypermkt
December 01, 2019

脆弱性から学ぶ
Webセキュリティ Part2/study-web-security-from-vulnerability2

バーチー @hypermkt
2019.12.01 PHPカンファレンス
https://phpcon.php.gr.jp/2019/

脆弱性から学ぶ
Webセキュリティ Part1 はこちら
https://speakerdeck.com/hypermkt/study-web-security-from-vulnerability1

022fe97731555344992c588527848cb7?s=128

hypermkt

December 01, 2019
Tweet

Transcript

  1. ੬ऑੑ͔ΒֶͿ WebηΩϡϦςΟ Part 2 όʔνʔ @hypermkt 2019.12.01 PHPΧϯϑΝϨϯε 1

  2. ࣗݾ঺հ • όʔνʔ / @hypermkt • ιϑτ΢ΣΞΤϯδχΞ • [‘PHPer’, ‘Laravel’,

    ‘Vue.js’] • https://blog.hypermkt.jp/ 2
  3. 2019/11/18ൃച
 Software Design 2019೥12݄߸ʹॳدߘ͠·ͨ͠!!! 3

  4. ͸͡Ίʹ

  5. ຊτʔΫ͕ఏڙ͢Δ͜ͱ • ΤϯδχΞ͕WebηΩϡϦςΟΛֶͿඞཁੑ • ੬ऑੑͷ֓ཁͱରࡦ 5

  6. ຊτʔΫ͕ఏڙ͠ͳ͍͜ͱ • ֎෦੬ऑੑ਍அ΍੬ऑੑݕ஌πʔϧʹ͍ͭͯ • ιϑτ΢ΣΞ੡඼ɾΠϯϑϥͷ੬ऑੑରࡦ 6

  7. ຊτʔΫͷର৅ऀ • WebΞϓϦέʔγϣϯΤϯδχΞ(αʔόʔαΠυ) • ॳ৺ऀʙதڃऀ • WebηΩϡϦςΟʹڵຯ͕͋Δ • αʔϏεɾγεςϜΛकΓ͍ͨํ 7

  8. օ͞Μʹ࣋ͪؼͬͯཉ͍͠΋ͷ • ੬ऑੑͷո͍͠೏͍ 8

  9. ໨࣍ 1. ΤϯδχΞ͕WebηΩϡϦςΟΛֶͿඞཁੑ 2. ੬ऑੑ͔ΒֶͿWebηΩϡϦςΟ 3. ࢀߟɾҾ༻ࢿྉ 4. ·ͱΊ 9

  10. Part 2…?

  11. ੬ऑੑ͔ΒֶͿWebηΩϡϦςΟ 
 in PHPΧϯϑΝϨϯεԭೄ2019 11 IUUQTTQFBLFSEFDLDPNIZQFSNLUTUVEZXFCTFDVSJUZGSPNWVMOFSBCJMJUZ Part 1 ※ ͋ͱ͚ͮ!!

  12. PHPΧϯϑΝϨϯεԭೄ2019Ͱ͸ • SQLΠϯδΣΫγϣϯ • ΫϩεαΠτɾεΫϦϓςΟϯά • CSRF • ʹ͍͓ͭͯ࿩͠·ͨ͠! 12

  13. ΤϯδχΞ͕WebηΩϡϦςΟΛ ֶͿඞཁੑ

  14. զʑͷγεςϜɾαʔϏε͸
 ৗʹૂΘΕ͍ͯΔ

  15. ௚ۙ൒೥ʹXSS੬ऑੑ͕ٸ૿ 15 ग़య*1" ৘ใॲཧػߏ 
 ιϑτ΢ΣΞ౳ͷ੬ऑੑؔ࿈৘ใʹؔ͢Δಧग़ঢ়گ<೥ୈ࢛൒ظʢ݄ʙ݄ʣ>
 IUUQTXXXJQBHPKQpMFTQEG

  16. ੬ऑੑͷڴҖ • ݸਓ৘ใͷӾཡ • WebαΠτͷվ͟Μ • ΢Πϧεײછ • ผͷར༻ऀ΁ͷͳΓ͢·͠ •

    WebαΠτΛར༻ෆՄʹ͢Δ • ϨϐϡςʔγϣϯϦεΫ(اۀʹର͢ΔϚΠφεධՁʣ • ܦࡁతଛࣦ 16
  17. ੬ऑੑͱ͸

  18. ιϑτ΢ΣΞ΍γεςϜΛѱ༻Ͱ͖Δόά ੬ऑੑͱ͸

  19. ιϑτ΢ΣΞ΍γεςϜΛѱ༻Ͱ͖Δόά ੬ऑੑͱ͸ ͭ·Γզʑ։ൃऀʹ࡞ΒΕ͍ͯΔ

  20. ͳͥ։ൃऀ͸੬ऑੑΛ࡞ͬͯ͠·͏ͷ͔ʁ 20

  21. ͳͥ։ൃऀ͸੬ऑੑΛ࡞ͬͯ͠·͏ͷ͔ʁ • ੬ऑੑʹؔ͢Δ஌ࣝෆ଍ • ΞϓϦέʔγϣϯઃܭෆ଍ 21

  22. Ͳ͏ͨ͠Β
 ҆શͳΞϓϦέʔγϣϯͷ։ൃ͕ Ͱ͖Δ͔

  23. ੬ऑੑͷ֓ཁɾڴҖɾରࡦʹ ͍ͭͯ஌Δ͜ͱ

  24. ੬ऑੑʹ͍ͭͯ஌Δ͜ͱͰɺ ҆શͳWebΞϓϦέʔγϣϯ։ൃ ͕Ͱ͖ΔΑ͏ʹͳΔ

  25. ҰॹʹWebηΩϡϦςΟΛ ֶΜͰ͍͖·͠ΐ͏!

  26. ੬ऑੑ͔ΒֶͿWebηΩϡϦςΟ

  27. ੈͷதʹ͸༷ʑͳ੬ऑੑ͕͋Δ • SQLΠϯδΣΫγϣϯ • ΫϩεαΠτεΫϦϓςΟϯά • CSRF • σΟϨΫτϦτϥόʔαϧ •

    OSίϚϯυɾΠϯδΣΫγϣϯ • ηογϣϯ؅ཧͷෆඋ • HTTP/ϝʔϧϔομʔΠϯδΣΫγϣϯ • ΞΫηε੍ޚ΍ೝՄ੍ޚͷܽམ • ͳͲ 27
  28. ࠓ೔͸ҎԼ3఺Λղઆ͠·͢ • SQLΠϯδΣΫγϣϯ • ΫϩεαΠτεΫϦϓςΟϯά • CSRF • σΟϨΫτϦτϥόʔαϧ •

    OSίϚϯυɾΠϯδΣΫγϣϯ • ηογϣϯ؅ཧͷෆඋ • HTTP/ϝʔϧϔομʔΠϯδΣΫγϣϯ • ΞΫηε੍ޚ΍ೝՄ੍ޚͷܽམ • ͳͲ 28
  29. ੬ऑੑରࡦͷߏ͑

  30. ੬ऑੑͷରࡦํ๏͸̎௨Γ • ࠜຊతղܾ • อݥతରࡦ 30

  31. • ࠜຊతղܾ • ੬ऑੑΛ࡞Γࠐ·ͳ͍࣮૷Λ࣮ݱ͢Δํ๏ • ੬ऑੑΛૂͬͨ߈ܸΛແޮԽ͢Δ • อݥతରࡦ • ੬ऑੑΛૂͬͨ߈ܸʹΑΔӨڹΛܰݮ͢Δํ๏

    • ੬ऑੑͷݪҼΛແ͘͢΋ͷͰ͸ͳ͍ 31
  32. ͲͪΒΛબ୒͢΂͖͔ʁ

  33. ঢ়گʹԠͯ͡൑அΛ͢Δ • جຊతʹ͸ࠜຊతղܾͰ੬ऑੑΛແޮԽ͢Δͷ͕ཧ૝త • ୠ͠ӡ༻தͷΞϓϦέʔγϣϯʹ͓͍ͯɺ࣌ؒɾϦιʔεɾ Өڹൣғ͔Β͙͢ʹࠜຊతղܾ͕࣮ࢪͰ͖ͳ͍৔߹ʹ
 อݥతରࡦ͸࢑ఆରԠͱͯ͠༗ޮ 33

  34. ΍͍͖ͬͯ·͠ΐ͏

  35. σΟϨΫτϦɾτϥόʔαϧ Directory Traversal

  36. σΟϨΫτϦɾτϥόʔαϧͱ͸ • ϑΝΠϧ໊ͷࢦఆͷ࣮૷ʹ໰୊͕͋Δ৔߹ʹɺ
 ߈ܸऀʹ೚ҙͷϑΝΠϧ͕ࢦఆ͞Εɺ
 ॏཁͳϑΝΠϧ͕Ӿཡɾ࡟আ͞Εͯ͠·͏੬ऑੑ 36 ੬ऑੑͷ͋ΔαΠτ ᶃෆਖ਼ϦΫΤετΛ ૹ৴ 8FCαʔόʔ

    ᶄॏཁϑΝΠϧ͕
 Ӿཡ͞Εͯ͠·͏  pMFFUDQBTTXE ߈ܸऀ
  37. ڴҖ • ৘ใ࿙͍͑ • ॏཁͳϑΝΠϧ͕Ӿཡɾฤूɾ࡟আ͞ΕΔ 37

  38. ݪҼ • ϑΝΠϧ໊ͱͯ͠ઈରύεɾ૬ରύεͷܗͰ
 ҟͳΔσΟϨΫτϦΛࢦఆͰ͖Δ • ૊ΈཱͯͨϑΝΠϧʹର͢ΔΞΫηεՄ൱ͷνΣοΫΛ ͍ͯ͠ͳ͍ 38

  39. 39 σΟϨΫτϦɾτϥόʔαϧྫ ೖྗύϥϝʔλʔΛͦͷ··౉͍ͯ͠Δ ߈ܸྫ ӾཡͰ͖ͯ͸͍͚ͳ͍ϑΝΠϧ͕
 ӾཡͰ͖͍ͯΔ!!

  40. Ӿཡ͞ΕͨΒࠔΔϑΝΠϧɺͨ͘͞Μ͋Γ·͢ΑͶ…. • /etc/hosts • /etc/passwd • wp-config.php • my.cnf •

    ϩάϑΝΠϧ • ͳͲͳͲ… 40
  41. ո͍͠೏͍ • ֎෦ύϥϝʔλʔ͔ΒϑΝΠϧ໊Λ౉࣮͢૷͕͋Δͱո ͍͠ 41

  42. ࠜຊతղܾ • ֎෦͔ΒϑΝΠϧ໊Λࢦఆ͢Δ࢓༷Λආ͚Δ • ྫʣ಺෦తʹϑΝΠϧ໊Λݻఆʹ͢Δ • ϑΝΠϧ໊ʹσΟϨΫτϦؚ໊͕·Εͳ͍Α͏ʹ͢Δ • ྫʣ 42

    ϙΠϯτ!
  43. อݥతରࡦ • ϑΝΠϧ໊Λӳ਺ࣈʹݶఆͯ͠ɺσΟϨΫτϦɾτϥόʔαϧʹ ༻͍ΒΕΔه߸จࣈΛ࢖༻ෆՄʹ͢Δ 43 ϙΠϯτ!

  44. OSίϚϯυɾΠϯδΣΫγϣϯ OS Command Injection

  45. OSίϚϯυΠϯδΣΫγϣϯͱ͸ • ֎෦͔Βͷ߈ܸʹΑΓɺαʔόʔͷOSίϚϯυ͕࣮ߦ ͞Εͯ͠·͏໰୊ 45 ੬ऑੑͷ͋ΔαΠτ ᶃෆਖ਼ϦΫΤετΛ ૹ৴ 8FCαʔόʔ ᶄ04ίϚϯυ͕


    ࣮ߦ͞ΕΔ IPHF!IPHFDPNSNGVHBJNQPSUBOUpMF ߈ܸऀ
  46. ڴҖ • ৘ใ࿙͍͑ • ॏཁͳϑΝΠϧ͕Ӿཡɾฤूɾ࡟আ͞ΕΔ • WebαΠτΛར༻ෆՄʹ͢Δ • ผαʔόʔ΁ͷ߈ܸͷ౿Έ୆ʹ͞ΕΔ 46

  47. ݪҼ • OSͷγΣϧݺͼग़͕͠Ͱ͖Δؔ਺ʹɺෆਖ਼ͳίϚϯυ ͕஫ೖ͞Εͯ͠·͏ 47

  48. OSίϚϯυΠϯδΣΫγϣϯྫ • ݱࡏϑΝΠϧ͕༗Δ৔ॴʹσΟϨΫτϦΛ࡞੒͢Δ ϓϩάϥϜ͕͋Δ 48 ೖྗύϥϝʔλʔΛͦͷ··౉͍ͯ͠Δ!!

  49. 49 ೖྗύϥϝʔλʔΛͦͷ··౉͍ͯ͠Δ!! • ෆਖ਼ͳೖྗྫɿ • ࣮ߦ͞ΕΔίϚϯυɿ ηϛίϩϯʮ;ʯ Λར༻ͯ͠LinuxίϚϯυΛ
 ࿈ଓ࣮ͯ͠ߦͤ͞Δ OFXEJSSNFUDIPTUT

    TZTUFN lNLEJSQWBSXXXBQQOFXEJSSNFUDIPTUTz ຊ౰ʹϑΝΠϧ͕࡟আ͞ΕΔ…
  50. ةݥ͗͢Δ…

  51. γΣϧݺͼग़͠ػೳ͕͋ΔPHPؔ਺ • system • exec • passthru • shell_exec •

    popen 51
  52. ո͍͠೏͍ • PHPͷγΣϧݺͼग़͕͠Մೳͳؔ਺Λ࢖༻͍ͯ͠Δ 52 • system • exec • passthru

    • shell_exec • popen
  53. ࠜຊతղܾᶃ • γΣϧݺͼग़͠ػೳͷ͋ΔPHPؔ਺Λ࢖༻͠ͳ͍ • OSίϚϯυΛ࣮ߦ͠ͳ͍࣮૷ํ๏Λબ୒͢Δ • ྫʣOSίϚϯυͷ mail ΍ sendmail

    Λ࢖༻ͤͣ PHPͷmb_send_mailؔ਺Λ࢖༻͢Δ 53
  54. ࠜຊతղܾᶄ • OSίϚϯυʹ౉͢ύϥϝʔλʔΛΤεέʔϓ͢Δ͜ͱ ʹΑΓɺҰͭͷจࣈྻͱͯ͠஋Λ౉ͤΔͷͰ҆શʹͳΔ • PHPͰ͸ɺescapeshellarg Λ࢖༻͢Δ 54

  55. อݥతରࡦ • ύϥϝʔλʔͷݕূ • Ҿ਺ΛݫີʹνΣοΫͯ͠ɺڐՄͨ͠ύϥϝʔλʔͷΈ Λ௨͢ 55

  56. ηογϣϯ؅ཧͷෆඋ

  57. ηογϣϯ؅ཧͷෆඋͱ͸ • ηογϣϯͷൃߦͱ؅ཧʹෆඋ͕͋৔߹ʹൃੜ͢Δ੬ऑ ੑ 57

  58. ߈ܸྫ • ηογϣϯϋΠδϟοΫ • ηογϣϯIDͷݻఆԽ / ผ໊: Session Fixation 58

  59. ηογϣϯϋΠδϟοΫͱ͸ • ηογϣϯIDΛԿΒ͔ͷํ๏Ͱ౪ΈɺଞਓʹͳΓ͢·͢͜ͱ 59 ߈ܸऀ ར༻ऀ ੬ऑੑͷ͋ΔαΠτ ᶃ߈ܸεΫϦϓτΛ ࢓ࠐΉ ᶄ੬ऑੑͷ͋ΔαΠτʹ


    ΞΫηε͢Δ ᶅηογϣϯ*%Λ౪Έग़͠ ᶆ੒Γ͢·͠ϩάΠϯ
  60. ηογϣϯIDͷݻఆԽ߈ܸ • ߈ܸऀ͕औಘͨ͠ηογϣϯIDΛαΠτͷ੬ऑੑΛར༻ͯ͠ɺ
 Ϣʔβʔʹނҙʹઃఆͤ͞Δɻར༻ऀ͕ϩάΠϯ͢Δ͜ͱͰɺ
 ߈ܸऀͷͳΓ͢·͠Λ੒ཱͤ͞Δ 60 ߈ܸऀ ར༻ऀ ੬ऑੑͷ͋ΔαΠτ ᶃαΠτʹΞΫηεͯ͠


    ηογϣϯ*%Λऔಘ ᶄηογϣϯ*%ͷૹΓࠐΈ ᶅαΠτʹϩάΠϯ ᶆͳΓ͢·͠੒ཱ
  61. Ͳ͏΍ͬͯར༻ऀʹηογϣϯIDΛૹΓࠐΉͷ͔ • ηογϣϯɾΞμϓγϣϯ / Session Adoption • ࣗ෼͕ൃߦ͍ͯ͠ͳ͍ηογϣϯIDΛ༗ޮͳηογϣϯIDͱͯ͠ڐՄ
 ͯ͠͠·͏͜ͱ •

    ࠶ݱྫʣ 1.URLʹΑΔηογϣϯID͕อ࣋Ͱ͖Δঢ়ଶͱ͢Δ 2.߈ܸंʹΑΓ֎෦αΠτ͔Β http://example.jp/?PHPSESSID=hoge ʹ༠ಋ͞ΕΔ 3.ར༻ऀ͸ͦͷঢ়ଶͰϩάΠϯ͢Δ 61 ηογϣϯIDͷURLอ࣋Մઃఆ
 session.use_cookies: 1 session.use_only_cookies: 0 session.use_trans_sid: 1
  62. ڴҖ • ৘ใ࿙͍͑ • ϩάΠϯޙʹར༻ऀͷΈ͕ӾཡՄೳͳ৘ใͷӾཡɺૢ ࡞ɺѱ༻ 62

  63. ݪҼ 1. XSS • ෆਖ਼ͳεΫϦϓτʹΑΓηογϣϯID͕औಘ͞ΕΔ • ηογϣϯϋΠδϟοΫʹѱ༻͞ΕΔ 2. ਪଌՄೳͳηογϣϯID •

    ηογϣϯID͕ਪଌ͞ΕΔ͜ͱʹΑΓηογϣϯID͕औಘ͞ΕΔ • ηογϣϯϋΠδϟοΫʹѱ༻͞ΕΔ 3. ηογϣϯIDͷURLύϥϝʔλʔར༻ • ྫ) http://example.jp/?PHPSESSID=XXX • ࠷ۙͷγεςϜͰ͸΄΅ແ͍ɻݹ͍ΨϥέʔγεςϜʹݟΒΕΔ • RefererϔομʔʹΑΓηογϣϯID͕࿙Ӯ͢Δ • ηογϣϯϋΠδϟοΫ/ηογϣϯIDͷݻఆԽʹѱ༻͞ΕΔ 4. ೝূલޙͰηογϣϯID͕ಉ͡ • ηογϣϯIDͷݻఆԽʹѱ༻͞ΕΔ 63
  64. ࠜຊతղܾ 1.XSSରࡦ 2.ηογϣϯIDΛਪଌࠔ೉ͳ΋ͷʹ͢Δ 3.ηογϣϯID͸ΫοΩʔͷΈͰอ࣋͢Δ 4.ೝূ͕੒ޭͨ͠Β৽͍͠ηογϣϯΛ։࢝͢Δ 64

  65. XSSରࡦ 65 w ΢Σϒϖʔδ্ͷશͯͷग़ྗՕॴͰΤεέʔϓॲཧΛ͢Δ w Ϣʔβʔ͕ೖྗͨ͠จࣈྻΛ)5.-λάͱͯ͠ղऍ͠ͳ͍Α͏ʹॲཧ Λ͢Δ͜ͱ w ಛघจࣈΛ)5.-ΤϯςΟςΟʹม׵͢Δ͜ͱͰରԠͰ͖Δ 

    ˠ MU  ˠ HU l ˠ RVPU ` ˠ   ˠ BNQ
  66. ηογϣϯIDΛਪଌࠔ೉ͳ΋ͷʹ͢Δ • ҆શͳཚ਺ΛݩʹηογϣϯIDΛൃߦ͢Δ • PHP5.4Ҏ߱ • ҉߸࿦తٖࣅཚ਺ੜ੒ث(CSPRNG) Λ࢖༻ͯ҆͠શͳηογϣϯID͕ൃߦ͞ΕΔ Α͏ʹͳ͍ͬͯΔ •

    PHP5.4ະຬ • php.iniʹҎԼઃఆΛՃ͑ͯ҆શͳηογϣϯཚ਺ΛݩʹηογϣϯIDΛൃߦ͢Δ 66 [Session] session.entropy_file = /dev/urandom session.entroy_length = 32 PHP 5.4͔ΒσϑΥϧτͰ͜ͷઃఆʹͳ͍ͬͯΔɻͦͷ··ͰOKɻ
  67. ηογϣϯID͸ΫοΩʔͷΈͰอ࣋ɺURLύϥϝʔλʔͰอ࣋͠ͳ͍ 67 ໊લ σϑΥϧτ஋ આ໌ TFTTJPOVTF@DPPLJFT lz ηογϣϯͷอ࣋ʹΫοΩʔΛ
 ར༻͢Δ TFTTJPOVTF@POMZ@DPPLJFT

    lz ΫοΩʔͷΈʹηογϣϯΛ
 อ࣋͢Δ TFTTJPOVTF@USBOT@TJE lz 63-ʹηογϣϯ*%อ࣋Λ
 ͠ͳ͍ σϑΥϧτ஋ͷ··Ͱ php.iniઃఆ
  68. ೝূ͕੒ޭͨ͠Β৽͍͠ηογϣϯΛ։࢝͢Δ • ʮsession_regenerate_id(true) ʯͰݹ͍ηογϣϯΛ
 ഁغͯ͠৽͍͠ηογϣϯIDΛൃߦ • ηογϣϯIDͷݻఆԽ߈ܸͷ๷ࢭ 68

  69. ͥͻطଘઃఆΛݟ௚ͯ͠Έ͍ͯͩ͘͞

  70. ࢀߟɾҾ༻ࢿྉ

  71. • ମܥతʹֶͿ ҆શͳWebΞϓ Ϧέʔγϣϯͷ࡞Γํ ୈ2൛ ੬ ऑੑ͕ੜ·ΕΔݪཧͱରࡦͷ࣮ ફ / ಙؙ

    ߒ (ஶ) • IPA ҆શͳ΢ΣϒαΠτͷ࡞Γ ํ ୈ7൛
 https://www.ipa.go.jp/ security/vuln/websecurity.html 71
  72. ·ͱΊ

  73. ·ͱΊ • զʑͷγεςϜɾαʔϏε͸ৗʹૂΘΕ͍ͯΔ • αʔϏεͷ҆શੑΛߴΊΔͨΊʹ͸ɺΤϯδχΞࣗ਎ͷ WebηΩϡϦςΟೳྗ޲্͕ඞཁ • ຊ೔ڞ༗ͨ͠੬ऑੑରࡦΛ͖͔͚ͬʹօ͞Μͷ
 αʔϏεɾγεςϜͷ҆શੑ͕޲্Ͱ͖ͨΒ޾͍Ͱ͢ 73

  74. ิ଍ࢿྉ

  75. CookieʹSecureଐੑΛՃ͑Δ • HTTPS௨৴࣌ͷΈCookie͕ϒϥ΢β͔Βૹ৴ͤ͞ɺ
 HTTP௨৴࣌ͷCookieྲྀग़Λ๷͙ • php.ini ͷ session.cookie_secure Λ 1

    ʹ͢Δ͜ͱͰରԠՄ 75 ग़య: https://www.php.net/manual/ja/session.configuration.php#ini.session.cookie-secure
  76. 76 ग़య: http://dsas.blog.klab.org/archives/52136166.html

  77. ཁ఺: PHPͷηογϣϯID͸҉߸࿦తʹऑ͍ཚ਺ੜ ੒ثΛ࢖͓ͬͯΓɺηογϣϯϋΠδϟοΫͷةݥ ੑ͕͋Δ • PHPͷηογϣϯIDͷൃߦॲཧʹɺҎԼͷ૊Έ߹ΘͤΛMD5ʹ௨͠ ͯੜ੒͍ͯ͠ΔɻۃΊͯݶఆతͳ৚͕݅ͩɺηογϣϯIDͷਪଌՄ ೳͱ͍͏࿦จ͕ެද͞Ε͍ͯΔɻ • ϦϞʔτIPΞυϨε

    • λΠϜελϯϓ • ཚ਺ʢ҉߸࿦తٙࣅཚ਺ൃੜثͰ͸ͳ͍ 77 ग़య: http://dsas.blog.klab.org/archives/52136166.html