Created
December 7, 2017 17:47
-
-
Save khanzf/51d122b1e5af7d253ddcaac091ccd478 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
''' | |
Recursively downloads Debian/Ubuntu/Kali packages and all associated dependencies | |
By: Farhan Khan ([email protected]) ([email protected]) | |
You MUST run this on the same distribution AND version of the target system. | |
This only downloads the latest version of the package available within the | |
target distribution. | |
Download a single package: | |
Example run: ./apt-recursive -p package_name | |
Download from a list | |
Example run: ./apt-recursive -l packages.lst | |
''' | |
import subprocess | |
import argparse | |
import sys | |
import os | |
# Initial global variables | |
localfiles = os.listdir() # Stores local files in current directory | |
dash_count = 0 # Used to print '-' characters | |
def download_recursive(debname, dash_count): | |
print("\033[44mTop Level: %s\033[0m" % debname) | |
raw_output = subprocess.getoutput('apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends %s | grep -v "^ "' % debname) | |
if 'No packages found' in raw_output: | |
print('\033[41mSkipping: %s, package does not exist\033[0m' % debname) | |
return | |
packages = [package.strip(":").strip("<").strip(">") for package in raw_output.split('\n')] | |
for package in packages: | |
if package == '': # Not sure why some package names are empty, not printing otherwise | |
continue | |
file_check = subprocess.getoutput("apt-cache show %s | grep Filename | awk '{print $2}' | rev | cut -d'/' -f1 | rev" % package) | |
if file_check == '': # If the return is empty, ignore | |
continue | |
if file_check in localfiles: | |
print("Skipping package: %s, already downloaded in %s" % (package, file_check)) | |
continue | |
print("Downloading %s" % package) | |
subprocess.getoutput("apt-get download %s" % package) | |
localfiles.append(file_check) | |
def argument_parse(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--package', '-p', type=str, help="Specify individual package") | |
parser.add_argument('--list', '-l', type=str, help="Specify list of packages") | |
args = parser.parse_args() | |
if args.package and args.list: | |
print("Cannot specify both -p and -l") | |
sys.exit() | |
if not args.package and not args.list: | |
print("Must specify -p or -l") | |
sys.exit() | |
return args | |
def main(): | |
args = argument_parse() | |
if args.package: | |
download_recursive(args.package, 0) | |
elif args.list: | |
try: | |
f = open(args.list) | |
for package_line in f.readlines(): | |
package_line = package_line.strip('\n') | |
download_recursive(package_line, 0) | |
except: | |
print("Unable to open '%s', check permissions or if it exists." % args.list) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment