
ãã€ã¯ããœããã¯ãã¢ããªã±ãŒã·ã§ã³ãä¿è·ããããã®æ°ãããã¯ãããžãäœåºŠãå®è£
ããããšã§ããšã¯ã¹ããã€ãèšè¿°åã䜿ã£ãçµããã®ãªãæŠäºã«åã€è©Šã¿ãæŸæ£ããŸããã ä»åãWindowsãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®éçºè
ã¯ããã®åé¡ã«æ ¹æ¬çã«åãçµã¿ãåé¡ã®æ ¹æ¬ã«èŠç¹ãç§»ããŸããã äœããã®åœ¢ã§ã®ã»ãŒãã¹ãŠã®ãšã¯ã¹ããã€ãã®äœæ¥ã¯ãã¢ããªã±ãŒã·ã§ã³å®è¡ã®ãããŒãååããããšãç®çãšããŠããããããã®ç¬éãç£èŠããããã«ã¢ããªã±ãŒã·ã§ã³ããæãããããšã¯å®³ã«ãªããŸããã
å¶åŸ¡ãããŒã®æŽåæ§ã®æŠå¿µã¯ã2005幎ã«èª¬æãããŸããã ãããŠä»ã10幎åŸãMicrosoftã®éçºè
ã¯ããã®ã³ã³ã»ããã®äžå®å
šãªå®è£
ã§ããControl Flow Guardãçºè¡šããŸããã
å¶åŸ¡ãããŒã¬ãŒããšã¯äœã§ããïŒ
å¶åŸ¡ãããŒã¬ãŒãïŒGuard CFãCFGïŒã¯ããŠãŒã¶ãŒããã³ã«ãŒãã«ã¢ãŒãã¢ããªã±ãŒã·ã§ã³ã®ãã€ããªè匱æ§ãæªçšããããã»ã¹ãè€éã«ããããšãç®çãšããæ¯èŒçæ°ããWindowsãšã¯ã¹ããã€ãç·©åã¡ã«ããºã ã§ãã ãã®ã¡ã«ããºã ã®æ©èœã¯ã鿥åŒã³åºããæ€èšŒããããšã§ããããã«ãããæ»æè
ãå®è¡ã¹ã¬ãããååããã®ãé²ããŸãïŒããšãã°ãä»®æ³é¢æ°ã®ããŒãã«ãäžæžãããããšã«ããïŒã 以åã®é²åŸ¡ã¡ã«ããºã ïŒ SafeSEH ã ASLR ã DEPãªã©ïŒãšçµã¿åãããããšã§ ããšã¯ã¹ããã€ãã®äœæè
ã«ãšã£ãŠã¯é çã®çš®ã§ãã
ãã®ã»ãã¥ãªãã£æ©èœã¯ãMicrosoft Windows 8.1ïŒUpdate 3ãKB3000850ïŒããã³Windows 10ã®ãŠãŒã¶ãŒãå©çšã§ããŸãã
CFGããµããŒãããããã°ã©ã ã®ã³ã³ãã€ã«ã¯ãMicrosoft Visual Studio 2015ã§å©çšã§ããŸãïŒ æå¹ã«ããæ¹æ³ã¯ïŒ ïŒã
Linuxãã¡ããªã®OSã®å¶åŸ¡ãããŒæŽåæ§ã®æŠå¿µã«åºã¥ãä¿è·ã¡ã«ããºã ã®åæ§ã®å®è£
ã¯ã PaXæ¡åŒµã§å©çšã§ããŸãã
å¶åŸ¡ãããŒã¬ãŒãã®ä»çµã¿
ãŠãŒã¶ãŒã¢ãŒãã§ã®CFGã®åçãèæ
®ããŠãã ããã ãã®ã¡ã«ããºã ã«ã¯ã2ã€ã®äž»èŠãªã³ã³ããŒãã³ãããããŸããã¢ãã¬ã¹ã®ããããããïŒã«ãŒãã«ã«ãã£ãŠå¶åŸ¡ãããïŒãšãåŒã³åºããã颿°ã®ãã€ã³ã¿ãŒããã§ãã¯ããæé ïŒãŠãŒã¶ãŒã¢ããªã±ãŒã·ã§ã³ã«ãã£ãŠäœ¿çšãããïŒã§ãã
ãã¹ãŠã®CFG IMAGE_LOAD_CONFIG_DIRECTORY
ã¯ãã³ã³ãã€ã«æã«IMAGE_LOAD_CONFIG_DIRECTORY
å®è¡å¯èœãã¡ã€ã«ã«èšé²ãããŸãã

GuardCFCheckFunctionPointer
æ€èšŒæé ãžã®ãã€ã³ã¿ãŒGuardCFFunctionTable
颿°ã®æå¹ãªã¢ãã¬ã¹ã®ããŒãã«ïŒã«ãŒãã«ããããããããåæåããããã«äœ¿çšïŒGuardCFFunctionCount
ããŒãã«å
ã®é¢æ°ã®æ°GuardFlags
ãã©ã°
IMAGE_DLLCHARACTERISTICS_GUARD_CF
ãã©ã°ãIMAGE_NT_HEADERS.OptionalHeader.DllCharacteristics
ããããŒã«å
¥åããããã®å®è¡å¯èœãã¡ã€ã«ãCFGã¡ã«ããºã ããµããŒãããŠããããšã瀺ããŸãã
ãã¹ãŠã®ãµãŒãã¹æ
å ±ã¯ã /loadconfig
å®è¡ããããšã«ãããMicrosoft Visual Studio 2015ã®dumpbin.exe
ããŒã«ïŒ Microsoft Visual Studio 14.0 \ VC \ bin \ dumpbin.exe ïŒã䜿çšããŠ/loadconfig
ãŸãã

