Stack clash style attacks

What is stack clash style attacks?

计算机上运行的程序都需要一块特殊的内存区域称为“栈”,栈空间通常是动态单向增长的,以Linux内核为例,操作系统为了防止栈空间过早分配产生的内存浪费,采用了栈延迟分配策略,按Page粒度逐步向低地址扩展增长。栈可用空间最低地址位置上有个特殊的页称为Stack Guard Page,当访问到达该页时,将触发严重错误,使程序终止执行。

攻击者故意分配较大的栈空间,但不触发访问,可有可能跳过对Stack Guard Page的访问,如果精心安排,或运气较好,就有可能将低地址方向的其它内存区域作为栈来使用,从而有机会突破栈不可执行保护。

How to prevent?

GCC编译器实现了stack clash protection功能,通过参数-fstack-clash-protection可启用。不是所有的目标架构都实现以支持该功能。

How it works?

GCC实现stack clash protection的方法是为每个函数生成一段代码,该代码执行在业务代码之前,按Page粒度逐个预访问函数framesize空间,达到一定能触发stack guard page访问的目的。


#include <stdio.h>

main (int argc, char *argv[])
    char buffer[1024 * 1024];

    printf ("%p", buffer);

    return 0;
00000001200008d0 <main>:                                  
   1200008d0:   03a01825    move    v1,sp                 
   1200008d4:   3c0c0010    lui t0,0x10                   
   1200008d8:   006c602f    dsubu   t0,v1,t0              
   1200008dc:   6463f000    daddiu  v1,v1,-4096           
   1200008e0:   146cfffe    bne v1,t0,1200008dc <main+0xc>
   1200008e4:   fc600000    sd  zero,0(v1)                
   1200008e8:   fd80fff0    sd  zero,-16(t0)              
   1200008ec:   67bd8010    daddiu  sp,sp,-32752          
   1200008f0:   3c03000f    lui v1,0xf                    
   1200008f4:   ffbc7fe0    sd  gp,32736(sp)              
   1200008f8:   3c1c0002    lui gp,0x2                    
   1200008fc:   34638020    ori v1,v1,0x8020              
   120000900:   0399e02d    daddu   gp,gp,t9              
   120000904:   ffbf7fe8    sd  ra,32744(sp)              
   120000908:   03a3e82f    dsubu   sp,sp,v1              
   12000090c:   679c83d0    daddiu  gp,gp,-31792          


Irreducible loop

Control-flow graph

(a) an if-then-else
(b) a while loop
(c) a natural loop with two exits, e.g. while with an if…break in the middle; non-structured but reducible
(d) an irreducible CFG: a loop with two entry points, e.g. goto into a while or for loop

Java case

public class IrreducibleLoop {
    public static void test(int loop) {


super public class IrreducibleLoop
    version 63:0
  public Method "<init>":"()V" 
    stack 1 locals 1
        invokespecial    Method java/lang/Object."<init>":"()V";
  public static Method test:"(I)V" 
    stack 2 locals 2
    L0: iconst_0;
        ifne    L2;
    L1: stack_frame_type append;
        locals_map int;
        if_icmpge    L3;
    L2: stack_frame_type same;
        goto    L1;
    L3: stack_frame_type chop1;

} // end Class IrreducibleLoop

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 12000; i++) {


java -jar asmtools-core-7.0.b10-ea.jar jasm IrreducibleLoop.jasm
java -XX:TieredStopAtLevel=1 -Xcomp -XX:CompileCommand=compileonly,IrreducibleLoop::* Main


ch341-uart converter now disconnected from ttyUSB0

usb 1-3.4: USB disconnect, device number 18
usb 1-3.1: new full-speed USB device number 19 using xhci_hcd
usb 1-3.1: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.54
usb 1-3.1: New USB device strings: Mfr=0, Product=2, SerialNumber=0
usb 1-3.1: Product: USB2.0-Ser!
ch341 1-3.1:1.0: ch341-uart converter detected
ch341-uart ttyUSB0: break control not supported, using simulated break
usb 1-3.1: ch341-uart converter now attached to ttyUSB0
usb 1-3.1: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
ch341 1-3.1:1.0: device disconnected


sudo mv /usr/lib/udev/rules.d/90-brltty-device.rules /usr/lib/udev/rules.d/90-brltty-device.rules.disabled
sudo mv /usr/lib/udev/rules.d/90-brltty-uinput.rules /usr/lib/udev/rules.d/90-brltty-uinput.rules.disabled
sudo udevadm control --reload-rules