waliedassar

KdUpdateTimeSlipEvent KernelDebugger Trick

Jul 2nd, 2013
280
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //http://waleedassar.blogspot.com
  2. //http://www.twitter.com/waleedassar
  3.  
  4. //------If KdPitchDebugger is true i.e. no kernel debuggers present,
  5. //then the Referenced event Object by NtSetSystemInformation will not be
  6. //dereferenced by the "KdUpdateTimeSlipEvent" function.
  7. //This can be detected by checking the "PointerCount" field in the
  8. //"_OBJECT_HEADER" structure for the corresponding event object.
  9.  
  10. //Also, check
  11. //http://everdox.blogspot.com/2013/07/time-slip-dpc-kernel-debugger-detection.html
  12.  
  13. #include "stdafx.h"
  14. #include "windows.h"
  15. #include "stdio.h"
  16.  
  17.  
  18.  
  19. #define ObjectBasicInformation 0
  20. #define SystemTimeSlipNotification 0x2E
  21.  
  22.  
  23. struct _OBJECT_BASIC_INFORMATION
  24. {
  25.    unsigned long Attributes;
  26.    ACCESS_MASK DesiredAccess;
  27.    unsigned long HandleCount;
  28.    unsigned long ReferenceCount;
  29.    unsigned long PagedPoolUsage;
  30.    unsigned long NonPagedPoolUsage;
  31.    unsigned long Reserved[3];
  32.    unsigned long NameInformationLength;
  33.    unsigned long TypeInformationLength;
  34.    unsigned long SecurityDescriptorLength;
  35.    LARGE_INTEGER CreationTime;
  36. };
  37.  
  38. extern "C"
  39. {
  40.     int __stdcall ZwQueryObject(HANDLE,
  41.                                 unsigned long,
  42.                                 _OBJECT_BASIC_INFORMATION*,
  43.                                 unsigned long,
  44.                                 unsigned long*);
  45.  
  46.     int __stdcall ZwSetSystemInformation(unsigned long,
  47.                                          void*,
  48.                                          unsigned long);
  49. }
  50. //-----------------Priv. Stuff-----------------------------
  51. struct UNICODE_STRING
  52. {
  53.     unsigned short len;        //length in bytes
  54.     unsigned short max_len;    //length in bytes + 2 null zeros
  55.     wchar_t* pStr;
  56. };
  57.  
  58. struct OBJECT_ATTRIBUTES
  59. {
  60.   unsigned long      Length;
  61.   HANDLE          RootDirectory;
  62.   UNICODE_STRING* ObjectName;
  63.   unsigned long           Attributes;
  64.   void*           SecurityDescriptor;
  65.   void*           SecurityQualityOfService;
  66. };
  67.  
  68. BOOL Acquire_Systemtime_Privilege()
  69. {
  70.    
  71.     LUID X;
  72.     if(!LookupPrivilegeValue(0,"SeSystemtimePrivilege",&X))
  73.     {
  74.            return FALSE;
  75.     }
  76.     HANDLE hToken;
  77.     if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken) )
  78.     {
  79.         return FALSE;
  80.     }
  81.     TOKEN_PRIVILEGES T={0};
  82.     T.PrivilegeCount=1;
  83.     T.Privileges[0].Luid=X;
  84.     T.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
  85.  
  86.     if(!AdjustTokenPrivileges(hToken,FALSE,&T,0,0,0) )
  87.     {
  88.         return FALSE;
  89.     }
  90.     return TRUE;
  91. }
  92. //--------------------------------------------------------------------
  93.  
  94.  
  95. int main(int argc, char* argv[])
  96. {
  97.     HANDLE hEvent = CreateEvent(0,FALSE,FALSE,0);
  98.     if(hEvent == INVALID_HANDLE_VALUE)
  99.         {
  100.             printf("Can't create events!\r\n");
  101.             /* hehe, thanks @nickeverdox */
  102.             return 0;
  103.         }
  104.        
  105.     _OBJECT_BASIC_INFORMATION ObjBasic={0};
  106.     int ret = ZwQueryObject(hEvent,ObjectBasicInformation,& ObjBasic,sizeof(ObjBasic),0);
  107.     printf("return value is %x\r\n",ret);
  108.  
  109.     unsigned long RefCount = ObjBasic.ReferenceCount;
  110.     printf("Reference Count is %x\r\n",ObjBasic.ReferenceCount);
  111.  
  112.  
  113.     BOOL bRet = Acquire_Systemtime_Privilege();
  114.     if(!bRet) printf("Can't acquire SeSystemtimePrivilege\r\n");
  115.  
  116.     ret = ZwSetSystemInformation(SystemTimeSlipNotification,&hEvent,4);
  117.     printf("return value is %x\r\n",ret);
  118.  
  119.     //Now check the reference count to detect kernel debuggers------------------
  120.    
  121.        //------If KdPitchDebugger is true i.e. no kernel debuggers present,
  122.        //then the Referenced event Object by NtSetSystemInformation will not be
  123.        //dereferenced by the "KdUpdateTimeSlipEvent" function.
  124.        //This can be detected by checking the "PointerCount" field in the
  125.        //"_OBJECT_HEADER" structure for the corresponding event object.
  126.  
  127.     memset(&ObjBasic,0,sizeof(ObjBasic));
  128.     ret = ZwQueryObject(hEvent,ObjectBasicInformation,& ObjBasic,sizeof(ObjBasic),0);
  129.     printf("return value is %x\r\n",ret);
  130.     printf("Reference Count is %x\r\n",ObjBasic.ReferenceCount);
  131.  
  132.  
  133.     if(RefCount == ObjBasic.ReferenceCount) printf("Kernel Debugger present\r\n");
  134.     else printf("No Kernel Debuggers\r\n");
  135.     return 0;
  136. }
RAW Paste Data