Homework 05: Initial Import
This commit is contained in:
parent
6cfb927838
commit
0ea62d069c
3 changed files with 217 additions and 0 deletions
27
homework05/Makefile
Normal file
27
homework05/Makefile
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
test:
|
||||||
|
@$(MAKE) -sk test-all
|
||||||
|
|
||||||
|
test-all: test-searx test-hulk
|
||||||
|
|
||||||
|
test-data:
|
||||||
|
@curl -sLO https://www3.nd.edu/~pbui/teaching/cse.20289.sp25/static/txt/homework05/hulk.hashes
|
||||||
|
@echo "*.hashes" > .gitignore
|
||||||
|
@echo "*.test" >> .gitignore
|
||||||
|
|
||||||
|
test-scripts: test-data
|
||||||
|
@curl -sLO https://www3.nd.edu/~pbui/teaching/cse.20289.sp25/static/txt/homework05/searx.test
|
||||||
|
@curl -sLO https://www3.nd.edu/~pbui/teaching/cse.20289.sp25/static/txt/homework05/hulk.test
|
||||||
|
@chmod +x ./*.test
|
||||||
|
|
||||||
|
test-searx: test-scripts searx.py
|
||||||
|
@echo Testing SearX ...
|
||||||
|
@./searx.test -v
|
||||||
|
@echo
|
||||||
|
|
||||||
|
test-hulk: test-scripts hulk.py
|
||||||
|
@echo Testing Hulk ...
|
||||||
|
@./hulk.test -v
|
||||||
|
@echo
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f *.test *.hashes
|
||||||
126
homework05/hulk.py
Normal file
126
homework05/hulk.py
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from typing import Iterable, Iterator
|
||||||
|
|
||||||
|
import concurrent.futures
|
||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
|
||||||
|
ALPHABET = string.ascii_lowercase + string.digits
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
|
||||||
|
def usage(exit_code: int=0):
|
||||||
|
print('''Usage: hulk.py [-a ALPHABET -c CORES -l LENGTH -p PATH -s HASHES]
|
||||||
|
-a ALPHABET Alphabet to use in permutations
|
||||||
|
-c CORES CPU Cores to use
|
||||||
|
-l LENGTH Length of permutations
|
||||||
|
-p PREFIX Prefix for all permutations
|
||||||
|
-s HASHES Path of hashes file''', file=sys.stderr)
|
||||||
|
sys.exit(exit_code)
|
||||||
|
|
||||||
|
def sha1sum(s: str) -> str:
|
||||||
|
''' Compute SHA1 digest for given string.
|
||||||
|
|
||||||
|
>>> sha1sum('a')
|
||||||
|
'86f7e437faa5a7fce15d1ddcb9eaeaea377667b8'
|
||||||
|
'''
|
||||||
|
# TODO: Use the hashlib library to produce the SHA1 hex digest of the given
|
||||||
|
# string.
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def permutations(length: int, alphabet: str=ALPHABET) -> Iterator[str]:
|
||||||
|
''' Recursively yield all permutations of alphabet up to given length.
|
||||||
|
|
||||||
|
>>> for p in permutations(2, 'ab'): print(p)
|
||||||
|
aa
|
||||||
|
ab
|
||||||
|
ba
|
||||||
|
bb
|
||||||
|
'''
|
||||||
|
# TODO: Use yield to create a generator function that recursively produces
|
||||||
|
# all the permutations of the given alphabet up to the provided length.
|
||||||
|
yield ''
|
||||||
|
|
||||||
|
def flatten(sequence: Iterable[Iterable[str]]) -> Iterator[str]:
|
||||||
|
''' Flatten sequence of iterables.
|
||||||
|
|
||||||
|
>>> for p in flatten([['a', 'b'], ['c', 'd']]): print(p)
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
'''
|
||||||
|
# TODO: Iterate through sequence and yield from each iterator in sequence.
|
||||||
|
yield ''
|
||||||
|
|
||||||
|
def crack(hashes: set[str], length: int, alphabet: str=ALPHABET, prefix: str='') -> list[str]:
|
||||||
|
''' Return all password permutations of specified length that are in hashes
|
||||||
|
by trying all possible permutations sequentially.
|
||||||
|
|
||||||
|
>>> for p in crack({sha1sum(l) for l in 'abc'}, 1, 'abcd'): print(p)
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
'''
|
||||||
|
# TODO: Return list comprehension that iterates over a sequence of
|
||||||
|
# candidate permutations and checks if the sha1sum of each candidate is in
|
||||||
|
# hashes.
|
||||||
|
return []
|
||||||
|
|
||||||
|
def whack(arguments: tuple[set[str], int, str, str]) -> list[str]:
|
||||||
|
''' Call the crack function with the specified list of arguments
|
||||||
|
|
||||||
|
>>> for p in whack([{sha1sum(l) for l in 'abc'}, 1, 'abcd', '']): print(p)
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
'''
|
||||||
|
return []
|
||||||
|
|
||||||
|
def smash(hashes: set[str], length: int, alphabet: str=ALPHABET, prefix: str='', cores: int=1) -> Iterator[str]:
|
||||||
|
''' Return all password permutations of specified length that are in hashes
|
||||||
|
by cracking subsets of all possible permutations concurrently.
|
||||||
|
|
||||||
|
>>> for p in smash({sha1sum(l) for l in 'abc'}, 1, 'abcd'): print(p)
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
'''
|
||||||
|
# TODO: Create generator expression with arguments to pass to whack and
|
||||||
|
# then use ProcessPoolExecutor to apply whack to all items in expression.
|
||||||
|
yield ''
|
||||||
|
|
||||||
|
# Main Execution
|
||||||
|
|
||||||
|
def main(arguments: list[str]=sys.argv[1:]) -> None:
|
||||||
|
''' Smashes given hashes to determine passwords with specified alphabet,
|
||||||
|
length, and prefix. Uses multiple cores (ie. processes) if specified.
|
||||||
|
|
||||||
|
>>> main('-a abcdefg -l 2'.split())
|
||||||
|
cg
|
||||||
|
fg
|
||||||
|
gg
|
||||||
|
'''
|
||||||
|
alphabet = ALPHABET
|
||||||
|
cores = 1
|
||||||
|
hashes_path = 'hulk.hashes'
|
||||||
|
length = 1
|
||||||
|
prefix = ''
|
||||||
|
|
||||||
|
# TODO: Parse command line arguments
|
||||||
|
|
||||||
|
# TODO: Load hashes set
|
||||||
|
|
||||||
|
# TODO: Execute smash function
|
||||||
|
|
||||||
|
# TODO: Print all found passwords
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
|
# vim: set sts=4 sw=4 ts=8 expandtab ft=python:
|
||||||
64
homework05/searx.py
Normal file
64
homework05/searx.py
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
''' searx.py - SearX from the command line '''
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
|
||||||
|
URL = 'https://searx.ndlug.org/search'
|
||||||
|
LIMIT = 5
|
||||||
|
ORDERBY = 'score'
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
|
||||||
|
def usage(exit_status: int=0) -> None:
|
||||||
|
''' Print usage message and exit. '''
|
||||||
|
print(f'''Usage: searx.py [-u URL -n LIMIT -o ORDERBY] QUERY
|
||||||
|
|
||||||
|
Fetch SearX results for QUERY and print them out.
|
||||||
|
|
||||||
|
-u URL Use URL as the SearX instance (default is: {URL})
|
||||||
|
-n LIMIT Only display up to LIMIT results (default is: {LIMIT})
|
||||||
|
-o ORDERBY Sort the search results by ORDERBY (default is: {ORDERBY})
|
||||||
|
|
||||||
|
If ORDERBY is score, the results are shown in descending order. Otherwise,
|
||||||
|
results are shown in ascending order.''', file=sys.stderr)
|
||||||
|
sys.exit(exit_status)
|
||||||
|
|
||||||
|
def searx_query(query: str, url: str=URL) -> list[dict]:
|
||||||
|
''' Returns lists of results for query from SearX.
|
||||||
|
|
||||||
|
>>> searx_query('Python', 'https://yld.me/iB1T') # doctest: +ELLIPSIS
|
||||||
|
[{'url': 'https://www.python.org/', 'title': 'Welcome to Python.org', ...}]
|
||||||
|
'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
def print_results(results: list[dict], limit: int=LIMIT, orderby: str=ORDERBY) -> None:
|
||||||
|
''' Print results of SearX query.
|
||||||
|
|
||||||
|
>>> print_results(searx_query('Python', 'https://yld.me/iB1T')) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
|
||||||
|
1. Welcome to Python.org [...]
|
||||||
|
https://www.python.org/
|
||||||
|
...
|
||||||
|
'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Main Execution
|
||||||
|
|
||||||
|
def main(arguments=sys.argv[1:]) -> None:
|
||||||
|
''' Searches SearX and print results.
|
||||||
|
|
||||||
|
>>> main('-u https://yld.me/iB1T Python'.split()) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
|
||||||
|
1. Welcome to Python.org [...]
|
||||||
|
https://www.python.org/
|
||||||
|
...
|
||||||
|
'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
|
# vim: set sts=4 sw=4 ts=8 expandtab ft=python:
|
||||||
Loading…
Reference in a new issue