honeycomb 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
data/lib/honeycomb.rb CHANGED
@@ -17,8 +17,8 @@
17
17
  # with this program. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
- require 'honeycomb/interact'
21
20
  require 'honeycomb/environment'
22
21
  require 'honeycomb/default_setup'
23
22
  require 'honeycomb/model'
24
-
23
+ require 'honeycomb/honeypot'
24
+ require 'honeycomb/database'
@@ -0,0 +1 @@
1
+ require 'honeycomb/database/interact'
@@ -0,0 +1,71 @@
1
+ # honeycomb - Tool to manage and analyze data from the Dionaea Honeypot
2
+ # Project
3
+ # Josh Grunzweig
4
+ # Copyright (C) 2011 Trustwave Holdings
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify it
7
+ # under the terms of the GNU General Public License as published by the
8
+ # Free Software Foundation, either version 3 of the License, or (at your
9
+ # option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful, but
12
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
+ # for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+
20
+
21
+ module Honeycomb
22
+ module Database
23
+ class Interact
24
+
25
+ # Used for executing a query against all databases at once.
26
+ def all(&block)
27
+ all_values = []
28
+ ::DataMapper::Repository.adapters.each do |repo|
29
+ if repo[0] == :default
30
+ next
31
+ end
32
+ begin
33
+ response = DataMapper.repository(repo[0]) {yield}
34
+ if response.kind_of?(DataMapper::Collection)
35
+ response.each do |x|
36
+ all_values << x
37
+ end
38
+ else
39
+ all_values << response if response
40
+ end
41
+ rescue Exception => e
42
+ #puts e.message
43
+ end
44
+ end
45
+ all_values
46
+ end
47
+
48
+ # Used for executing a query against a single database.
49
+ def individual(repo, &block)
50
+ all_values = []
51
+ begin
52
+ response = DataMapper.repository(repo[0]) {yield}
53
+ if response.kind_of?(DataMapper::Collection)
54
+ response.each do |x|
55
+ all_values << x
56
+ end
57
+ else
58
+ all_values << response if response
59
+ end
60
+ rescue Exception => e
61
+ #puts e.message
62
+ end
63
+ all_values
64
+ end
65
+
66
+ end # class Manage
67
+ end # module Database
68
+ end # module Honeycomb
69
+
70
+
71
+
@@ -0,0 +1 @@
1
+ require 'honeycomb/honeypot/manage'
@@ -0,0 +1,204 @@
1
+ # honeycomb - Tool to manage and analyze data from the Dionaea Honeypot
2
+ # Project
3
+ # Josh Grunzweig
4
+ # Copyright (C) 2011 Trustwave Holdings
5
+ #
6
+ # This program is free software: you can redistribute it and/or modify it
7
+ # under the terms of the GNU General Public License as published by the
8
+ # Free Software Foundation, either version 3 of the License, or (at your
9
+ # option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful, but
12
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
+ # for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License along
17
+ # with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ require 'net/ssh'
21
+ require 'net/scp'
22
+ require 'open3'
23
+
24
+ module Honeycomb
25
+ module Honeypot
26
+ class Manage
27
+
28
+ attr_accessor :db_path, :bin_path, :base_path, :username, :servers, :key
29
+
30
+ # This initializes a Honeycomb::Interact object and sets all the necessary
31
+ # variables which are used by other methods of the object.
32
+ #
33
+ # Variables and their purpose:
34
+ # * db_path - Path where databases are stored/saved
35
+ # * bin_path - Path where binaries are stored/saved
36
+ # * username - Username to connect to remote honeypot servers
37
+ # * key - Path to private key which is used for connections to honeypot
38
+ # servers
39
+ # * servers - Array of servers to connect to
40
+ # * base_path - Base location where Dionaea is installed to (Default per
41
+ # installation instructions: /opt/dionaea)
42
+ def initialize(db_path = nil, bin_path = nil, username = nil, key = nil,
43
+ servers = nil, base_path = nil)
44
+ self.db_path = Honeycomb::Env::CONFIG[:download_databases] ||
45
+ self.db_path = Pathname.new(__FILE__).dirname.dirname.dirname.dirname.expand_path.join('data').join('logsql/').to_s ||
46
+ db_path
47
+ self.bin_path = Honeycomb::Env::CONFIG[:download_binaries] ||
48
+ self.bin_path = Pathname.new(__FILE__).dirname.dirname.dirname.dirname.expand_path.join('data').join('binaries/').to_s ||
49
+ bin_path
50
+ self.username = Honeycomb::Env::CONFIG["honey_config"]["username"] ||
51
+ username
52
+ self.key = Honeycomb::Env::CONFIG["honey_config"]["key"] || key
53
+ self.servers = Honeycomb::Env::CONFIG["honey_config"]["servers"] ||
54
+ servers
55
+ self.base_path = Honeycomb::Env::CONFIG["honey_config"]["path"] ||
56
+ base_path
57
+ end
58
+
59
+ # This method will attempt to download all binaries from all servers
60
+ # specified in Honeycomb::Interact.servers.
61
+ #
62
+ # It will attempt to store all binaries into the folder specified in
63
+ # Honeycomb::Interact.bin_path.
64
+ #
65
+ # Additionally, rsync is utilized to transfer these files. It was
66
+ # chosen to use rsync over scp in order to limit the amount of
67
+ # bandwidth used between the client and servers.
68
+ #
69
+ # Arguments:
70
+ # * server - Array of servers to query
71
+ def download_binaries(server = self.servers)
72
+ server.each do |server|
73
+ tries = 0
74
+ puts "Downloading binaries from #{server} ..."
75
+ begin
76
+ Open3::popen3("rsync -v --force --ignore-errors --times -r -u -e \"ssh -i #{self.key}\" #{self.username}@#{server}:#{self.base_path}/var/dionaea/binaries/ #{self.bin_path}") { |stdin, stdout, stderr|
77
+ puts stdout.read.strip
78
+ puts stderr.read.strip
79
+ }
80
+ rescue
81
+ tries += 1
82
+ retry if tries <= 3
83
+ puts "Unable to connect. Moving on ..."
84
+ next
85
+ end
86
+ end
87
+ end
88
+
89
+ # This method will attempt to download all databases from all servers
90
+ # specified in Honeycomb::Interact.servers.
91
+ #
92
+ # It will attempt to store all binaries into the folder specified in
93
+ # Honeycomb::Interact.db_path.
94
+ #
95
+ # Additionally, scp is utilized to transfer these files. During tests,
96
+ # it was discovered that rsync had less than ideal results when
97
+ # downloading these files. While the transfer would appear to occur
98
+ # without error, the databases were often found to be corrupt.
99
+ #
100
+ # Arguments:
101
+ # * server - Array of servers to query
102
+ def download_databases(server = self.servers)
103
+ server.each do |server|
104
+ tries = 0
105
+ begin
106
+ Net::SSH.start(server, self.username, :keys => self.key) do |session|
107
+ puts "Downloading database from #{server} ..."
108
+ session.scp.download!(base_path + "/var/dionaea/logsql.sqlite",
109
+ self.db_path + "#{server}.sqlite")
110
+ end
111
+ rescue Errno::ETIMEDOUT
112
+ tries += 1
113
+ retry if tries <= 3
114
+ puts "Unable to connect. Moving on ..."
115
+ next
116
+ rescue Exception => e
117
+ puts "Error encountered: #{e.message}"
118
+ next
119
+ end
120
+ end
121
+ end
122
+
123
+ # This method will execute a command via ssh on all servers specified in
124
+ # the Honeycomb::Interact.servers variable. This command calls the internal
125
+ # ssh_command method in order to properly function.
126
+ #
127
+ # Argument:
128
+ # * command - Command to execute
129
+ #
130
+ # Returns:
131
+ # * Nothing
132
+ #
133
+ # Multiple strings with the results are outputted to the screen.
134
+ def execute_command(command)
135
+ response = self.ssh_command(command)
136
+ response.each do |server_hash|
137
+ puts "Executing #{command} on #{server_hash[:server]}:"
138
+ puts "\t#{server_hash[:result].gsub!(/\n/,"\n\t")}"
139
+ end
140
+ end # end execute_command
141
+
142
+ # This method is used internally by the execute_command method.
143
+ # It will take a command as an argument and execute it on ever server
144
+ # that is stored in Honeycomb::Interact.servers. The results are
145
+ # stored in a hash which is returned in an Array.
146
+ #
147
+ # Argument:
148
+ # * command - Command to be executed
149
+ #
150
+ # Returns:
151
+ # * Array of hashes -
152
+ # [{:server => <server_name>, :result => <result_of_command>}]
153
+ def ssh_command(command)
154
+ results = []
155
+ self.servers.each do |server|
156
+ begin
157
+ Net::SSH.start(server, self.username, :keys => self.key) do |session|
158
+ session.exec command do |ch, stream, data|
159
+ if stream == :stderr
160
+ results << {:server => server, :result => "ERROR: #{data}"}
161
+ else
162
+ results << {:server => server, :result => data}
163
+ end
164
+ end
165
+ end
166
+ rescue
167
+ next
168
+ end
169
+ end
170
+ return results
171
+ end
172
+
173
+
174
+
175
+ # This method will query the diskspace on all remote servers by calling
176
+ # the internal ssh_command method. It executes the command 'df -h /' and
177
+ # parses the results. The response is then parsed to return the total
178
+ # percentage of diskspace being used currently on each host.
179
+ #
180
+ # Arguments:
181
+ # * None
182
+ #
183
+ # Returns:
184
+ # * [ {:server => "Server Hostname", :result =>
185
+ #
186
+ # Multiple strings with the results are outputted to the screen.
187
+ def check_diskspace
188
+ response = self.ssh_command("df -h /")
189
+ all_usage = []
190
+ response.each do |server_hash|
191
+ usage = server_hash[:result]
192
+ if usage =~ /^(\/\w+)+.+\S+\s+\S+\s+\S+\s+(([0-9]+)%)/m
193
+ all_usage << {:server => server_hash[:server], :result => $2}
194
+ end
195
+ end
196
+ all_usage
197
+ end # end check_diskspace
198
+
199
+ end # class Manage
200
+ end # module Honeypot
201
+ end # module Honeycom
202
+
203
+
204
+
@@ -64,6 +64,8 @@ module Honeycomb
64
64
  # configuration.
