Beispiel #1
0
 def request_pool(self):
     try:
         clients = {}
         end = False
         while not end:
             try:
                 client = self.client_queue.get(timeout=5)
                 if client == (0,0):
                     end = True
                 else:
                     if client[0] not in clients:
                         clients.update({client[0]: {"timestamp": time.time(), "testcases": []}})
                     else:
                         clients[client[0]]["timestamp"] = time.time()
                         if len(clients[client[0]]["testcases"]) <= 10:
                             clients[client[0]]["testcases"].append(client[1])
                         else:
                             clients[client[0]]["testcases"].pop(0)
                             clients[client[0]]["testcases"].append(client[1])
             except:
                 pass
             for c in clients.keys():
                 if time.time() - clients[c]["timestamp"] >= 30:
                     self.save_testcase(c, clients[c]["testcases"])
                     del clients[c]
     except Exception as e:
         raise PJFBaseException(e.message)
 def execute(self, obj):
     """
     Perform the actual external fuzzing, you may replace this method in order to increase performance
     """
     try:
         if self.config.stdin:
             self.spawn(self.config.command,
                        stdin_content=obj,
                        stdin=True,
                        timeout=1)
         else:
             if "@@" not in self.config.command:
                 raise PJFMissingArgument(
                     "Missing @@ filename indicator while using non-stdin fuzzing method"
                 )
             for x in self.config.command:
                 if "@@" in x:
                     self.config.command[self.config.command.index(
                         x)] = x.replace("@@", obj)
             self.spawn(self.config.command, timeout=2)
         self.logger.debug(
             "[{0}] - PJFExternalFuzzer successfully completed".format(
                 time.strftime("%H:%M:%S")))
         return self._out
     except KeyboardInterrupt:
         return ""
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #3
0
 def fuzz_elements(self, element):
     """
     Fuzz all elements inside the object
     """
     try:
         if type(element) == dict:
             for key in element:
                 if self.config.parameters:
                     if self.config.exclude_parameters:
                         fuzz = key not in self.config.parameters
                     else:
                         fuzz = key in self.config.parameters
                 else:
                     fuzz = True
                 if fuzz:
                     if type(element[key]) == dict:
                         element[key] = self.fuzz_elements(element[key])
                     elif type(element[key]) == list:
                         element[key] = self.fuzz_elements(element[key])
                     else:
                         element[key] = self.mutator.fuzz(element[key])
         elif type(element) == list:
             arr = []
             for key in element:
                 if type(key) == dict:
                     arr.append(self.fuzz_elements(key))
                 elif type(key) == list:
                     arr.append(self.fuzz_elements(key))
                 else:
                     arr.append(self.mutator.fuzz(key))
             element = arr
             del arr
     except Exception as e:
         raise PJFBaseException(e.message)
     return element
Beispiel #4
0
 def start_monitor(self, standalone=True):
     """
     Run command in a loop and check exit status plus restart process when needed
     """
     try:
         self.start()
         cmdline = shlex.split(self.config.process_to_monitor)
         if standalone:
             signal.signal(signal.SIGINT, self.shutdown)
         self.process = subprocess.Popen(cmdline,
                                         stdin=PIPE,
                                         stdout=PIPE,
                                         stderr=PIPE)
         while self.process and not self.finished:
             self.process.wait()
             if self._is_sigsegv(self.process.returncode):
                 if self.config.debug:
                     print "[\033[92mINFO\033[0m] Process crashed with \033[91mSIGSEGV\033[0m, waiting for testcase..."
                 while not self.got_testcase():
                     time.sleep(1)
                 self.save_testcase(
                     self.testcase[-10:])  # just take last 10 testcases
             if self.process:
                 self.process = subprocess.Popen(cmdline,
                                                 stdin=PIPE,
                                                 stdout=PIPE,
                                                 stderr=PIPE)
     except OSError:
         self.shutdown()
         self.process = False
         self.got_testcase = lambda: True
         raise PJFProcessExecutionError("Binary <%s> does not exist" %
                                        cmdline[0])
     except Exception as e:
         raise PJFBaseException("Unknown error please send log to author")
