Core

Agent

client.py client side responsible for the managing clients and scan execution flow.

class dscan.client.Agent(config)[source]

Bases: object

Agent client implementation.

do_auth()[source]

Initiate the authentication.

Returns

True if the status code of the last operation is dscan.models.structures.Status.SUCCESS False otherwise.

Return type

bool

do_ready()[source]

This is recursive method and is responsible for, notifying the server is ready to execute a new scan, launch the scan and save the report. Until the server returns no target to scan.

is_connected()[source]

Check if the agent is still connected and not yet finished.

Returns

True if the client has disconnected or the terminate event has been triggered, else False.

Return type

bool

send_status(status)[source]
Parameters

status – int of a valid dscan.models.structures.Status

shutdown()[source]

Set the terminate event On, to shutdown the agent.

start()[source]

Start the client connects to the server and authenticates.

Returns

True if was able to connect and authentication was successful else False.

Return type

bool

Server

server.py server side responsible for the managing clients and scan execution flow.

class dscan.server.AgentHandler(*args, terminate_event, context, **kwargs)[source]

Bases: socketserver.BaseRequestHandler

HEADER = '<B'

Created when an agent connects, holds all the agents available actions. Terminates when scan targets finishes or an agent disconnects.

property agent

string representation of a connection ip:port.

Returns

str format of agent name ip:port

dispatcher()[source]

Command dispatcher all logic to decode and dispatch the call.

do_auth()[source]

Handles the agent’s authentication.

do_ready()[source]

After the authentication the agent notifies the server, that is ready to start scanning. This will handle the request and send a target to be scanned.

do_report()[source]

When the scan the ends, the agent notifies the server that is ready to send the report. This method will handle the report transfer save the report in the reports directory and make the target as finished if the file hashes match.

handle()[source]

First method to be called by BaseRequestHandler. responsible for initial call to authentication do_auth, and dispatcher, the connection is kept alive as long as agent is connected and their are targets to be delivered.

property is_connected

Check if the client is still connected, the terminate event has not been set and all stages are finished or not.

Returns

True if the client has disconnected or the terminate event has been triggered, else False

Return type

bool

send_status(code)[source]

Sends a status code to the server.

Parameters

code (dscan.models.structures.Status) –

class dscan.server.DScanServer(*args, options, **kwargs)[source]

Bases: socketserver.ThreadingMixIn, socketserver.TCPServer

Foundation of the Server. Implements the shutdown with threading.Event, and ssl configurations. and injects threading.Event to the RequestHandlerClass

allow_reuse_address = True
daemon_threads = True
finish_request(request, client_address)socketserver.BaseRequestHandler[source]

Finish one request by instantiating RequestHandlerClass.

Returns

RequestHandlerClass

Return type

´RequestHandlerClass´

get_request()tuple[source]

Used to add ssl support.

Returns

returns a ssl.wrap_socket

Return type

´ssl.wrap_socket´

property secret_key
Returns

str secret key generated in the config based on the certificate

shutdown()[source]

An override to allow a local terminate event to be set!

Output

out.py Display the information and status.

class dscan.out.ContextDisplay(context)[source]

Bases: dscan.out.Display

Context is displayed as a table.

ACTIVE_STAGES_HEADERS = ['Stage', 'Nº Targets', 'Nº Finished', 'Completion %']
STAGES_HEADERS = ['Nº Stages', 'Nº Pending Tasks', 'Completion %']
TASK_HEADERS = ['Agent', 'Stage', 'Task Status', 'Target Ip']
show()[source]

Takes the context’s status, active stages status, and task status and prints them in a tabular format.

class dscan.out.Display[source]

Bases: object

Visualisation of the current execution status.

CLEAR_CURRENT_LINE = '\x1b[1K\x1b[0G'
CLEAR_SCREEN = '\x1b[H\x1b[2J\x1b[3J'
TITLE = 'Distributed Scan Status'
disable_echo()[source]
inline(message)[source]
Parameters

message – string message to print underneath the table printer.

print_table(headers, data, clear=False)[source]

Created based on active code recepie.

Parameters
  • headerslist of str table headers.

  • data – a list of tuple with the data to be showed.

  • clearbool clear the previous print.

print_title(title)[source]
Parameters

title – Title of the tabular output.

show()[source]

meant to be overwritten

Models Parsers

parsers.py parsers models, input ip address list collapse, or scanner results to parse.