ã¬ãŒããã©ã°
Windows 10ïŒ1511ïŒã®winnt.h
ããããŒãã¡ã€ã«ã«ã¯ã次ã®CFGãã©ã°ãå«ãŸããŠããŸãïŒåŸè
ã¯ãã©ã°ã§ããããã¹ã¯ã§ã¯ãããŸããïŒã
IMAGE_GUARD_CF_INSTRUMENTED
ïŒ0x00000100ïŒ-ã¢ãžã¥ãŒã«ã¯ãã·ã¹ãã ã®ãµããŒãã§å®è¡ãããŒããã§ãã¯ããŸãIMAGE_GUARD_CFW_INSTRUMENTED
ïŒ0x00000200ïŒ-ã¢ãžã¥ãŒã«ã¯ãå®è¡ã®å®å
šæ§ããã§ãã¯ããã¹ã¬ãããæžã蟌ã¿ãŸãIMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT
ïŒ0x00000400ïŒ-ã¢ãžã¥ãŒã«ã«ã¯æå¹ãªé¢æ°ã®ããŒãã«ãå«ãŸããŠããŸãIMAGE_GUARD_SECURITY_COOKIE_UNUSED
ïŒ0x00000800ïŒ-ã¢ãžã¥ãŒã«ã¯ã»ãã¥ãªãã£Cookieã䜿çšããŸããïŒ/ GSïŒIMAGE_GUARD_PROTECT_DELAYLOAD_IAT
ïŒ0x00001000ïŒ-ã¢ãžã¥ãŒã«ã¯èªã¿åãå°çšã®é
å»¶ããŒãã€ã³ããŒãããŒãã«ãèªã¿åãå°çšããµããŒãããŸãIMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION
ïŒ0x00002000ïŒ-é
å»¶èªã¿èŸŒã¿ã€ã³ããŒãããŒãã«ã¯ç¬èªã®.didat
ã»ã¯ã·ã§ã³ã«ãããŸãIMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK
ïŒ0xF0000000ïŒ-æå¹ãªé¢æ°Guard CFã®ããŒãã«ã®1ã€ã®èŠçŽ ã®ã¹ãããã¯ããããã®ãããã§ãšã³ã³ãŒããããŸãïŒåèŠçŽ ã®è¿œå ãã€ãæ°ïŒ
ããã¯ãæ¢åã®ãã©ã°ã®äžå®å
šãªãªã¹ãã§ããããšã«æ³šæããŠãã ããã æãå®å
šãªãªã¹ãã¯ã link.exe
ãã¡ã€ã«ïŒãªã³ã«ãŒïŒã®å
éšããååŸã§ããŸãã

ãŸããããã€ãã®è峿·±ããã©ã°ã®ååšã«æ³šæãæã䟡å€ããããŸããããã®å
Œξ
å ±ã¯å
¥æã§ããŸããã ãã€ã¯ããœããã®éçºè
ã¯ãæžã蟌ã¿ã¢ãã¬ã¹ïŒ IMAGE_GUARD_CFW_INSTRUMENTED
ïŒã確èªããããã«ã远å ã®CFGã¡ã«ããºã ããã¹ãããŠããããã§ãã
ãããããã
ã«ãŒãã«ãOSïŒ nt!MiInitializeCfg
ïŒãnt!MiInitializeCfg
ãšã nt!MiInitializeCfg
ãããããããäœæãããŸããããã¯ããã¹ãŠã®ããã»ã¹ã®å
±æã»ã¯ã·ã§ã³ã§ãã CFGããµããŒãããããã»ã¹ãéå§ãããšãããã»ã¹ã®ã¢ãã¬ã¹ç©ºéãžã®ããããããã®ãããã³ã°ïŒãããã³ã°ïŒãçºçããŸãã ãã®åŸãã¢ãã¬ã¹ãšãããããããµã€ãºãntdll!LdrSystemDllInitBlock
å
¥åãããŸãã
颿°ã¢ãã¬ã¹ãšããããããã®ããããšã®æ¯èŒã¯ãå®è¡å¯èœãã¡ã€ã«ããŒããŒïŒ nt!MiParseImageCfgBits
ïŒã«ãã£ãŠå®è¡ãããŸãã ããããããã®åãããã¯ã8ãã€ãã®ãŠãŒã¶ãŒããã»ã¹ã¢ãã¬ã¹ç©ºéãæ
åœããŸãã ãã¹ãŠã®æå¹ãªé¢æ°ã®å
é ã®ã¢ãã¬ã¹ã¯ãããããããå
ã®å¯Ÿå¿ãããªãã»ããã®åäžãããã«é¢é£ä»ããããŠããããã以å€ã¯ãã¹ãŠ0ã§ãã

