dvash 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/dvash CHANGED
@@ -1,6 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require 'bundler/setup'
4
2
  require 'dvash'
5
3
 
6
4
  Dvash.start
@@ -1,34 +1,23 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  Gem::Specification.new do |s|
4
+ # Variables:
4
5
  s.name = "dvash"
5
- s.version = "0.1.0"
6
-
7
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["Ari Mizrahi"]
9
- s.date = "2013-05-02"
6
+ s.version = "0.1.1"
7
+ s.authors = "Ari Mizrahi"
8
+ s.date = "2013-07-21"
10
9
  s.description = "Part honeypot, part defense system. Opens up ports and simulates services in order to look like an attractive target. Hosts that try to connect to the fake services are considered attackers and blocked from all access."
10
+ s.summary = "Honeypot defense system"
11
11
  s.email = "codemunchies@gmail.com"
12
- s.executables = ["dvash"]
13
- s.files = ["etc/dvash-baseline.conf", "lib/dvash/honeyports/ipv4/http.rb", "lib/dvash/honeyports/ipv4/rdp.rb", "lib/dvash/honeyports/ipv4/ssh.rb", "lib/dvash/honeyports/ipv4/telnet.rb", "lib/dvash/honeyports/ipv6/http.rb", "lib/dvash/honeyports/ipv6/rdp.rb", "lib/dvash/honeyports/ipv6/ssh.rb", "lib/dvash/os/linux.rb", "lib/dvash/os/mac.rb", "lib/dvash/os/windows.rb", "lib/dvash/application.rb", "lib/dvash/core.rb", "lib/dvash.rb", "dvash.gemspec", "Gemfile", "README.md"]
14
12
  s.homepage = "http://github.com/codemunchies/dvash"
15
- s.require_paths = ["lib"]
16
- s.rubygems_version = "1.8.25"
17
- s.summary = "Honeypot defense system"
18
13
  s.license = "GPL-3"
19
14
 
20
- if s.respond_to? :specification_version then
21
- s.specification_version = 3
15
+ # Pragmatically Gathered
16
+ s.executables = "dvash"
17
+ s.files = Dir["{lib,bin}/**/*"]
18
+ s.files += [File.basename(__FILE__), "Gemfile", "README.md", "LICENSE"]
19
+ s.require_paths = ["lib"]
22
20
 
23
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
24
- s.add_runtime_dependency(%q<parseconfig>, ["~> 1.0"])
25
- s.add_runtime_dependency(%q<bundler>, ["~> 1.3"])
26
- else
27
- s.add_dependency(%q<parseconfig>, ["~> 1.0"])
28
- s.add_dependency(%q<bundler>, ["~> 1.3"])
29
- end
30
- else
31
- s.add_dependency(%q<parseconfig>, ["~> 1.0"])
32
- s.add_dependency(%q<bundler>, ["~> 1.3"])
33
- end
21
+ # Dependencies
22
+ s.add_dependency("parseconfig", "~> 1.0")
34
23
  end
@@ -1,5 +1,4 @@
1
1
  require 'dvash/application'
2
-
3
2
  require 'optparse'
4
3
 
5
4
  #
@@ -20,48 +19,40 @@ require 'optparse'
20
19
  #
21
20
 
22
21
  module Dvash
23
-
22
+ # Start the CLI and instantiate [Dvash]
23
+ # @params [Hash] instantiate paths to set default config values
24
24
  def self.start(paths={})
25
25
 
26
- #
27
26
  # Set default path to config and log files
28
- # TODO: These settings assume Linux default paths, should determine the operating system then configure accordingly
29
- #
27
+ # TODO: These settings assume Linux default paths, it should determine the
28
+ # operating system then configure accordingly
30
29
  paths[:config_path] = '/etc/dvash.conf'
31
30
  paths[:log_path] = '/var/log/dvash.conf'
32
31
 
33
- #
34
- # A command-line interface using OptionParser
35
- #
32
+ # Command-line interface
36
33
  OptionParser.new do |opts|
37
- opts.banner = "Dvash 0.1.0 ( http://www.github.com/codemunchies/dvash )\n"
34
+ # Banner information
35
+ opts.banner = "Dvash 0.1.1 ( http://www.github.com/codemunchies/dvash )\n"
38
36
  opts.banner += "Usage: dvash [options]"
