4.堆溢出和COM漏洞寻找
2019-12-27 22:13:44 Author: bbs.pediy.com(查看原文) 阅读量:174 收藏

[原创]4.堆溢出和COM漏洞寻找

1天前 160

堆溢出

  • 案例代码
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <iostream.h>

struct tagNode
{
    char szName[8];
  struct tagNode *pNext;
};

struct tagTest
{
  short Magic;
  short nLength;
  char *szBuf;
};

void test(char *szPwd)
{
  tagNode *pHead = NULL; 
  tagNode *pNode = NULL; 
  FILE *fp = NULL;
  fp = fopen("name.txt", "r+");
  if (fp == NULL)
  {
    exit(-1);
  }

  int nRet = EOF;
  for (int i = 0; i < 3; i++)
  {
    pNode = new struct tagNode;
    nRet = fscanf(fp, "%s", pNode->szName);

    pNode->pNext = pHead;
    pHead = pNode;
  }

  for (pNode = pHead; pNode != NULL; pNode = pNode->pNext)
  {
    printf("%s\r\n", pNode->szName);
  }

  pNode = pHead;
  fscanf(fp, "%s", pNode->szName);

  pNode = pHead->pNext;
  fscanf(fp, "%s", pNode->szName);

  for (pNode = pHead; pNode != NULL; pNode = pNode->pNext)
  {
    printf("%s\r\n", pNode->szName);
  }

  if (fp)
  {
    fclose(fp);
    fp = NULL;
  }
}

int main(int argc, char* argv[])
{
  char szPwd[] = "Hello";
  test(szPwd);

  system("pause");
  return 0;
}
  • 先观察代码
    可以得到一个类似结构得链表,如果在这里溢出修改pNext的话,因为fscanf结束后,还有pNode->pNext = pHead,会还原回去所以这里不行。

    for (int i = 0; i < 3; i++)
    {
      pNode = new struct tagNode;
      nRet = fscanf(fp, "%s", pNode->szName);
    
      pNode->pNext = pHead;
      pHead = pNode;
    }
    


    这句代码的作用就是输入,没用写入的机会,所以也没用

    for (pNode = pHead; pNode != NULL; pNode = pNode->pNext)
    {
      printf("%s\r\n", pNode->szName);
    }
    

    而这两句代码能够溢出数据,并且不会被写回,这里解释下为什么非要溢出改pNext,如果仅仅只是溢出数据,那么任何一个fscanf(fp, "%s", pNode->szName);这样的写法都能够随便溢出,但是我们缺少能够执行我们shellcode的机会。第一个fscanf修改我们要第二次要写入数据的位置。第二个fscanf
    会写入第二次数据,这次我们把数据写到哪里,能够有机会执行,又能够有写的权限?

    pNode = pHead;
    fscanf(fp, "%s", pNode->szName);
    
    pNode = pHead->pNext;
    fscanf(fp, "%s", pNode->szName);
    

    继续看,下面调用了两个函数,printffclose
    例如:printf里面会调用WriteFileReadFile等api
    fclose会调用CloseHandle等api,感兴趣的话可以OD自己跟进去看
    如果这些api通过IAT表调用的话,那么我们第二次写入的shellcode放入api在IAT表的地址,那么不就会执行到我们的shellcode吗?

    for (pNode = pHead; pNode != NULL; pNode = pNode->pNext)
    {
      printf("%s\r\n", pNode->szName);
    }
    
    if (fp)
    {
      fclose(fp);
      fp = NULL;
    }
    
  • 进入printf函数查看间接调用的API
    看到了WriteFile

    也可以用访问断点来查看是否调用

    发现有间接访问

    记录下
    00430250 >76C83ED3  kernel32.ReadFile
    
  • 编写读入的数据
    fscanf遇到\x0D\x0A\x0C....会被截断

    第一个循环构造的链表
    ![]
    接下来是我们定位的溢出位置的第一次执行,把ReadFileIAT地址给写进去

    crtl+g过去看发现是我们api地址

    写进去了但是崩溃了为什么呢?
    因为call 这个地址跳过去一个不对的地址肯定崩

    红框就是填写shllecode地址,正好是写入位置+4

    在这个地址下硬件执行断点,发现可以来一切正常

寻找Com组件的漏洞

  • 寻找com漏洞工具
  1. 查看所有的com组件 COM Explorer
  2. 漏洞自动挖掘工具 COMRaider

[进行中] 看雪20周年庆典12月28日上海举办,LV四级(中级)以上会员免费参与!,同时在校学生免费参加:学生报名链接!

最后于 12小时前 被自然dashen编辑 ,原因:


文章来源: https://bbs.pediy.com/thread-256927.htm
如有侵权请联系:admin#unsafe.sh