def mutateXML(inputDict: dict): if inputDict.get('file') != FileType.XML: return logger.info('Running: Mutate XML...') root = ET.ElementTree(ET.fromstring(parse.getInputFromDict(inputDict))).getroot() nodes = findXMLNodes(root) # choose a random node, move it to be child of another random node that isn't one of its children # the randomness is pointless because am trying all anyway and would need an insanely huge xml for that to take 3 mins for src in random.sample(nodes.keys(), len(nodes.keys())): # try with node removed nodes[src][-1].remove(src) sendXML(root) nodes[src][-1].append(src) # removing and adding back changes the order but w/e # move to be the child of any other valid node validDstNodes = list(removeNode(nodes.copy(), src)) for dst in random.sample(validDstNodes, len(validDstNodes)): parent = nodes[src].pop() dst.append(src) nodes[src].append(dst) # set new parent parent.remove(src) # remove from old parent sendXML(root) mutationsXML(nodes, root) dst.remove(src) parent.append(src) nodes[src].remove(dst) nodes[src].append(parent) if not crashBuffer.empty(): return
def mutateBytes(inputDict: dict): logger.info('Running: Mutate bytes...') inputBytes = parse.getInputFromDict(inputDict) cases = [(i, j) for i in range(len(inputBytes)) for j in range(len(bcases))] # takes ~.2 seconds to generate list for (500, 0x100) random.shuffle(cases) removes = [] for case in cases: # logger.debug(case) index = case[0] byte = case[1] if inputBytes[index] == b'\n' and inputDict['file'] in [FileType.PLAINTEXT, FileType.CSV]: # to not screw up number of lines required... continue # remove byte if index not in removes: payload = inputBytes[:index] + inputBytes[index+1:] sendBuffer.put(payload) removes.extend([index]) # replace byte if index < len(inputBytes)-1: # replace byte replacepayload = inputBytes[:index] + byte.to_bytes(1, 'little') + inputBytes[index+1:] # insert byte insertpayload = inputBytes[:index] + byte.to_bytes(1, 'little') + inputBytes[index:] else: replacepayload = inputBytes[:index] + byte.to_bytes(1, 'little') insertpayload = inputBytes + byte.to_bytes(1, 'little') sendBuffer.put(replacepayload) sendBuffer.put(insertpayload)
def invalidMultiplyInput(inputDict: dict, repeatTimes: int = 15): logger.info('Running: Syntax-less multiply...') rawInput = parse.getInputFromDict(inputDict) multiplier = 1 for _ in range(repeatTimes): multiplier *= 2 inputString = rawInput * multiplier sendBuffer.put(inputString)
def deepXML(inputDict: dict, maxMultiplier: int = 20): if (inputDict.get('file') != FileType.XML): return logger.info("Running: Xml depth mutation...") tree = ET.fromstring(parse.getInputFromDict(inputDict)) # finding a leaf node parent, child = [None, None] root = tree while (True): try: children = list(root.iter()) if (len(children) < 2): # should only be one parent = children[0] child = parent else: parent = children[0] child = children[1] if len(child) == 0: break root = child except Exception as e: logger.debug("DeepXML error: " + str(e)) return except: logger.debug("Unknown exception in deepXML") return # getting the raw xml tag # by adding to child once parent = child child = copy.deepcopy(child) parent.append(child) # manual parsing go brr treeString = ET.tostring(tree).decode() parentString = ET.tostring(parent).decode() childString = ET.tostring(child).decode() head, tail = treeString.split(parentString) startTag, endTag = parentString.split(childString) multiplier = 1 for _ in range(maxMultiplier): multiplier*=2 inputString = head + startTag*multiplier + childString + endTag*multiplier + tail sendBuffer.put(inputString.encode())
def multiplyJSON(inputDict: dict, repeatTimes: int=15): if inputDict.get('file') != FileType.JSON: return logger.info('Running: Multiply JSON...') rawJson = parse.getInputFromDict(inputDict) jsonObj = json.loads(rawJson) multiplier = 1 for _ in range(repeatTimes): multiplier *= 2 inputString = json.dumps([jsonObj] * multiplier) sendBuffer.put(inputString.encode())
def send(words: dict) -> str: inputString = parse.getInputFromDict(words) p = Popen(binary, stdin=PIPE, stdout=PIPE) output, error = p.communicate(inputString.encode()) logger.debug(output.decode()) if (error): logger.error(error) if p.returncode == -11: # segfault code return inputString return None
def multiplyXML(inputDict: dict, maxMultiplier: int = 15): if inputDict.get('file') != FileType.XML: return logger.info('Running: Multiply XML...') rawXml = ET.ElementTree(ET.fromstring(parse.getInputFromDict(inputDict))) multiplier = 1 root = rawXml.getroot() newRoot = copy.deepcopy(root) for _ in range(maxMultiplier): multiplier *= 2 newRoot.extend(list(root) * multiplier) inputString = ET.tostring(newRoot) sendBuffer.put(inputString)
def sendPayload(sendBuffer: Queue, crashBuffer: Queue): while True: words = sendBuffer.get() if words is None or not crashBuffer.empty(): break inputString = parse.getInputFromDict(words) p = Popen(binary, stdin=PIPE, stdout=PIPE) output, error = p.communicate(inputString.encode()) logger.debug(output.decode()) if (error): logger.error(error) if p.returncode == -11: crashBuffer.put(inputString)
def mutateValues(inputDict: dict, start=0): logger.info('Running: Mutate values...') if start > len(inputDict['values']): logger.error("value too large") return for fieldType in ['values', 'tags']: if fieldType not in inputDict: continue for i in range(start, len(inputDict[fieldType])): testcases = allcases tmp = inputDict[fieldType][i] for case in testcases: if not crashBuffer.empty(): return inputDict[fieldType][i] = case sendBuffer.put(parse.getInputFromDict(inputDict)) inputDict[fieldType][i] = tmp
def longJSONList(inputDict: dict, maxMultiplier: int = 20): if (inputDict.get('file') != FileType.JSON): return logger.info("Running: Long JSON list...") j = json.loads(parse.getInputFromDict(inputDict)) listKeys = [] for key in j: if isinstance(j[key], list): listKeys.append(key) if len(listKeys) == 0: j["AFDSFDSADSAFDSA"] = ["A"] listKeys.append("AFDSFDSADSAFDSA") for key in listKeys: inputObj = copy.deepcopy(j) for _ in range(2, maxMultiplier): if len(inputObj[key]) == 0: inputObj[key].append("B") inputObj[key].extend(inputObj[key]) sendBuffer.put(json.dumps(inputObj).encode())
def csvMutateCpl(inputDict: dict): values = inputDict['values'] for i in range(1, len(values)): if len(values) % i == 0: inputDict['cpl'] = i-1 sendBuffer.put(parse.getInputFromDict(inputDict))