åŒã³åºããã颿°ã®ãã€ã³ã¿ãŒã確èªããæé
ã³ã³ãã€ã«æ®µéã§ã®ããã°ã©ã å
ã®æé»çãªåŒã³åºãã¯ãåŒã³åºããã颿°ã®ã¢ãã¬ã¹ããã§ãã¯ããããšã«ãããã¬ãŒã åãããŸãã æ€èšŒæé ã®ã¢ãã¬ã¹ã¯ãç©ºã®æé ã®ã¢ãã¬ã¹ãæåã«èšå®ããããããå®è¡å¯èœãã¡ã€ã«ã®ããŒããŒã«ãã£ãŠèšå®ãããããã«ããäžäœäºææ§ãç¶æãããŸãã
ããããããããããã«ãCFGãªãã§ã³ã³ãã€ã«ãããåãã³ãŒããèŠãŠã¿ãŸãããã
å
ã®C ++ã³ãŒãïŒ
class CSomeClass { public: virtual void doSomething() { std::cout << "hello"; } }; int main() { CSomeClass *someClass = new CSomeClass(); someClass->doSomething(); return 0; }
ASMãªã¹ãïŒã¯ãªããã³ã°ïŒïŒ
mov eax, [ecx] ; EAX = CSomeClass::vftable call dword ptr [eax] ; [EAX] = CSomeClass::doSomething()
ã³ã³ãã€ã«ããŒ/ã¬ãŒãã䜿çšïŒcfïŒ
mov eax, [edi] ; EAX = CSomeClass::vftable mov esi, [eax] ; ESI = CSomeClass::doSomething() mov ecx, esi call ds:___guard_check_icall_fptr ; checks that ECX is valid function pointer mov ecx, edi call esi
æåã®ã±ãŒã¹ã§ã¯ãã³ãŒãã¯ä»®æ³é¢æ°ããŒãã«ã¹ããŒãã£ã³ã°ææ³ã䜿çšããæ»æãåãããããªããŸãã æ»æè
ããã®è匱æ§ã®æªçšäžã«ãªããžã§ã¯ãã®ããŒã¿ãäžæžãã§ããå Žåã颿°someClass->doSomething()
ãåŒã³åºããšãæ»æè
ãå¶åŸ¡ããã³ãŒããå®è¡ããããã«ä»®æ³é¢æ°ããŒãã«ã眮ãæããã¢ããªã±ãŒã·ã§ã³å®è¡ãããŒãã€ã³ã¿ãŒã»ããã§ããŸãã
å¶åŸ¡ãããŒã¬ãŒãã䜿çšããå Žåã¯ãåŒã³åºããã颿°ã®ã¢ãã¬ã¹ãæåã«ããããããã§æ€èšŒãããŸãã 察å¿ãããããããŒãã®å ŽåããœãããŠã§ã¢äŸå€ãçºçããŸãã
Guard CFã¡ã«ããºã ããµããŒãããOSã§ãã®ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšãå®è¡å¯èœãã¡ã€ã«ããŒããŒããããããããäœæãããã§ãã¯ããã·ãŒãžã£ã®ã¢ãã¬ã¹ãntdll!LdrpValidateUserCallTarget
ã
Windows 10ïŒãã«ã1511ïŒã®ãã®æ©èœã¯ã次ã®ããã«å®è£
ãããŠããŸãã

å
¥åã¢ãã¬ã¹0x0B3385B0ã®äŸã䜿çšããŠããã®é¢æ°ã®ã¢ã«ãŽãªãºã ãç ç©¶ããŸãã
B3385B0 16 = 10110011001110000101 10110 000 2
ãã®é¢æ°ã¯ã ecx
ä»ããŠæ€èšŒæžã¿ã¢ãã¬ã¹ãåãåãecx
ã ããããããã¢ãã¬ã¹ã¯ã edx
å
¥åedx
ãŸãã ç§ã®å Žåãããããããã¯0x01430000ã«ãããŸãã

3ãã€ãïŒ24ãããïŒã®äžäœïŒäžç·ä»ãïŒã¢ãã¬ã¹ã¯ãããããããã®ãªãã»ããã«å¯Ÿå¿ããŸãã ãã®å Žåããªãã»ããã¯0xB3385
ãŸãã ããããããã®åäœã¯4ãã€ãïŒ32ãããïŒã§ãããããç®çã®ã»ã«ãååŸããã« + * 4
ãèšç®ããå¿
èŠããããŸãã ãã®äŸã§ã¯ã 0x01430000 + 0xB3385 * 4 = 0x16FCE14
ãŸãã ããããããã»ã«å€ã¯edx
æžã蟌ãŸedx
ãŸãã

ã¿ãŒã²ããã»ã«ãååŸããŸãããæ¬¡ã«ãèå³ã®ãããããã®æ°ã決å®ããå¿
èŠããããŸãã æ°å€ã¯ãã¢ãã¬ã¹ã®æ¬¡ã®5ãããã®å€ã§ãïŒå€ªåã§åŒ·èª¿è¡šç€ºïŒã ãã ãããã§ãã¯å¯Ÿè±¡ã®ã¢ãã¬ã¹ã16ãã€ãã®å¢çã§æŽåãããŠããªãå ŽåïŒ address & 0xf != 0
ïŒã奿°ãããã䜿çšãããããšã«æ³šæããŠãã ããïŒ offset | 0x1
ïŒã ãã®å Žåãã¢ãã¬ã¹ã¯æŽåããããããçªå·ã¯10110 2 = 22 10ã«ãªããŸãã
çŸåšã¯ãããããã¹ããå®è¡ããŠãããå€ããã§ãã¯ããã ãã§ãã bt
åœä»€ã¯ãæåã®ã¬ãžã¹ã¿ã®ãããå€ããã§ãã¯ããŸãããã®ã·ãŒã±ã³ã¹çªå·ã¯ã2çªç®ã®ã¬ãžã¹ã¿ã®æäžäœ5ãããïŒã¢ãžã¥ã32ïŒããååŸãããŸãã ãããã1ã®å Žåã Carry Flag (CF)
ãèšå®ãããããã°ã©ã ã¯éåžžã¢ãŒãã§å®è¡ããç¶ããŸãã 
ãã以å€ã®å Žåã ntdll!RtlpHandleInvalidUserCallTarget
颿°ãåŒã³åºãããããã°ã©ã ã¯ã¹ã¿ãã¯äžã®0xAãã©ã¡ãŒã¿ãŒãæã€29çªç®ã®å²ã蟌ã¿ã§çµäºããŸãnt!_KiRaiseSecurityCheckFailure(FAST_FAIL_GUARD_ICALL_CHECK_FAILURE)
ã€ãŸãã nt!_KiRaiseSecurityCheckFailure(FAST_FAIL_GUARD_ICALL_CHECK_FAILURE)
ã

