最近看了HITCON 2014一个议题
- https://hitcon.org/2014/downloads/E210%E5%8A%8D%E5%BF%83%20-%20%E4%B9%8C%E4%BA%91%E7%9A%84%E8%BF%99%E4%BA%9B%E5%B9%B4.pptx
分享其中一页,五年前看是一种心态,现在看又是另一番滋味,或许再过五年,一切又都变了,大家现在应该更推崇知识付费吧
这两周接二连三的出现大厂数据泄露,前脚英伟达,后脚三星就跟上了,泄露的内容大家可以自行阅读下面这张截图
请有缘人自取
- magnet:?xt=urn:btih:FXZGNQTWZOCYDND27IERZ7HBXWWXYLUZ&dn=Samsung&tr=udp%3A%2F%http://2Fpublic.popcorn-tracker.org%3A6969%2Fannounce
希望今年Pwn2Own能带出很多好的漏洞与攻击手法
我这几天主要是在看iMessage那个Zero-Click的漏洞,PJ0也发布了一篇博客《A deep dive into an NSO zero-click iMessage exploit: Remote Code Execution》
- https://googleprojectzero.blogspot.com/2021/12/a-deep-dive-into-nso-zero-click.html
简单讲讲漏洞细节,先描述下JBIG2的原理,对于黑白图像的文本来说,扫描完之后相同的符号对应的图像大体上都差不多,但是落实在数据上尤其是像素级别就会有差异,JBIG2会维护一个位图表,将扫描到的符号对应到位图表里的位图,如果存在对应的位图,就记录位图表偏移,如果不存在则添加这个符号对应的位图,再记录偏移,最后再对位图表进行压缩,如此一来即可实现对扫描数据的压缩效果
如图所示,一共有六个符号e
出现,但是每个符号细节上的像素都有所差异,如果全都存储一遍很占空间
如果我们将其全部使用第一个符号e
来替代,并且记录下每个符号e
所在坐标,就可以只存储一次符号e
所对应的位图,极大实现压缩效果
然后是Segment,如果要仔细分析的话是一定要理解JBIG2Stream里的Segment含义,一段JBIG2Stream由非常多的Segment组成,每个Segment表现为一段二进制数据,其实对应出来就是一个渲染指令,还有位图表,通过Segment类型字段分发到不同的分支里去对页面做处理
当进行文本区域解码的时候,会先处理引用的位图Segment,将所有引用到的位图数据全部导入,然后再去解码,在计算位图数量的时候,存在整数溢出漏洞,导致申请的堆空间偏小,后续循环写入位图数据时导致堆溢出
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
GBool lossless, Guint length,
Guint *refSegs, Guint nRefSegs)
{
...
// get symbol dictionaries and tables
codeTables = new GList();
numSyms = 0; // 位图计数器
for (i = 0; i < nRefSegs; ++i) // 引用的Segment数量
{
if ((seg = findSegment(refSegs[i]))) // 通过Segment序号找到对应的对象
{
if (seg->getType() == jbig2SegSymbolDict) // 类型为位图表的Segment
{
numSyms += ((JBIG2SymbolDict *)seg)->getSize(); // 将当前Segment的位图数量叠加到位图计数器 <-- 此处发生整数溢出
}
else if (seg->getType() == jbig2SegCodeTable)
{
codeTables->append(seg);
}
}
else
{
error(errSyntaxError, getPos(),
"Invalid segment reference in JBIG2 text region");
delete codeTables;
return;
}
}
...
// get the symbol bitmaps
syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *)); // 在整数溢出的情况下,位图计数器numSyms会变成一个较小的值,申请下来的堆空间也相对较小
kk = 0;
for (i = 0; i < nRefSegs; ++i) // 遍历引用的Segment
{
if ((seg = findSegment(refSegs[i]))) // 通过Segment序号获取到对应的对象
{
if (seg->getType() == jbig2SegSymbolDict) // 类型为位图表的Segment
{
symbolDict = (JBIG2SymbolDict *)seg; // 转换类型为位图表
for (k = 0; k < symbolDict->getSize(); ++k)
{
syms[kk++] = symbolDict->getBitmap(k); // 将位图指针写入申请的堆空间 <-- 此处发生堆溢出
}
}
}
}
...
}
利用过程我这里不描述了,有兴趣可以等待PJ0的第二篇文章,非常天才的利用
Saelo前段时间在今年的BlueHat上也讲了一个相关的议题,不过和文章的内容差不多,没有新增太多跟漏洞利用相关的内容
- https://saelo.github.io/presentations/bluehat_il_22_a_brief_history_of_imessage_exploitation.pdf
这个漏洞要理解整个流程其实还是有点难度的,首先要清楚PDF的格式,如何将JBIG2Stream嵌入到PDF里,然后是Segment的格式,不然解析过程那些字段位移取值判断操作很难明白是在做什么
推荐看看JBIG2的文档,顺带看下后面的样例讲解,理解了之后再去看源码就清楚多了
同时今年BlueHat还有一个议题,DAY ONE晚上九点二十五到十点零五那个,不知道什么时候会有Slides放出来,我倒是很期待学习下,不敢贴细节,放个带锚点的导航
- https://www.microsoftrnd.co.il/bluehatil/abstracts#collapse-6
这两天有一个玄武的瓜,想不到在我划水咸鱼的日子里,别人家的世界这么精彩
每年安全圈都有那么几个瓜让人热闹一下,前年有,去年有,今年也有,在圈子里混了这么多年,通常有瓜的时候,两头我都认识,也知道背后的真实情况(这次我两头都不熟),所以站在这样的角度去看大家的反应,还挺有趣的,有的人啥都不知道就口无遮拦评价别人的样子还真是让人讨厌
也给各位提了个醒,如果你离职的时候老板让你上交你这些年的研究成果与技术文档,或者是你写的Fuzzer,漏洞扫描器,甚至是0day,你是交呢?还是不交呢?
最后说点题外话
北方的战斗民族公开了一份文档,各位如有兴趣可翻阅
- https://disk.yandex.ru/d/62hsNB8kC7MXPQ
我直接贴一张大家最关心的,右下角那位Doctor,不知道现在是不是正在被查水表
附上这位Doctor的个人介绍,还真是专业对口