patronus_fati 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rspec +2 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +165 -0
  7. data/README.md +29 -0
  8. data/Rakefile +21 -0
  9. data/bin/patronus_fati +54 -0
  10. data/kismet_configs/pat_fat_startup.sh +3 -0
  11. data/kismet_configs/patronus_fati_kismet.conf +88 -0
  12. data/lib/patronus_fati/cap_struct.rb +97 -0
  13. data/lib/patronus_fati/connection.rb +85 -0
  14. data/lib/patronus_fati/consts.rb +85 -0
  15. data/lib/patronus_fati/data_mapper/crypt_flags.rb +83 -0
  16. data/lib/patronus_fati/data_mapper/null_table_prefix.rb +7 -0
  17. data/lib/patronus_fati/data_models/access_point.rb +74 -0
  18. data/lib/patronus_fati/data_models/alert.rb +24 -0
  19. data/lib/patronus_fati/data_models/ap_frequency.rb +14 -0
  20. data/lib/patronus_fati/data_models/ap_signal.rb +12 -0
  21. data/lib/patronus_fati/data_models/client.rb +69 -0
  22. data/lib/patronus_fati/data_models/client_frequency.rb +14 -0
  23. data/lib/patronus_fati/data_models/client_signal.rb +12 -0
  24. data/lib/patronus_fati/data_models/common.rb +49 -0
  25. data/lib/patronus_fati/data_models/connection.rb +48 -0
  26. data/lib/patronus_fati/data_models/mac.rb +48 -0
  27. data/lib/patronus_fati/data_models/probe.rb +13 -0
  28. data/lib/patronus_fati/data_models/ssid.rb +35 -0
  29. data/lib/patronus_fati/data_observers/access_point_observer.rb +53 -0
  30. data/lib/patronus_fati/data_observers/alert_observer.rb +12 -0
  31. data/lib/patronus_fati/data_observers/client_observer.rb +52 -0
  32. data/lib/patronus_fati/data_observers/connection_observer.rb +66 -0
  33. data/lib/patronus_fati/data_observers/probe_observer.rb +11 -0
  34. data/lib/patronus_fati/data_observers/ssid_observer.rb +53 -0
  35. data/lib/patronus_fati/event_handler.rb +27 -0
  36. data/lib/patronus_fati/factory_base.rb +56 -0
  37. data/lib/patronus_fati/message_models/ack.rb +5 -0
  38. data/lib/patronus_fati/message_models/alert.rb +10 -0
  39. data/lib/patronus_fati/message_models/battery.rb +6 -0
  40. data/lib/patronus_fati/message_models/bssid.rb +43 -0
  41. data/lib/patronus_fati/message_models/bssidsrc.rb +15 -0
  42. data/lib/patronus_fati/message_models/btscandev.rb +11 -0
  43. data/lib/patronus_fati/message_models/capability.rb +5 -0
  44. data/lib/patronus_fati/message_models/channel.rb +13 -0
  45. data/lib/patronus_fati/message_models/client.rb +45 -0
  46. data/lib/patronus_fati/message_models/clisrc.rb +17 -0
  47. data/lib/patronus_fati/message_models/clitag.rb +6 -0
  48. data/lib/patronus_fati/message_models/common.rb +15 -0
  49. data/lib/patronus_fati/message_models/critfail.rb +5 -0
  50. data/lib/patronus_fati/message_models/error.rb +6 -0
  51. data/lib/patronus_fati/message_models/gps.rb +6 -0
  52. data/lib/patronus_fati/message_models/info.rb +11 -0
  53. data/lib/patronus_fati/message_models/kismet.rb +8 -0
  54. data/lib/patronus_fati/message_models/nettag.rb +6 -0
  55. data/lib/patronus_fati/message_models/packet.rb +10 -0
  56. data/lib/patronus_fati/message_models/plugin.rb +8 -0
  57. data/lib/patronus_fati/message_models/protocols.rb +5 -0
  58. data/lib/patronus_fati/message_models/remove.rb +6 -0
  59. data/lib/patronus_fati/message_models/source.rb +10 -0
  60. data/lib/patronus_fati/message_models/spectrum.rb +8 -0
  61. data/lib/patronus_fati/message_models/ssid.rb +25 -0
  62. data/lib/patronus_fati/message_models/status.rb +5 -0
  63. data/lib/patronus_fati/message_models/string.rb +6 -0
  64. data/lib/patronus_fati/message_models/terminate.rb +5 -0
  65. data/lib/patronus_fati/message_models/time.rb +6 -0
  66. data/lib/patronus_fati/message_models/trackinfo.rb +8 -0
  67. data/lib/patronus_fati/message_models/wepkey.rb +6 -0
  68. data/lib/patronus_fati/message_models.rb +39 -0
  69. data/lib/patronus_fati/message_parser.rb +44 -0
  70. data/lib/patronus_fati/message_processor/alert.rb +15 -0
  71. data/lib/patronus_fati/message_processor/bssid.rb +47 -0
  72. data/lib/patronus_fati/message_processor/capability.rb +24 -0
  73. data/lib/patronus_fati/message_processor/client.rb +55 -0
  74. data/lib/patronus_fati/message_processor/critfail.rb +8 -0
  75. data/lib/patronus_fati/message_processor/error.rb +7 -0
  76. data/lib/patronus_fati/message_processor/protocols.rb +7 -0
  77. data/lib/patronus_fati/message_processor/ssid.rb +48 -0
  78. data/lib/patronus_fati/message_processor.rb +52 -0
  79. data/lib/patronus_fati/version.rb +3 -0
  80. data/lib/patronus_fati.rb +68 -0
  81. data/patronus_fati.gemspec +41 -0
  82. data/spec/data_models/access_point_spec.rb +26 -0
  83. data/spec/data_models/alert_spec.rb +12 -0
  84. data/spec/data_models/client_spec.rb +25 -0
  85. data/spec/data_models/connection_spec.rb +86 -0
  86. data/spec/data_models/mac_spec.rb +26 -0
  87. data/spec/patronus_fati_spec.rb +13 -0
  88. data/spec/spec_helper.rb +71 -0
  89. data/wrapper.rb +19 -0
  90. 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
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.db
4
+ *.db-journal
5
+ *.log
6
+ .bundle
7
+ .config
8
+ .yardoc
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --default-return void --private --protected
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in patronus_fati.gemspec
4
+ gemspec
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,3 @@
1
+ #!/bin/bash
2
+
3
+ sudo /usr/bin/kismet_server --no-logging --config-file patronus_fati_kismet.conf --daemonize --silent
@@ -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