2021-01-26 21:36:26 +00:00
|
|
|
from itertools import product
|
2021-01-27 11:42:01 +00:00
|
|
|
import signal
|
|
|
|
from subprocess import DEVNULL, PIPE, Popen, TimeoutExpired
|
2021-01-26 21:36:26 +00:00
|
|
|
|
2021-01-27 10:44:08 +00:00
|
|
|
chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ '
|
|
|
|
|
2021-01-27 11:42:01 +00:00
|
|
|
# Prevent zombie processes
|
|
|
|
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
|
|
|
|
|
2021-01-26 21:36:26 +00:00
|
|
|
|
|
|
|
def check_pair(script, instr, outstr):
|
2021-01-27 11:42:01 +00:00
|
|
|
process = Popen(
|
|
|
|
["/usr/bin/env", "bash", "-c", "--", script],
|
|
|
|
stdin=PIPE,
|
|
|
|
stdout=PIPE,
|
|
|
|
stderr=DEVNULL,
|
|
|
|
)
|
|
|
|
|
2021-01-27 11:04:14 +00:00
|
|
|
try:
|
2021-01-27 11:42:01 +00:00
|
|
|
stdout, stderr = process.communicate(instr.encode(), timeout=5)
|
|
|
|
return process.returncode == 0 and stdout == outstr.encode()
|
|
|
|
except TimeoutExpired:
|
|
|
|
try:
|
|
|
|
process.kill()
|
|
|
|
stdout, stderr = process.communicate()
|
|
|
|
except ProcessLookupError:
|
|
|
|
pass
|
|
|
|
|
2021-01-27 11:04:14 +00:00
|
|
|
return False
|
2021-01-26 21:36:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
def check_pairs(script, pairs):
|
|
|
|
for pair in pairs:
|
|
|
|
if not check_pair(script, *pair):
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
def find_script(pairs, max_length):
|
|
|
|
candidates = []
|
2021-01-27 10:44:08 +00:00
|
|
|
chars_count = len(chars)
|
|
|
|
total_options = int((chars_count ** (max_length + 1) - 1) / (chars_count - 1))
|
2021-01-26 21:36:26 +00:00
|
|
|
current_option = 0
|
|
|
|
|
|
|
|
for length in range(max_length + 1):
|
2021-01-27 10:44:08 +00:00
|
|
|
for letters in product(chars, repeat=length):
|
|
|
|
current_option += 1
|
|
|
|
|
2021-01-26 21:36:26 +00:00
|
|
|
if current_option % 1000 == 0:
|
|
|
|
print(f"Progress: {current_option}/{total_options}")
|
|
|
|
|
|
|
|
script = "".join(letters)
|
|
|
|
|
|
|
|
if check_pairs(script, pairs):
|
|
|
|
print("> Found candidate:", script)
|
|
|
|
candidates.append(script)
|
|
|
|
|
|
|
|
print("Candidates:", candidates)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
# Identity
|
|
|
|
print("\nSearching for identity")
|
|
|
|
find_script((
|
|
|
|
("1", "1"),
|
2021-01-27 11:41:45 +00:00
|
|
|
("42", "42"),
|
|
|
|
("1984", "1984"),
|
2021-01-27 10:44:44 +00:00
|
|
|
), max_length=3)
|
2021-01-26 21:36:26 +00:00
|
|
|
|
|
|
|
# Successor
|
2021-01-27 11:04:14 +00:00
|
|
|
# print("\nSearching for successor")
|
|
|
|
# find_script((
|
|
|
|
# ("1", "2"),
|
|
|
|
# ("2", "3"),
|
|
|
|
# ("3", "4"),
|
|
|
|
# ), max_length=5)
|