65
65
  def self.setup!(dir = Pathname.new(__FILE__).dirname.dirname.dirname.expand_path.join('data').join('logsql/').to_s)
66
66
  num = 1
67
+ # Don't plan on ever using the default database, but DataMapper complains
68
+ # if you don't specify one. A necessary evil.
67
69
  DataMapper.setup(:default, "sqlite:///#{dir}honeypot.sqlite")
68
70
  self.all_databases.each do |database|
69
71
  DataMapper.setup(num.to_s.to_sym, "sqlite:///#{dir}#{database}")
@@ -0,0 +1,2 @@
1
+ # this is just a helper file for scripts to setup the spookt libpath
2
+ $: << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: honeycomb
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Josh Grunzweig
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-07-01 00:00:00 -05:00
13
+ date: 2011-07-08 00:00:00 -05:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -178,10 +178,13 @@ files:
178
178
  - data/logsql/honeypot.sqlite
179
179
  - etc/config.yml.example
180
180
  - lib/honeycomb.rb
181
+ - lib/honeycomb/database.rb
182
+ - lib/honeycomb/database/interact.rb
181
183
  - lib/honeycomb/default_setup.rb
182
184
  - lib/honeycomb/environment.rb
185
+ - lib/honeycomb/honeypot.rb
186
+ - lib/honeycomb/honeypot/manage.rb
183
187
  - lib/honeycomb/interact.rb
