漏洞出现在PushcdlStack函数中,如下所示
程序中将*pStackPtr加一后,执行pStack[*pStackPtr] = value。这里没有校验*pStackPtr加一后的值是否超过pStack大小,造成栈溢出。
回到调用PushcdlStack函数的上一层函数Parse_cdl,如下所示
部分无关代码这里没有显示,只看漏洞相关代码,opcode是从文件读取中的,所以可控;当opcode == DLS_CDL_CONST时,x的值也来从文件中读取,所以可控;
循环的最后会执行漏洞函数PushcdlStack(stack, &stackPtr, x),stack大小为CDL_STACK_SIZE(CDL_STACK_SIZE的值为8),stackPtr初始值为-1,
因此我们只要循坏执行PushcdlStack(stack, &stackPtr, x)函数8次之后,stackPtr等于7,再执行一次PushcdlStack(stack, &stackPtr, x),
即可将可控x写入stack[8],造成栈溢出。
漏洞是在解析.xmf文件时出现的
修复方案就是将PushcdlStack函数if (*pStackPtr >= CDL_STACK_SIZE)改为if (*pStackPtr >= CDL_STACK_SIZE - 1)
以下是该漏洞的git diff
通过比较,可以看出漏洞是由于对frameCount的值没有进行校验,导致的整形溢出
frameCount本身是无符号整型
在size_t bufferSize = (buffer == NULL ? roundup(frameCount) : frameCount) * mFrameSize;中frameCount*frameCount肯回造成溢出
导致最终bufferSize的值小于frameCount) * mFrameSize
之后的代码会以bufferSize的值申请一块内存,之后对这块内存进行访问时,会造成缓冲区溢出
直接查看漏洞点
State是我们可以控制的,s.client是一个IBinder指针,之后通过比较binder->getInterfaceDescriptor()字符串和ISurfaceComposerClient::descriptor
的值,之后进行类型转换,将s.client转换为Client,之后调用setClientStateLocked(client, s.state)
在setClientStateLocked函数中会执行Client对象的虚函数
可以看到,类型转换前,校验知识简单的比较了两个字符串的值,我们可以伪造一个符合条件的对象,进而在调用虚函数时,执行伪造对象的虚函数
修复方案如下
漏洞代码如下:
在调用mLastTrack指针的函数前没有验证mLastTrack指针是否为空,造成空指针引用漏洞
在MPEG4Extractor对象的构造函数中,将mLastTrack的值置为空
修复方案就是增加空指针校验,通过查看源码可以看到处理其他case时是有校验的,可是偏偏这一个case没有校验,有点意思
漏洞点
这里主要是因为mCblk对象的特殊性,mCblk位于共享内存,在一个进程使用期间被另一个进程使用,通过进程间通信控制mCblk这个对象
所以这里即使判断了mCblk->clientIndex和mCblk->serverIndex值的有效性,在之后有可能mCblk->serverIndex和mCblk->serverIndex值会被其他进程改变
从而在之后越界访问缓冲区
修复方案就是保存事先mCblk->clientIndex和mCblk->serverIndex值,如下:
漏洞代码如下
传入的URI在解析后直接被调用了删除dropfile。缺少了权限检查
修复方案:
官网修复方案是直接把dropFile(Uri.parse(uriString), context);这一句删掉了
漏洞点:
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-2-26 16:52
被五千年木编辑
,原因: 略