win32k.sysÎó²îÍÚ¾ò˼Ð÷½â¶Á
Ðû²¼Ê±¼ä 2020-05-09Ò»¡¢Ñо¿Åä¾°
4ÔÂ1ÈÕ£¬£¬ÒÔÉ«ÁÐÇå¾²Ñо¿Ô±Gil DabahÔÚ²©¿ÍÉÏÐû²¼ÁËһƪ¹ØÓÚwin32kÎó²îÑо¿ÎÄÕ£¬£¬ÐÎòÁËÔõÑùͨ¹ýÄں˹¤¾ßµÄDestroyº¯ÊýºÍwin32k user-mode callback»º½â²½·¥µÄÌØÕ÷À´Ñ°ÕÒUAFÎó²îµÄÐÂ˼Ð÷¡£¡£
Ϊ´Ë£¬£¬¿Ðý¹ú¼ÊÓÎÏ·ADLab¶Ôwin32kÏà¹ØÄں˻úÖÆ¾ÙÐÐÑо¿ÆÊÎö£¬£¬²¢¶ÔÕâÀàÎó²îµÄÍÚ¾ò˼Ð÷¾ÙÐÐÏêϸ½â¶ÁÆÊÎö¡£¡£
¶þ¡¢win32kÎó²î»º½âÓë¶Ô¿¹
2.1 win32k user-mode callbackÎó²î
ÓÉÓÚÉè¼ÆÔµ¹ÊÔÓÉ£¬£¬win32kÇý¶¯ÐèÒª´¦Öóͷ£Ðí¶àÓû§²ãµÄ»Øµ÷£¬£¬ÕâЩ»Øµ÷¸øwin32kÄ£¿£¿£¿£¿éµÄÇå¾²´øÀ´Á˺ÜÊÇ´óµÄÒþ»¼£¬£¬²¢ÔÚÒÑÍù10Äêʱ¼äТ˳ÁË´ó×ÚµÄÎó²î¡£¡£
ΪÁ˱ãÓÚÎó²îÐÎò£¬£¬ÒÔÈçÏÂα´úÂë¾ÙÐоÙÀýÆÊÎö¡£¡£
NtUserSysCall()
£û
PWND p = CreateWindowEx(¡);
somecallback();
xxxSetWindowStyle(p);
£ý
ÉÏÊö´úÂëÖ´ÐÐЧ¹ûÈçÏÂͼËùʾ£¬£¬Óû§²ãÖ´ÐеÄijº¯Êýͨ¹ýsyscall´«ÈëÄں˲㣬£¬µ±Äں˲ã´úÂëÖ´Ðе½somecallbackÕâÒ»¾äʱ£¬£¬Óû§²ã¿ÉÒÔÔÚÓû§½ç˵µÄcallbackº¯ÊýÖлñµÃ´úÂëÖ´ÐеÄʱ»ú£¬£¬ÈôÊÇÓû§ÔÚcallbackº¯ÊýŲÓÃÁËDestroyWindowº¯ÊýÏú»Ù´°¿Úp£¬£¬Äں˲ãµÄÏìÓ¦Ïú»Ù´úÂ뽫»á±»Ö´ÐУ¬£¬pµÄÏìÓ¦ÄÚ´æ±»ÊÍ·Å£¬£¬»Øµ÷Ö´ÐÐÍê±Ï£¬£¬NtUserSysCallº¯Êý¼ÌÐøÖ´ÐУ¬£¬µ±Ö´Ðе½xxxSetWindowStyle(p)Ò»¾äʱ£¬£¬ÓÉÓÚpµÄÄÚ´æÒѾ±»ÊÍ·Å´Ó¶øµ¼ÖÂUAFÎó²îµÄ±¬·¢¡£¡£
2.2 user-mode callbackÎó²î»º½â»úÖÆ
ΪÁ˱ÜÃâÉÏÊöÎÊÌâµÄ±¬·¢£¬£¬Î¢ÈíÔÚ¹¤¾ßÖÐÒýÈëÁËÒ»¸öÒýÓüÆÊý£¨¹¤¾ß+0x8´¦£©£¬£¬¹¤¾ß·ÖÅÉʱÒýÓüÆÊýΪ1£¬£¬µ±Ö´Ðй¤¾ßµÄDestroyº¯ÊýʱÒýÓüÆÊý¼õ1£¬£¬µ±ÒýÓüÆÊýΪ0ʱ¹¤¾ß»á±»ÕæÕýÊÍ·Å¡£¡£Î¢Èíͨ¹ýËøµÄ¿´·¨Îª¹¤¾ßÌí¼ÓºÍïÔÌÒýÓüÆÊý£¬£¬ÔÚwin32kÖÐΪ¹¤¾ßÖÎÀíÒýÓüÆÊýµÄËøÓÐÁ½ÖÖ»®·ÖÊÇÔÝÊ±Ëø£¨ÏìÓ¦º¯ÊýΪThreadLock/ ThreadUnlock£©ºÍÓÀÊÀËø£¨ÏìÓ¦º¯ÊýΪHMAssignmentLock/ HMAssignmentUnlock£©¡£¡£¾ÓɼӹÌÖ®×ÓÅ®ÂëÌåÏÖΪÈçÏÂÐÎʽ£º
NtUserSysCall()
£û
PWND p = CreateWindowEx(¡);
ThreadLock(p);
Somecallback();
xxxSetWindowStyle(p);
ThreadUnlock();
£ý
ͨ¹ýÉÏÊö´úÂ룬£¬¿ÉÒÔ°ü¹Ü×ÝÈ»callback±»Ö´ÐУ¬£¬pÔÚxxxSetWindowStyleº¯ÊýÖ´ÐеÄʱ¼äÒ²²»»á±»ÊÍ·Å¡£¡£
2.3»º½â»úÖÆµÄ¶Ô¿¹ÊÖÒÕ
ÉÏÒ»½ÚÌáµ½Á˹¤¾ßµÄÒýÓüÆÊý£¬£¬ÈôÊǹ¤¾ßµÄÒýÓüÆÊýΪÕý£¬£¬×ÝȻִÐй¤¾ßµÄdestroyº¯Êý£¬£¬¹¤¾ßûÓÐÕæÕý±»ÊÍ·Å£¬£¬ÈÔÈ»´æÁôÔÚÄÚ´æÖУ¬£¬ÕâÖÖ¹¤¾ß±»Î¢Èí¿ª·¢Õß³ÆÎª½©Ê¬£¨Zombie£©¹¤¾ß¡£¡£Ò»µ©½©Ê¬¹¤¾ßµÄÒýÓüÆÊýïÔ̵½0Ëü½«»áÏûÊÅ£¬£¬¿ÉÊÇÔÚ´Ë֮ǰËüÈÔÈ»±£´æÄÚ´æÖУ¬£¬Ö»ÊÇÓû§²ãÎÞ·¨»á¼û¸Ã¹¤¾ß¡£¡£
ͬʱΪÁ˱ÜÃ⽩ʬ¹¤¾ß¼ÌÐø´æÁôÔÚÄÚ´æÖУ¬£¬ËøµÄÊͷź¯Êý£¨ThreadUnlock/ HMAssignmentUnlock£©Ò»Ñùƽ³£»á°üÀ¨¹¤¾ßµÄÊÍ·Å»·½Ú¡£¡£
¹¤¾ßµÄDestroyº¯ÊýÉÐÓÐÒ»¸öÌØÕ÷¾ÍÊÇÔÚÊÍϰà¾ßµÄͬʱ£¬£¬Destroyº¯ÊýÒ²»áÊÍϰà¾ßµÄ×Ó×ÊÔ´£¬£¬ÆäÀú³Ì¿ÉÒÔ¼òÒªÐÎòÈçÏ¡£¡£
void xxxDestroyWindow(PWND pwnd)
£û
xxxFW_DestroyAllChildren(); // Destroy child windows, if exist!
if (NULL != pwnd->spmenu) // If there¡¯s a menu, remove and destroy it.
£û
PMENU tmp = pwnd->spmenu;
if (HMAssignmentUnlock(&pwnd->spmenu)) // If it¡¯s still locked
£û
DestroyMenu(tmp); // Try destroying it (it can remain a zombie).
£ý
£ý
DereferenceClass(pwnd);
if (HMMarkObjectDestroy(pwnd)) // Check for zero refs!
HmFreeObject(pwnd); // Only now free the object and handle pair.
£ý
DestroyWindowÔÚµÚÒ»´ÎŲÓÃʱÊÍ·Å×Ó×ÊÔ´£¬£¬Ò»µ©´°¿Ú²»ÔÙ±»ÒýÓ㬣¬¾ä±úÖÎÀíÆ÷¾Í»áÔÙ´ÎÍêÈ«Ïú»ÙËü£¬£¬Ò»Ñùƽ³£ÇéÐÎÏ£¬£¬µÚ¶þ´ÎÏú»ÙDestroyº¯Êý²»»áÔÚÐÐÖ¹ÖÃ×Ó×ÊÔ´£¬£¬ÓÉÓÚµÚÒ»´ÎÒѾÊÍ·ÅÁËËùÓеÄ×Ó×ÊÔ´¡£¡£
¿ÉÊÇÊÂÇéÍùÍù²»ÊÇÕâô¼òÆÓ£¬£¬ÊÂʵÉÏ×ÝÈ»ÊÇÒ»¸öÒѾŲÓùýÏìÓ¦Destroyº¯ÊýÊͷŵĽ©Ê¬¹¤¾ß£¬£¬ÈÔÈ»ÓÐʱ»ú¶ÔÆä×Ô¼º¾ÙÐÐһЩ¸ü¸Ä£¨»Øµ÷Ö®ºóÄں˴úÂëÈÔ»á¶Ô¹¤¾ß¾ÙÐÐһЩ²Ù×÷£©£¬£¬ÎÒÃǰÑÕâÖÖÇéÐνÐ×öZombie Reload£¬£¬µ±¸Ã½©Ê¬¹¤¾ßÓÉÓÚÒýÓüÆÊýΪ0¶ø±»ÕæÕýÊÍ·Åʱ£¬£¬Ö®Ç°µÄ¸ü¸Ä²Ù×÷½«»á¸øÄں˴øÀ´Ò»Ð©Òþ»¼¡£¡£
¹ØÓÚÈçÏ´úÂëÆ¬¶Ï£º
ThreadLock(pwnd);
xxxSomeCallback(); // Here we can destroy pwnd from user-mode.
InternalSetTimer(pwnd, ...); // reuse pwnd without check wether it is destroyed
ThreadUnlock();
SomefunctionUseTimer(); //UAF of Timer
ÎÒÃÇÔÚÓû§²ã»Øµ÷ÖжÔpwndÖ´ÐÐÁËDestroyº¯Êý£¬£¬È»ºóͨ¹ýInternalSetTimerΪ֮ÉèÖÃÁËÒ»¸ö¼ÆÊ±Æ÷£¬£¬µ±ThreadUnlock½«pwndÕæÕýÊͷŵÄʱ¼ä£¬£¬¼ÆÊ±Æ÷Ò²½«±»ÊÍ·Å£¬£¬ÄÇô½ÓÏÂÀ´¶Ô¼ÆÊ±Æ÷µÄ²Ù×÷½«»áµ¼ÖÂUAFÎó²îµÄ±¬·¢¡£¡£
Èý¡¢°¸ÀýÆÊÎö
ÉÏÒ»½ÚÎÒÃÇÌÖÂÛÁ˹¤¾ßµÄÒýÓüÆÊýºÍËø¸ø¹¤¾ß´øÀ´µÄеÄÇå¾²Òþ»¼£¬£¬¿ÉÊÇÕæÕýµÄÌôÕ½ÔÚÓÚÎÒÃÇÔõÑùÈ·¶¨Ò»¶Î´úÂëÖб£´æÎó²î£¬£¬Òªº¦µãÊÇÈ·±£ÔÚunlockº¯ÊýÖÐÊͷŵŤ¾ßÔÚÔËÐе½ÓÐÎÊÌâµÄ´úÂëʱÆäÒýÓüÆÊýÓ¦¸ÃΪ1£¬£¬Ö»ÓÐÕâÑùÎÒÃDzŻªÔÚÓû§²ã»Øµ÷ŲÓÃÆäDestroyº¯Êý£¬£¬²¢Í¨¹ýunlockº¯Êý½«Õâ¸ö¹¤¾ßÕæÕýÊͷŵô£¨ÉÏËøµÄʱ¼ä»á×ö+1´¦Öóͷ££©£¬£¬ÕâÒ²ÊÇÎÒÃǽÓÏÂÀ´ÐèÒªÌÖÂ۵ġ£¡£ÏÂÃæÎÒÃÇͨ¹ýÒ»¸ö°¸ÀýÀ´ÆÊÎöÎó²îÍÚ¾ò˼Ð÷¡£¡£
3.1Îó²î³ÉÒò
ÏÂͼÊÇxxxMnOpenHierarchyº¯ÊýµÄ´úÂëÆ¬¶Ï¡£¡£
ͼÖÐͨ¹ýxxxCreateWindowEx¿ÉÒÔ»ñµÃÒ»¸ö·µ»ØÓû§²ãÖ´ÐÐcallbackº¯ÊýµÄʱ»ú£¬£¬xxxCreateWindowEx½¨ÉèµÄ´°¿Ú½«×÷Ϊ¸¸´°¿Ú*(struct tagWND **)(**v3 + 8)£¨ÉÏͼºì¿ò£©µÄ×Ó´°¿Ú£¬£¬ÈôÊÇÎÒÃÇ¿ÉÒÔͨ¹ýThreadUnlockÊͷŸ¸´°¿Ú£¬£¬ÄÇô×Ó´°¿Úv32Ò²»á±»ÊÍ·Å£¬£¬ÒÔÊǵ±ºóÐøµÄsafe_cast_fnid_to_PMENUWNDº¯Êý½«v32×÷Ϊ²ÎÊýÖ´ÐÐʱ¾Í»á±¬·¢ÎÊÌ⣬£¬ÖµµÃ×¢ÖØµÄÊÇͨ¹ý»Øµ÷ÊÍ·Åv32ÊÇÐÐÇ·ºàµÄ£¬£¬ÈôÊÇÕâÑùxxxCreateWindowEx½«»á·µ»Ø0£¬£¬ÎÞ·¨Í¨¹ýifÅжϡ£¡£
ÕâÀïµÄÎÊÌâ¾ÍÔÚÓÚÔõÑù°ü¹Ü¸¸´°¿ÚÔÚThreadUnlockº¯ÊýÖ´ÐеÄʱ¼äÒýÓüÆÊýΪ1£¬£¬ÓÉÓÚÒªÖ´ÐÐxxxMnOpenHierarchyº¯ÊýÐèÒª½«¸¸´°¿Ú¹ØÁªµ½Ò»¸ömenu´°¿ÚÉÏ£¬£¬´Ëʱ¸¸´°¿ÚºÍmenu´°¿Ú½«»á±»Ò»¸öÓÀÊÀËøËø×¡£¬£¬ÏÂÃæÎÒÃÇÏÈÈÝÔõÑùÈÆ¹ýÓÀÊÀËø¡£¡£
3.2 Îó²îÍÚ¾ò˼Ð÷
Ê×ÏÈÎÒÃǽ¨ÉèÁËg_hMenuOwnerºÍg_hNewOwnerÁ½¸ö´°¿Ú£¬£¬ÆäÖÐg_hMenuOwnerµÄ²Ëµ¥¾ä±úΪhMenu£¬£¬ËüÒ²ÊÇg_hNewOwnerµÄËùÓÐÕß¡£¡£
ÔÚÉÏÊö½¨ÉèÀú³ÌÖУ¬£¬ÄÚºËͨ¹ýLockPopuMenuº¯Êý»®·ÖΪhMenuºÍg_hMenuOwnerÌí¼ÓÁËÓÀÊÀËø£¬£¬ÎªÁ˸濢ÊÍ·ÅÄ¿µÄ£¬£¬Õâ¸öÓÀÊÀËøÐèÒª±»Èƹý¡£¡£
´ËÊ±ËøºÍËùÓÐÕߵĹØÏµÊÇÕâÑùµÄ£º
½ÓÏÂÀ´ÎÒÃÇͨ¹ýSetWindowsHookEx¸ø´°¿ÚÌí¼ÓÁËWH_CBT¹³×Ó£¬£¬²¢Èô°¿Ú½øÈëÐÂÎÅÑ»·ÖС£¡£
SendMessage²Ù×÷Ϊg_hMenuOwnerÌí¼ÓÒ»¸öÔÝÊ±Ëø£¬£¬ÓÉÓÚºóÐøµÄËùÓй¥»÷¶¼ÊÇÔÚmessageµÄ»Øµ÷ÖоÙÐУ¬£¬ÒÔÊǹØÓÚg_hMenuOwnerÀ´ËµÕâ¸öÔÝÊ±ËøÊÇÎÞ·¨Êͷŵ쬣¬ÈôÊÇÏëÒª½á¹¹Ò»¸öÎó²îʹÓÃÇéÐÎÊ×ÏÈÐèÒªÓÃһЩҪÁìÀ´ÈƹýËü¡£¡£
ÏÖÔÚµÄÇéÐÎÄð³ÉÁËÏÂͼËùʾ£º
µ±ÐÂÎÅΪHCBT_CREATEWNDʱ£¬£¬ÎÒÃǵÚÒ»´ÎµÖ´ïxxxMNOpenHierarchyº¯ÊýÄÚ²¿µÄxxxCreateWindowEx¡£¡£
ÕâÀï¿ÉÒÔͨ¹ý½ç˵¹ØÓÚHCBT_CREATEWNDÐÂÎŵĴ¦Öóͷ£»ñµÃÖ´ÐÐÓû§²ã»Øµ÷´úÂëµÄʱ»ú£¬£¬ÕâÒ»²½µÄÖ÷ҪĿµÄÊÇΪÁË»ñÈ¡MenuµÄWnd¡£¡£
µ±ÎüÊÕµ½µÄÐÂÎÅΪWM_ENTERIDLEʱ£¬£¬ÎÒÃÇÔÚ´°¿ÚµÄÐÂÎŻص÷ÖÐͨ¹ýPostMessageÏ·¢ÐÂÎÅ¡£¡£
·¢ËÍÐÂÎź󣬣¬Çý¶¯³ÌÐòÀ´µ½ÁËxxxMNKeyDownº¯ÊýÄÚ²¿Å²ÓÃxxxSendMessage´¦¡£¡£
ͨ¹ýWM_NEXTMENUÐÂÎŵĻص÷º¯Êý×îÏÈΪLPARAM¸³Öµ£¬£¬¸³Öµ²Ù×÷ÊÇΪÁËÐÞ¸ÄhMenuµÄOwner£¬£¬ÕâÑù¾Í¿ÉÒÔ½«OwnerµÄÔÝÊ±ËøÈÆ¹ý¡£¡£
´ËʱÄں˻á½Óµ½Ïú»ÙmenuµÄÐÂÎÅ£¬£¬Í¨¹ýÓû§²ãµÄ»Øµ÷º¯Êý·µ»Ø1×èÖ¹menuµÄÏú»Ù¡£¡£
xxxMNKeyDownº¯Êýͨ¹ýUnlockPopupMenu½«g_hMenuOwnerÉíÉϵÄÓÀÊÀËø±»È¥µô¡£¡£
È¡¶ø´úÖ®µÄÊÇg_hNewOwner¼ÓÉÏÁËÒ»¸öËø£¬£¬hMenuµÄOwnerÒ²´Óg_hMenuOwnerÄð³ÉÁËg_hNewOwner¡£¡£
Õâʱ£¬£¬ËøµÄ¹ØÏµÄð³ÉÁË£º
½ÓÏÂÀ´³ÌÐòµÚ¶þ´Î½øÈëµ½xxxMNOpenHierarchyº¯Êý²¢Í¨¹ýxxxSendMessage·¢ËÍÁËÐÂÎÅ¡£¡£
´Ëʱͨ¹ýÉèÖÃWM_INITMENUPOPUP»Øµ÷À´»ñµÃÓû§²ãÖ´ÐеÄʱ»ú£¬£¬WM_INITMENUPOPUP»Øµ÷º¯Êýͨ¹ýSetWindowsHookExº¯ÊýÉèÖÃÁËÒ»¸öеÄhook£¬£¬Ä¿µÄÊÇΪÁËÔÚxxxMnOpenHierarchyº¯Êý½¨Éè×Ó´°¿ÚµÄʱ¼ä»ñµÃÓû§²ãÖ´ÐÐȨÏÞ¡£¡£
xxxMnOpenHierarchyº¯Êý¼ÌÐøÏòÏÂÖ´ÐУ¬£¬ÔÙ´ÎÀ´µ½xxxCreateWindowEx´¦¡£¡£
xxxCreateWindowExŲÓÃÁ˸ոÕÉèÖõĻص÷º¯ÊýchildMenuHookProc¡£¡£
Ôڻص÷º¯ÊýchildMenuHookProcÖУ¬£¬SendMessage·¢ËÍÁËWM_NEXTMENUÐÂÎÅ£¬£¬Í¨¹ý¸Ã½ç˵¸ÃÐÂÎŵĻص÷º¯ÊýÔÙ´ÎÐ޸IJÎÊýLPARAM£¬£¬ÕâÊÇΪÁËÈ¥µôg_hNewOwnerÉíÉϵÄÓÀÊÀËø¡£¡£
MenuµÄOwner¹ØÏµÔٴα»¸Ä±ä£¬£¬xxxMNKeyDownͨ¹ýº¯ÊýUnlockPopMenuÈ¥µôg_hNewOwnerÉíÉϵÄÓÀÊÀËø¡£¡£²¢½«Õâ¸öËøÖØÐ¼ÓÔÚÁËg_hMenuOwnerÉÏ¡£¡£
Õâ¸öʱ¼ä£¬£¬ËùÓеÄËø¶¼ÒÑ¾×ªÒÆµ½ÁËg_hMenuOwnerÉíÉÏ£¬£¬¶øÓÉÓÚWH_CBT¹³×ÓÒѾ±»ÒƳý£¬£¬menu½«±»ÆúÓ㬣¬g_hNewOwner½«°Ñн¨ÉèµÄ´°¿Úlinkµ½×Ô¼ºÉíÉÏ¡£¡£Õâ¸öʱ¼äÇéÐÎÄð³ÉÁËÏÂÃæµÄÑù×Ó£¬£¬g_hNewOwnerÉíÉÏÒѾûÓÐÐèÒªÈÆ¹ýµÄËøÁË¡£¡£
½Ó×ÅchildMenuHookProcͨ¹ýSetWindowsHookExº¯ÊýÓÖÒ»´ÎÉèÖÃÁ˻ص÷º¯Êý²¢Í¨¹ýSetWindowLongPtrº¯ÊýÀ´Å²ÓÃËü£¬£¬»Øµ÷º¯ÊýÏú»ÙÁËg_hNewOwnerºÍxxxCreateWindowExÌìÉúµÄд°¿Ú¡£¡£
xxxCreateWindowEx·µ»ØµÄֵΪffff871b80239130£¬£¬Õâ¾ÍÊÇxxxCreateWindowEx½¨ÉèµÄ×Ó´°¿Ú¡£¡£
½ÓÏÂÀ´¾Í¿ÉÒÔͨ¹ýThreadUnlockÀ´Ïú»Ùg_hNewOwnerºÍÆäн¨ÉèµÄ×Ó´°¿ÚÀ´»ñµÃÒ»¸öUAFÎó²î¡£¡£
ËÄ¡¢×Ü ½á
±¾ÎĶÔwin32kÎó²îÍÚ¾òÐÂ˼Ð÷¾ÙÐÐÁËÏêϸ½â¶Á£¬£¬ÆäÖаüÀ¨½«unlockº¯ÊýºÍ¹¤¾ßµÄDestroyº¯ÊýµÄÌØÕ÷¹ØÁªÔÚÒ»Æð£¬£¬²¢°Ñ¹¤¾ßµÄ×Ó×ÊÔ´×÷Ϊ¹¥»÷Ä¿µÄѰÕÒÐµĹ¥»÷ÃæµÄÎó²îÍÚ¾ò˼Ð÷¡£¡£ÁíÍ⣬£¬ÔõÑùͨ¹ý¹¤¾ßÄÚ²¿µÄÌØÕ÷È¥ÈÆ¹ýËø¶Ô¹¤¾ßµÄËø¶¨µÄ˼Ð÷ºÍ¼¼ÇÉ£¬£¬Ò²ºÜÊǾßÓÐ½è¼øÒâÒå¡£¡£