Beispiel #5
0
 def web_fuzzer(self):
     try:
         from tools import TOOLS_DIR
         if not self.config.auto:
             to_fuzz = {'lvl1': {"lvl2": [1, 1.0, "True"]}, "lvl1-1": [{"none": None, "inf": [{"a": {"a": "a"}}]}]}
         else:
             to_fuzz = self.config.generate_json(self.config.grammar_path)
         run = "{0} http://127.0.0.1:8080/fuzzer.html".format(self.config.browser_auto)
         config = PJFConfiguration(Namespace(json=to_fuzz,
                                             html=TOOLS_DIR,
                                             ports=self.config.ports,
                                             content_type="text/plain",
                                             debug=True,
                                             nologo=True,
                                             level=2,
                                             utf8=self.config.utf8,
                                             indent=self.config.indent,
                                             notify=True,
                                             fuzz_web=True,
                                             strong_fuzz=self.config.strong_fuzz,
                                             process_to_monitor=run,
                                             recheck_ports=False))
         server = PJFServer(config)
         server.run()
         print "[\033[92mINFO\033[0m] Available URLs"
         for url in self.get_urls():
             print "[\033[92m*\033[0m] {0}".format(url)
         try:
             while True:
                     time.sleep(1)
         except KeyboardInterrupt:
             server.stop()
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #6
0
 def browser_autopwn(self):
     try:
         from tools import TOOLS_DIR
         if not self.config.auto:
             to_fuzz = {'lvl1': {"lvl2": [1, 1.0, "True"]}, "lvl1-1": [{"none": None, "inf": [{"a": {"a": "a"}}]}]}
         else:
             to_fuzz = self.config.generate_json(self.config.grammar_path)
         run = "{0} http://127.0.0.1:8080/fuzzer.html".format(self.config.browser_auto)
         config = PJFConfiguration(Namespace(json=to_fuzz,
                                             html=TOOLS_DIR,
                                             ports=self.config.ports,
                                             content_type="text/plain",
                                             debug=True,
                                             nologo=True,
                                             level=2,
                                             utf8=self.config.utf8,
                                             indent=self.config.indent,
                                             notify=True,
                                             strong_fuzz=self.config.strong_fuzz,
                                             process_to_monitor=run,
                                             recheck_ports=False))
         monitor = PJFProcessMonitor(config)
         server = PJFServer(config)
         server.run()
         try:
             while True:
                     monitor.start_monitor(standalone=False)
         except KeyboardInterrupt:
             monitor.shutdown()
             server.stop()
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #7
0
 def spawn(self,
           cmd,
           stdin_content="",
           stdin=False,
           shell=False,
           timeout=2):
     """
     Spawn a new process using subprocess
     """
     try:
         if type(cmd) != list:
             raise PJFInvalidType(type(cmd), list)
         if type(stdin_content) != str:
             raise PJFInvalidType(type(stdin_content), str)
         if type(stdin) != bool:
             raise PJFInvalidType(type(stdin), bool)
         self._in = stdin_content
         try:
             self.process = subprocess.Popen(cmd,
                                             stdout=PIPE,
                                             stderr=PIPE,
                                             stdin=PIPE,
                                             shell=shell)
             self.finish_read(timeout, stdin_content, stdin)
             if self.process.poll() is not None:
                 self.close()
         except KeyboardInterrupt:
             return
     except OSError:
         raise PJFProcessExecutionError("Binary <%s> does not exist" %
                                        cmd[0])
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #8
0
 def fuzz_stdin(self):
     try:
         result = PJFExternalFuzzer(self.config).execute(json_eval.dumps(self.config.json))
         if result:
             sys.stdout.write(result)
         else:
             self.fuzz()
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #9
0
 def get_urls(self):
     try:
         for iface in netifaces.interfaces():
             net = netifaces.ifaddresses(iface)
             if netifaces.AF_INET in net:
                 yield "http://{0}:{1}/fuzzer.html".format(net[netifaces.AF_INET][0]['addr'],
                                                           self.config.ports["servers"]["HTTP_PORT"])
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #10
0
 def start_http_server(self):
     try:
         server = PJFServer(self.config)
         server.run()
         try:
             while True:
                 time.sleep(1)
         except KeyboardInterrupt:
             server.stop()
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #11
0
 def get_fuzzed(self, indent=False, utf8=False):
     """
     Return the fuzzed object
     """
     try:
         if "array" in self.json:
             return self.fuzz_elements(dict(self.json))["array"]
         else:
             return self.fuzz_elements(dict(self.json))
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #12
0
 def custom_html(self, filepath):
     """
     Serve custom HTML page
     """
     try:
         response.headers.append("Access-Control-Allow-Origin", "*")
         response.headers.append("Accept-Encoding", "identity")
         response.headers.append("Content-Type", "text/html")
         return static_file(filepath, root=self.config.html)
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #13
0
 def fuzz_command_line(self):
     try:
         with tempfile.NamedTemporaryFile(delete=False) as temp_file:
             temp_file.write(json_eval.dumps(self.config.json))
             temp_file.close()
             setattr(self, "temp_file_name", temp_file.name)
             if self.config.debug:
                 print "[\033[92mINFO\033[0m] Generated temp file \033[91m%s\033[0m" % self.config.temp_file_name
         result = PJFExternalFuzzer(self.config).execute(self.config.temp_file_name)
         with open(self.config.temp_file_name, "wb") as fuzzed:
             fuzzed.write(result)
             fuzzed.close()
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #14
0
 def fuzz_external(self, stdin_input=False):
     try:
         import shlex
         import os
         dir_name = "testcase_{0}".format(
             os.path.basename(shlex.split(self.config.command[0])[0]))
         try:
             f = [0]
             for (_, _, filenames) in os.walk(dir_name):
                 f.extend([
                     int(t.split("_")[1].split(".")[0]) for t in filenames
                 ])
                 break
             last = max(f) + 1
         except OSError:
             last = 0
         j = PJFFactory(self.config)
         j_fuzz = j.fuzzed
         if not stdin_input:
             with tempfile.NamedTemporaryFile(delete=False) as temp_file:
                 temp_file.write(j_fuzz)
                 temp_file.close()
                 setattr(self.config, "temp_file_name", temp_file.name)
             if self.config.debug:
                 print "[\033[92mINFO\033[0m] Generated temp file \033[91m%s\033[0m" % self.config.temp_file_name
             result = PJFExternalFuzzer(self.config).execute_sigsegv(
                 self.config.temp_file_name)
         else:
             setattr(self.config, "temp_file_name", False)
             result = PJFExternalFuzzer(self.config).execute_sigsegv(j_fuzz)
         if result:
             print "[\033[92mINFO\033[0m] Program crashed with \033[91mSIGSEGV\033[0m/\033[91mSIGABRT\033[0m"
             if self.config.debug:
                 print "[\033[92mINFO\033[0m] Saving testcase..."
             try:
                 os.mkdir(dir_name)
             except OSError:
                 pass
             with open("{0}/testcase_{1}.json".format(dir_name, last),
                       "wb") as t:
                 t.write(j_fuzz)
                 t.close()
         else:
             if self.config.temp_file_name:
                 os.unlink(self.config.temp_file_name)
             print "[\033[92mINFO\033[0m] Program exited normally"
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #15
0
 def save_testcase(self, ip, testcases):
     try:
         count = 0
         dir_name = "testcase_{0}".format(ip)
         print "[\033[92mINFO\033[0m] Client {0} seems to not respond anymore, saving testcases".format(ip)
         try:
             os.mkdir(dir_name)
         except OSError:
             pass
         for test in testcases:
             with open("{0}/testcase_{1}.json".format(dir_name, count), "wb") as t:
                 t.write(test)
                 t.close()
                 count += 1
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #16
0
 def serve(self):
     """
     Serve fuzzed JSON object
     """
     try:
         fuzzed = self.json.fuzzed
         if self.config.fuzz_web:
             self.client_queue.put((request.environ.get('REMOTE_ADDR'), fuzzed))
         response.headers.append("Access-Control-Allow-Origin", "*")
         response.headers.append("Accept-Encoding", "identity")
         response.headers.append("Content-Type", self.config.content_type)
         if self.config.notify:
             PJFTestcaseServer.send_testcase(fuzzed, '127.0.0.1', self.config.ports["servers"]["TCASE_PORT"])
         yield fuzzed
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #17
0
 def __contains__(self, items):
     """
     Check if JSON object contains a key
     """
     try:
         if type(items) != list:
             raise PJFInvalidType(items, list)
         ret = 0
         for item in items:
             for key in self.json:
                 if isinstance(self.json[key], PJFFactory):
                     ret += item in self.json[key]
                 elif item == key:
                     ret += 1
         return len(items) == ret
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #18
0
 def start_file_fuzz(self):
     try:
         with open(self.config.json_file, "rb") as json_file:
             if not self.config.strong_fuzz:
                 setattr(self, "json", literal_eval(json_file.read()))
                 json = PJFFactory(self.config)
             else:
                 try:
                     setattr(self, "json", literal_eval(json_file.read()))
                 except:
                     json_file.seek(0)
                     setattr(self, "json", json_file.read())
                 json = PJFFactory(self.config)
                 json_file.close()
         with open(self.config.json_file, "wb") as json_file:
             json_file.write(json.fuzzed)
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #19
0
 def handle(self, sock):
     """
     Handle the actual TCP connection
     """
     try:
         size = struct.unpack("<I", sock.recv(4))[0]
         data = ""
         while len(data) < size:
             data += sock.recv(size - len(data))
         if len(self.testcase) >= 100:
             del self.testcase
             self.testcase = list()
         self.testcase.append(data)
         sock.close()
     except socket.error as e:
         raise PJFSocketError(e.message)
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #20
0
 def shutdown(self, *args):
     """
     Shutdown the running process and the monitor
     """
     try:
         self._shutdown()
         if self.process:
             self.process.wait()
             self.process.stdout.close()
             self.process.stdin.close()
             self.process.stderr.close()
         self.finished = True
         self.send_testcase('', '127.0.0.1',
                            self.config.ports["servers"]["TCASE_PORT"])
         self.logger.debug(
             "[{0}] - PJFProcessMonitor successfully completed".format(
                 time.strftime("%H:%M:%S")))
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #21
0
 def send_testcase(json, ip, port):
     """
     Send a raw testcase
     """
     try:
         json = struct.pack("<I", len(json)) + json
         try:
             s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             s.connect((ip, int(port)))
             s.send(json)
             s.shutdown(socket.SHUT_RDWR)
             s.close()
             return True
         except socket.error:
             return False
     except socket.error as e:
         raise PJFSocketError(e.message)
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #22
0
 def fuzzed(self):
     """
     Get a printable fuzzed object
     """
     try:
         if self.config.strong_fuzz:
             fuzzer = PJFMutators(self.config)
             if self.config.url_encode:
                 return urllib.quote(fuzzer.fuzz(json.dumps(self.config.json)))
             else:
                 if type(self.config.json) in [list, dict]:
                     return fuzzer.fuzz(json.dumps(self.config.json))
                 else:
                     return fuzzer.fuzz(self.config.json)
         else:
             if self.config.url_encode:
                 return urllib.quote(self.get_fuzzed(self.config.indent, self.config.utf8))
             else:
                 return self.get_fuzzed(self.config.indent, self.config.utf8)
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #23
0
 def save_testcase(self, testcase):
     """
     Save all testcases collected during monitoring
     """
     try:
         if self.config.debug:
             print "[\033[92mINFO\033[0m] Saving testcase..."
         dir_name = "testcase_{0}".format(
             os.path.basename(
                 shlex.split(self.config.process_to_monitor)[0]))
         try:
             os.mkdir(dir_name)
         except OSError:
             pass
         for test in testcase:
             with open(
                     "{0}/testcase_{1}.json".format(dir_name,
                                                    self.testcase_count),
                     "wb") as t:
                 t.write(test)
                 t.close()
             self.testcase_count += 1
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #24
0
 def start_process_monitor(self):
     try:
         PJFProcessMonitor(self.config).start_monitor()
     except Exception as e:
         raise PJFBaseException(e.message)
Beispiel #25
0
 def fuzz(self):
     try:
         json = PJFFactory(self.config)
         sys.stdout.write("{0}\n".format(json.fuzzed))
     except Exception as e:
         raise PJFBaseException(e.message)