22ãããç®ããã§ãã¯ããããšã«ãããåŒã³åºããã颿°ã®ã¢ãã¬ã¹ãæå¹ã§ããããšã確èªã§ããŸãã
Pythonã§ã®ãã®ã¢ã«ãŽãªãºã ã®å®è£
ã¯æ¬¡ã®ãšããã§ãã
def calculate_bitmap_offset(addr): offset = (addr >> 8) * 4 bit = (addr >> 3) % 32 aligned = (addr & 0xF == 0) if not aligned: bit = bit | 1 print "addr = 0x%08x, offset = 0x%x, bit index = %u, aligned? %s" % (addr, offset, bit, "yes" if aligned else "no") calculate_bitmap_offset(0x0B3385B0)
ã¹ã¯ãªããã®çµæïŒ
addr = 0x0b3385b0, offset = 0x2cce14, bit index = 22, aligned? yes
äŸå€
ãã¹ãŠã®å Žåã«ãããŠãç¡å¹ãªé¢æ°ã®åŒã³åºãã29çªç®ã®å²ã蟌ã¿ã§çµäºããããã§ã¯ãããŸããã ntdll!RtlpHandleInvalidUserCallTarget
颿°ã§ã¯ã次ã®ãã§ãã¯ãè¡ãããŸãã
- çŸåšã®ããã»ã¹ã§DEPãæå¹ã«ãªã£ãŠããŸããïŒ
- å®å
ã¢ãã¬ã¹ã«å¿
èŠãªæš©éããããŸããïŒ
PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE
ïŒ - ãæå¶ããããåŒã³åºãã
ntdll!RtlGuardAllowSuppressedCalls
ãŸãntdll!RtlGuardAllowSuppressedCalls
- å®å
ã¢ãã¬ã¹ã¯ãæå¶ããããŠããŸã
ntdll!RtlpGuardIsSuppressedAddress
ãã®é¢æ°ã®æ¬äŒŒã³ãŒãã¯æ¬¡ã®ãšããã§ãã