39
- #
40
- # Option to set an alternate configuration file
41
- #
37
+ # Set an alternate configuration file
42
38
  opts.on("--config-file [PATH]", "Set path to config file") do |arg|
43
39
  paths[:config_path] = arg
44
40
  end
45
- #
46
- # Option to set an alternate log file destination and filename
47
- #
41
+ # Set an alternate log file destination and filename
48
42
  opts.on("--log-file [PATH]", "Set path to log file") do |arg|
49
43
  paths[:log_path] = arg
50
44
  end
51
45
  end.parse!
52
46
 
53
- #
54
- # Create and start an Application instance
55
- #
47
+ # Create and start an application instance on Dvash
48
+ # @return [Dvash] application instance
56
49
  begin
57
50
  application = Dvash::Application.new(paths)
58
51
  application.start
59
52
  rescue
60
- # TODO: Use 'logger' gem to output debug information
53
+ # TODO: Use [logger] gem to output debug information
61
54
  puts "couldn't start application"
62
55
  exit
63
56
  end
64
-
65
-
66
57
  end
67
58
  end
@@ -1,57 +1,40 @@
1
1
  require 'dvash/core'
2
-
3
2
  require 'parseconfig'
4
3
 
5
4
  module Dvash
5
+ #
6
+ # Main application methods, the glue that holds it all together
7
+ #
8
+ class Application < Core
6
9
 
7
- class Application < Core
8
-
9
- #
10
- # Methods that should run when the Dvash Application object is created
11
- # Requires one argument of type Array including paths to configuration
12
- # file and destination for log file
13
- #
14
- def initialize(paths)
15
- #
16
- # Create @honey_threads Array to hold all 'honeyport' threads
17
- #
18
- @honey_threads = Array.new
19
- #
20
- # Load passed Array paths into @paths for use in the class
21
- #
22
- @paths = paths
23
- #
24
- # Call method to load the configuration file
25
- #
26
- load_conf
27
- #
28
- # Call method to validate the operating system and load necessary Dvash methods
29
- #
30
- validate_os
31
- end
32
-
33
- #
34
- # Fire in the hole!
35
- #
36
- def start
37
- #
38
- # Make sure we are running with elevated privileges
39
- #
40
- unless valid_user?
41
- # TODO: Use 'logger' gem to output debug information
42
- puts "invalid user"
43
- exit
44
- end
10
+ # Methods that should run when [Dvash] is created
11
+ # @params [Hash] includes paths to config and log file
12
+ def initialize(paths)
13
+ # Instantiate @honey_threads [Array] to hold all honeyport threads
14
+ @honey_threads = Array.new
15
+ # Load passed [paths]
16
+ @paths = paths
17
+ # Load the configuration file
18
+ load_conf
19
+ # Validate the operating system and load necessary [Dvash] methods
20
+ validate_os
21
+ end
45
22
 
46
- #
47
- # Call method to load all 'honeyports' set as 'true' in the configuration file
48
- #
49
- load_honeyport
50
- #
51
- # Start all loaded threads
52
- #
53
- @honey_threads.each { |thr| thr.join }
54
- end
23
+ # Fire in the hole!
24
+ def start
25
+ # Make sure we are running with elevated privileges
26
+ unless valid_user?
27
+ # TODO: Use [logger] gem to output debug information
28
+ puts "invalid user"
29
+ exit
30
+ end
31
+ # Load all honeyports set true in the configuration file
32
+ load_honeyport
33
+ # Let the user know we're running
34
+ puts "Dvash is running..."
35
+ # Start all loaded threads
36
+ @honey_threads.each { |thr| thr.join }
37
+ end
55
38
 
56
- end
39
+ end
57
40
  end
@@ -2,128 +2,108 @@ require 'ipaddr'
2
2
  require 'securerandom'
3
3
 
4
4
  module Dvash
5
+ #
6
+ # Core class contains methods all other classes depend on to function properly.
7
+ #
8
+ class Core
5
9
 
6
- class Core
10
+ # Validates user
11
+ # We must be root to create entries in the firewall
12
+ # @return [Boolean] true|false
13
+ def valid_user?
14
+ Process.uid == 0
15
+ end
7
16
 