class dscan.models.parsers.ReportsParser(reports_path, pattern)[source]

Bases: object

XML Nmap results parser.

hosts_up()[source]
Returns

list of hosts up.

Return type

list

class dscan.models.parsers.TargetOptimization(fpath, cidr='/24')[source]

Bases: object

This class takes lists of hosts or networks, and attempts to optimize

them by either split big cidr like /8 /16 in /24 or in rage format 192.168.10.1-4.

save(targets)[source]

Takes a list of targets to optimize and saves it in the workspace path.

Parameters

targetslist of targets (str and top optimize.

Type

targets: list of str

dscan.models.parsers.parse_args()[source]

Used by main to parse the user arguments.

Returns

argparse instance.

Return type

argparse.ArgumentParser

Models Scanner

scanner.py scanner runtime models

class dscan.models.scanner.Config(config, options)[source]

Bases: object

Runtime configurations

BASE = ('base', 'reports')
SSL_CERTS = ('certs', 'sslcert', 'sslkey', 'ciphers', 'cert-hostname')
get_work_path(path)[source]
class dscan.models.scanner.Context(options)[source]

Bases: object

Context is a thread safe proxy like class, responsible for all the execution flow and inherent logic. Acts as a proxy between the active stages and the stage implementation.

active_stages_status()[source]
Returns

list of tuples with active stages status.

Return type

list of tuples

completed(agent)[source]

Marks a agent task as complete.

Parameters

agent (str) – ip:port of agent

classmethod create(options)[source]
Parameters

options (´ServerConfig´) – instance of ServerConfig

Returns

instance of Context

Return type

´Context`

ctx_status()[source]
downloading(agent)[source]

Marks a agent task as Downloading, notifying that the report download has started.

Parameters

agent (str) – ip:port of agent

get_report(agent, file_name)[source]
Parameters
  • agent (str) – str with ipaddress and port in ip:port format

  • file_name (str) – name of the file sent by the agent.

Returns

file descriptor to save the scan report.

interrupted(agent)[source]

Marks a task as interrupted, when agent disconnects for example.

Parameters

agent (str) – ip:port of agent

property is_finished
Returns

bool iterates the active stages and collects all the finished properties, returns True if all of them are true.

pop(agent)[source]

Gets the next Task from the current Active Stage, if their are no pending Tasks to be executed. Pending tasks are tasks that are canceled or restored from a previous interrupted session. If a stage is finished (no more targets), the next stage will take another stage from the list until its finished.

Parameters

agent – str with ipaddress and port in ip:port format, this allows the server to manage multiple agents in one host. to run multiple clients at once.

Returns

A target to scan! task

Return type

tuple

running(agent)[source]

After the server sends a target the agent notifies the task has started.

Parameters

agent (str) – ip:port of agent

tasks_status()[source]
Returns

list of tuple of active task’s status.

Return type

list of `tuple`s

class dscan.models.scanner.DiscoveryStage(targets_path, options, outdir, ltargets_path)[source]

Bases: dscan.models.scanner.Stage

process_results()[source]

When this stage is finished the Context will call this method to create a list of live targets.

class dscan.models.scanner.File(path)[source]

Bases: object

Creates a stateful file object allows file to restore its previous state.

exists()[source]
Returns a Boolean if the path is a valid file.

proxy call to os.path.isfile.

Returns

True if path is a valid file.

isempty()[source]

Check if the file is emtpy.

Returns

True if the file is empty

open(mode='r')[source]
readable()[source]
Returns

True if file is readable.

readline()[source]
class dscan.models.scanner.STATUS(value)[source]

Bases: enum.Enum

Each Scan task has the following states: - Scheduled: the default state set when its created. - Running: Set after the agent has confirmed the task has started executing. - Interrupted: Set when the task is aborted by agent, or the server has been halted. - Downloading: Set when the agent notifies its ready to sent the report. - Completed: Set only after the report has been received successfully

COMPLETED = 5
DOWNLOADING = 4
INTERRUPTED = 3
RUNNING = 2
SCHEDULED = 1
class dscan.models.scanner.ScanProcess(output)[source]

Bases: object

Used by the agent (client side), its a proxy class to provide an interface to interact with libnmap responsible for the actual execution. Its implementation allows handling, duplicate file names, with numeric prefix, as well as keeping status on the execution process.

TASK_HEADERS = ['Target', 'Nª completed Scans', 'Status']
print(target, progress)[source]
report_name(extension)[source]

Checks if a report with the current target.extension exists, and prepends a number if it does.

Parameters

extension – xml, nmap.

Returns

path str path and filename, the filename will be prefixed, by a number if the base+extension already exists in the outdir.

Return type

str

run(target, options, callback)[source]

Executes the scan on a given target.

Parameters
  • target

  • options

  • callback – callback function to report status to the server.

Returns

report object

Return type

dscan.models.structures.Report

show_status(nmapscan=None)[source]
Parameters

nmapscan (libnmap.process.NmapProcess) – takes libnmap.process.NmapProcess instance to display the current status of the scan.

class dscan.models.scanner.ServerConfig(config, options, outdir)[source]

Bases: object

Server configuration parser.

SCAN_CONF = 'nmap-scan'
SERVER = ('server', 'stats', 'targets', 'live-targets', 'trace')
save_context(ctx)[source]

Serializes the context to resume later.

Parameters

ctx (Context) – instance of Context

target_optimization(targets)[source]

Takes a list of ip Addresses and groups all sequential ips in cidr notation.

Parameters

targetslist of str

Type

list of str

class dscan.models.scanner.Stage(stage_name, targets_path, options, outdir)[source]

Bases: object

as_tuple()[source]

Returns the information as tuple, nlines, finished targets and %, used by Display to print scanner status.

Returns

tuple of strings.

Return type

tuple of str.

close()[source]
inc_finished()[source]
property isfinished
Returns True if the number of lines is equal to the number of

finished targets.

Returns

bool

Return type

bool

next_task()[source]

Get next target from the file.

Returns

Task.

Return type

Task

property percentage

Calculates the completion of this stage.

Returns

float of of the % completion.

Return type

float

process_results()[source]

Meant to be overwritten, like for example stages like ping sweep aka discovery.

class dscan.models.scanner.Task(stage_name, options, target)[source]

Bases: object

Representation of a scan task. A scan task is sent to an agent with a target and, scan options. Each task has the following states: - Scheduled: the default state set when its created. - Running: Set after the agent has confirmed the task has started executing. - Interrupted: Set when the task is aborted by agent, or the server has been halted. - Downloading: Set when the agent notifies its ready to sent the report. - Completed: Set only after the report has been received successfully.

as_tuple()[source]

returns a tuple with the target and scan options.

Returns

tuple options, target

Rtype tuple

update(status)[source]

Models Structures

structures.py network elements of the scanner

class dscan.models.structures.Auth(*args, sock=None)[source]

Bases: dscan.models.structures.Structure

Authentication Request from an Agent to server!

data
op_code = 1
class dscan.models.structures.Command(*args, sock=None)[source]

Bases: dscan.models.structures.Structure

Scan task information ! Send by the server to the agent. final format is <BB?s?s

op_code = 3
options
target
class dscan.models.structures.ExitStatus(*args, sock=None)[source]

Bases: dscan.models.structures.Structure

Scan Result Status ! Send both server and agent to signal the exit status of a operation. final format is <BB

op_code = 4
status
class dscan.models.structures.Operations(value)[source]

Bases: enum.IntEnum

Commands available!

AUTH = 1
COMMAND = 3
READY = 2
REPORT = 5
STATUS = 4
class dscan.models.structures.Ready(*args, sock=None)[source]

Bases: dscan.models.structures.Structure

Ready to start Scan ! Sent by an Agent to the server With the client’s current user id

alias
op_code = 2
uid
class dscan.models.structures.Report(*args, sock=None)[source]

Bases: dscan.models.structures.Structure

When an agent’s task terminates, it initiates a report transfer request

filehash
filename
filesize
op_code = 5
class dscan.models.structures.Status(value)[source]

Bases: enum.IntEnum

Code values for the response status.

FAILED = 255
FINISHED = 2
SUCCESS = 0
UNAUTHORIZED = 1
UNFINISHED = 3
class dscan.models.structures.Structure(*args, sock=None)[source]

Bases: object

HEADER = '<B'

The object representation for the info exchanged between agents and servers.

classmethod create(sock)[source]
op_code = None
pack()[source]

Returns a struct.pack string ready to be sent :return: struct.pack

setData(*args)[source]
unpack(sock)[source]

Unpacks a known command based on the predefined :param sock: :return: Instance of a message subclass