ãæå¶ããããã³ãŒã«ã«é¢ããå
Œξ
å ±ã¯ãããŸããã ãããã®åŒã³åºãã«ã¯ã³ã³ãã€ã©ãŒã®ãµããŒããå¿
èŠã§ãããšããèšããŸããGuardFlags
ãã©ã°ã§IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK
ãã¹ã¯ãèšå®ããã³ã³ãã€ã©ãŒãæ¡åŒµããŒãã«ãçæããå¿
èŠããããŸãã ãã®ãã¹ã¯ã«å¯Ÿå¿ãããã€ãã«ã¯ã GuardCFFunctionTable
ããŒãã«ã®èŠçŽ ã®è¿œå ãµã€ãºã®å€ãæ ŒçŽãããŸãã 颿°ã®ã¢ãã¬ã¹ããæå¶ããããŠããå Žåãã¢ãã¬ã¹ã«ç¶ããã€ãã¯1ã«çãããªããã°ãªããŸããã
ããšãã°ãå¿
èŠãªã¢ããªã±ãŒã·ã§ã³ã®CFGOptions
ãã©ã¡ãŒã¿ãŒã1ã«èšå®ããããšã«ãããã¬ãžã¹ããªãã©ã³ãHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\
ã䜿çšããŠããæå¶ããããåŒã³åºãã解決ã§ããŸãã
å¶åŸ¡ãããŒã¬ãŒãã®åŒ±ç¹
ä»ã®é²åŸ¡ã¡ã«ããºã ãšåæ§ã«ãCFGã«ã¯ããã€ãã®åŒ±ç¹ããããŸãã
ãã®å Žåã ntdll!RtlpHandleInvalidUserCallTarget
ã¯åžžã«ç¡å¹ãªã¢ãã¬ã¹ã®å®è¡ãèš±å¯ãããããããã»ã¹DEPããªãã«ãããšCFGãã§ãã¯ã®æå³ã倱ãããŸãã
ããããããã¢ãã¬ã¹ã¯åºå®ã¢ãã¬ã¹ã«ä¿åããããŠãŒã¶ãŒã¢ãŒãããç°¡åã«èšç®ã§ããŸãã ãŠãŒã¶ãŒã¯ããããããå
ã®ããŒã¿ã倿ŽããããšãçŠããããŠããŸãããæªçšè
ã¯äœããã®åœ¢ã§ãã®å¶éãåé¿ããæ¹æ³ãèŠã€ããŸãã
å®è¡å¯èœãã¡ã€ã«ãCFGãµããŒãã䜿çšããŠã³ã³ãã€ã«ãããŠããªãå Žåãå®è¡å¯èœãã¡ã€ã«ã«ãã£ãŠããŒããããã¢ãžã¥ãŒã«ã®CFGãµããŒãã¯ãã®æå³ã倱ããŸãã æ€èšŒæé ã®ãããããããšã¢ãã¬ã¹ã¯ãå®è¡å¯èœãã¡ã€ã«ãCFGã¡ã«ããºã ããµããŒãããŠããå Žåã«ã®ã¿å
¥åããããããã¢ãžã¥ãŒã«ã³ãŒãå
ã®ãã§ãã¯ã¯åçŽãªã¹ã¿ãã«ãªããŸãã
CFGã¯ã³ã³ãã€ã«ããã»ã¹ã«äŸåããŠããããããµãŒãããŒãã£ã®ã¢ãžã¥ãŒã«ãå€ãMicrosoftã¢ãžã¥ãŒã«ã§ãããCFGã§ä¿è·ãããå®è¡å¯èœãã¡ã€ã«ã®è匱æ§ã§ãã ããããããã¯ãã³ã³ãã€ã©ãŒã«ãã£ãŠçæãããæå¹ãªé¢æ°ã¢ãã¬ã¹ã®ããŒãã«ã«åŸã£ãŠã³ã³ãã€ã«ããããããCFGãµããŒãã®ãªããã¹ãŠã®ã¢ãžã¥ãŒã«ã³ãŒãã¯ãããããããã§æå¹ãªå®å
ãšããŠããŒã¯ãããŸãã
ã¢ãã¬ã¹ç©ºéã®8ãã€ãããšã«1ãããã責任ãè² ããŸãããå®éã«ã¯ã1ã€ã®æŽåã¢ãã¬ã¹ã1ã€ã®å¶æ°ãããã«å¯Ÿå¿ããæ¬¡ã®å¥æ°ããããã¢ãã¬ã¹ç©ºéã®15ãã€ãã«çŽã¡ã«å¯Ÿå¿ããŸãã ããã確èªããã«ã¯ãäžèšã®Pythonã¹ã¯ãªãããã«ãŒãã§å®è¡ããçµæãåæããŸãã
addr = 0x08f38480, offset = 0x23ce10, bit index = 16, aligned? yes addr = 0x08f38481, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f38482, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f38483, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f38484, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f38485, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f38486, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f38487, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f38488, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f38489, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f3848a, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f3848b, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f3848c, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f3848d, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f3848e, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f3848f, offset = 0x23ce10, bit index = 17, aligned? no addr = 0x08f38490, offset = 0x23ce10, bit index = 18, aligned? yes addr = 0x08f38491, offset = 0x23ce10, bit index = 19, aligned? no addr = 0x08f38492, offset = 0x23ce10, bit index = 19, aligned? no addr = 0x08f38493, offset = 0x23ce10, bit index = 19, aligned? no addr = 0x08f38494, offset = 0x23ce10, bit index = 19, aligned? no ...
æ»æè
ã¯ãä¿¡é ŒãããŠããªãæ©èœã調æŽãããŠããªãéããä¿¡é Œãããæ©èœã®ããè¿ãã§ä¿¡é Œã§ããªãæ©èœãåŒã³åºãæ©äŒãæã€ããšã«ãªããŸãã
åçã«çæããã颿°ïŒããšãã°ã JIT颿°ïŒã¯ã颿°ã®çææ®µéã§æé»çãªåŒã³åºãã®ãã§ãã¯ãæäŸããå¿
èŠããããããéçºè
ããã®ç¹å¥ãªæ³šæãå¿
èŠã§ãã ããã«å ããŠã ntdll!NtAllocVirtualMemory
ããã³ntdll!NtProtectVirtualMemory
ã®æšæºçãªåäœã§ã¯ãã¡ã¢ãªãå®è¡å¯èœã«ãªã£ãå ŽåïŒ PAGE_EXECUTE_*
ïŒãControl Flow Guardããããããã®ã¡ã¢ãªé åå
šäœã«1ããããé
眮ããããšãèæ
®ããå¿
èŠããããŸãã
CFGã¯ãæ»æè
ã颿°ã®ãªã¿ãŒã³ã¢ãã¬ã¹ã倿Žãããšãã«ãå®è¡ã¹ã¬ãããã€ã³ã¿ãŒã»ãããããã®ãé²ãããšã¯ã§ããŸããã
- CFGã®èгç¹ããã®ã©ã€ãã©ãªé¢æ°ïŒWinAPIãªã©ïŒã®åŒã³åºãã¯æå¹ã§ãããæ»æè
ã¯å¿
èŠãªãã©ã¡ãŒã¿ãŒã§ã¹ã¿ãã¯/ã¬ãžã¹ã¿ãŒãåããåé¡ã解決ããå¿
èŠããããŸãã
Adobe Flash Playerã®äŸã䜿çšããå¶åŸ¡ãããŒã¬ãŒããã€ãã¹ã®å®è£
Windows 8以éãAdobe Flash Playerãã©ã°ã€ã³ã¯Internet Explorerã«çµ±åãããWindows 8.1ïŒUpdate 3ïŒã§ã¯CFGãµããŒããä»å±ããŠããŸãã Adobe Flash Playerã®ãšã¯ã¹ããã€ãã«ã¯ãã³ã³ãããŒã«ãããŒã¬ãŒããã€ãã¹ã®å®è£
ãããã€ããããŸããããã®ããã€ãã¯çŸåšã§ãé¢é£ããŠããŸãã

