Beispiel #1
0
def main(keyspace):
    graph = Graph(uri='http://localhost:4567', keyspace=keyspace)

    # Get address of printf to use for next query
    query1 = 'match $func isa function, has func-name contains "printf", has asm-address $a; offset 0; limit 100; select $a;'
    result1 = graph.execute(query1)
    if len(result1) > 0:
        print("Found potential calls at the following addresses:")
        for addr in result1:
            print(addr['a']['value'])

    # If printf is found continue query
    for printf_func in result1:
        # Pull any instructions that use printf and don't use a modifier (have var type and not data type)
        func_addr = int(printf_func['a']['value'], 16)
        print("Scanning address {}".format(hex(func_addr)))
        query2 = 'match $x isa instruction, has operation-type "MLIL_CALL_SSA", has asm-address $a; $y isa "MLIL_CONST_PTR"; ($x,$y); $z isa constant, has constant-value {}; ($y,$z); $l isa list, has list-size 1; ($x,$l); $s isa "MLIL_VAR_SSA"; ($l,$s); offset 0; limit 500; select $x, $a;'.format(
            func_addr)
        result2 = graph.execute(query2)

        # If there is an instruction that uses printf without modifier, output instruction
        if result2:
            for instr in result2:
                asm_addr = instr['a']['value']
                print("CWE-134: Uncontrolled Format String possible at {} ".
                      format(asm_addr))
Beispiel #2
0
def main(keyspace):
    global graph
    graph = Graph(uri='http://localhost:4567', keyspace=keyspace)

    #Find a variable being compared
    query1 = graph.execute('match {$comp isa MLIL_CMP_SGE;} or {$comp isa MLIL_CMP_SLE;} or {$comp isa MLIL_CMP_SLT;} or {$comp isa MLIL_CMP_SGT;};$node isa MLIL_VAR_SSA;$cons isa MLIL_CONST;($comp, $node);($comp, $cons);$varssa isa variable-ssa has var $var;($node, $varssa);select $comp, $var;offset 0;') 

    #Parse the output of query1 into the compare statements and varaible names
    comp, var = [], []
    if query1:
        for entry in query1:
            comp.append(entry['comp']['id'])
            var.append(entry['var']['value'])
    else:
        fail()
    for entry in comp:
        #Do upper bound check
        if ('SGE' or 'SGT') in entry:
            lower = lowerCheck()
            if lower:
                for item in lower:
                    if item['var']['value'] not in var:
                        #failed to find upper bound check
                        addr = get_addr(entry)
                        print('CWE-129: Missing upper bound check at ' + str(addr[0]['addr']['value']))
                    else:
                        adddr = get_addr(entry)
            else:
                addr = get_addr(entry)
                print('CWE-129: Missing upper bound check at ' + str(addr[0]['addr']['value']))
        #Do lower bound check
        else:
            upper = upperCheck()
            if upper:
                for item in upper:
                    if item['var']['value'] not in var:
                        #failed to find lower bound check
                        addr = get_addr(entry)
                        print('CWE-129: Missing lower bound check at ' + str(addr[0]['addr']['value']))
                    else:
                        addr = get_addr(entry)  
            else:
                addr = get_addr(entry)
                print('CWE-129: Missing lower bound check at ' + str(addr[0]['addr']['value']))
def main(keyspace):
    graph = Graph(uri='http://localhost:4567', keyspace=keyspace)

    # Check for gets() function
    # Get address of function to use for next query
    function_name = 'gets'
    query1 = 'match $func isa function, has func-name contains "{}", has asm-address $a; select $a;'.format(
        function_name)
    result1 = graph.execute(query1)

    # If the function is found continue query
    if result1:
        # Get all instructions that have function name
        func_addr = int(result1[0]['a']['value'], 16)
        query2 = 'match $x has operation-type "MLIL_CALL_SSA" has asm-address $a; $y isa"MLIL_CONST_PTR"; ($x,$y); $z isa constant, has constant-value {}; ($y,$z); select $x, $a;'.format(
            func_addr)
        result2 = graph.execute(query2)

        # If there are instructions that use the function check the instructions
        for instr in result2:
            ins_addr = instr['a']['value']
            print(
                "CWE-120: Buffer Copy Without Checking Size of Input at {}\n".
                format(ins_addr))
