WIT 写完整性测试

标签: DFI


Abstract

用于防止内存错误  

WIT在编译时刻用过程间指向性分析[23]计算CFG和程序中可能被每个指令写的一系列objects。然后装备代码防止不在静态分析所得到的集合里的指令修改objects,并且保证间接控制跳转符合CFG。为了提升精确度,WIT在原始的程序objects间插入小的guards。我们描述了一个实现,降低了空间和时间损耗,并且可以实用因为它不用进行修改的编译C和C++程序,没有误报。平均时间损耗7%(CPU密集型benchmarks)。

WIT使用指向性分析对每一个object和写操作赋一个color,所有可以被一条指令进行写操作的objects具有相同的color,装备代码在运行时记录 object colors并且检查指令写到正确的color。存储单元的color记录在一个color表中,当objects被分配和释放时color表会相应更新。写检查在表中查阅正在被写的存储单元的color并且检查是否和写指令的color一致。如此确保了写完整性。

haha

WIT也会给间接跳转指令和可能间接跳转的函数的入口点一个color,由此所有可能被同一条指令call的函数有相同的color。WIT装备代码在color表中记录函数colors并且检查间接跳转指令。间接跳转在表中查找目标地址的color,并且检查是否与间接跳转指令的color匹配。这些检查和写检查确保了CFI。CFI防止攻击者绕过我们的检查并且提供了第二道防线来防御写检查没有探测到的攻击。
优化:
1. 静态分析找到不违反写完整性的访问和只有安全访问的objects,我们只装备不安全的写操作,并且对所有安全的objects赋给同样的颜色。这会减少写检查的数目和color表的损耗。降低了需要用来表示color的bit数。我们所有的实验中,一个字节足够表示颜色。
2. color表使用紧凑表示,可以有效率的查找。color表用一个字节表示一个8字节的存储,降低了12.5%的空间损耗。
3. Third, we reduce the cost of updating color table entries on function calls. Since most local variables are safe, we only update entries for guards and unsafe variables on function entry and we reset these entries to the color of safe objects on function exit.

2. Overview

WIT有compile-time和runtime两个部件。
// Example vulnerable code: simplified Web server with a buffer overflow vulnerability.

1: char cgiCommand[1024];
2: char cgiDir[1024];
3:
4: void ProcessCGIRequest(char* msg, int sz) {
5: int i=0;
6: while (i < sz) {
7: cgiCommand[i] = msg[i];
8: i++;
9: }
10:
11: ExecuteRequest(cgiDir, cgiCommand);
12: }

lines 5-9 存在缓冲区溢出漏洞,如果message过长,攻击者可以重写cgiDir(里面是CGI commond调用的可执行文件的路径)来运行任意可执行程序(例如shell)。这是一个non-control-data attack,不违反CFI。

使用指向性分析[23]计算程序中每条指令可能修改的obiects,上例中,分析计算出 the set {i} for the instructions at lines 5 and 8, and the set {cgiCommand} for the instruction at line 7.

为了降低运行时的损耗,提出写安全检查来计算安全的指令和objects。不违反写完整性的指令为安全指令,如果所有的能修改object的指令都是安全的,那么这个object是安全的。上例中, instructions 5 and 8 are safe because they can only modify i and, therefore, i is safe. ProcessCGIRequest的参数也是安全的。instruction 7 is not safe because it may modify objects other than cgiCommand depending on i’s value.

对所有的安全指令和objects的color设为0。上例中, 变量 msg, sz, and i and instructions 5 and 8 are assigned color 0 because they are safe. We assign color 3 to variable cgiCommand and instruction 7, and color 4 to variable cgiDir.

为了降低漏报率(由于指向性分析的不精确导致),在原始程序的不安全的objects之间插入小得guards。 Guard objects have color 0 or 1。这些color永远不能赋给不安全的指令以确保WIT能检测到重写guards或者安全的objects。

函数的color集合与objects,guards的color集合不相交。这可以防止不安全的指令重写代码并且防止代码区域外的控制转移。

WIT加了额外的编译阶段来装备以实现写完整性和控制流完整性。有四种类型的instrumention:to insert guards, to maintain the color table, to check writes, and to check indirect calls. Guards 8个字节大小. 上例中,  add guards just before cgiCommand, between cgiCommand and cgiDir, and just after cgiDir。