ãã€ãããã¯ã³ãŒããã€ãã¹
Adobe Flash Playerã¯JITã³ã³ãã€ã«ãåºç¯å²ã«äœ¿çšãããããActionScriptã³ãŒãã®è§£éãªã©ã®ãªãœãŒã¹ã倧éã«æ¶è²»ããæäœãåé¿ã§ããŸãã ãã ããåè¿°ã®ããã«ãåçã«çæããã颿°ã«ã¯ãéçºè
ã«ãã远å ã®æ³šæãå¿
èŠã§ãã 以äžã«èª¬æãã2ã€ã®åé¿çã¯ãã¡ã¢ãªå²ãåœãŠã«é¢ããéçºè
ã®çç¥ã®çµæã§ãã
åçã³ãŒãã§ã®æé»çãªåŒã³åºããã§ãã¯ã®æ¬ åŠ
ãã®æ¹æ³ã¯ãCore Securityã®ç ç©¶è
ã§ããFranciscoFalcónã«ããCVE-2015-0311ã®ãšã¯ã¹ããã€ãåæã§ææ¡ããã³å®è£
ãããŸããã å
ã®èšäºã§ã¯ãåé¿çã®ããã»ã¹ã«ã€ããŠããªã詳现ã«èª¬æããŠããŸãã ãã®ã¡ãœããã®æ¬è³ªã¯ãç¹å®ã®ActionScriptã¯ã©ã¹ã®ä»®æ³é¢æ°ã®å
éšããŒãã«ã倿Žããããšã§ãã ãã®åŸããã®ã¯ã©ã¹ã®ã¡ãœããã®1ã€ããåçã«çæããã颿°ã®æ¬äœããåŒã³åºãå¿
èŠããããŸãã ByteArray
ã¯ã©ã¹ã¯ããã®ç®çã«é©ããŠããŸãã
ByteArray
ãªããžã§ã¯ãã®æ§é ïŒ

ãªãã»ãã$ + 8ã«ã¯ãã¯ã©ã¹VTable
ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒããããŸãã

VTable
ã¯ã©ã¹ã¯ãActionScriptã¯ã©ã¹ã®ä»®æ³é¢æ°ããŒãã«ã®å
éšè¡šçŸã§ãïŒã€ãŸããC ++ãçæãããã®ã§ã¯ãããŸããïŒã
ãã®ã¯ã©ã¹ã®ãªããžã§ã¯ãã«ã¯ã MethodEnv
ã¯ã©ã¹ã®ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒãå«ãŸããŠããŸãã

ãã®ã¯ã©ã¹ã¯ActionScriptã¡ãœããã®èª¬æã§ãããã¡ã¢ãªå
ã®ãªãã»ãã$ + 4ã«ãã颿°æ¬äœãžã®ãã€ã³ã¿ãŒãå«ãŸããŠããŸãã
ãªãã»ãã$ + D4ã®VTable
ãªããžã§ã¯ãã«ã¯ã ByteArray::toString()
ã¡ãœããã®èª¬æãå«ãŸããŠããŸãã ã¡ã¢ãªãžã®ä»»æã®èªã¿åãããã³æžã蟌ã¿ãå¯èœãªãããæ»æè
ã¯ByteArray::toString()
å®è¡ããããšã§ã颿°ãã€ã³ã¿ãŒã颿°æ¬äœïŒ MethodEnv + 4
ïŒã«å€æŽããã¢ããªã±ãŒã·ã§ã³å®è¡ãããŒãå®å
šã«ã€ã³ã¿ãŒã»ããã§ããŸãã
ããã¯ããã®ã¯ã©ã¹ã®ã¡ãœãããJITã³ãŒãããåŒã³åºããããšããäºå®ã«ããå¯èœã«ãªããŸãã

äžèšã®ã¹ã¯ãªãŒã³ã·ã§ããã§ãããããã«ããã®é¢æ°ã¯åçã«çæããããããæåã«åŒã³åºãããã¢ãã¬ã¹ããã§ãã¯ããã«æé»çãªåŒã³åºããçºçããŸãã
ãã®CFGã®åé¿çã¯ãAdobe Flash PlayerããŒãžã§ã³18.0.0.160ïŒKB3065820ã2015幎6æïŒã®ãªãªãŒã¹ã§ä¿®æ£ãããŸããã ä¿®æ£ã®æ§æã¯æ¬¡ã®ãšããã§ããJIT颿°ã«æé»çãªåŒã³åºããå«ãŸããŠããå ŽåãJITã³ã³ãã€ã©ã¯æé»çãªåŒã³åºãã®çŽåã«ãã¹ãããã·ãŒãžã£åŒã³åºããæ¿å
¥ããŸãã
åç颿°ã®æ¬æå
ã®ã¢ãã¬ã¹ã¯ãã¹ãŠæå¹ã§ãã
以åã®åé¿çã¯ãæé»çãªåŒã³åºããè¡ã颿°ã®æ¬ é¥ã®ããã«å¯èœã§ããã ãããŠããã®ã¡ãœããã¯ãæé»çã«åŒã³åºããã颿°ã®æ¬ é¥ã®ããã«å¯èœã§ãã
Center of Vulnerability Researchã®Yuri DrozdovãšLyudmila Drozdovaã®ç ç©¶è
ã¯ã Defcon Russia ConferenceïŒSt. Petersburgã2015ïŒã§ãã®CFGãã€ãã¹ææ³ãçºè¡šããŸãã ïŒ ãã¬ãŒã³ããŒã·ã§ã³ ã èšäº ïŒã 圌ãã®æ¹æ³ã¯ãå®è¡å¯èœã¡ã¢ãªãå²ãåœãŠããšãã«ãã«ãŒãã«ããã¹ãŠã®å²ãåœãŠãããã¡ã¢ãªã®CFGããããããã«åäžããããèšå®ãããšããäºå®ã«åºã¥ããŠããŸãã ãã®åäœãäœã«ã€ãªããããèŠãŠã¿ãŸãããã
ã¢ãã¬ã¹0x69BC9080ã«ç¹å®ã®JIT颿°ãããããã®æ¬æã«æ¬¡ã®ã³ãŒããå«ãŸããŠãããšããŸãã

