You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
//===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===////// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.// See https://llvm.org/LICENSE.txt for license information.// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception////===----------------------------------------------------------------------===////// This file is a part of AddressSanitizer (ASan).//// Public interface header.//===----------------------------------------------------------------------===//#ifndefSANITIZER_ASAN_INTERFACE_H#defineSANITIZER_ASAN_INTERFACE_H#include<sanitizer/common_interface_defs.h>#ifdef__cplusplusextern"C" {
#endif/// Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable.////// This memory must be previously allocated by your program. Instrumented/// code is forbidden from accessing addresses in this region until it is/// unpoisoned. This function is not guaranteed to poison the entire region -/// it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan/// alignment restrictions.////// \note This function is not thread-safe because no two threads can poison or/// unpoison memory in the same memory region simultaneously.////// \param addr Start of memory region./// \param size Size of memory region.void__asan_poison_memory_region(voidconstvolatile*addr, size_tsize);
/// Marks a memory region (<c>[addr, addr+size)</c>) as addressable.////// This memory must be previously allocated by your program. Accessing/// addresses in this region is allowed until this region is poisoned again./// This function could unpoison a super-region of <c>[addr, addr+size)</c> due/// to ASan alignment restrictions.////// \note This function is not thread-safe because no two threads can/// poison or unpoison memory in the same memory region simultaneously.////// \param addr Start of memory region./// \param size Size of memory region.void__asan_unpoison_memory_region(voidconstvolatile*addr, size_tsize);
// Macros provided for convenience.#if__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
/// Marks a memory region as unaddressable.////// \note Macro provided for convenience; defined as a no-op if ASan is not/// enabled.////// \param addr Start of memory region./// \param size Size of memory region.#defineASAN_POISON_MEMORY_REGION(addr, size) \
__asan_poison_memory_region((addr), (size))
/// Marks a memory region as addressable.////// \note Macro provided for convenience; defined as a no-op if ASan is not/// enabled.////// \param addr Start of memory region./// \param size Size of memory region.#defineASAN_UNPOISON_MEMORY_REGION(addr, size) \
__asan_unpoison_memory_region((addr), (size))
#else#defineASAN_POISON_MEMORY_REGION(addr, size) \
((void)(addr), (void)(size))
#defineASAN_UNPOISON_MEMORY_REGION(addr, size) \
((void)(addr), (void)(size))
#endif
/* Main program. */intCTL_CDECLmain(intargc, char*argv[]) {
txCtxh;
char*progname;
/* Get program name */progname=tail(argv[0]);
--argc;
++argv;
/* Allocate program context */h=malloc(sizeof(structtxCtx_));
if (h==NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
returnEXIT_FAILURE;
}
memset(h, 0, sizeof(structtxCtx_));
h->app=APP_TX;
h->appSpecificInfo=NULL; /* unused in tx.c, used in rotateFont.c & mergeFonts.c */h->appSpecificFree=txFree;
txNew(h, progname);
h->t1r.flags=0; /* I initialize these here,as I need to set the std Encoding flags before calling setMode. */h->cfr.flags=0;
h->cfw.flags=0;
h->dcf.flags=DCF_AllTables | DCF_BreakFlowed;
h->dcf.level=5;
h->svr.flags=0;
h->ufr.flags=0;
h->ufow.flags=0;
h->t1w.options=0;
// 设置cff模式setMode(h, mode_cff);
// argv[1] 文件名,对应上面argv--doSingleFileSet(h, argv[0]);
if (h->failmem.iFail==FAIL_REPORT) {
fflush(stdout);
fprintf(stderr, "mem_manage() called %ld times in this run.\n",
h->failmem.iCall);
}
txFree(h);
return0;
}
fuzz CVE-2019-1118
这篇来分析一下
CVE-2019-1118
,问题为stack corruption in OpenType font handling due to negative cubeStackDepth
漏洞复现
搭建环境,简单复现一下
根据给出的
poc
测试可以发现,出错了,但是被
afdko
捕获了。这样的话,在重点位置设一下断点,再来看一下
首先测试一下
do_blend_cube.otf
看一下效果
结合着反汇编代码看,效果可能更好
可以发现
h->cube
数组取值是通过乘法实现的,当索引为-1
即h->cubeStackDepth==-1
时,再变换一下
相当于
h->cube
指针向前移动了一个数组值,即0x1920
个字节再来看看
struct _t2cCtx
的大小向前移动了,但是
((struct cube)h->cube)-1
的位置还是在_t2cCtx
结构体中,验证一下继续单步执行到这,索引值得出
继续
si
此时
可以发现
0x9d3f8 > 0x31880
,验证也确实还在结构体中。这样的话,即使是
h->cubeStackDepth==-1
也不会导致内存访问出错,最多也就是分析错误,被afkdo
捕获也就不奇怪了。我们的结果也确实是这样但是
PJ0
给的例子中,存在了一个叫做redzone patch
的操作,打完patch
之后会出现user-after-poison
的错误。就像这样
如果我们想这样的话,该怎么做呢?
很遗憾,关于手动设置
redzone
的资料特别少,中文基本上就是纯空白了。而且我发现,基本上这个方法就是PJ0
自己成员在用,其他人很少有使用过的。为了实现这个功能,我把
sanitizer
的实现资料和相关redzone
的源码全部简单过了一遍,最后弄懂了redzone
的相关定义和用法,这部分想要了解的话,自己查资料吧,内容比较多,可以重点看一下PJ0
介绍sanitizer
的几个paper
。最后在
sanitizer/asan_interface.h
中看到了这部分代码宏定义
ASAN_UNPOISON_MEMORY_REGION
指向__asan_poison_memory_region
,利用这个函数可以设置redzone
,之后利用__asan_unpoison_memory_region
解除设置方法找到了,那就来看具体代码,设置
redzone
,在do_blend_cube
函数中这里有一点需要注意,
poison
的size
一定要设置的够大,否则会没有poison
的效果,我这里是取_t2cCtx
结构体的大小,这样就保证了怎么移动我们都能检测到来看一下效果
fuzzing 代码
还是这么写
main
函数出现异常利用上面的测试一下即可。
fuzz
代码我公开了,测出有效洞可得找我哈 : )还不会的话,只能看我的具体项目了,一起学习
fuzz
哈后记
这个漏洞开始
redzone patch
的检测,我自己不会写,花了很长时间后来慢慢摸索出来了,就自己写了一个后来我又给这个漏洞的发现者j00ru发了邮件,向他要了他的
redzone patch
,他很爽快的答应了,并将代码以附件的形式发给我了。这里我们来分析一下(比我的
redzone
检测不知道要高到哪里去了)能有机会看到这么有实际作用的
redzone
检测代码,且看且珍惜首先来看一下结构体的几处更改
第一处
接下来的几处
可以发现,在这个最重要的结构体里基本所有的数组都做了
redzone
标记,这样也就基本保证了这个结构体里的数组指针,在发生越界操作时,大概率会操作
redzone
的数据,从而被捕获到。再来看一下
poison
具体详细的
patch
代码,自己琢磨吧,这种redzone patch
的方式,记住,分析crashes
肯定用得上!参考
Microsoft DirectWrite / AFDKO stack corruption in OpenType font handling due to negative cubeStackDepth
The text was updated successfully, but these errors were encountered: