欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]CVE-2017-0101-Win32k提权分析笔记

[原创]CVE-2017-0101-Win32k提权分析笔记

CVE-2017-0101-Win32k提权分析笔记

    学习内核提权相关知识,拿CVE-2017-0101这个漏洞练习,于是有了这篇笔记。CVE-2017-0101是位于Win32K中的一个整形溢出漏洞,通过利用可实现内核提权。学习过程中,查阅了很多资料,尤其是xiaodao师傅的博客文章,给予了莫大的帮助。阅读xiaodao师傅博客,深感到师傅内功的深厚,无比佩服。本篇笔记以初学者的视角,尽量避开太多的Windows内核GDI内部实现逻辑相关知识,对该漏洞进行分析,调试,最终POC内核提权。         

    原xiaodao师傅最终pool fengshui 最终使用Bitmap+Palette实现,关键内存布局为0xDF8-0x1F0-0x18。我对其进行修改,使用Btimap+Bitmap实现,关键布局方式为0xD88-0x260-0x18。

    环境: x86  win7 sp1 

漏洞分析

粗略分析理解漏洞过程:

    定位漏洞代码位置可选择找到对应补丁修复后,使用diff工具对比其函数差异定位到对应函数代码片段,阅读相关公开信息,我们可知漏洞发生在Win32k-EngRealizeBrush函数内,此处直接贴出该部分代码,后续所有讨论都基于该函数代码。

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;

}

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功