# CWE-134 Uncontrolled Format String
#
# Vuln Info: This vulnerability comes from using printf without a modifier
# Ex: cgc_printf(message);          <--Bad
#     cgc_printf("%s", message);    <--Good
#
# Methodology:
# 1. Check if file has a printf function
# 2. Check if any instructions use printf
# 3. Check if params in printf are data type(correct) or var_type(incorrect, no modifier i.e. %s used)
#
# Try it on: Barcoder, Checkmate, *Kaprica_Go
#============================================================================================================

from grakn.client import Graph
graph = Graph(uri='http://localhost:4567', keyspace='grakn')

# Get address of printf to use for next query
query1 = 'match $func isa function, has name contains "printf", has asm-address $a; select $a;'
result1 = graph.execute(query1)

# If printf is found continue query
for printf_func in result1:
    printf_addr = printf_func['a']['value']

    # Pull any instructions that use printf and don't use a modifier (have var type and not data type)
    func_addr = int(result1[0]['a']['value'], 16)
    query2 = 'match $x has operation-type "MLIL_CALL_SSA", has asm-address $a; $y isa "MLIL_CONST_PTR"; ($x,$y); $z isa constant, has constant-value {}; ($y,$z); $l isa "list", has list-size != 2; ($x,$l); $s isa "MLIL_VAR_SSA"; ($l,$s); offset 0; limit 30;select $x, $a;'.format(
        func_addr)
    result2 = graph.execute(query2)
#=======================================================================================
# CWE-788: Access of Memory Location After End of Buffer
#
# Vuln Info: The software reads or writes to a buffer using an index or pointer that
#            references a memory location after the end of the buffer.
#
# Methodology:
# 1.Find any arrays
# 2.Find indexing variables for said arrays
# 3.Look to see if those variables are used in a comparison (bounds check)
#=======================================================================================

import sys
from grakn.client import Graph
graph = Graph(uri='http://localhost:4567', keyspace='grakn')


#Exits script
def fail():
    return 0
    sys.exit()


#Searches for potential array declarations
def query1():
    result = graph.execute(
        'match $set isa instruction, has operation-type "MLIL_SET_VAR_SSA";$ptr isa MLIL_CONST_PTR;($set, $ptr);$reg isa variable-ssa, has var $index;($set, $reg);offset 0;'
    )
    return result