当一个object被分配时,把它存储位置的color设为object的color。上例中, WIT adds instrumentation at the beginning of main to set the color of the storage locations occupied by cgiCommand to 3, the color of the storage for cgiDir to 4, and the color of the storage for the guards around them to 0。

为了降低更新color表的损耗,初始化所有存储单元的color表为0,当安全的objects被分配时不更新color表。Instead, we only update the colors for locations corresponding to unsafe objects on function entry. On function exit, we reset color table entries that we updated on function entry to 0. Therefore, there is no instrumentation to update the color table on function entry or exit for ProcessCGIRequest.

上例中, WIT adds write checks only before instruction 7 to check if the location being written has color 3. It does not add write checks before lines 5 and 8 because these instructions are safe。

WIT的防御依赖于指向性分析的精度,比如两个相同color的object可以相互赋值。

WIT可以防御上述例子。The write check before line 7 fails and raises an exception if an attacker attempts to overflow cgiCommand. When i is 1024, the color of the location being written is 0 (which is the color of the guard) rather than 3 (which is the color of cgiCommand). Even without guards, WIT would be able to detect this attack because the colors of cgiCommand and cgiDir are different。

3. Static analysis

We implemented the points-to and the write safety analysis using the Phoenix compiler framework [30]. These analysis operate on Phoenix’s medium level intermediate representation (MIR), which enables them to be applied to different languages and target architectures。

        i = ASSIGN 0 
$L6:    t273 = COMPARE(LT) _i, _sz 
        CONDITIONALBRANCH(True) t273, $L8, $L7 
$L8:    t278 = ADD _msg, _i 
        t276 = ADD &_cgiCommand, _i 
        [t276] = ASSIGN [t278] 
        _i = ADD _i, 1 
        GOTO $L6 
$L7:    CALL &_ExecuteRequest,&_cgiDir,&_cgiCommand

Figure 2. Example vulnerable code in mediumlevel intermediate representation (MIR).
  
  We use an inter-procedural points-to analysis due to Andersen [8] that is flow and context insensitive but scales to large programs. It computes a points-to set for each pointer,which is the set of logical objects the pointer may refer to. The logical objects are local and global variables and dynamically allocated objects (for example, allocated with malloc). We use a single logical object to represent all objects that are dynamically allocated at the same point in the program but we do cloning of simple allocation wrappers to improve analysis precision. Our implementation is similar to the one described in [23] but it is field-insensitive rather
than field-based (i.e., it does not distinguish between the different fields in a structure, union, or class). We use Phoenix to compile each source file to MIR and write points-to constraints to a file. The analysis reads the constraints file, computes the points-to sets, and stores them in a file.

In addition, the write safety analysis runs a simple intra-procedural pointer-range analysis to compute writes through pointers that are always in bounds. The instructions that perform these writes are marked safe.

While making the global pass over all source files to collect constraints for the points-to analysis, we also run the write safety analysis. We write unsafe pointers to a file. A pointer is unsafe if it is dereferenced for writing by an unsafe instruction.

We use an iterative process to compute color sets, which include objects and unsafe pointer dereferences that must be assigned the same color because they may alias each other.

WIT uses a similar algorithm to assign colors to functions that may be called indirectly.

4. Instrumentation

4.1 Color table

We implemented WIT for 32-bit x86 machines running Windows.We used several Phoenix plugins [30] to generate WIT’s instrumentation.

WIT maintains a color table that maps memory addresses to colors. The color table must cover the whole user virtual address space and it is accessed often by write and indirect call checks.

To keep the color table small, we divide the virtual memory of the instrumented program into aligned eight-byte slots. The color table is implemented as an array with an eight-bit color identifier for each of these slots.Therefore,it introduces a space overhead of only 12.5%.

We are able to record a single color for each eight-byte slot because we generate code such that no two objects with distinct colors ever share the same slot. It is easy to enforce this requirement for heap objects because they are eight-byte aligned and for functions because they are 16-byte aligned. But since the stack and data sections are only four-byte aligned in 32-bit x86 architectures,we cannot currently force eight byte alignment of objects in these sections without introducing runtime overhead.

