diff options
author | Evgeny Zinoviev <me@ch1p.io> | 2021-06-06 01:37:50 +0300 |
---|---|---|
committer | Evgeny Zinoviev <me@ch1p.io> | 2021-06-06 01:37:50 +0300 |
commit | 7c1494cd502e1a99f96f27b12ddf23a84de188b5 (patch) | |
tree | 0a236d75fa14ed9176d8013a0b4c00d8ea64cb86 | |
parent | fe07ea26f41be1eda6f8cccc591a5165dd3fb135 (diff) |
refactor code, add manual-scan script
-rw-r--r-- | lib/results.py | 52 | ||||
-rw-r--r-- | lib/scanner.py (renamed from scanner.py) | 0 | ||||
-rw-r--r-- | lib/util.py | 4 | ||||
-rw-r--r-- | lib/worker.py | 38 | ||||
-rwxr-xr-x | manual-scan | 27 | ||||
-rwxr-xr-x | suddenly-opened-ports-checker (renamed from suddenly-opened-ports-checker.py) | 92 |
6 files changed, 124 insertions, 89 deletions
diff --git a/lib/results.py b/lib/results.py new file mode 100644 index 0000000..1565c4b --- /dev/null +++ b/lib/results.py @@ -0,0 +1,52 @@ +from threading import Lock +from lib.util import Colored +from lib.scanner import PortState +from ch1p import telegram_notify + + +class Results: + def __init__(self): + self.warnings = [] + self.mutex = Lock() + + def add(self, worker): + host = worker.get_host() + with self.mutex: + if not worker.done: + print(f'{Colored.RED}{worker.name}: scanning failed{Colored.END}') + return + + if worker.name != host: + print(f'{worker.name} ({host}):') + else: + print(f'{host}:') + + opened = [] + results = worker.get_results() + for port, state in results: + if state != PortState.OPEN: + continue + + opened.append(port) + if not worker.is_expected(port): + self.warnings.append(f'<b>{worker.name}</b> ({host}): port {port} is open') + print(f' {Colored.RED}{port} opened{Colored.END}') + else: + print(f' {Colored.GREEN}{port} opened{Colored.END}') + + if worker.opened: + for port in worker.opened: + if port not in opened: + self.warnings.append( + f'<b>{worker.name}</b> ({host}): port {port} is NOT open') + print(f' {Colored.RED}{port} not opened{Colored.END}') + print() + + def has_warnings(self): + return len(self.warnings) > 0 + + def notify(self, chat_id=None, token=None): + text = '<b>❗️Attention!</b>\n\n' + text += '\n'.join(self.warnings) + + telegram_notify(text, parse_mode='html', chat_id=chat_id, token=token) diff --git a/scanner.py b/lib/scanner.py index f78e4f6..f78e4f6 100644 --- a/scanner.py +++ b/lib/scanner.py diff --git a/lib/util.py b/lib/util.py new file mode 100644 index 0000000..c6087a7 --- /dev/null +++ b/lib/util.py @@ -0,0 +1,4 @@ +class Colored: + GREEN = '\033[92m' + RED = '\033[91m' + END = '\033[0m'
\ No newline at end of file diff --git a/lib/worker.py b/lib/worker.py new file mode 100644 index 0000000..f8d6c55 --- /dev/null +++ b/lib/worker.py @@ -0,0 +1,38 @@ +import logging + +from threading import Thread +from lib.scanner import TCPScanner + +logger = logging.getLogger(__name__) + + +class Worker(Thread): + def __init__(self, name, host, opened=None, concurrency=None, timeout=None): + Thread.__init__(self) + + assert concurrency is not None + + self.done = False + self.name = name + self.concurrency = concurrency + self.opened = opened + + scanner_kw = {} + if timeout is not None: + scanner_kw['timeout'] = timeout + self.scanner = TCPScanner(host, range(0, 65535), **scanner_kw) + + def run(self): + logger.info(f'starting {self.name} ({self.concurrency} threads)') + self.scanner.scan(num_threads=self.concurrency) + self.done = not self.scanner.failed + logger.info(f'finished {self.name}') + + def get_results(self): + return self.scanner.results + + def is_expected(self, port): + return (self.opened is not None) and (port in self.opened) + + def get_host(self): + return self.scanner.host diff --git a/manual-scan b/manual-scan new file mode 100755 index 0000000..3318ae1 --- /dev/null +++ b/manual-scan @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +import logging + +from argparse import ArgumentParser +from lib.worker import Worker +from lib.results import Results + + +if __name__ == '__main__': + parser = ArgumentParser() + parser.add_argument('--host', type=str, required=True) + parser.add_argument('--threads', type=int, default=200) + parser.add_argument('--timeout', type=int, default=5) + parser.add_argument('--verbose', action='store_true') + args = parser.parse_args() + + logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + level=(logging.DEBUG if args.verbose else logging.INFO)) + + results = Results() + worker = Worker(args.host, args.host, [], + concurrency=args.threads, + timeout=args.timeout) + worker.start() + worker.join() + + results.add(worker)
\ No newline at end of file diff --git a/suddenly-opened-ports-checker.py b/suddenly-opened-ports-checker index f45f0ff..4cf423c 100755 --- a/suddenly-opened-ports-checker.py +++ b/suddenly-opened-ports-checker @@ -5,98 +5,12 @@ import math from pprint import pprint from argparse import ArgumentParser -from ch1p import telegram_notify -from threading import Thread, Lock -from html import escape -from scanner import TCPScanner, PortState +from lib.worker import Worker +from lib.results import Results -mutex = Lock() logger = logging.getLogger(__name__) -class Colored: - GREEN = '\033[92m' - RED = '\033[91m' - END = '\033[0m' - - -class Results: - def __init__(self): - self.warnings = [] - self.mutex = Lock() - - def add(self, worker): - host = worker.get_host() - with self.mutex: - if not worker.done: - print(f'{Colored.RED}{worker.name}: scanning failed{Colored.END}') - return - - print(f'{worker.name} ({host}):') - - opened = [] - results = worker.get_results() - for port, state in results: - if state != PortState.OPEN: - continue - - opened.append(port) - if not worker.is_expected(port): - self.warnings.append(f'<b>{worker.name}</b> ({host}): port {port} is open') - print(f' {Colored.RED}{port} opened{Colored.END}') - else: - print(f' {Colored.GREEN}{port} opened{Colored.END}') - - if worker.opened: - for port in worker.opened: - if port not in opened: - self.warnings.append( - f'<b>{worker.name}</b> ({host}): port {port} is NOT open') - print(f' {Colored.RED}{port} not opened{Colored.END}') - print() - - def has_warnings(self): - return len(self.warnings) > 0 - - def notify(self, chat_id=None, token=None): - text = '<b>❗️Attention!</b>\n\n' - text += '\n'.join(self.warnings) - - telegram_notify(text, parse_mode='html', chat_id=chat_id, token=token) - - -class Worker(Thread): - def __init__(self, name, host, opened=None, concurrency=None, timeout=None): - Thread.__init__(self) - - assert concurrency is not None - - self.done = False - self.name = name - self.concurrency = concurrency - self.opened = opened - - scanner_kw = {} - if timeout is not None: - scanner_kw['timeout'] = timeout - self.scanner = TCPScanner(host, range(0, 65535), **scanner_kw) - - def run(self): - logger.info(f'starting {self.name} ({self.concurrency} threads)') - self.scanner.scan(num_threads=self.concurrency) - self.done = not self.scanner.failed - logger.info(f'finished {self.name}') - - def get_results(self): - return self.scanner.results - - def is_expected(self, port): - return (self.opened is not None) and (port in self.opened) - - def get_host(self): - return self.scanner.host - - def main(): parser = ArgumentParser() parser.add_argument('--config', type=str, required=True, @@ -113,7 +27,7 @@ def main(): help='just print results, don\'t send to telegram') args = parser.parse_args() - # setup loggign + # setup logging logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=(logging.DEBUG if args.verbose else logging.INFO)) |