8
- #
9
- # Validates user, must be root
10
- #
11
- def valid_user?
12
- Process.uid == 0
13
- end
17
+ # Validates an IP address
18
+ # IP Address should be valid IPv4 or IPv6 addresses
19
+ # @return [Boolean] true|false
20
+ def valid_ip?(address)
21
+ begin
22
+ IPAddr.new("#{address}")
23
+ true
24
+ rescue
25
+ false
26
+ end
27
+ end
14
28
 
15
- #
16
- # Validates an IP address, must be valid IPv4 or IPv6 address
17
- #
18
- def valid_ip?(address)
19
- begin
20
- IPAddr.new("#{address}")
21
- true
22
- rescue
23
- false
24
- end
25
- end
29
+ # Validates the operating system
30
+ # OS must be Windows 7+, OS X, or Linux
31
+ # Creates a new instance of the operating system specific Dvash libraries
32
+ # required to block IP addresses properly, @@os is used as a class variable
33
+ # to call its methods from within a Honeyport
34
+ def validate_os
35
+ # Rubygems platform data
36
+ system = RUBY_PLATFORM
37
+ # Use regular expressions to determine operating system
38
+ case system
39
+ # WINDOWS
40
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
41
+ # Create Dvash Windows object for use within 'honeyports' modules
42
+ require 'dvash/os/windows'
43
+ @@os = Dvash::Windows.new
44
+ # MAC OS X
45
+ when /darwin|mac os/
46
+ # Create Dvash Mac OS X object for use within 'honeyports' modules
47
+ require 'dvash/os/mac'
48
+ @@os = Dvash::Mac.new
49
+ # LINUX
50
+ when /linux/
51
+ # Create Dvash Linux object for use within 'honeyports' modules
52
+ require 'dvash/os/linux'
53
+ @@os = Dvash::Linux.new
54
+ # BSD
55
+ when /solaris|bsd/
56
+ # TODO: BSD support
57
+ exit
58
+ else
59
+ # TODO: Use [logger] gem to output debug information
60
+ puts "invalid operating system"
61
+ exit
62
+ end
63
+ end
26
64
 
27
- #
28
- # Validates the operating system, must be windows, os x, or linux
29
- # Creates a new instance the operating system specific Dvash libraries required to block IP addresses properly
30
- # @@os is used as a class variable to call its methods from within a Honeyport
31
- #
32
- def validate_os
33
- #
34
- # Store rubygems platform data
35
- #
36
- system = RUBY_PLATFORM
37
- #
38
- # Use regular expressions to determine operating system
39
- #
40
- case system
41
- # WINDOWS
42
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
43
- #
44
- # Create Dvash Windows object for use within 'honeyports' modules
45
- #
46
- require 'dvash/os/windows'
47
- @@os = Dvash::Windows.new
48
- # MAC OS X
49
- when /darwin|mac os/
50
- #
51
- # Create Dvash Mac OS X object for use within 'honeyports' modules
52
- #
53
- require 'dvash/os/mac'
54
- @@os = Dvash::Mac.new
55
- # LINUX
56
- when /linux/
57
- #
58
- # Create Dvash Linux object for use within 'honeyports' modules
59
- #
60
- require 'dvash/os/linux'
61
- @@os = Dvash::Linux.new
62
- # BSD
63
- when /solaris|bsd/
64
- # TODO: BSD support
65
- exit
66
- else
67
- # TODO: Use 'logger' gem to output debug information
68
- puts "invalid operating system"
69
- exit
70
- end
71
- end
65
+ # Loads the configuration file using [ParseConfig]
66
+ def load_conf
67
+ begin
68
+ @@cfgfile = ParseConfig.new(@paths[:config_path])
69
+ rescue
70
+ # TODO: Use 'logger' gem to output debug information
71
+ puts "invalid configuration file"
72
+ exit
73
+ end
74
+ end
72
75
 