184
- - lib/honeycomb/interact/interact.rb
185
188
  - lib/honeycomb/model.rb
186
189
  - lib/honeycomb/model/connections.rb
187
190
  - lib/honeycomb/model/dcerpcbinds.rb
@@ -199,6 +202,7 @@ files:
199
202
  - lib/honeycomb/model/resolves.rb
200
203
  - lib/honeycomb/model/virustotals.rb
201
204
  - lib/honeycomb/model/virustotalscans.rb
205
+ - scripts/honeycomb_libpath.rb
202
206
  - spec/honeycomb_spec.rb
203
207
  - spec/spec_helper.rb
204
208
  - tasks/irb.rake
@@ -216,7 +220,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
216
220
  requirements:
217
221
  - - ">="
218
222
  - !ruby/object:Gem::Version
219
- hash: 3018595793207636104
223
+ hash: 4172282462216369784
220
224
  segments:
221
225
  - 0
222
226
  version: "0"
@@ -1,392 +0,0 @@
1
- # honeycomb - Tool to manage and analyze data from the Dionaea Honeypot
2
- # Project
3
- # Josh Grunzweig
4
- # Copyright (C) 2011 Trustwave Holdings
5
- #
6
- # This program is free software: you can redistribute it and/or modify it
7
- # under the terms of the GNU General Public License as published by the
8
- # Free Software Foundation, either version 3 of the License, or (at your
9
- # option) any later version.
10
- #
11
- # This program is distributed in the hope that it will be useful, but
12
- # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
- # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
- # for more details.
15
- #
16
- # You should have received a copy of the GNU General Public License along
17
- # with this program. If not, see <http://www.gnu.org/licenses/>.
18
- #
19
-
20
- require 'net/ssh'
21
- require 'net/scp'
22
- require 'open3'
23
-
24
- module Honeycomb
25
-
26
- class Interact
27
-
28
- attr_accessor :db_path, :bin_path, :base_path, :username, :servers, :key
29
-
30
- # This initializes a Honeycomb::Interact object and sets all the necessary
31
- # variables which are used by other methods of the object.
32
- #
33
- # Variables and their purpose:
34
- # * db_path - Path where databases are stored/saved
35
- # * bin_path - Path where binaries are stored/saved
36
- # * username - Username to connect to remote honeypot servers
37
- # * key - Path to private key which is used for connections to honeypot
38
- # servers
39
- # * servers - Array of servers to connect to
40
- # * base_path - Base location where Dionaea is installed to (Default per
41
- # installation instructions: /opt/dionaea)
42
- def initialize(db_path = nil, bin_path = nil, username = nil, key = nil,
43
- servers = nil, base_path = nil)
44
- self.db_path = Honeycomb::Env::CONFIG[:download_databases] ||
45
- self.db_path = Pathname.new(__FILE__).dirname.dirname.dirname.dirname.expand_path.join('data').join('logsql/').to_s ||
46
- db_path
47
- self.bin_path = Honeycomb::Env::CONFIG[:download_binaries] ||
48
- self.bin_path = Pathname.new(__FILE__).dirname.dirname.dirname.dirname.expand_path.join('data').join('binaries/').to_s ||
49
- bin_path
50
- self.username = Honeycomb::Env::CONFIG["honey_config"]["username"] ||
51
- username
52
- self.key = Honeycomb::Env::CONFIG["honey_config"]["key"] || key
53
- self.servers = Honeycomb::Env::CONFIG["honey_config"]["servers"] ||
54
- servers
55
- self.base_path = Honeycomb::Env::CONFIG["honey_config"]["path"] ||
56
- base_path
57
- end
58
-
59
- # This method will attempt to download all binaries from all servers
60
- # specified in Honeycomb::Interact.servers.
61
- #
62
- # It will attempt to store all binaries into the folder specified in
63
- # Honeycomb::Interact.bin_path.
64
- #
65
- # Additionally, rsync is utilized to transfer these files. It was
66
- # chosen to use rsync over scp in order to limit the amount of
67
- # bandwidth used between the client and servers.
68
- #
69
- # Arguments:
70
- # * server - Array of servers to query
71
- def download_binaries(server = self.servers)
72
- server.each do |server|
73
- tries = 0
74
- puts "Downloading binaries from #{server} ..."
75
- begin
76
- Open3::popen3("rsync -v --force --ignore-errors --times -r -u -e \"ssh -i #{self.key}\" #{self.username}@#{server}:#{self.base_path}/var/dionaea/binaries/ #{self.bin_path}") { |stdin, stdout, stderr|
77
- puts stdout.read.strip
78
- puts stderr.read.strip
79
- }
80
- rescue
81
- tries += 1
82
- retry if tries <= 3
83
- puts "Unable to connect. Moving on ..."
84
- next
85
- end
86
- end
87
- end
88
-
89
- # This method will attempt to download all databases from all servers
90
- # specified in Honeycomb::Interact.servers.
91
- #
92
- # It will attempt to store all binaries into the folder specified in
93
- # Honeycomb::Interact.db_path.
94
- #
95
- # Additionally, scp is utilized to transfer these files. During tests,
96
- # it was discovered that rsync had less than ideal results when
97
- # downloading these files. While the transfer would appear to occur
98
- # without error, the databases were often found to be corrupt.
99
- #
100
- # Arguments:
101
- # * server - Array of servers to query
102
- def download_databases(server = self.servers)
103
- server.each do |server|
104
- tries = 0
105
- begin
106
- Net::SSH.start(server, self.username, :keys => self.key) do |session|
107
- puts "Downloading database from #{server} ..."
108
- session.scp.download!(base_path + "/var/dionaea/logsql.sqlite",
109
- self.db_path + "#{server}.sqlite")
110
- end
111
- rescue Errno::ETIMEDOUT
112
- tries += 1
113
- retry if tries <= 3
114
- puts "Unable to connect. Moving on ..."
115
- next
116
- rescue Exception => e
117
- puts "Error encountered: #{e.message}"
118
- next
119
- end
120
- end
121
- end
122
-
123
- # This method will execute a command via ssh on all servers specified in
124
- # the Honeycomb::Interact.servers variable. This command calls the internal
125
- # ssh_command method in order to properly function.
126
- #
127
- # Argument:
128
- # * command - Command to execute
129
- #
130
- # Returns:
131
- # * Nothing
132
- #
133
- # Multiple strings with the results are outputted to the screen.
134
- def execute_command(command)
135
- response = self.ssh_command(command)
136
- response.each do |server_hash|
137
- puts "Executing #{command} on #{server_hash[:server]}:"
138
- puts "\t#{server_hash[:result].gsub!(/\n/,"\n\t")}"
139
- end
140
- end # end execute_command
141
-
142
- # This method will query the diskspace on all remote servers by calling
143
- # the internal ssh_command method. It executes the command 'df -h /' and
144
- # parses the results. The response is then parsed to return the total
145
- # percentage of diskspace being used currently on each host.
146
- #
147
- # Arguments:
148
- # * None
149
- #
150
- # Returns:
151
- # * [ {:server => "Server Hostname", :result =>
152
- #
153
- # Multiple strings with the results are outputted to the screen.
154
- def check_diskspace
155
- response = self.ssh_command("df -h /")
156
- all_usage = []
157
- response.each do |server_hash|
158
- usage = server_hash[:result]
159
- if usage =~ /^(\/\w+)+.+\S+\s+\S+\s+\S+\s+(([0-9]+)%)/m
160
- all_usage << {:server => server_hash[:server], :result => $2}
161
- end
162
- end
163
- all_usage
164
- end # end check_diskspace
165
-
166
- # Only leaving this in here because it does a decent job of showing some
167
- # of the stuff you can do with these DataMapper database bindings.
168
- #
169
- # This method was mainly created to be utilized for another project. It
170
- # takes the md5 as in argument and performs a series of queries against
171
- # all of the database to retrieve a large amount of data about that
172
- # provided binary (in md5 checksum)
173
- #
174
- # Multiple encounters can be returned. These encounters are uniqued based
175
- # on the URL of the download. Additionally, if duplicates of a given url
176
- # are discovered, the encounter with the earliest timestamp is added to
177
- # the hash.
178
- #
179
- # Argument:
180
- # * md5 - MD5 String of the binary to be examined.
181
- #
182
- # Returns:
183
- # * Hash -
184
- # {:md5 => <md5_provided>,
185
- # :encounters = [{ :url => <url_discovered>,
186
- # :original_filename => <md5_provided>,
187
- # :remote_host => <ip_address>,
188
- # :source_timestamp => <Time>,
189
- # :source => "Honeypot - <ip_address>",
190
- # :virustotal => {:url => <url>,
191
- # :timestamp => <timestamp_of_vt_scan>,
192
- # :results => {:scanner => <scanner>,
193
- # :result => <result>}
194
- # }
195
- # }
196
- def self.get_md5_info(md5)
197
- all_encounters = []
198
- all_instances = self.all{Honeycomb::Download.all(:download_md5_hash => md5)}
199
- all_instances.each do |instance|
200
- all_encounters << {:url => instance.download_url}
201
- end
202
- num = 0
203
- all_encounters.uniq! {|e| e[:url] }
204
- all_encounters.each do |url|
205
- all_connections = self.all{Honeycomb::Download.all(:download_md5_hash => md5,
206
- :download_url => url[:url]).connections}
207
- connection = {}
208
- all_connections.each do |conn|
209
- if not connection[:source_timestamp].nil?
210
- if Time.at(connection[:source_timestamp]) > Time.at(conn.connection_timestamp.to_i)
211
- connection[:source_timestamp] = Time.at(conn.connection_timestamp.to_i)
212
- connection[:remote_host] = conn.remote_host
213
- connection[:source] = conn.local_host
214
- end
215
- else
216
- connection[:source_timestamp] = Time.at(conn.connection_timestamp.to_i)
217
- connection[:remote_host] = conn.remote_host
218
- connection[:source] = conn.local_host
219
- end
220
- end
221
- all_encounters[num][:original_filename] = md5
222
- all_encounters[num][:remote_host] = connection[:remote_host]
223
- all_encounters[num][:source_timestamp] = connection[:source_timestamp]
224
- all_encounters[num][:source] = "Honeypot - #{connection[:source]}"
225
- virustotal_links = self.all{Honeycomb::Virustotal.first(:virustotal_md5_hash => md5).virustotal_permalink}
226
- virustotal_timestamp = self.all{Honeycomb::Virustotal.first(:virustotal_md5_hash => md5).virustotal_timestamp}
227
- virustotal_results = {}
228
- self.all{Honeycomb::Virustotal.first(:virustotal_md5_hash => md5).virustotalscans}.each do |vtscan|
229
- virustotal_results[:scanner] = vtscan.virustotalscan_scanner
230
- virustotal_results[:result] = vtscan.virustotalscan_result
231
- end
232
- all_encounters[num][:virustotal] = {:url => virustotal_links,
233
- :timestamp => virustotal_timestamp, :results => virustotal_results} if virustotal_links
234
- num += 1
235
- end
236
- return {:md5 => md5, :encounters => all_encounters}
237
- end
238
-
239
-
240
-
241
- # This method will call the get_md5_info method on all binaries located
242
- # in the provided directory. This information is then outputted to screen
243
- # (soon to be changed).
244
- #
245
- # Again, only leaving this in here because it does a decent job of showing
246
- # the kind of information you can pull.
247
- #
248
- # Argument:
249
- # * dif - Directory of binaries
250
- #
251
- # Retruns:
252
- # * Nothing
253
- #
254
- # Multiple items are outputted to the screen.
255
- def self.get_all_md5_info(dir = Pathname.new(__FILE__).dirname.dirname.dirname.dirname.expand_path.join('data').join('binaries/').to_s)
256
- results = []
257
- all_binaries = Dir.entries(dir)
258
- all_binaries.each do |bin|
259
- if bin =~ /\w{32}/
260
- require 'pp'
261
- pp self.get_md5_info(bin)
262
- end
263
- end
264
- end
265
-
266
- # Used for executing a query against all databases at once.
267
- def all(&block)
268
- all_values = []
269
- ::DataMapper::Repository.adapters.each do |repo|
270
- if repo[0] == :default
271
- next
272
- end
273
- begin
274
- response = DataMapper.repository(repo[0]) {yield}
275
- if response.kind_of?(DataMapper::Collection)
276
- response.each do |x|
277
- all_values << x
278
- end
279
- else
280
- all_values << response if response
281
- end
282
- rescue Exception => e
283
- #puts e.message
284
- end
285
- end
286
- all_values
287
- end
288
-
289
- # Used for executing a query against a single database.
290
- def individual(repo, &block)
291
- all_values = []
292
- begin
293
- response = DataMapper.repository(repo[0]) {yield}
294
- if response.kind_of?(DataMapper::Collection)
295
- response.each do |x|
296
- all_values << x
297
- end
298
- else
299
- all_values << response if response
300
- end
301
- rescue Exception => e
302
- #puts e.message
303
- end
304
- all_values
305
- end
306
-
307
- # This method was created mainly for my own benefit, but I figured I'd
308
- # leave it in here in case anyone else would like to use it. Was doing
309
- # some statistics for a co-worker who was looking for information about
310
- # the IP addresses which has connected to my honeypots.
311
- #
312
- # It's a little clunky right now, and I ended up just performing actual
313
- # SQL queries due to memory issues (Some of my databases are over 10 gigs
314
- # in size). It will write a list of IP addresses and the number of times
315
- # encountered to the following log file:
316
- #
317
- # ip_reputation.txt
318
- #
319
- # The format of the data is:
320
- #
321
- # <ip_address>,<count>
322
- #
323
- # In order from most encountered to least encountered. I also ignore
324
- # people that have connected to these honeypots less than 200 times.
325
- #
326
- def self.ip_reputation_rule
327
- all_connections_hash = {}
328
-
329
- ::DataMapper::Repository.adapters.each do |repo|
330
- if repo[0] == :default
331
- next
332
- end
333
- response = repo[1].select("SELECT COUNT(remote_host), remote_host FROM connections WHERE connection_type = \"accept\" GROUP BY remote_host ORDER BY COUNT(remote_host)")
334
- response.each do |struct|
335
- ip = struct.to_a[1]
336
- count = struct.to_a[0]
337
- if all_connections_hash[ip]
338
- all_connections_hash[ip] = all_connections_hash[ip].to_i +
339
- count.to_i
340
- else
341
- all_connections_hash[ip] = count.to_i
342
- end
343
- end
344
- end
345
- all_connections_hash = all_connections_hash.sort_by { |k,v| -1*v }
346
- File.open("ip_reputation.txt", 'w') do |f|
347
- all_connections_hash.each do |ip,count|
348
- if count > 200
349
- f.write("#{ip},#{count}\n")
350
- end
351
- end
352
- end
353
- end
354
-
355
- # This method is used internally by the execute_command method.
356
- # It will take a command as an argument and execute it on ever server
357
- # that is stored in Honeycomb::Interact.servers. The results are
358
- # stored in a hash which is returned in an Array.
359
- #
360
- # Argument:
361
- # * command - Command to be executed
362
- #
363
- # Returns:
364
- # * Array of hashes -
365
- # [{:server => <server_name>, :result => <result_of_command>}]
366
- def ssh_command(command)
367
- results = []
368
- self.servers.each do |server|
369
- begin
370
- Net::SSH.start(server, self.username, :keys => self.key) do |session|
371
- session.exec command do |ch, stream, data|
372
- if stream == :stderr
373
- results << {:server => server, :result => "ERROR: #{data}"}
374
- else
375
- results << {:server => server, :result => data}
376
- end
377
- end
378
- end
379
- rescue
380
- next
381
- end
382
- end
383
- return results
384
- end
385
-
386
-
387
- end # end Interact
388
-
389
- end # end Honeycomb
390
-
391
-
392
-