Instead,we force unsafe objects and guard objects in the stack and data sections to be four-byte aligned and we insert a four-byte aligned pad after unsafe objects. For an unsafe object of size s, the pad is eight-bytes long if �s/4� is even and four-bytes long if �s/4� is odd. We set �s/8� color table entries to the color of the unsafe object when the pad is four-bytes long and �s/8�+1 when the pad is eight-bytes long. We should be able to reduce the space overhead when targeting 64-bit x86 architectures because the stack and data sections are eight-byte aligned in these architectures.

Since our points-to analysis does not distinguish between different fields in objects and between different elements in arrays,we always assign the same color to all the elements of an array and to all the fields of an object. Therefore, it is not necessary to change the layout of arrays and objects,which is important for backwards compatibility.

We only require eight bits to represent colors because the write safety analysis is very effective at reducing the number of objects that we must assign colors to. However,it is possible that more bits will be required to represent colors in very large programs. If this ever happens, there are several things we can do. For example, we can increase the size of color table entries to 16-bits and increase memory slot sizes to 16-bytes, or use 8-bit color identifiers at the expense of worse coverage.

The color table can be accessed efficiently. Since there are 2 GB of virtual address space available for the user in Windows XP and Windows Vista, we allocate 256 MB of virtual address space for the color table 2. We rely on the operating system to allocate physical pages for the color table on demand when they are first accessed. The base of the color table is currently at address 40000000h. So to compute the address of the color table entry for a storage location,we take the address of the storage location, shift it right by three, and add 40000000h.

To protect the color table from being overwritten by an attacker, we read-protect the pages in the table that contain the entries for the virtual address range occupied by the table itself. With the base of the table at 40000000h,we protect the pages in the address range 48000000h to 4A000000h (color table原地址:256MB,为40000000h-50000000h)to prevent reads and writes. Since we add checks before unsafe writes and control-flow integrity ensures that the attacker cannot bypass these checks, the attacker cannot overwrite the color table because the write check would trigger a read fault on the protected address range. This technique was first described in [44].

4.2 Inserting guards

The guards are eight-bytes long to match the size of the slots that we record colors for in the color table. The instrumentation to insert these guards is different for the stack, heap, and global data sections.

To insert guards in the stack, we replace the compiler phase that lays out local variables in a stack frame by our implementation. We segregate safe local variables from unsafe ones to reduce the space overhead. First, we allocate contiguous storage for the safe local variables. Then we allocate storage for the guards, pads, and unsafe local variables. This allows us to insert only n+1 guards and pads for n unsafe local variables: the guard that prevents overflows of a variable prevents underflows of the next variable.

In the rare case where a function argument is written by an unsafe instruction, we cannot easily insert guards and pads around it. Therefore, we copy the argument to a local variable and rewrite the instructions to refer to the copy.This local variable is marked unsafe and we insert guards and pads around it.

We mark all heap-allocated objects as unsafe but we do not insert pads or guards around them. The standard heap allocator in Windows Vista, Windows XP SP2, and Windows 2003 inserts an eight-byte header before each allocated object. We use this header as a guard by simply setting its color to 1 in the color table.

We add guards and pads between all variables in the .data section and .bss sections but not in the read-only data section (.rdata).

We plan to implement an optimization that avoids the need for most guards by laying out stack and global objects such that adjacent objects have different colors.

4.3 Maintaining the color table

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 8,592评论 0 23
  • 这红尘这么美,美得我想放下脚步,慢慢欣赏。怕错过蝴蝶张开翅膀的声音,怕错过烟火升起时的一瞬间绚丽。
    玖瑶阅读 214评论 0 1
  • 概述 SeekBar,拖动条。主要的要点是自定义的样式,拖动条的值,拖动条值改变的监听器等等。 1.SeekBar...
    CokeNello阅读 17,587评论 2 19
  • 八月就又要结束了,暑假也即将进入尾声。在陆续开学的日子里,青子给大一的新生er们,写了一个科普贴,希望对即将进入大...
    夢萝青子ccc阅读 554评论 1 9
  • 前些天去幼儿园接沛沛,因为稍晚了一点,沛沛看见我就大哭起来,埋怨我太晚来接他,又有一天我去接他,他因为老师没有给他...
    梁琰阅读 330评论 2 2