ãã®é¢æ°ãæ£ç¢ºã«äœãããã®ãã¯èå³ããããŸãã;ã¢ãã¬ã¹0x69BC90F0ã®FF D0
åœä»€ã®2ãã€ãã«æ³šæããã ãã§ãã æ©èœã®éå§ããã®åœä»€ã®éäžã«çªç¶ç§»åãããšã©ããªããŸããïŒ ããã«äœããããŸãïŒ

FF D0
ã¯call eax
ããšã«ä»ãªããŸããïŒ ããã¯ãäžèŠç¡å®³ãªæ©èœãæ»æè
ã«ãšã£ãŠåªããæšçã«ãªã£ãæ¹æ³ã§ããã€ãŸããå¶åŸ¡ãããŒã¬ãŒãããã§ãã¯ããªãæé»çãªåŒã³åºãã§ãã å¿
èŠãªãã€ãã·ãŒã±ã³ã¹ãéæããæ¹æ³ãšãå¿
èŠãªã¢ãã¬ã¹ãã¬ãžã¹ã¿ã«æžãèŸŒãæ¹æ³ã®2ã€ã ãã®è³ªåã«å¯ŸåŠããå¿
èŠããããŸãã
å¿
èŠãªã·ãŒã±ã³ã¹ã¯ãActionScriptã³ãŒãã詊ãã ãã§çæã§ããŸãã NanojitïŒ AVM JITã³ã³ãã€ã©ãŒïŒãçæãããã³ãŒããé£èªåãããšããäºå®ãèæ
®ããã ãã§ãããããç°¡åãªæ¹æ³ã¯ãããŸããã Nanojitããã®æ©èœãã©ã®ããã«å€ããããèŠãŠã¿ãŸãããã
public static function useless_func():uint { return 0xD5EC; }
çµæïŒ

ãŸã£ããæåŸ
ããŠããªãã£ãã çµéšçã«ãããšãã°ããã®ããŒãžã§ã³ã®ã³ãŒãã«ã¢ã¯ã»ã¹ã§ããŸãã
public static function useless_func():void { useless_func2(0x11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); } public static function useless_func2(arg1:uint, arg2:uint, arg3:uint, a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u, v, w, x, y, z):void { }
æåã®é¢æ°ã®æ¬äœã«ã¯ãæ¬¡ã®æç€ºãå«ãŸããŸãã

èå³ã®ããFF 11
ãã€ãã¯call [ecx]
åœä»€ã§ãïŒ

æé»ã®åŒã³åºãããããŸãããä»ã ecx
å¶åŸ¡ãããã¢ãã¬ã¹ãå
¥åããå¿
èŠããããŸãã useless_func()
颿°ãuseless_func()
ãããšãã«ããã®ã¬ãžã¹ã¿ã«äœãæ ŒçŽãããŠãããã確èªããŸãã

颿°ãåŒã³åºãããæç¹ã§ã MethodEnv
ã¯ã©ã¹ã®ãªããžã§ã¯ãã¯ecx
ã¬ãžã¹ã¿ã«ãããŸãã ãã®ã¯ã©ã¹ã®æåã®DWORD㯠ãä»®æ³é¢æ°ããŒãã«ïŒC ++ã³ã³ãã€ã©ãŒã«ãã£ãŠçæããããã®ïŒãžã®ãã€ã³ã¿ãŒã§ãã ãã®ããŒãã«ã¯useless_func()
ã¡ãœããã®åŒã³åºãæã«ã¯äœ¿çšãããªããããã¡ãœãããåŒã³åºãããåã«æ»æè
ããã€ã³ã¿ãŒãèªåã®æš©å©ã«çœ®ãæããããšã劚ãããã®ã¯äœããããŸããã
ãã®ã¢ã«ãŽãªãºã ã®å®è£
ã¯æ¬¡ã®ãšããã§ãã
var class_addr:uint = read_addr(UselessClass); var vtable:uint = read_dword(class_addr + 8); var methodenv:uint = read_dword(vtable + 0x54);
ãããã£ãŠãã¢ããªã±ãŒã·ã§ã³ã®å®è¡ãããŒãã€ã³ã¿ãŒã»ãããããã®å Žåã¯ROPã¬ãžã§ããã®å®è¡ã«ç§»åããããšãã§ããŸããã
ãã®CFGã®åé¿çã¯ãããŒãžã§ã³18.0.0.194ïŒKB3074219ã2015幎6æïŒã§ä¿®æ£ãããŠããŸãã ä¿®æ£ã¯ãæ°ãããã©ã°ã䜿çšããããšã§ã
PAGE_TARGETS_INVALID/PAGE_TARGETS_NO_UPDATE
ïŒ0x40000000ïŒã¯ãæ°ããWinAPI颿°SetProcessValidCallTargets
ãšçµã¿åãããVirtualAlloc
ããã³VirtualProtect
颿°çšã§ãã
å®è¡å¯èœã¡ã¢ãªãå²ãåœãŠããšãã®PAGE_TARGETS_INVALID
ãã©ã°ã¯ãã¡ã¢ãªãã±ãŒã·ã§ã³å
šäœã«PAGE_TARGETS_NO_UPDATE
ããã¡ã¢ãªã¿ã€ããå®è¡å¯èœã«å€æŽãããšãã¯PAGE_TARGETS_NO_UPDATE
ãã©ã°ã«ããââãã¿ãŒã²ããã¡ã¢ãªãã±ãŒã·ã§ã³ã®ããããããã倿ŽãããŸããã
ãã®ä¿®æ£ã¯ãAVMã«ãŒãã«ãœãŒã¹ã³ãŒã ïŒ AVMPI / MMgcPortWin.cpp ïŒã®AVMPI_makeCodeMemoryExecutable
颿°ã§ç¢ºèªã§ããŸãã

