From 41329391ab9fd0643681d9e7561c52cdc3b8703e Mon Sep 17 00:00:00 2001 From: Brian Pow Date: Thu, 10 Sep 2020 23:20:39 +0800 Subject: [PATCH 1/4] remove 1000 images limit --- fat.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/fat.py b/fat.py index 0a98cb3..569dfcc 100755 --- a/fat.py +++ b/fat.py @@ -29,11 +29,15 @@ def show_banner(): """) -def get_next_unused_iid(): - for i in range(1, 1000): +def get_next_unused_iid(i=1): + while True: if not os.path.isdir(os.path.join(firmadyne_path, "scratch", str(i))): - return str(i) - return "" + if not os.path.isfile(os.path.join(firmadyne_path, "images", str(i) + ".tar.gz")): + break + else: + print("[!] Skipped ID %d since image files found but no scratch folder exists." % i) + i += 1 + return str(i) def run_extractor(firm_name): @@ -57,13 +61,8 @@ def run_extractor(firm_name): if os.path.isfile(image_tgz): iid = get_next_unused_iid() - if iid == "" or os.path.isfile(os.path.join(os.path.dirname(image_tgz), iid + ".tar.gz")): - print ("[!] Too many stale images") - print ("[!] Please run reset.py or manually delete the contents of the scratch/ and images/ directory") - return "" - os.rename(image_tgz, os.path.join(os.path.dirname(image_tgz), iid + ".tar.gz")) - print ("[+] Image ID:", iid) + print ("[+] Allocated image ID:", iid) return iid return "" From e298c457e87afadf18b857d34aec8762924658ec Mon Sep 17 00:00:00 2001 From: Brian Pow Date: Fri, 11 Sep 2020 21:44:43 +0800 Subject: [PATCH 2/4] fix typo in message --- fat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fat.py b/fat.py index 569dfcc..a8efb52 100755 --- a/fat.py +++ b/fat.py @@ -35,7 +35,7 @@ def get_next_unused_iid(i=1): if not os.path.isfile(os.path.join(firmadyne_path, "images", str(i) + ".tar.gz")): break else: - print("[!] Skipped ID %d since image files found but no scratch folder exists." % i) + print("[!] Skipped ID %d since image file found but no scratch folder exists." % i) i += 1 return str(i) From 975bfef728176156480050b59884528bdac88e98 Mon Sep 17 00:00:00 2001 From: Brian Pow Date: Fri, 11 Sep 2020 21:49:25 +0800 Subject: [PATCH 3/4] reuse image ID if the same firmware has been extracted before, improve error handling when extracting --- fat.py | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/fat.py b/fat.py index a8efb52..4a809e9 100755 --- a/fat.py +++ b/fat.py @@ -40,7 +40,7 @@ def get_next_unused_iid(i=1): return str(i) -def run_extractor(firm_name): +def run_extractor(firm_name, brand, sql): print ("[+] Firmware:", os.path.basename(firm_name)) print ("[+] Extracting the firmware...") @@ -51,11 +51,29 @@ def run_extractor(firm_name): firm_name, os.path.join(firmadyne_path, "images") ] - + if brand: + extractor_args = ["-b", brand] + extractor_args + if sql: + extractor_args = ["-sql", sql] + extractor_args + child = pexpect.spawn(extractor_cmd, extractor_args, timeout=None) - child.expect_exact("Tag: ") - tag = child.readline().strip().decode("utf8") - child.expect_exact(pexpect.EOF) + responses = child.read().strip().decode("utf8").split("\n") + if responses[0].startswith(">> Database Image ID:"): + iid = responses[0].split(":")[1].strip() + print ("[+] Found image ID:", iid) + return iid + if len(responses) == 2 and responses[1].strip()=='>> Skipping: completed!': + print ("[!] Some leftover files found at %s, please clean up first." % os.path.join(firmadyne_path,"images")) + return "" + + tag = None + for response in responses: + if response.startswith('>> Tag:'): + tag = response.split(":")[1].strip() + break + + if not tag: + return "" image_tgz = os.path.join(firmadyne_path, "images", tag + ".tar.gz") @@ -143,6 +161,8 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument("firm_path", help="The path to the firmware image", type=str) parser.add_argument("-q", "--qemu", metavar="qemu_path", help="The qemu version to use (must exist within qemu-builds directory). If not specified, the qemu version installed system-wide will be used", type=str) + parser.add_argument("-s","--sql", dest="sql", action="store", default=None, help="Hostname of SQL server") + parser.add_argument("-b","--brand", dest="brand", action="store", default=None, help="Brand of the firmware image") args = parser.parse_args() qemu_ver = args.qemu @@ -154,7 +174,7 @@ def main(): print ("[+] Using system qemu") qemu_dir = None - image_id = run_extractor(args.firm_path) + image_id = run_extractor(args.firm_path, args.brand, args.sql) if image_id == "": print ("[!] Image extraction failed") From 6b8e3a2c8d7091a4d46fd4783d010b227ee14f32 Mon Sep 17 00:00:00 2001 From: Brian Pow Date: Wed, 14 Oct 2020 22:38:58 +0800 Subject: [PATCH 4/4] allow manually assign image id --- fat.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/fat.py b/fat.py index 4a809e9..d577205 100755 --- a/fat.py +++ b/fat.py @@ -40,7 +40,7 @@ def get_next_unused_iid(i=1): return str(i) -def run_extractor(firm_name, brand, sql): +def run_extractor(firm_name, brand, sql, iid): print ("[+] Firmware:", os.path.basename(firm_name)) print ("[+] Extracting the firmware...") @@ -68,21 +68,24 @@ def run_extractor(firm_name, brand, sql): tag = None for response in responses: + print(response) if response.startswith('>> Tag:'): tag = response.split(":")[1].strip() break - + if not tag: return "" image_tgz = os.path.join(firmadyne_path, "images", tag + ".tar.gz") if os.path.isfile(image_tgz): - iid = get_next_unused_iid() - os.rename(image_tgz, os.path.join(os.path.dirname(image_tgz), iid + ".tar.gz")) - print ("[+] Allocated image ID:", iid) + if not iid: + iid = get_next_unused_iid() + os.rename(image_tgz, os.path.join(os.path.dirname(image_tgz), iid + ".tar.gz")) + print ("[+] Allocated image ID:", iid) + else: + print ("[+] Image ID:", iid) return iid - return "" @@ -163,6 +166,7 @@ def main(): parser.add_argument("-q", "--qemu", metavar="qemu_path", help="The qemu version to use (must exist within qemu-builds directory). If not specified, the qemu version installed system-wide will be used", type=str) parser.add_argument("-s","--sql", dest="sql", action="store", default=None, help="Hostname of SQL server") parser.add_argument("-b","--brand", dest="brand", action="store", default=None, help="Brand of the firmware image") + parser.add_argument("-i","--image-id", dest="iid", action="store", default=None, help="Manually assign Image ID") args = parser.parse_args() qemu_ver = args.qemu @@ -174,7 +178,7 @@ def main(): print ("[+] Using system qemu") qemu_dir = None - image_id = run_extractor(args.firm_path, args.brand, args.sql) + image_id = run_extractor(args.firm_path, args.brand, args.sql, args.iid) if image_id == "": print ("[!] Image extraction failed")