Skip to content

Commit

Permalink
Merge branch 'master' into masscan_connector
Browse files Browse the repository at this point in the history
  • Loading branch information
svkirillov committed Apr 4, 2020
2 parents 21982a1 + ae1f2b1 commit 1d21e23
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 67 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<p align="center"><i>The basic CLI interface of the Grinder Framework</i></p>
</div>

## Contents
## Table of Contents
1. [Description](#description)
1. [Grinder Workflow](#grinder-workflow)
1. [Grinder Map](#grinder-map)
Expand Down Expand Up @@ -89,6 +89,7 @@ For example, the hosts will be automatically checked for availability with ping
### Basic
- :heavy_exclamation_mark: [Python 3.6+](https://www.python.org/downloads/)
- :heavy_exclamation_mark: [python3-tk](https://docs.python.org/3/library/tkinter.html) library
- :heavy_exclamation_mark: [FreeType](https://www.freetype.org/) library (Python 3.8+ and MacOS required)
### Accounts
- :heavy_exclamation_mark: [Shodan](https://account.shodan.io/register) and [Censys](https://censys.io/register) accounts
Required to collect hosts, both free and full accounts are suitable. Also, it's possible to use only one account (Censys or Shodan, Shodan is preferable).
Expand Down
22 changes: 19 additions & 3 deletions grinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,28 @@

import sys

from multiprocessing import freeze_support

from grinder.asciiart import AsciiOpener
from grinder.core import GrinderCore
from grinder.interface import GrinderInterface


class GrinderProcessWrap:
"""
Fix Processes "RuntimeError" related
to bootstrapping phase (MacOS case)
"""

@staticmethod
def import_core():
freeze_support()
from grinder.core import GrinderCore as _core

return _core


if __name__ == "__main__":
GrinderCore = GrinderProcessWrap.import_core()
AsciiOpener.print_opener()
interface = GrinderInterface()
interface.check_python_version()
Expand Down Expand Up @@ -34,8 +51,7 @@

search_results = (
core.batch_search(
queries_filename=args.queries_file,
not_incremental=args.not_incremental
queries_filename=args.queries_file, not_incremental=args.not_incremental
)
if args.run
else core.load_results(queries_filename=args.queries_file)
Expand Down
2 changes: 1 addition & 1 deletion grinder/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1355,7 +1355,7 @@ def vulners_scan(

# Check for top-ports if defined
arguments = (
f"-Pn -sV --script=.{vulners_path} --host-timeout {str(host_timeout)}s"
f"-Pn -sV --open --script=.{vulners_path} --host-timeout {str(host_timeout)}s"
)
if top_ports:
arguments = f"{arguments} --top-ports {str(top_ports)}"
Expand Down
2 changes: 1 addition & 1 deletion grinder/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import sys
from functools import wraps
from os import path, makedirs, system
from os import system
from time import time, strftime, gmtime


Expand Down
4 changes: 2 additions & 2 deletions grinder/defaultvalues.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class DefaultNmapScanValues:
TOP_PORTS = None
SUDO = False
HOST_TIMEOUT = 30
ARGUMENTS = "-Pn -T4 -A"
ARGUMENTS = "-Pn -T4 -A --open"
WORKERS = 10


Expand All @@ -143,7 +143,7 @@ class DefaultProcessManagerValues:

PORTS = None
SUDO = False
ARGUMENTS = "-Pn -A"
ARGUMENTS = "-Pn -A --open"
WORKERS = 10


Expand Down
71 changes: 42 additions & 29 deletions grinder/nmapprocessmanager.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#!/usr/bin/env python3

from multiprocessing import Process, JoinableQueue, Manager
from datetime import datetime
from multiprocessing import Process, JoinableQueue, Manager, freeze_support
from os import system
from time import sleep
from datetime import datetime

from grinder.decorators import exception_handler
from grinder.defaultvalues import DefaultProcessManagerValues
from grinder.errors import (
NmapProcessingRunError,
NmapProcessingManagerOrganizeProcessesError,
)
from grinder.nmapconnector import NmapConnector
from grinder.defaultvalues import DefaultProcessManagerValues


class NmapProcessingDefaultManagerValues:
Expand All @@ -23,15 +23,6 @@ class NmapProcessingDefaultManagerValues:
EMPTY_QUEUE_POLLING_RATE = 1.0


class NmapProcessingResults:
"""
This is results collector to gain
results directly from a process
"""

RESULTS = Manager().dict({})


class NmapProcessing(Process):
"""
Create custom Nmap process. The reason to create
Expand All @@ -49,13 +40,15 @@ def __init__(
ports: str,
sudo: bool,
hosts_quantity: int,
results_pool: dict,
):
Process.__init__(self)
self.queue = queue
self.arguments = arguments
self.ports = ports
self.sudo = sudo
self.quantity = hosts_quantity
self.results_pool = results_pool

@exception_handler(expected_exception=NmapProcessingRunError)
def run(self) -> None:
Expand All @@ -74,9 +67,15 @@ def run(self) -> None:
sleep(NmapProcessingDefaultManagerValues.EMPTY_QUEUE_POLLING_RATE)
continue
try:
index, host = self.queue.get()
# Poll with POLLING_RATE interval
sleep(NmapProcessingDefaultManagerValues.POLLING_RATE)

# Get host info from queue
index, host = self.queue.get()
if (index, host) == (None, None):
self.queue.task_done()
return

host_ip = host.get("ip", "")
host_port = host.get("port", "")
port_postfix = "Default"
Expand All @@ -103,13 +102,12 @@ def run(self) -> None:

results = nm.get_results()
if results.get(host_ip).values():
NmapProcessingResults.RESULTS.update(
{host_ip: results.get(host_ip)}
)
self.results_pool.update({host_ip: results.get(host_ip)})
except:
self.queue.task_done()
else:
self.queue.task_done()
pass
self.queue.task_done()
if self.queue.empty():
return


class NmapProcessingManager:
Expand All @@ -127,6 +125,9 @@ def __init__(
arguments=DefaultProcessManagerValues.ARGUMENTS,
workers=DefaultProcessManagerValues.WORKERS,
):
freeze_support()
self.manager = Manager()
self.results_pool = self.manager.dict({})
self.hosts = hosts
self.workers = workers
self.arguments = arguments
Expand All @@ -140,18 +141,32 @@ def organize_processes(self) -> None:
:return: None
"""
queue = JoinableQueue()
for index, host in enumerate(self.hosts):
queue.put((index, host))
processes = []
for _ in range(self.workers):
freeze_support()
process = NmapProcessing(
queue, self.arguments, self.ports, self.sudo, len(self.hosts)
queue,
self.arguments,
self.ports,
self.sudo,
len(self.hosts),
self.results_pool,
)
process.daemon = True
processes.append(process)
for process in processes:
process.start()
try:
process.start()
except OSError:
pass
for index, host in enumerate(self.hosts):
queue.put((index, host))
for _ in range(self.workers):
queue.put((None, None))
queue.join()
for process in processes:
if process.is_alive():
process.terminate()

def start(self) -> None:
"""
Expand All @@ -160,21 +175,19 @@ def start(self) -> None:
"""
self.organize_processes()

@staticmethod
def get_results() -> dict:
def get_results(self) -> dict:
"""
Return dictionary with Nmap results
:return: Nmap results
"""
return NmapProcessingResults.RESULTS
return self.results_pool

@staticmethod
def get_results_count() -> int:
def get_results_count(self) -> int:
"""
Return quantity of Nmap results
:return: quantity of results
"""
return len(NmapProcessingResults.RESULTS)
return len(self.results_pool)

def __del__(self):
"""
Expand Down
Loading

0 comments on commit 1d21e23

Please sign in to comment.