73
- #
74
- # Loads the configuration file using ParseConfig
75
- #
76
- def load_conf
77
- begin
78
- @@cfgfile = ParseConfig.new(@paths[:config_path])
79
- rescue
80
- # TODO: Use 'logger' gem to output debug information
81
- puts "invalid configuration file"
82
- exit
83
- end
84
- end
76
+ # Load all Honeyports set true in the configuration file
77
+ def load_honeyport
78
+ # Read honeyports group in configuration file, parse keys and values
79
+ @@cfgfile['honeyports'].each do |key, value|
80
+ if value == 'true' then
81
+ ipver, proto = key.split("_")
82
+ # Load methods for all honeyports set true
83
+ begin
84
+ require "dvash/honeyports/#{ipver}/#{proto}"
85
+ rescue
86
+ # TODO: Use [logger] gem to output debug information
87
+ puts "couldn't load dvash/honeyports/#{ipver}/#{proto}"
88
+ exit
89
+ end
90
+ # Push the loaded honeyport into a thread
91
+ @honey_threads << Thread.new { Dvash::Honeyport.new.send(key) }
92
+ end
93
+ end
94
+ end
85
95
 
86
- #
87
- # Load all Honeyports set 'true' in the configuration file
88
- #
89
- def load_honeyport
90
- #
91
- # Read 'honeyports' group in configuration file, parse keys and values
92
- #
93
- @@cfgfile['honeyports'].each do |key, value|
94
- if value == 'true' then
95
- ipver, proto = key.split("_")
96
- #
97
- # Load methods for all 'honeyports' set to 'true'
98
- #
99
- begin
100
- require "dvash/honeyports/#{ipver}/#{proto}"
101
- rescue
102
- # TODO: Use 'logger' gem to output debug information
103
- puts "couldn't load dvash/honeyports/#{ipver}/#{proto}"
104
- exit
105
- end
106
- #
107
- # Push the loaded 'honeyport' into a thread
108
- #
109
- @honey_threads << Thread.new { Dvash::Honeyport.new.send(key) }
110
- end
111
- end
112
- end
96
+ # Generate a random string 64 bytes long
97
+ # @return [String] random bytes
98
+ def random_data
99
+ SecureRandom.random_bytes(64)
100
+ end
113
101
 
114
- #
115
- # Return a string of random characters 64 bytes long
116
- #
117
- def random_data
118
- SecureRandom.random_bytes(64)
119
- end
102
+ # Client source IP address in a [TCPServer]
103
+ # @return [String] client IP
104
+ def client_ip(client)
105
+ client.peeraddr[3]
106
+ end
120
107
 
121
- #
122
- # Return the client source IP address from a TCPServer object
123
- #
124
- def client_ip(client)
125
- client.peeraddr[3]
126
- end
127
-
128
- end
108
+ end
129
109
  end
@@ -9,43 +9,32 @@
9
9
  #
10
10
  ###############################################################################
11
11
  module Dvash
12
+ #
13
+ # Main Honeyport class to simulate daemons
14
+ #
15
+ class Honeyport < Core
12
16
 
13
- class Honeyport < Core
17
+ def ipv4_http
18
+ # IPv4 TCPServer object
19
+ # @return [TCPServer] tcp/80 HTTPd
20
+ server = TCPServer.new(80)
21
+ # Infinite listening loop
22
+ loop do
23
+ # Fork a new instance of [TCPServer] when a client connects
24
+ Thread.fork(server.accept) do |client|
25
+ # Validate client has a valid IP address
26
+ # @return [Boolean] true|false
27
+ if valid_ip?(client_ip(client)) then
28
+ # Send the connected client junk data
29
+ client.puts(random_data)
30
+ # Block the IP address
31
+ @@os.block_ip(client_ip(client))
32
+ end
33
+ # Close the connection to the client and kill the forked process
34
+ client.close
35
+ end
36
+ end
37
+ end
14
38
 
15
- def ipv4_http
16
- #
17
- # Create a new IPv4 TCPServer object
18
- #
19
- server = TCPServer.new(80)
20
- #
21
- # Infinite loop listens on port 80 pretending to be an HTTP server
22
- #
23
- loop do
24
- #
25
- # Fork a new instance of the TCPServer object when a client connects
26
- # TODO: Maybe we should not send junk data until after the client IP has been validated
27
- #
28
- Thread.fork(server.accept) do |client|
29
- #
30
- # Send the connected client junk data
31
- #
32
- client.puts(random_data)
33
- #
34
- # Make sure the client has a valid IP address
35
- #
36
- if valid_ip?(client_ip(client)) then
37
- #
38
- # Block the IP address
39
- #
40
- @@os.block_ip(client_ip(client))
41
- end
42
- #
43
- # Close the connection to the client and kill the forked process
44
- #
45
- client.close
46
- end
47
- end
48
- end
49
-
50
- end
39
+ end
51
40
  end