File: NDiffLibs.txt

package info (click to toggle)
ndiff 0.05beta4-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 300 kB
  • ctags: 254
  • sloc: perl: 1,806; makefile: 56
file content (274 lines) | stat: -rw-r--r-- 8,083 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

This file contains some basic examples on how to use the
internal libraries included with NDiff to do useful things
with nmap data in Perl.

This is just a starter - not all classes and methods are discussed
here.  Read the source.


-----------------------------------------------------------------
DataStore.pm:  handles external representations of nmap data
1. reading nmap data

TODO: There appears to be some redundancy of methods with respect to
prepare_tag() below. 


use PortScan::DataStore;
use Carp;

# define some tag associated with the ScanSet (results set)
my $input_tag = "10.0.1-net-30May";

# pass the tag through prepare_tag() to evaluate any embedded % substitutions
my $prepared_input_tag = PortScan::DataStore::prepare_tag( $input_tag );


# now generate a data store attached to the tag
my( $processed_input_tag, $input_data_store ) 
    = PortScan::DataStore::data_store_for( $prepared_input_tag );


# now retrieve the PortScan::ScanSet (results set) associated with the tag
my $input_scanset = $input_data_store->retrieve_scanset( $processed_input_tag );

# failed if $input_scanset is not defined
croak "can't get input scanset" if !defined $input_scanset;


-----------------------------------------------------------------
DataStore.pm:  
2. writing nmap data

use PortScan::DataStore;
use Carp;

# read in or generate a ScanSet...

my $scan_set = ...

# ... manipulations on the ScanSet...

# now prepare to write the ScanSet...


# define some tag associated with the ScanSet (results set)
my $output_tag = "10.0.1-net-30May-processed";

# pass the tag through prepare_tag() to evaluate any embedded % substitutions
my $prepared_output_tag = PortScan::DataStore::prepare_tag( $output_tag );

# associate the tag with the ScanSet
$scan_set->tag( $output_tag );

# now generate a data store attached to the tag
my( $processed_output_tag, $output_data_store ) 
    = PortScan::DataStore::data_store_for( $prepared_output_tag );


# now retrieve the PortScan::ScanSet (results set) associated with the tag
my $result = $output_data_store->put_scanset( $scan_set );

croak "couldn't write scanset $prepared_output_tag" if $result != 0;



-----------------------------------------------------------------

ScanSet.pm: container for a set of hosts all scanned at the same time


use ScanSet;
use PortSpec;

# normally one retrieves a ScanSet from a DataStore but it is 
# possible one would generate one programmatically as well
#

# see ScanSet.pm for description of the values passed in the
# constructor...in this example will set them after construction

my $set = new PortScan::ScanSet( "", {}, {}, {} );

# associate a tag with the set
$set->tag( "syn-scan-Thursday" );  