def main(keyspace):
    graph = Graph(uri='http://localhost:4567', keyspace=keyspace)

    # Functions with indexes for (dest, sizeof(dest)) stored in dict
    functions = {"receive_delim": (1,2), "fgets": (0,1), "strncpy": (0,2), "receive_until": (0,2), "memcpy": (0,2), "freaduntil": (1,2)}
    
    # Check for potential vuln in each function
    for function_name in functions:
       # Get address of function to use for next query
        query1 = 'match $func isa function, has func-name contains "{}", has asm-address $a; select $a;'.format(function_name)
        result1 = graph.execute(query1)
        
        # If the function is found continue query
        if result1: 
            
            # Get all instructions that have function name
            func_addr = int(result1[0]['a']['value'], 16)
            query2 = 'match $x has operation-type "MLIL_CALL_SSA"; $y isa"MLIL_CONST_PTR"; ($x,$y); $z isa constant, has constant-value {}; ($y,$z); select $x;'.format(func_addr)
            result2 = graph.execute(query2)
            
            # If there are instructions that use the function check the instructions 
            if result2:

                buff_index = functions[function_name][0] + 1
                size_index = functions[function_name][1] + 1
                
                for instr in result2:
                    Id = instr['x']['id']
                    query3 = 'match $x id "' + Id + '"; $l isa list; ($x,$l); (from-node: $l, $q); $q has edge-label $e; (from-node: $q, $v); {$v has var $s;} or {$v has constant-value $s;}; select $e, $s;'
                    result3 = graph.execute(query3)
            
                    # This section grabs instrution params and insert into an array 
                    param_array = [0, 0, 0, 0, 0, 0, 0, 0]

                    for ele in result3:
                        index = int(ele['e']['value'])
                        val = ele['s']['value']
                        param_array[index] = val

                    # Get var name - This is done to determine how many bytes the variable is
                    var_name = param_array[buff_index]
                    var_name = var_name.split('#',1)[0].lstrip()

                    # NOTE Enhancement Make finding buff_size the same as string_size
                    # This assumes that buffer_size is a number, breaks when its a var or register 
                    # Get buffer size 
                    try:
                        buff_size = int(param_array[size_index])
                    except ValueError as err:
                        continue

                    # Get size of string in by finding initialization Ex. var_88 = &var_58        
                    # Find where string is initialzed
                    query4 = 'match $x id "{}"; $y isa basic-block; ($x,$y); $z isa instruction, has operation-type "MLIL_SET_VAR_SSA"; ($y,$z); {{$v1 isa variable, has var "{}";}} or {{$v1 isa variable-ssa, has var "{}";}}; ($z, $v1); $w isa MLIL_ADDRESS_OF; ($w, $z); $v isa variable, has var-size $s; ($w, $v); offset 0; limit 30;offset 0; limit 30;'.format(Id, var_name, var_name)
                    result4 = graph.execute(query4)
                    
                    if (result4):
                        string_size = result4[0]['s']['value']
                        
                        # Finally Determine if buffer size == sizeof(str)
                        if string_size != buff_size:
                            instruction_ID = result4[0]['x']['id']
                            query5 = 'match $i id {}, has asm-address $a; select $a;'.format(instruction_ID)
                            result5 = graph.execute(query5)
                            instr_addr = result5[0]['a']['value']

                            print("CWE-121: Stack-based Overflow possible at {}".format(instr_addr))
def main(keyspace):
    global graph
    graph = Graph(uri='http://localhost:4567', keyspace=keyspace)

    # Find possible arrays
    array = []
    q1 = query1()
    if q1:
        i = 0
        for item in q1:
            array.append(q1[i]['index']['id'])
            i += 1
    else:
        fail()

    # Find loops involving the array
    block = []
    q2 = query2()
    if q2:
        i = 0
        for item in q2:
            if q2[i]['index']['id'] in array:
                block.append(q2[i]['block']['id'])
            i += 1
    else:
        fail()
    
    # Do the 'loop' blocks contain if statements?
    if_id = []
    block2 = block.copy()
    for item in block2:
        q3 = query3(item)
        if not q3:
            block.remove(item)

    # Find the loop counters
    var, version, var_id, reg, reg_type, block2 = [], [], [], [], [], block.copy()
    for entry in block2:
        q4 = query4(entry)
        if q4:
            i = 0
            for item in q4:
                reg.append(item['reg']['id'])
                reg_type.append(item['reg']['isa'])
                var.append(item['index']['value'])
                version.append(item['version']['value'])
                var_id.append(item['index']['id'])
                i += 1
        else:
            block.remove(entry)
    i = len(var) - 1

    # Find is the bounds of the loop counter are checked
    var2 = []
    q5 = query5()
    i = 0
    for entry in q5:
        var2.append(q5[i]['var']['value'])
        i += 1
    
    # Any variables in var[] but not var2[] are potential vulnerabilities
    i = 0
    for entry in var:
        if entry not in var2:
            q6 = query6(reg_type[i], reg[i])
            print('CWE-788: Array index missing bounds check at ' + q6[0]['adr']['value'] + ' associated with '+ var[i] + '#' + str(version[i]) + ' id = ' + var_id[i] + ' sub of ' + reg_type[i] + ' id = ' + reg[i])
        i += 1