SetProcessValidCallTargets
颿°ã®åŒã³åºãSetProcessValidCallTargets
ã AVMPI_makeTargetValid
ïŒ AVMPI / MMgcPortWin.cpp ïŒã§å®è£
ãããŠãAVMPI_makeTargetValid
ã

ãã®ããšãããCFGæ¡ä»¶äžã§åçã«çæãããã³ãŒããã¡ã¢ãªã«é
眮ãããšãã®ã¢ã¯ã·ã§ã³ã®æ£ããã·ãŒã±ã³ã¹ã¯æ¬¡ã®ããã«ãªããšçµè«ä»ããããšãã§ããŸãã
VirtualAlloc(PAGE_READWRITE)
- éžæããé åã«ã³ãŒããæžã
VirtualProtect(PAGE_EXECUTE_READ |
PAGE_TARGETS_NO_UPDATE )
SetProcessValidCallTargets()
ãããŠããã¡ãããåçã³ãŒãå
ã®æé»çãªåŒã³åºããå¿ããªãã§ãã ããã
WinAPIã®åé¿ç
å¶åŸ¡ãããŒã¬ãŒãã®ç¢ºèªã§ã¯ãçä¿¡ã¢ãã¬ã¹ã®æ€èšŒãè¡ãããŸããããŠãŒã¶ãŒæ©èœã®éå§ã ããæå¹ãªã¢ãã¬ã¹ã§ã¯ãããŸããã ãã¹ãŠã®WinAPI颿°ã¯ãã€ã³ããŒãããŒãã«ã®ä»ã®é¢æ°ãšåæ§ã«ãæé»çãªåŒã³åºãã®æå¹ãªå®å
ã§ãã æ»æè
ãå®è¡ã¹ã¬ãããçŽæ¥ã©ã€ãã©ãªé¢æ°ã«å€æããã·ã§ã«ã³ãŒããŸãã¯ROPã¬ãžã§ããããã€ãã¹ããããšã劚ãããã®ã¯äœããããŸããã ããã«é©ããåè£ã¯ãWinAPI颿°kernel32!WinExec
ã§ãã
Yuki Chen Qihoo 360 Vulcan Team SyScan (, 2015) , Internet Explorer 11 . BlackHat (, 2015) Francisco Falcón Adobe Flash Player.
Francisco Falcón toString()
Vector
, , .
, WinExec
. , , 2 : LPCSTR lpCmdLine
UINT uCmdShow
.
lpCmdLine
â , ( ).uCmdShow
â .
:

3 . . , 0 = SW_HIDE
( ). MethodEnv
.

, 4 , ActionScript- . 4 , WinExec
.
, 4 . , , cmd\0
( Windows). , , , .
:
var class_addr:uint = read_addr(UselessClass); var vtable:uint = read_dword(class_addr + 8); var methodenv:uint = read_dword(vtable + 0x50);
WinAPI Flash- . , , Flash Exploiter Metasploit.
, :

, , , .
Flash- (payload) HackingTeam. . WinAPI kernel32!VirtualProtect
, , , Control Flow Guard.
apply()
Function
( core/FunctionClass.cpp )

core->exec->apply(get_callEnv(), thisArg, (ArrayObject*)AvmCore::atomToScriptObject(argArray));
, , ActionScript.

, GitHub . 64- Flash Metasploit .
Control Flow Guard
CFG Adobe Flash Player. Flash, , Control Flow Guard Internet Explorer 11.
ãããã«
, Control Flow Guard Windows. Microsoft , , Control Flow Integrity, , . , Microsoft .
, CFG.
. Intel, , , ROP- â CET (Control-flow Enforcement Technology) ( ). , CET Control Flow Guard.
Jack Tang, Trend Micro Threat Solution Team. Exploring Control Flow Guard in Windows 10.
mj0011, Qihoo 360 Vulcan Team. Windows 10 Control Flow Guard Internals.
Source code for the Actionscript virtual machine, GitHub.
Francisco Falcon, Core Security. Exploiting Adobe Flash Player in the era of Control Flow Guard.