# add one or more scanned ports to the master set
# each host contained in a ScanSet is assumed to have had
# this master set of ports scanned
$set->add_scanned_port( new PortScan::PortSpec( 80, 'open', 'tcp', "", "", "", "" ) );
$set->add_scanned_port( new PortScan::PortSpec( 22, 'open, 'tcp', "", "", "", "" ) );
$set->add_scanned_port( new PortScan::PortSpec( 43, 'closed', 'udp', "", "", "", "" ) );


# add a few hosts to the set
# normally one might have added some ports to the hosts 
$set->add_host( new PortScan::ScannedHost( undef, {}, '192.168.2.3', 'closed' ) );
$set->add_host( new PortScan::ScannedHost( undef, {}, '192.168.2.4', 'closed' ) );
$set->add_host( new PortScan::ScannedHost( undef, {}, '192.168.2.123', 'closed' ) );
$set->add_host( new PortScan::ScannedHost( undef, {}, '192.168.2.200', 'closed' ) );


# oops, need to remove one
$set->remove_host( '192.168.2.200' );

# retrieve a host for some reason
my $check = $set->get_host( '192.168.2.200' );

# will return undef if not found
print "not found" if ! defined $check;


# print out all hosts

my @hosts = $set->hosts_sorted_list;

foreach my $h ( @hosts )
{
  # do something...
  # $h is an instance of PortScan::ScannedHost
}


-----------------------------------------------------------------

ScannedHost.pm: encapsulates the information about a host scanned with nmap

use PortScan::ScannedHost;
use PortScan::PortSpec;

# create a new ScannedHost instance
my $host = new PortScan::ScannedHost( undef, {}, "10.0.1.12", "closed" );

# "closed" is the "Ignored State" in nmap terms.  All ports not
# explicitly added to the host, but which exist in the hosts's
# owner-ScanSet master set, will have this Ignored State applied to it.
#
# Nmap models the information this way to save space during runtime and
# in results display and storage.  The "interesting ports" listed for a
# given host are the exceptions to the Ignored State.  The Ignored State
# applies only to the remaining ports which were scanned, which is
# the ScanSet's master set minus those interesting ports.


# add a PortScan::PortSpec instance
$host->add_port( new PortScan::PortSpec( 80, "open", "tcp", "", "", "", "" ) );

# add some ports using a slightly more convenient method

$host->set_port( 22, "open", "tcp", "", "", "", "" );
$host->set_port( 43, "open", "tcp", "", "", "", "" );
$host->set_port( 43, "filtered", "udp", "", "", "", "" );


# remove a port, which are referenced by opaque keys defined 
# by PortScan::PortSpec
$host->remove_port( PortScan::PortSpec::make_key( 80, "tcp" ) );


# retrieve a port, or undef
# note that ScannedHost methods use ( proto, port ) while PortSpec
# methods use ( prot, proto ).  Mea culpa.
my $port = $host->get_port( "tcp", "80" );
carp "no such port" if ! defined $port;


# get a hashref of all ports contained
my $specs = $host->port_specs();

# iterate over the hash of specs and do something
while my( $key, $pspec ) = each %$specs
{
  # do something with each $pspec, which is an instance of PortScan::PortSpec

  # $key is an opaque key created by PortScan::PortSpec, but can always be
  # split into ( port, proto ) by PortScan::PortSpec::decode_key

  my( $port, $proto ) = PortScan::PortSpec::decode_key( $key );
}

# get the sorted list of ports contained and iterate over them
my $sorted_specs = $host->port_specs_sorted_list
foreach my $pspec ( @sorted_specs )
{
  # do something...$pspec is a PortScan::PortSpec instance
}


# get the state associated with some port, but only if explicitly
# inserted into the host (the ScannedHosts's owner/ScanSet is not checked)
# will return the psuedo-state "unknown" if the port isn't found.
my $state = $host->get_state( "tcp", 22 );
print "tcp/22 -> '$state'\n";



-----------------------------------------------------------------

PortSpec.pm: Encapsulates the properties of a "port", in the general
             sense for TCP and UDP


use PortScan::PortSpec;
use PortScan::ScannedHost;

# generate a PortSpec
my $spec = new PortScan::PortSpec( 80, "open", "tcp", "", "", "", "" );

# the four trailing parameters are defined by nmap and require some
# further research by documentation.  The second of the four is 
# the well-known service name.


# insert the spec into a ScannedHost instance
$some_host->add_port( $spec );


# make a copy of the PortSpec
my $spec2 = $spec->clone();


# query the members and print

print "port number: " .  $spec->number();
print "port state: " .   $spec->state();
print "port proto: " .   $spec->proto();
print "port service: " . $spec->service();
print "port user1: " .   $spec->u1();
print "port user2: " .   $spec->u2();
print "port user3: " .   $spec->u3();


# for internal use of ndiff, map the state to
# a canonical uppercase single-character code

my $code = $spec->state_sm;

print "open" if $code eq "O";
print "closed" if $code eq "C";
print "filtered" if $code eq "F";
...


# print out a canonical key for the well-known service name

print "service for port http/tcp: " 
      . PortScan::PortSpec::spec->known_port_by_name( "http", "tcp" );


# print out a canonical key for the well-known port number

print "service for port 80/tcp: " 
      . PortScan::PortSpec::spec->known_port_by_number( 80, "tcp" );

-----------------------------------------------------------------

TODO:
 IPAddress.pm
 ScanComparison.pm
 NmapFile.pm
 ScanContext.pm
 SetOps.pm