def pull(self, remote, local): cmd = " ".join(["pull", remote, local]) data = self.adb(cmd) if "pulled." not in data: log.warning("%s pull %s Failed." % (self.serial, remote)) else: log.success("%s pull %s succeed." % (self.serial, remote))
def _compile(code, werror, flags, libs): digest = md5sumhex(code + str(werror) + str(flags) + str(libs)) if digest in __cache: return __cache[digest] sopath = os.path.join(__tempdir, digest + '.so') try: if os.path.exists(sopath): return CDDL(sopath) except: pass cpath = os.path.join(__tempdir, digest + '.c') with open(cpath, 'w') as f: f.write(code) flags += [ '-fPIC', '-shared', '-O3', '-march=native', '-mtune=native', '-Wall' ] if werror: flags.append('-Werror') cmd = ['gcc'] + flags + ['-o', sopath, cpath] + libs p = Popen(cmd, stderr=PIPE) _, s = p.communicate() s = s.replace(cpath + ':', '').replace(cpath, '') if p.returncode <> 0: log.error('GCC error (%s):' % cpath) log.trace(s) sys.exit(p.returncode) elif s <> '': log.warning('GCC warning (%s):' % cpath) log.trace(s) return CDLL(sopath)
def RunJohn(self, filenName, algoType): isSuccess = False progress = log.progress("Cracking hash from file: " + highlightRed(filenName)) process = subprocess.run((self.johnPath, filenName, algoType, "--wordlist=" + self.wordlistPath), check=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) if ('krb5asrep' in algoType): regexHashUser = r"(.*[^\s-])\s+\(\$krb5\w+\$23\$(\w+-?\w+)@.+\.\w+\)" elif ('krb5tgs' in algoType): regexHashUser = r"(.*[^\s-])\s+\(\?\)" else: log.warning('Fail to detect hash !') return isSuccess output = process.stdout.decode() for output in output.splitlines(): x = re.search(regexHashUser, output) if (x is not None): if ('krb5asrep' in algoType): print("", end='\t') log.success("Cread Found: '" + highlightGreen(x.group(2)) + ":" + highlightGreen(x.group(1)) + "'") isSuccess = True elif ('krb5tgs' in algoType): print("", end='\t') log.success("Cread Found: '" + highlightGreen(x.group(1)) + "'") isSuccess = True else: log.warning('Fail get hash !') progress.success(status='Done') return isSuccess
def encrypt(plain_text: bytes, key: bytes, skip_first_round: bool = False) -> bytes: # Check key parameter length key_length = len(key) if (key_length != KEY_LENGTH): log.warning( "Key does not have the correct length: {} != {}".format( KEY_LENGTH, key_length)) exit() else: log.success("Key have the correct length: {} == {}".format( KEY_LENGTH, key_length)) # Check plain text parameter length plain_length = len(plain_text) if (plain_length % CHUNK_LENGTH != 0): log.warning( "Text to encrypt does not have the correct length: {} % {} != 0" .format(plain_length, CHUNK_LENGTH)) exit() else: log.success( "Text to encrypt has the correct length: {} % {} == 0".format( plain_length, CHUNK_LENGTH)) log.info("Text to encrypt is: {}".format( Converter.bytes_to_hex(plain_text))) # Get keys used for encryption keys = BC4Worker._generate_keys(key, plain_length // CHUNK_LENGTH, skip_first_round) # Split text in chunks and encrypt encrypted_text: bytes = bytes() for i in range(0, plain_length, CHUNK_LENGTH): # Get parts that will be XORed plain_part = plain_text[i:i + CHUNK_LENGTH] key_part = keys[i:i + CHUNK_LENGTH] # Encrypt with XOR ciphertext_part = Converter.bytes_to_int( plain_part) ^ Converter.bytes_to_int(key_part) encrypted_text += Converter.int_to_bytes(ciphertext_part) # Log if VERBOSE: log.info("The #{} encryption is {} (meaning {} ^ {})".format( i // CHUNK_LENGTH, Converter.int_to_hex(ciphertext_part), Converter.bytes_to_hex(plain_part), Converter.bytes_to_hex(key_part))) # Log if VERBOSE: log.info("Ciphertext is: {}".format( Converter.bytes_to_hex(encrypted_text))) # Encode encrypted text and return return encrypted_text
def UserOldPassword(self): printTitle("[-] Users with old password") passwordMinAge = 100 timeFilter = "(pwdLastSet<=%s)" % self.__datetime_to_mstimestamp( datetime.datetime.now() - datetime.timedelta(days=passwordMinAge)) OBJECT_TO_SEARCH = '(&(objectCategory=user)' + timeFilter + ')' ATTRIBUTES_TO_SEARCH = ['pwdLastSet', 'sAMAccountName'] result = self.__SearchServerLdap(OBJECT_TO_SEARCH, ATTRIBUTES_TO_SEARCH) for info in result: timestamp = int(info[1]['pwdLastSet'][0].decode()) username = info[1]['sAMAccountName'][0].decode() if (timestamp != 0): value = datetime.datetime(1601, 1, 1) + datetime.timedelta( seconds=timestamp / 10000000) now = datetime.datetime.now() lastChange = now - value if (lastChange.days > 100): log.warning("Username: "******"Password last change: " + highlightRed(str((now - value).days)) + " days ago " + value.strftime('%Y-%m-%d %H:%M:%S'))
def one(cls, word, code, timing, size, color, words, lines, word_present): """ Display an entry in the table :param word: The word found :param code: The HTTP status code from the response :param timing: The time of the request execution :param size: Byte size of the response :param color: The HTTP status code to apply :param words: The words count in the response content :param lines: The lines count in the response content :param word_present: Is the word present in the response content """ timing += "ms" out = ("|{}|{}{}{}|{}|{}|{}|{}|{}|".format( ' ' + word[:33] + ((33 - len(word)) * " "), ' ' + fg(color), code[:8] + ((8 - len(code)) * " "), attr('reset'), ' ' + timing[:23] + ((23 - len(timing)) * " "), ' ' + size[:15] + ((15 - len(size)) * " "), ' ' + words[:15] + ((15 - len(words)) * " "), ' ' + lines[:15] + ((15 - len(lines)) * " "), ' ' + word_present[:19] + ((19 - len(word_present)) * " "), )) log.warning(out)
def _compile(code, werror, flags, libs): digest = md5sumhex(code + str(werror) + str(flags) + str(libs)) if digest in __cache: return __cache[digest] sopath = os.path.join(__tempdir, digest + '.so') try: if os.path.exists(sopath): return CDDL(sopath) except: pass cpath = os.path.join(__tempdir, digest + '.c') with open(cpath, 'w') as f: f.write(code) flags += ['-fPIC', '-shared', '-O3', '-march=native', '-mtune=native', '-Wall'] if werror: flags.append('-Werror') cmd = ['gcc'] + flags + ['-o', sopath, cpath] + libs p = Popen(cmd, stderr = PIPE) _, s = p.communicate() s = s.replace(cpath + ':', '').replace(cpath, '') if p.returncode <> 0: log.error('GCC error (%s):' % cpath) log.trace(s) sys.exit(p.returncode) elif s <> '': log.warning('GCC warning (%s):' % cpath) log.trace(s) return CDLL(sopath)
def sync_device_to_host(self, device_dir, host_dir): cmd = "adb-sync -s %s --reverse %s %s" % (self.serial, device_dir, host_dir) result = exeute_cmd(cmd) if "Total: " not in result: log.warning("%s sync %s Failed." % (self.serial, device_dir)) else: log.success("%s sync %s succeed." % (self.serial, device_dir))
def ResovelIpAddress(ServerName): try: data = socket.gethostbyname_ex(ServerName) ipAddres = data[2][0] except Exception: log.warning("Fail to resolve ServerName: " + ServerName) return None return ipAddres
def kill_process(self, location, process_name): if location == "host": self.kill_host_process(process_name) elif location == "device": self.kill_device_process(process_name) else: log.warning("The location should be either host or device.") return None
def prompt_for_match(matches): log.warning('SELECT LIBC VERSION') for i, m in enumerate(matches): log.info('%d: %s' % (i+1, m)) sel = int(input('> ')) print('') return matches[sel-1]
def get_process_list(self, location, process_name): if location == "host": pids = self.get_host_process_list(process_name) elif location == "device": pids = self.get_device_process_list(process_name) else: log.warning("The location should be either host or device.") return None log.debug("pids: %s" % str(pids)) return pids
def on_message(message, data): if message['type'] == 'send': info = json.loads(str(message['payload']).encode('string-escape'), strict=False) filename = PATH + info["name"] + ".dat" with open(filename, "a+") as f: json.dump(info, f) f.write("\n") log.info("stored call to " + info["name"]) else: log.warning("Could not parse: " + str(message))
def connect(self): if self.connected(): log.warning('Already connected to %s on port %d' % self.target) return log.waitfor('Opening connection to %s on port %d' % self.target) self.sock = socket.socket(self.family, self.type, self.proto) self.sock.settimeout(self.timeout) self.sock.connect(self.target) self.lhost = self.sock.getsockname()[0] self.lport = self.sock.getsockname()[1] log.succeeded()
def push(self, local, remote): cmd = " ".join(["push", local, remote]) data = self.adb(cmd) if "pushed." in data: log.success("%s push %s succeed." % (self.serial, remote)) else: log.warning("%s push %s Failed." % (self.serial, local)) log.info(" retry push..") while self.get_device_state() != "device": sleep(10) self.reset() self.push(local, remote)
def tricky_sha_inputs(): # Hand-crafted to succeed on the first try: block = "0000000000000000014a6c756a385603e2b1eccafbdf974e11ee851072d54303" while True: req = requests.get(f"https://blockchain.info/rawblock/{block}?format=hex") header = bytes.fromhex(req.text[: 80 * 2]) base = sha256(header).digest() if sha256(base).digest().endswith(b"\0\0\0\0\0\0\0\0"): yield block, base else: log.warning("Block not sufficient") block = header[4:][:32][::-1].hex()
def generate_payload_aligned(rop): payload1 = OFFSET + rop if (len(payload1) % 16) == 0: return payload1 else: payload2 = OFFSET + p64(RET) + rop if (len(payload2) % 16) == 0: log.info("Payload aligned successfully") return payload2 else: log.warning(f"I couldn't align the payload! Len: {len(payload1)}") return payload1
def connect(self): if self.connected(): log.warning('Already connected to %s on port %d' % self.target) return if not self.silent: log.waitfor('Opening connection to %s on port %d' % self.target) self.sock = socket.socket(self.family, self.type, self.proto) self.sock.settimeout(self.timeout) self.sock.connect(self.target) self.lhost = self.sock.getsockname()[0] self.lport = self.sock.getsockname()[1] if not self.silent: log.succeeded()
def __init__(self, serial, cfg: dict): self.serial = serial self.cfg = cfg self.host_fuzzer_path = cfg["host_fuzzer_path"] self.fuzzer_name = os.path.basename(self.host_fuzzer_path) self.host_model_dir = cfg["host_model_dir"] self.host_seed_dir = cfg["host_seed_dir"] self.device_work_dir = cfg["device_work_dir"] self.device_fuzzer_path = os.path.join(self.device_work_dir, self.fuzzer_name) self.max_instance_number = cfg["max_instance_number"] # count how many fuzzers ever run, as some may be died. self.accumulated_fuzzer_num = 0 # how many logcat, as logcat may be died? self.accumulated_logcat_num = 0 # how many dmesg, as dmesg may be died. self.accumulated_dmesg_num = 0 self.dmesg_pid = -1 # device dir self.host_log_dir = os.path.join(self.cfg["current_log_dir"], self.serial) if os.path.exists(self.host_log_dir): if os.path.isdir(self.host_log_dir): pass else: log.warning("The log %s dir must not be an existing file!" % self.host_log_dir) exit(0) else: os.makedirs(self.host_log_dir) self.flash_count = 0 self.flash_cfg = json.load(open("flash.cfg")) self.flasher = Flasher(self.serial, self.flash_cfg) # restart device script on device self.device_restart_device_script_path = os.path.join( self.device_work_dir, os.path.basename(self.cfg["restart_device_script_path"])) self.max_tombstone_count = self.cfg["max_tombstone_count"] self.device_manager_log_path = os.path.join(self.host_log_dir, "device_manager.log")
def pause(n=None): """Waits for either user input or a specific number of seconds.""" try: if n is None: log.info('Paused (press enter to continue)') raw_input('') else: log.waitfor('Continueing in') for i in range(n, 0, -1): log.status('%d... ' % i) pwn.sleep(1) log.succeeded('Now') except KeyboardInterrupt: log.warning('Interrupted') sys.exit(1)
def pause(n = None): """Waits for either user input or a specific number of seconds.""" try: if n is None: log.info('Paused (press enter to continue)') raw_input('') else: log.waitfor('Continueing in') for i in range(n, 0, -1): log.status('%d... ' % i) pwn.sleep(1) log.succeeded('Now') except KeyboardInterrupt: log.warning('Interrupted') sys.exit(1)
def _on_message(self, message, data): """Process the method call messages""" if message['type'] == 'send': #info = json.loads(str(message['payload']).encode('string-escape'), strict=False) info = message['payload'] if self.print_calls: pretty_print(info, log.info) if self.write_results: filename = os.path.join(self.path, info["name"] + ".dat") with open(filename, "a+") as f: json.dump(info, f) f.write("\n") else: log.warning(str(message).encode('string-escape'))
def start(self, cmd, args, env): if self.connected(): log.warning('Program "%s" already started' % cmd) return log.waitfor('Starting program "%s"' % cmd) self.proc = Popen( tuple(cmd.split()) + args, stdin=PIPE, stdout=PIPE, stderr=PIPE, env = env, bufsize = 0) fd = self.proc.stdout.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) self.stdout = fd log.succeeded()
def find_libc(*args): find_argv = [os.path.join(LIBCDB_DIR, 'find')] + list(args) proc = subprocess.Popen(find_argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE) matches = proc.stdout.readlines() if not matches: log.warning('No matches found for "%s" in libc db!' % ' '.join(args)) exit(1) if len(matches) > 1: selection = prompt_for_match(matches) else: selection = matches[0] lib_id = extract_id(selection) return lib_id
def run_new_remote_gdbserver(host, port): gdbserver_pid = None log.info("Attempting to connect to remote debugging gdbserver") try: remote_telnet = remote(host, PORTS["DEBUG_TELNET_PORT"]) except KeyboardInterrupt: raise SystemExit(log.warning("SIGINT received, exiting gracefully...")) else: remote_telnet.sendline("pidof gdbserver.i686"), time.sleep(1) # Have to sleep because of polling delay recv_data = remote_telnet.recv_raw(2048).decode('ascii', errors="ignore") for line in recv_data.split("\n"): newline = line.strip("\n") if newline.isdigit(): gdbserver_pid = newline break if gdbserver_pid: log.info("killing stale gdbserver...") remote_telnet.sendline("kill -9 {}".format(gdbserver_pid)), time.sleep(1) log.info("starting new remote gdbserver and attaching...") remote_telnet.sendline("/flash/bin/gdbserver.i686 {}:{} --attach $(pidof www) &".format(host, port)), time.sleep(1) return True
def libc_resolve(dict_sym_addr, choice=0): if len(dict_sym_addr) <= 1: log.warning_once( "[libc-resolver]: No reliable result is guaranteed without at least two symbols" ) result = libcdb_wrapper.find(dict_sym_addr) log.info("Found:\n%s" % result) regex_lib_names = r"\((.*)\)" libs = re.findall(regex_lib_names, result, re.MULTILINE) if len(libs) > 1: log.warning( "[libc-resolver]: %d libraries are compatible, default choice is %d" % (len(libs), choice + 1)) libc = ELF(config.db_path + libs[choice] + ".so") libc.address = list(dict_sym_addr.values())[0] - libc.symbols[list( dict_sym_addr.keys())[0]] return (libc)
async def handle_request_exceptions(self, request): """ Handle the given requests errors ! :param request: The request to handle """ data = None try: data = await request.process() except aiohttp.InvalidURL as e: log.warning("Invalid URL, exiting ..") await self.stop() except aiohttp.ClientConnectionError as e: self.status(0, request._word, "Request failed !") color = Printer.get_code_color("ERROR") Printer.one("'" + request._word + "'", "ERROR", "0", "0", color, "0", "0", "N/A") return data
def loop(self): """ Launch the main fuzzy loop """ self.loop = asyncio.get_event_loop() # self.loop.set_debug(True) self.loop.set_exception_handler(exception_handler) try: self.loop.run_until_complete(self.process()) except KeyboardInterrupt as e: Printer.end() log.warning("Interrupted !") if self._verbose: print_exceptions() exit() Printer.end() log.warning("Ending !") if self._verbose: print_exceptions()
def get_offsets(symbol, addr, libc_id=None, run_oneg=False): if not libc_id: libc_id = find_libc(symbol, hex(addr)) offsets = dump_libc(libc_id, symbol) offsets.update(dump_libc(libc_id)) libc_base = addr - offsets[symbol] addrs = {'base': libc_base} for symbol in offsets.keys(): addrs[symbol] = libc_base + offsets[symbol] if run_oneg: log.warning('Fetching one_gadget results...') print_oneg_results(libc_id) return addrs
def start(self, cmd, args, env): if self.connected(): log.warning('Program "%s" already started' % cmd) return if not self.silent: log.waitfor('Starting program "%s"' % cmd) self.proc = Popen( tuple(cmd.split()) + args, stdin=PIPE, stdout=PIPE, stderr=PIPE, env = env, bufsize = 0) fd = self.proc.stdout.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) self.stdout = fd if not self.silent: log.succeeded()
def wipe_userdata_and_cache(self): log.info("start wiping userdata and cache.") cmd = [ "/usr/bin/adb -s %s reboot bootloader" % self.serial, "sleep 5", "/usr/bin/fastboot -s %s boot %s" % (self.serial, self.cfg["twrp_img_path"]), "sleep 25", "/usr/bin/adb -s %s shell recovery --wipe_data" % self.serial, ] cmd = "\n".join(cmd) result = exeute_cmd(cmd) log.info(result) if "I:AB_OTA_UPDATER := true" in result: log.success("wiping userdata and cache succeed.") else: log.warning("wiping userdata and cache failed.") # wait until boot completed sleep(30)
def leak(self, close=True, trim=True): """ :param close: :param trim: :return: """ current_round = 0 total_leak_counter = 0 leak_adjust_switch = False while True: log.info("Round: {}".format(current_round)) round_hits = 0 for _ in range(self.leak_attempts): leaked = self.leak_pointer(close=close, trim=trim) if leaked is not None: for pointer in leaked: log.info("-> 0x{}".format(pointer)) self.leakedlist.append(pointer) round_hits += 1 if round_hits == 0: log.warning("unable to leak valid pointers during round, " "trying again after {} seconds".format( self.leak_wait_time)) time.sleep(self.leak_wait_time) if leak_adjust_switch: leak_adjust_switch = False self.leak_attempts -= 10 else: leak_adjust_switch = True self.leak_attempts += 10 else: total_leak_counter += round_hits if current_round != self.leak_rounds: current_round += 1 else: break log.success("leaked {} possible pointers!".format(total_leak_counter)) return self.leakedlist
def __SearchServerLdap(self, OBJECT_TO_SEARCH, ATTRIBUTES_TO_SEARCH): resultSearch = [] try: result = self.ldapCon.search_s(self.baseDn, ldap.SCOPE_SUBTREE, OBJECT_TO_SEARCH, ATTRIBUTES_TO_SEARCH) for info in result: if (info[0] != None): resultSearch.append([info[0], info[1]]) if (len(resultSearch) == 0): log.warning("No entry found !") except ldap.OPERATIONS_ERROR as error: log.failure("OPERATIONS_ERROR: " + str(error)) exit(0) except ldap.LDAPError as error: log.failure("LDAPError: " + str(error)) exit(0) return resultSearch
def analyze_leaks(self, leakedlist=None): """ :param leakedlist: :return: """ sortedlist = list() if isinstance(leakedlist, list): if len(leakedlist) > 1: self.leakedlist = leakedlist elif len(self.leakedlist) < 2: log.warning("not enough pointers to analyse from leaked list") return False log.info("analyzing pointers from leaked list...") for pointer in self.leakedlist: sortedlist.append(int("0x{}".format(pointer), 16)) log.info("sorting pointers: ") sortedlist = sorted(sortedlist) for pointer in sortedlist: log.info("-> {}".format(hex(pointer))) duplicates = Counter(sortedlist) log.info("attempting to locate duplicates...") counter = 0 for key, value in duplicates.items(): if value > 1: log.info("found duplicate pointer: {}".format(hex(key))) counter += 1 if counter == 0: log.warning("could not locate any duplicates") return True
import os, tempfile from pwn import decoutils as _decoutils from pwn import log, md5sumhex from cPickle import load, dump __tempdir = os.path.join(tempfile.gettempdir(), 'pwn-memoize') if not os.path.exists(__tempdir): try: os.mkdir(__tempdir) except: log.warning('Could not create memoization dir: %s\n' % __tempdir) __tempdir = None elif not os.path.isdir(__tempdir): log.warning('Memoization path is not a dir: %s\n' % __tempdir) __tempdir = None def memoize(*args, **kwargs): '''Function memoization decorator. Args: use_mem (default True): Cache results in memory. use_file (default True): Cache results in files under /tmp/pwn-memoize. Used with no arguments is the same as setting mem = True and file = True.''' if len(args) == 1 and kwargs == {}: return _internal_memoize()(args[0]) else: return _internal_memoize(*args, **kwargs) _TYPE_VALUE = 0 _TYPE_EXCEPTION = 1