patronus_fati 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE +165 -0
- data/README.md +29 -0
- data/Rakefile +21 -0
- data/bin/patronus_fati +54 -0
- data/kismet_configs/pat_fat_startup.sh +3 -0
- data/kismet_configs/patronus_fati_kismet.conf +88 -0
- data/lib/patronus_fati/cap_struct.rb +97 -0
- data/lib/patronus_fati/connection.rb +85 -0
- data/lib/patronus_fati/consts.rb +85 -0
- data/lib/patronus_fati/data_mapper/crypt_flags.rb +83 -0
- data/lib/patronus_fati/data_mapper/null_table_prefix.rb +7 -0
- data/lib/patronus_fati/data_models/access_point.rb +74 -0
- data/lib/patronus_fati/data_models/alert.rb +24 -0
- data/lib/patronus_fati/data_models/ap_frequency.rb +14 -0
- data/lib/patronus_fati/data_models/ap_signal.rb +12 -0
- data/lib/patronus_fati/data_models/client.rb +69 -0
- data/lib/patronus_fati/data_models/client_frequency.rb +14 -0
- data/lib/patronus_fati/data_models/client_signal.rb +12 -0
- data/lib/patronus_fati/data_models/common.rb +49 -0
- data/lib/patronus_fati/data_models/connection.rb +48 -0
- data/lib/patronus_fati/data_models/mac.rb +48 -0
- data/lib/patronus_fati/data_models/probe.rb +13 -0
- data/lib/patronus_fati/data_models/ssid.rb +35 -0
- data/lib/patronus_fati/data_observers/access_point_observer.rb +53 -0
- data/lib/patronus_fati/data_observers/alert_observer.rb +12 -0
- data/lib/patronus_fati/data_observers/client_observer.rb +52 -0
- data/lib/patronus_fati/data_observers/connection_observer.rb +66 -0
- data/lib/patronus_fati/data_observers/probe_observer.rb +11 -0
- data/lib/patronus_fati/data_observers/ssid_observer.rb +53 -0
- data/lib/patronus_fati/event_handler.rb +27 -0
- data/lib/patronus_fati/factory_base.rb +56 -0
- data/lib/patronus_fati/message_models/ack.rb +5 -0
- data/lib/patronus_fati/message_models/alert.rb +10 -0
- data/lib/patronus_fati/message_models/battery.rb +6 -0
- data/lib/patronus_fati/message_models/bssid.rb +43 -0
- data/lib/patronus_fati/message_models/bssidsrc.rb +15 -0
- data/lib/patronus_fati/message_models/btscandev.rb +11 -0
- data/lib/patronus_fati/message_models/capability.rb +5 -0
- data/lib/patronus_fati/message_models/channel.rb +13 -0
- data/lib/patronus_fati/message_models/client.rb +45 -0
- data/lib/patronus_fati/message_models/clisrc.rb +17 -0
- data/lib/patronus_fati/message_models/clitag.rb +6 -0
- data/lib/patronus_fati/message_models/common.rb +15 -0
- data/lib/patronus_fati/message_models/critfail.rb +5 -0
- data/lib/patronus_fati/message_models/error.rb +6 -0
- data/lib/patronus_fati/message_models/gps.rb +6 -0
- data/lib/patronus_fati/message_models/info.rb +11 -0
- data/lib/patronus_fati/message_models/kismet.rb +8 -0
- data/lib/patronus_fati/message_models/nettag.rb +6 -0
- data/lib/patronus_fati/message_models/packet.rb +10 -0
- data/lib/patronus_fati/message_models/plugin.rb +8 -0
- data/lib/patronus_fati/message_models/protocols.rb +5 -0
- data/lib/patronus_fati/message_models/remove.rb +6 -0
- data/lib/patronus_fati/message_models/source.rb +10 -0
- data/lib/patronus_fati/message_models/spectrum.rb +8 -0
- data/lib/patronus_fati/message_models/ssid.rb +25 -0
- data/lib/patronus_fati/message_models/status.rb +5 -0
- data/lib/patronus_fati/message_models/string.rb +6 -0
- data/lib/patronus_fati/message_models/terminate.rb +5 -0
- data/lib/patronus_fati/message_models/time.rb +6 -0
- data/lib/patronus_fati/message_models/trackinfo.rb +8 -0
- data/lib/patronus_fati/message_models/wepkey.rb +6 -0
- data/lib/patronus_fati/message_models.rb +39 -0
- data/lib/patronus_fati/message_parser.rb +44 -0
- data/lib/patronus_fati/message_processor/alert.rb +15 -0
- data/lib/patronus_fati/message_processor/bssid.rb +47 -0
- data/lib/patronus_fati/message_processor/capability.rb +24 -0
- data/lib/patronus_fati/message_processor/client.rb +55 -0
- data/lib/patronus_fati/message_processor/critfail.rb +8 -0
- data/lib/patronus_fati/message_processor/error.rb +7 -0
- data/lib/patronus_fati/message_processor/protocols.rb +7 -0
- data/lib/patronus_fati/message_processor/ssid.rb +48 -0
- data/lib/patronus_fati/message_processor.rb +52 -0
- data/lib/patronus_fati/version.rb +3 -0
- data/lib/patronus_fati.rb +68 -0
- data/patronus_fati.gemspec +41 -0
- data/spec/data_models/access_point_spec.rb +26 -0
- data/spec/data_models/alert_spec.rb +12 -0
- data/spec/data_models/client_spec.rb +25 -0
- data/spec/data_models/connection_spec.rb +86 -0
- data/spec/data_models/mac_spec.rb +26 -0
- data/spec/patronus_fati_spec.rb +13 -0
- data/spec/spec_helper.rb +71 -0
- data/wrapper.rb +19 -0
- metadata +393 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1c1a12b8f0a8ff63c98abf53579cfd947510a80c
|
4
|
+
data.tar.gz: 7a5394b19d5f7e1be5fb162b49504acbed419070
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 88dbe30dea62bfbbbdfa609eb701f83209650eb30db168c07a4ab4b7e0af6441377facfb89fb4b80e1bac0cecb869c5eb05aaf182fb6d7ca55ddeef324617cca
|
7
|
+
data.tar.gz: 4513aab2a201d98b3aeaeed2c61b253118a6cae3d10c18053bbc77cbf5af1df2d437342bfa0cca7f823379f9a2b0e745c2526c146e314e7f649457d0a1e42027
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--default-return void --private --protected
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
GNU LESSER GENERAL PUBLIC LICENSE
|
2
|
+
Version 3, 29 June 2007
|
3
|
+
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
6
|
+
of this license document, but changing it is not allowed.
|
7
|
+
|
8
|
+
|
9
|
+
This version of the GNU Lesser General Public License incorporates
|
10
|
+
the terms and conditions of version 3 of the GNU General Public
|
11
|
+
License, supplemented by the additional permissions listed below.
|
12
|
+
|
13
|
+
0. Additional Definitions.
|
14
|
+
|
15
|
+
As used herein, "this License" refers to version 3 of the GNU Lesser
|
16
|
+
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
17
|
+
General Public License.
|
18
|
+
|
19
|
+
"The Library" refers to a covered work governed by this License,
|
20
|
+
other than an Application or a Combined Work as defined below.
|
21
|
+
|
22
|
+
An "Application" is any work that makes use of an interface provided
|
23
|
+
by the Library, but which is not otherwise based on the Library.
|
24
|
+
Defining a subclass of a class defined by the Library is deemed a mode
|
25
|
+
of using an interface provided by the Library.
|
26
|
+
|
27
|
+
A "Combined Work" is a work produced by combining or linking an
|
28
|
+
Application with the Library. The particular version of the Library
|
29
|
+
with which the Combined Work was made is also called the "Linked
|
30
|
+
Version".
|
31
|
+
|
32
|
+
The "Minimal Corresponding Source" for a Combined Work means the
|
33
|
+
Corresponding Source for the Combined Work, excluding any source code
|
34
|
+
for portions of the Combined Work that, considered in isolation, are
|
35
|
+
based on the Application, and not on the Linked Version.
|
36
|
+
|
37
|
+
The "Corresponding Application Code" for a Combined Work means the
|
38
|
+
object code and/or source code for the Application, including any data
|
39
|
+
and utility programs needed for reproducing the Combined Work from the
|
40
|
+
Application, but excluding the System Libraries of the Combined Work.
|
41
|
+
|
42
|
+
1. Exception to Section 3 of the GNU GPL.
|
43
|
+
|
44
|
+
You may convey a covered work under sections 3 and 4 of this License
|
45
|
+
without being bound by section 3 of the GNU GPL.
|
46
|
+
|
47
|
+
2. Conveying Modified Versions.
|
48
|
+
|
49
|
+
If you modify a copy of the Library, and, in your modifications, a
|
50
|
+
facility refers to a function or data to be supplied by an Application
|
51
|
+
that uses the facility (other than as an argument passed when the
|
52
|
+
facility is invoked), then you may convey a copy of the modified
|
53
|
+
version:
|
54
|
+
|
55
|
+
a) under this License, provided that you make a good faith effort to
|
56
|
+
ensure that, in the event an Application does not supply the
|
57
|
+
function or data, the facility still operates, and performs
|
58
|
+
whatever part of its purpose remains meaningful, or
|
59
|
+
|
60
|
+
b) under the GNU GPL, with none of the additional permissions of
|
61
|
+
this License applicable to that copy.
|
62
|
+
|
63
|
+
3. Object Code Incorporating Material from Library Header Files.
|
64
|
+
|
65
|
+
The object code form of an Application may incorporate material from
|
66
|
+
a header file that is part of the Library. You may convey such object
|
67
|
+
code under terms of your choice, provided that, if the incorporated
|
68
|
+
material is not limited to numerical parameters, data structure
|
69
|
+
layouts and accessors, or small macros, inline functions and templates
|
70
|
+
(ten or fewer lines in length), you do both of the following:
|
71
|
+
|
72
|
+
a) Give prominent notice with each copy of the object code that the
|
73
|
+
Library is used in it and that the Library and its use are
|
74
|
+
covered by this License.
|
75
|
+
|
76
|
+
b) Accompany the object code with a copy of the GNU GPL and this license
|
77
|
+
document.
|
78
|
+
|
79
|
+
4. Combined Works.
|
80
|
+
|
81
|
+
You may convey a Combined Work under terms of your choice that,
|
82
|
+
taken together, effectively do not restrict modification of the
|
83
|
+
portions of the Library contained in the Combined Work and reverse
|
84
|
+
engineering for debugging such modifications, if you also do each of
|
85
|
+
the following:
|
86
|
+
|
87
|
+
a) Give prominent notice with each copy of the Combined Work that
|
88
|
+
the Library is used in it and that the Library and its use are
|
89
|
+
covered by this License.
|
90
|
+
|
91
|
+
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
92
|
+
document.
|
93
|
+
|
94
|
+
c) For a Combined Work that displays copyright notices during
|
95
|
+
execution, include the copyright notice for the Library among
|
96
|
+
these notices, as well as a reference directing the user to the
|
97
|
+
copies of the GNU GPL and this license document.
|
98
|
+
|
99
|
+
d) Do one of the following:
|
100
|
+
|
101
|
+
0) Convey the Minimal Corresponding Source under the terms of this
|
102
|
+
License, and the Corresponding Application Code in a form
|
103
|
+
suitable for, and under terms that permit, the user to
|
104
|
+
recombine or relink the Application with a modified version of
|
105
|
+
the Linked Version to produce a modified Combined Work, in the
|
106
|
+
manner specified by section 6 of the GNU GPL for conveying
|
107
|
+
Corresponding Source.
|
108
|
+
|
109
|
+
1) Use a suitable shared library mechanism for linking with the
|
110
|
+
Library. A suitable mechanism is one that (a) uses at run time
|
111
|
+
a copy of the Library already present on the user's computer
|
112
|
+
system, and (b) will operate properly with a modified version
|
113
|
+
of the Library that is interface-compatible with the Linked
|
114
|
+
Version.
|
115
|
+
|
116
|
+
e) Provide Installation Information, but only if you would otherwise
|
117
|
+
be required to provide such information under section 6 of the
|
118
|
+
GNU GPL, and only to the extent that such information is
|
119
|
+
necessary to install and execute a modified version of the
|
120
|
+
Combined Work produced by recombining or relinking the
|
121
|
+
Application with a modified version of the Linked Version. (If
|
122
|
+
you use option 4d0, the Installation Information must accompany
|
123
|
+
the Minimal Corresponding Source and Corresponding Application
|
124
|
+
Code. If you use option 4d1, you must provide the Installation
|
125
|
+
Information in the manner specified by section 6 of the GNU GPL
|
126
|
+
for conveying Corresponding Source.)
|
127
|
+
|
128
|
+
5. Combined Libraries.
|
129
|
+
|
130
|
+
You may place library facilities that are a work based on the
|
131
|
+
Library side by side in a single library together with other library
|
132
|
+
facilities that are not Applications and are not covered by this
|
133
|
+
License, and convey such a combined library under terms of your
|
134
|
+
choice, if you do both of the following:
|
135
|
+
|
136
|
+
a) Accompany the combined library with a copy of the same work based
|
137
|
+
on the Library, uncombined with any other library facilities,
|
138
|
+
conveyed under the terms of this License.
|
139
|
+
|
140
|
+
b) Give prominent notice with the combined library that part of it
|
141
|
+
is a work based on the Library, and explaining where to find the
|
142
|
+
accompanying uncombined form of the same work.
|
143
|
+
|
144
|
+
6. Revised Versions of the GNU Lesser General Public License.
|
145
|
+
|
146
|
+
The Free Software Foundation may publish revised and/or new versions
|
147
|
+
of the GNU Lesser General Public License from time to time. Such new
|
148
|
+
versions will be similar in spirit to the present version, but may
|
149
|
+
differ in detail to address new problems or concerns.
|
150
|
+
|
151
|
+
Each version is given a distinguishing version number. If the
|
152
|
+
Library as you received it specifies that a certain numbered version
|
153
|
+
of the GNU Lesser General Public License "or any later version"
|
154
|
+
applies to it, you have the option of following the terms and
|
155
|
+
conditions either of that published version or of any later version
|
156
|
+
published by the Free Software Foundation. If the Library as you
|
157
|
+
received it does not specify a version number of the GNU Lesser
|
158
|
+
General Public License, you may choose any version of the GNU Lesser
|
159
|
+
General Public License ever published by the Free Software Foundation.
|
160
|
+
|
161
|
+
If the Library as you received it specifies that a proxy can decide
|
162
|
+
whether future versions of the GNU Lesser General Public License shall
|
163
|
+
apply, that proxy's public statement of acceptance of any version is
|
164
|
+
permanent authorization for you to choose that version for the
|
165
|
+
Library.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# PatronusFati
|
2
|
+
|
3
|
+
The Patron of Fate is an implementation of the Kismet client protocol in Ruby.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'patronus_fati'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install patronus_fati
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
task :environment do
|
4
|
+
base_path = File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
|
5
|
+
$LOAD_PATH.unshift(base_path) unless $LOAD_PATH.include?(base_path)
|
6
|
+
|
7
|
+
require 'patronus_fati'
|
8
|
+
end
|
9
|
+
|
10
|
+
task :database => [:environment] do
|
11
|
+
DataMapper.setup(:default, ENV['DATABASE_URL'] || 'sqlite::memory:')
|
12
|
+
DataMapper.repository(:default).adapter.resource_naming_convention = PatronusFati::NullTablePrefix
|
13
|
+
DataMapper.finalize
|
14
|
+
DataMapper.auto_upgrade!
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Start a pry session with the code loaded"
|
18
|
+
task :console => [:database, :environment] do
|
19
|
+
require 'pry'
|
20
|
+
pry
|
21
|
+
end
|
data/bin/patronus_fati
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.push(File.expand_path(File.join('..', '..', 'lib'), __FILE__))
|
4
|
+
|
5
|
+
require 'optparse'
|
6
|
+
require 'dm-sqlite-adapter'
|
7
|
+
require 'patronus_fati'
|
8
|
+
|
9
|
+
options = {
|
10
|
+
'database' => 'sqlite::memory:',
|
11
|
+
'port' => 2501,
|
12
|
+
'server' => '127.0.0.1'
|
13
|
+
}
|
14
|
+
|
15
|
+
OptionParser.new(nil, 32, ' ') do |opts|
|
16
|
+
opts.on('-d', '--db-path DB_PATH', 'Path where SQLite database will be stored') do |path|
|
17
|
+
options['database'] = ('sqlite://%s' % File.expand_path(path))
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-s', '--server SERVER', 'IP or hostname of running kismet server.') do |srv|
|
21
|
+
options['server'] = srv
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('-p', '--port PORT', 'Port that kismet server is running on.') do |port|
|
25
|
+
options['port'] = port.to_i
|
26
|
+
end
|
27
|
+
end.parse(ARGV)
|
28
|
+
|
29
|
+
def exception_logger(tag)
|
30
|
+
yield
|
31
|
+
rescue Interrupt
|
32
|
+
warn('Quitting...')
|
33
|
+
rescue => e
|
34
|
+
puts "(#{tag}) Rescued from error: #{e.message}"
|
35
|
+
puts e.backtrace
|
36
|
+
end
|
37
|
+
|
38
|
+
exception_logger('process') do
|
39
|
+
connection = PatronusFati.setup(options['server'], options['port'], options['database'])
|
40
|
+
connection.connect
|
41
|
+
|
42
|
+
PatronusFati.event_handler.on(:any) do |asset_type, event_type, msg, opts|
|
43
|
+
puts JSON.generate({asset_type: asset_type, event_type: event_type, data: msg, additional_data: opts, timestamp: Time.now})
|
44
|
+
end
|
45
|
+
|
46
|
+
while (line = connection.read_queue.pop)
|
47
|
+
next unless (obj = PatronusFati::MessageParser.parse(line))
|
48
|
+
responses = PatronusFati::MessageProcessor.handle(obj)
|
49
|
+
|
50
|
+
Array(responses).each { |msg| connection.write(msg) }
|
51
|
+
end
|
52
|
+
|
53
|
+
connection.disconnect
|
54
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
version=2009-newcore
|
2
|
+
servername=PatronusFatiKismet
|
3
|
+
|
4
|
+
logdefault=Kismet
|
5
|
+
logprefix=/tmp/patronus_fati_kismet
|
6
|
+
logtemplate=%p%n-%D-%t-%i.%l
|
7
|
+
|
8
|
+
hidedata=false
|
9
|
+
|
10
|
+
allowplugins=true
|
11
|
+
|
12
|
+
ncsource=wlan0
|
13
|
+
|
14
|
+
#preferredchannels=
|
15
|
+
|
16
|
+
# How many channels per second do we hop? (1-10)
|
17
|
+
channelvelocity=5
|
18
|
+
|
19
|
+
channellist=IEEE80211b:1:3,6:3,11:3,2,7,3,8,4,9,5,10
|
20
|
+
channellist=IEEE80211a:36,40,44,48,52,56,60,64,149,153,157,161,165
|
21
|
+
channellist=IEEE80211ab:1:3,6:3,11:3,2,7,3,8,4,9,5,10,36,40,44,48,52,56,60,64,149,153,157,161,165
|
22
|
+
|
23
|
+
listen=tcp://0.0.0.0:2501
|
24
|
+
allowedhosts=0.0.0.0/0
|
25
|
+
maxclients=5
|
26
|
+
|
27
|
+
maxbacklog=5000
|
28
|
+
|
29
|
+
# OUI file, expected format 00:11:22<tab>manufname
|
30
|
+
# IEEE OUI file used to look up manufacturer info. We default to the
|
31
|
+
# wireshark one since most people have that.
|
32
|
+
ouifile=/etc/manuf
|
33
|
+
ouifile=/usr/share/wireshark/wireshark/manuf
|
34
|
+
ouifile=/usr/share/wireshark/manuf
|
35
|
+
|
36
|
+
gps=false
|
37
|
+
gpstype=gpsd
|
38
|
+
gpshost=localhost:2947
|
39
|
+
gpsreconnect=true
|
40
|
+
|
41
|
+
# Do we export packets over tun/tap virtual interfaces?
|
42
|
+
tuntap_export=false
|
43
|
+
tuntap_device=kistap0
|
44
|
+
|
45
|
+
#alert=ADHOCCONFLICT,5/min,1/sec
|
46
|
+
alert=AIRJACKSSID,5/min,1/sec
|
47
|
+
alert=APSPOOF,10/min,1/sec
|
48
|
+
alert=BCASTDISCON,5/min,2/sec
|
49
|
+
alert=BSSTIMESTAMP,5/min,1/sec
|
50
|
+
#alert=CHANCHANGE,5/min,1/sec
|
51
|
+
alert=CRYPTODROP,5/min,1/sec
|
52
|
+
alert=DISASSOCTRAFFIC,10/min,1/sec
|
53
|
+
alert=DEAUTHFLOOD,5/min,2/sec
|
54
|
+
alert=DEAUTHCODEINVALID,5/min,1/sec
|
55
|
+
alert=DISCONCODEINVALID,5/min,1/sec
|
56
|
+
alert=DHCPNAMECHANGE,5/min,1/sec
|
57
|
+
alert=DHCPOSCHANGE,5/min,1/sec
|
58
|
+
alert=DHCPCLIENTID,5/min,1/sec
|
59
|
+
alert=DHCPCONFLICT,10/min,1/sec
|
60
|
+
alert=NETSTUMBLER,5/min,1/sec
|
61
|
+
alert=LUCENTTEST,5/min,1/sec
|
62
|
+
alert=LONGSSID,5/min,1/sec
|
63
|
+
alert=MSFBCOMSSID,5/min,1/sec
|
64
|
+
alert=MSFDLINKRATE,5/min,1/sec
|
65
|
+
alert=MSFNETGEARBEACON,5/min,1/sec
|
66
|
+
alert=NULLPROBERESP,5/min,1/sec
|
67
|
+
alert=PROBENOJOIN,5/min,1/sec
|
68
|
+
|
69
|
+
# Controls behavior of the APSPOOF alert. SSID may be a literal match (ssid=) or
|
70
|
+
# a regex (ssidregex=) if PCRE was available when kismet was built. The allowed
|
71
|
+
# MAC list must be comma-separated and enclosed in quotes if there are multiple
|
72
|
+
# MAC addresses allowed. MAC address masks are allowed.
|
73
|
+
#apspoof=Foo1:ssidregex="(?i:foobar)",validmacs=00:11:22:33:44:55
|
74
|
+
#apspoof=Foo2:ssid="Foobar",validmacs="00:11:22:33:44:55,aa:bb:cc:dd:ee:ff"
|
75
|
+
|
76
|
+
# How often (in seconds) do we write all our data files (0 to disable)
|
77
|
+
writeinterval=0
|
78
|
+
|
79
|
+
enablesound=false
|
80
|
+
enablespeech=false
|
81
|
+
|
82
|
+
logtypes=netxml
|
83
|
+
|
84
|
+
pcapdumpformat=ppi
|
85
|
+
|
86
|
+
# Where state info, etc, is stored. You shouldnt ever need to change this.
|
87
|
+
# This is a directory.
|
88
|
+
configdir=%h/.kismet/
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module PatronusFati
|
2
|
+
# Class generator similar to a struct but allows for using a hash as an
|
3
|
+
# unordered initializer. This was designed to work as an initializer for
|
4
|
+
# capability classes and thus has a few additional methods written in to
|
5
|
+
# support this functionality.
|
6
|
+
module CapStruct
|
7
|
+
# Creates a new dynamic class with the provided attributes.
|
8
|
+
#
|
9
|
+
# @param [Array<Symbol>] args The list of attributes of getters and
|
10
|
+
# setters.
|
11
|
+
def self.new(*args)
|
12
|
+
Class.new do
|
13
|
+
@attributes_keys = args.map(&:to_sym).dup.freeze
|
14
|
+
@supported_keys = []
|
15
|
+
|
16
|
+
# Any unspecified data filter will default to just returning the same
|
17
|
+
# value passed in.
|
18
|
+
@data_filters = Hash.new(Proc.new { |i| i })
|
19
|
+
|
20
|
+
# Returns the keys that are valid for this class (effectively it's
|
21
|
+
# attributes)
|
22
|
+
#
|
23
|
+
# @return [Array<Symbol>]
|
24
|
+
def self.attribute_keys
|
25
|
+
@attributes_keys
|
26
|
+
end
|
27
|
+
|
28
|
+
# Call and return the resulting value of the data filter requested.
|
29
|
+
#
|
30
|
+
# @param [Symbol] attr
|
31
|
+
# @param [Object] value
|
32
|
+
# @return [Object]
|
33
|
+
def self.data_filter(attr, value)
|
34
|
+
@data_filters[attr].call(value)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set the data filter to the provided block.
|
38
|
+
#
|
39
|
+
# @param [Symbol] attr
|
40
|
+
def self.set_data_filter(*attr)
|
41
|
+
blk = Proc.new
|
42
|
+
Array(attr).each { |a| @data_filters[a] = blk }
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return the intersection of our known attribute keys and the keys that
|
46
|
+
# the server has claimed to support. The order is important to be
|
47
|
+
# consistent between all returned runs of this.
|
48
|
+
#
|
49
|
+
# @return [Array<Symbol>]
|
50
|
+
def self.enabled_keys
|
51
|
+
attribute_keys & supported_keys
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return the keys the server has claimed to support (and maintain the order).
|
55
|
+
#
|
56
|
+
# @return [Array<Symbol>]
|
57
|
+
def self.supported_keys
|
58
|
+
@supported_keys
|
59
|
+
end
|
60
|
+
|
61
|
+
# Set the keys supported by the server.
|
62
|
+
#
|
63
|
+
# @param [Array<Symbol>] sk
|
64
|
+
def self.supported_keys=(sk)
|
65
|
+
@supported_keys = sk
|
66
|
+
end
|
67
|
+
|
68
|
+
attr_reader :attributes
|
69
|
+
|
70
|
+
def [](key)
|
71
|
+
@attributes[key.to_sym]
|
72
|
+
end
|
73
|
+
|
74
|
+
def []=(key, val)
|
75
|
+
if self.class.attribute_keys.include?(key.to_sym)
|
76
|
+
@attributes[key.to_sym] = self.class.data_filter(key.to_sym, val)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Configure and setup the instance with all the valid parameters for
|
81
|
+
# the dynamic class.
|
82
|
+
#
|
83
|
+
# @attrs [Symbol=>Object] attrs
|
84
|
+
def initialize(attrs)
|
85
|
+
@attributes = {}
|
86
|
+
attrs.each { |k, v| self[k] = v }
|
87
|
+
end
|
88
|
+
|
89
|
+
# Define all the appropriate setters and getters for this dynamic class.
|
90
|
+
args.each do |a|
|
91
|
+
define_method(a.to_sym) { self[a] }
|
92
|
+
define_method("#{a}=".to_sym) { |val| self[a] = val }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module PatronusFati
|
2
|
+
class Connection
|
3
|
+
attr_reader :port, :read_queue, :server, :write_queue
|
4
|
+
|
5
|
+
def initialize(server, port)
|
6
|
+
@server = server
|
7
|
+
@port = port
|
8
|
+
end
|
9
|
+
|
10
|
+
def connect
|
11
|
+
establish_connection
|
12
|
+
|
13
|
+
self.read_queue = Queue.new
|
14
|
+
self.write_queue = Queue.new
|
15
|
+
|
16
|
+
start_read_thread
|
17
|
+
start_write_thread
|
18
|
+
end
|
19
|
+
|
20
|
+
def connected?
|
21
|
+
!socket.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def disconnect
|
25
|
+
return unless connected?
|
26
|
+
|
27
|
+
Thread.kill(read_thread)
|
28
|
+
Thread.kill(write_thread)
|
29
|
+
|
30
|
+
socket.close
|
31
|
+
|
32
|
+
self.socket = nil
|
33
|
+
self.read_queue = nil
|
34
|
+
self.write_queue = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def write(msg)
|
38
|
+
write_queue.push(msg)
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
attr_accessor :read_thread, :socket, :write_thread
|
44
|
+
attr_writer :read_queue, :write_queue
|
45
|
+
|
46
|
+
def establish_connection
|
47
|
+
return if connected?
|
48
|
+
@socket = TCPSocket.new(server, port)
|
49
|
+
end
|
50
|
+
|
51
|
+
def start_read_thread
|
52
|
+
self.read_thread = Thread.new do
|
53
|
+
begin
|
54
|
+
while (line = socket.readline)
|
55
|
+
read_queue << line
|
56
|
+
end
|
57
|
+
rescue Timeout::Error
|
58
|
+
# Connection timed out...
|
59
|
+
exit 1
|
60
|
+
rescue EOFError
|
61
|
+
# We lost our connection...
|
62
|
+
exit 2
|
63
|
+
rescue => e
|
64
|
+
puts ('Unknown issue reading from socket: %s' % e.message)
|
65
|
+
exit 3
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def start_write_thread
|
71
|
+
self.write_thread = Thread.new do
|
72
|
+
begin
|
73
|
+
count = 0
|
74
|
+
while (msg = write_queue.pop)
|
75
|
+
socket.write("!%i %s\r\n" % [count, msg])
|
76
|
+
count += 1
|
77
|
+
end
|
78
|
+
rescue => e
|
79
|
+
puts ('Unknown issue writing to socket: %s' % e.message)
|
80
|
+
exit 1
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module PatronusFati
|
2
|
+
BSSID_TYPE_MAP = {
|
3
|
+
0 => 'infrastructure',
|
4
|
+
1 => 'adhoc',
|
5
|
+
2 => 'probe',
|
6
|
+
3 => 'turbocell',
|
7
|
+
4 => 'data',
|
8
|
+
255 => 'mixed',
|
9
|
+
256 => 'remove'
|
10
|
+
}
|
11
|
+
|
12
|
+
# 'DS' is short for distribution system, it has something to do with packet
|
13
|
+
# domains 'BSS' (the prefix on BSSID) but it's clear that identifier is more
|
14
|
+
# than what I thought it was...
|
15
|
+
CLIENT_TYPE_MAP = {
|
16
|
+
0 => 'unknown',
|
17
|
+
1 => 'from_ds',
|
18
|
+
2 => 'to_ds',
|
19
|
+
3 => 'inter_ds',
|
20
|
+
4 => 'established',
|
21
|
+
5 => 'adhoc',
|
22
|
+
6 => 'remove'
|
23
|
+
}
|
24
|
+
|
25
|
+
DATA_DELIMITER = /(\x01[^\x01]+\x01)|(\S+)/
|
26
|
+
|
27
|
+
# This map was retrieved from a combination of the packet_ieee80211.h header
|
28
|
+
# file and dumpfile_netxml.cc source in the kismet git repo.
|
29
|
+
SSID_CRYPT_MAP = {
|
30
|
+
0 => 'None',
|
31
|
+
1 => 'Unknown',
|
32
|
+
(1 << 1) => 'WEP',
|
33
|
+
(1 << 2) => 'Layer3',
|
34
|
+
(1 << 3) => 'WEP40',
|
35
|
+
(1 << 4) => 'WEP104',
|
36
|
+
(1 << 5) => 'WPA+TKIP',
|
37
|
+
(1 << 6) => 'WPA', # Appears deprecated but still in the kismet source
|
38
|
+
(1 << 7) => 'WPA+PSK',
|
39
|
+
(1 << 8) => 'WPA+AES-OCB',
|
40
|
+
(1 << 9) => 'WPA+AES-CCM',
|
41
|
+
(1 << 10) => 'WPA Migration Mode',
|
42
|
+
(1 << 11) => 'WPA+EAP', # Not a value that shows up in kismet exports... Bonus?
|
43
|
+
(1 << 12) => 'WPA+LEAP',
|
44
|
+
(1 << 13) => 'WPA+TTLS',
|
45
|
+
(1 << 14) => 'WPA+TLS',
|
46
|
+
(1 << 15) => 'WPA+PEAP',
|
47
|
+
(1 << 20) => 'ISAKMP',
|
48
|
+
(1 << 21) => 'PPTP',
|
49
|
+
(1 << 22) => 'Fortress',
|
50
|
+
(1 << 23) => 'Keyguard',
|
51
|
+
(1 << 24) => 'Unknown Protected',
|
52
|
+
(1 << 25) => 'Unknown Non-WEP',
|
53
|
+
(1 << 26) => 'WPS'
|
54
|
+
}
|
55
|
+
|
56
|
+
SSID_CRYPT_MAP_INVERTED = Hash[SSID_CRYPT_MAP.map { |k, v| [v, k] }]
|
57
|
+
|
58
|
+
SSID_TYPE_MAP = {
|
59
|
+
0 => 'beacon',
|
60
|
+
1 => 'probe_response',
|
61
|
+
2 => 'probe_request',
|
62
|
+
3 => 'file'
|
63
|
+
}
|
64
|
+
|
65
|
+
SERVER_MESSAGE = /
|
66
|
+
(?<header> [A-Z]+){0}
|
67
|
+
(?<data> .+){0}
|
68
|
+
|
69
|
+
^\*\g<header>:\s+\g<data>$
|
70
|
+
/x
|
71
|
+
|
72
|
+
# Number of seconds before we consider an access point as offline
|
73
|
+
AP_EXPIRATION = 300
|
74
|
+
|
75
|
+
# Number of seconds before we consider a client as no longer within range.
|
76
|
+
CLIENT_EXPIRATION = 1800
|
77
|
+
|
78
|
+
# How long before a connection between a client and an access point is
|
79
|
+
# consider no longer actively connected.
|
80
|
+
CONNECTION_EXPIRATION = 1800
|
81
|
+
|
82
|
+
# Number of seconds before we consider an access point no longer advertising an
|
83
|
+
# SSID.
|
84
|
+
SSID_EXPIRATION = 300
|
85
|
+
end
|