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º¯ÊýµÄÌØÕ÷¹ØÁªÔÚÒ»Æ𣬲¢°Ñ¹¤¾ßµÄ×Ó×ÊÔ´×÷Ϊ¹¥»÷Ä¿µÄÑ°ÕÒÐµĹ¥»÷ÃæµÄÎó²îÍÚ¾ò˼Ð÷¡£ÁíÍ⣬ÔõÑùͨ¹ý¹¤¾ßÄÚ²¿µÄÌØÕ÷È¥ÈƹýËø¶Ô¹¤¾ßµÄËø¶¨µÄ˼Ð÷ºÍ¼¼ÇÉ£¬Ò²ºÜÊǾßÓнè¼øÒâÒå¡£