堆溢出和COM漏洞寻找
2020-01-13 18:57:00 Author: mp.weixin.qq.com(查看原文) 阅读量:72 收藏

本文为看雪论坛优秀文章

看雪论坛作者ID:自然dashen

堆溢出

>>>>

案例代码

#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);

继续看,下面调用了两个函数,printf,fclose
例如:printf里面会调用WriteFile和ReadFile等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

>>>>

使用工具挖掘


点击statrt,然后点击Next:

打开文件夹,选择要分析的com组件。记得COM组件要注册:

生成脚本:


然后点击next,再点击Fuzz,跑完后就是这样的效果我们需要关注的就是这几个地方,有异常的就进去调试,判断是不是漏洞。
点击view设置我们的调试器:

右键选择Olly启动:


会自动填写参数,启动OD:


我们要知道我们是执行wscript这个exe调用脚本,然后调用COM组件:

>>>>

寻找COM组件的位置




在这个函数里面下断点,在DispCallFunc函数一直“步过”,直到见到Call reg时,我们就来到了进入COM某个函数边缘,F7进入。


进入之后观察栈有没有溢出的情况,会很明显的。


当我走到这个call,栈变的一眼就看出来了,然后进去分析这个函数既可以了。


发现了溢出位置:

- End -

看雪ID:自然dashen

https://bbs.pediy.com/user-710414.htm 

*本文由看雪论坛  自然dashen  原创,转载请注明来自看雪社区

推荐文章++++

应急服务辅助工具与系统溯源思路

利用auxv控制canary

未知黑客团队钓鱼样本分析

使用Binary Ninja去除ollvm流程平坦混淆

某盗链App逆向

好书推荐


公众号ID:ikanxue
官方微博:看雪安全
商务合作:[email protected]
“阅读原文”一起来充电吧!

文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&amp;mid=2458302786&amp;idx=1&amp;sn=cd6981a813005465e99b81417b560ccd&amp;chksm=b18189c886f600de187fbd64540d16d2017f6574705ab0f0154d6032ed37edcf74bb95a7c8eb#rd
如有侵权请联系:admin#unsafe.sh