CloudyScripts 1.6.1 → 1.7.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. data/Rakefile +1 -1
  2. data/lib/audit/checks/APACHE2.group +6 -0
  3. data/lib/audit/checks/APACHE2_CONFIG_01.check +36 -0
  4. data/lib/audit/checks/APACHE2_CONFIG_02.check +34 -0
  5. data/lib/audit/checks/APACHE2_CONFIG_03.check +60 -0
  6. data/lib/audit/checks/APACHE2_CONFIG_04.check +23 -0
  7. data/lib/audit/checks/APACHE2_CONFIG_05.check +23 -0
  8. data/lib/audit/checks/APACHE2_CONFIG_06.check +30 -0
  9. data/lib/audit/checks/APACHE2_INIT_1.check +14 -0
  10. data/lib/audit/checks/APACHE2_INIT_2.check +66 -0
  11. data/lib/audit/checks/APACHE2_INIT_3.check +13 -0
  12. data/lib/audit/checks/APACHE2_USER_7.check +17 -0
  13. data/lib/audit/checks/BACKUP_HOME_DOTFILES.check +26 -0
  14. data/lib/audit/checks/BACKUP_LOG.check +24 -0
  15. data/lib/audit/checks/BACKUP_MAIL.check +19 -0
  16. data/lib/audit/checks/BACKUP_WEB.check +12 -0
  17. data/lib/audit/checks/CONFIGURATION_BACKUP.check +14 -0
  18. data/lib/audit/checks/DIRECTORY_LISTING.check +14 -0
  19. data/lib/audit/checks/DISTRIBUTION_FACTS.check +60 -0
  20. data/lib/audit/checks/DMESG_OUTPUT.check +14 -0
  21. data/lib/audit/checks/FIND_GROUP_FILE.check +6 -0
  22. data/lib/audit/checks/FIND_PASSWD_FILE.check +8 -0
  23. data/lib/audit/checks/FIND_SHADOW_FILE.check +5 -0
  24. data/lib/audit/checks/FIND_SUDOERS_FILE.check +6 -0
  25. data/lib/audit/checks/FREE_SPACE.check +26 -0
  26. data/lib/audit/checks/HAS_AWK.check +30 -0
  27. data/lib/audit/checks/HAS_BASE.check +21 -0
  28. data/lib/audit/checks/HAS_CAT.check +18 -0
  29. data/lib/audit/checks/HAS_COMPRESSOR.check +30 -0
  30. data/lib/audit/checks/HAS_CUT.check +18 -0
  31. data/lib/audit/checks/HAS_DF.check +19 -0
  32. data/lib/audit/checks/HAS_DPKG.check +18 -0
  33. data/lib/audit/checks/HAS_FILE_DOWNLOADER.check +32 -0
  34. data/lib/audit/checks/HAS_FIND.check +18 -0
  35. data/lib/audit/checks/HAS_GREP.check +19 -0
  36. data/lib/audit/checks/HAS_GROUPCHECK.check +23 -0
  37. data/lib/audit/checks/HAS_GROUPS.check +19 -0
  38. data/lib/audit/checks/HAS_HOSTNAME.check +7 -0
  39. data/lib/audit/checks/HAS_ID.check +7 -0
  40. data/lib/audit/checks/HAS_LSB_RELEASE.check +16 -0
  41. data/lib/audit/checks/HAS_MOUNT.check +19 -0
  42. data/lib/audit/checks/HAS_NETSTAT.check +20 -0
  43. data/lib/audit/checks/HAS_PASSWD_CHECK.check +17 -0
  44. data/lib/audit/checks/HAS_PS.check +19 -0
  45. data/lib/audit/checks/HAS_ROUTE.check +19 -0
  46. data/lib/audit/checks/HAS_SH.check +19 -0
  47. data/lib/audit/checks/HAS_SORT.check +17 -0
  48. data/lib/audit/checks/HAS_STAT.check +17 -0
  49. data/lib/audit/checks/HAS_SUPERUSER.check +11 -0
  50. data/lib/audit/checks/HAS_TAIL.check +16 -0
  51. data/lib/audit/checks/HAS_TAR.check +7 -0
  52. data/lib/audit/checks/HAS_TR.check +22 -0
  53. data/lib/audit/checks/HAS_UNAME.check +7 -0
  54. data/lib/audit/checks/HAS_UNIQ.check +17 -0
  55. data/lib/audit/checks/HAS_WC.check +16 -0
  56. data/lib/audit/checks/HAS_WHO.check +18 -0
  57. data/lib/audit/checks/HAS_YUM.check +18 -0
  58. data/lib/audit/checks/LASTLOG.check +28 -0
  59. data/lib/audit/checks/LIST_ROUTES.check +33 -0
  60. data/lib/audit/checks/LIST_USER_ACCOUNTS.check +25 -0
  61. data/lib/audit/checks/LOADED_MODULES.check +22 -0
  62. data/lib/audit/checks/LOCAL_NMAP.check +97 -0
  63. data/lib/audit/checks/LOGGED_USERS.check +28 -0
  64. data/lib/audit/checks/LYNIS_AUTH.group +9 -0
  65. data/lib/audit/checks/LYNIS_AUTH_9204.check +43 -0
  66. data/lib/audit/checks/LYNIS_AUTH_9208.check +35 -0
  67. data/lib/audit/checks/LYNIS_AUTH_9216.check +24 -0
  68. data/lib/audit/checks/LYNIS_AUTH_9222.check +25 -0
  69. data/lib/audit/checks/LYNIS_AUTH_9226.check +24 -0
  70. data/lib/audit/checks/LYNIS_AUTH_9228.check +24 -0
  71. data/lib/audit/checks/LYNIS_AUTH_9252.check +19 -0
  72. data/lib/audit/checks/MAYBE_HAS_BZIP2.check +17 -0
  73. data/lib/audit/checks/MAYBE_HAS_CURL.check +17 -0
  74. data/lib/audit/checks/MAYBE_HAS_DU.check +17 -0
  75. data/lib/audit/checks/MAYBE_HAS_HOSTNAME.check +17 -0
  76. data/lib/audit/checks/MAYBE_HAS_ID.check +17 -0
  77. data/lib/audit/checks/MAYBE_HAS_LSB_RELEASE.check +15 -0
  78. data/lib/audit/checks/MAYBE_HAS_SUPERUSER.check +36 -0
  79. data/lib/audit/checks/MAYBE_HAS_TAR.check +19 -0
  80. data/lib/audit/checks/MAYBE_HAS_UNAME.check +17 -0
  81. data/lib/audit/checks/MAYBE_HAS_WGET.check +17 -0
  82. data/lib/audit/checks/MOUNTED_DEVICES.check +22 -0
  83. data/lib/audit/checks/MYSQL_HISTORY_1.check +29 -0
  84. data/lib/audit/checks/MYSQL_INIT_1.check +9 -0
  85. data/lib/audit/checks/MYSQL_INIT_2.check +12 -0
  86. data/lib/audit/checks/MYSQL_INIT_3.check +7 -0
  87. data/lib/audit/checks/PACKAGES_INSTALLED_DPKG.check +38 -0
  88. data/lib/audit/checks/PACKAGES_INSTALLED_YUM.check +36 -0
  89. data/lib/audit/checks/PASSWORD_INFORMATION.check +33 -0
  90. data/lib/audit/checks/PLATFORM_FACTS.check +35 -0
  91. data/lib/audit/checks/PORTS_OPEN_NETSTAT.check +121 -0
  92. data/lib/audit/checks/PROCESS_LIST.check +87 -0
  93. data/lib/audit/checks/SLOW.group +7 -0
  94. data/lib/audit/checks/SLOW_1.check +4 -0
  95. data/lib/audit/checks/SLOW_2.check +4 -0
  96. data/lib/audit/checks/SLOW_3.check +4 -0
  97. data/lib/audit/checks/SSH.group +14 -0
  98. data/lib/audit/checks/SSH_CONFIG_01.check +12 -0
  99. data/lib/audit/checks/SSH_CONFIG_02.check +15 -0
  100. data/lib/audit/checks/SSH_CONFIG_03.check +13 -0
  101. data/lib/audit/checks/SSH_CONFIG_04.check +11 -0
  102. data/lib/audit/checks/SSH_CONFIG_05.check +12 -0
  103. data/lib/audit/checks/SSH_CONFIG_06.check +12 -0
  104. data/lib/audit/checks/SSH_CONFIG_07.check +11 -0
  105. data/lib/audit/checks/SSH_CONFIG_08.check +12 -0
  106. data/lib/audit/checks/SSH_CONFIG_09.check +12 -0
  107. data/lib/audit/checks/SSH_CONFIG_10.check +15 -0
  108. data/lib/audit/checks/SSH_CONFIG_11.check +14 -0
  109. data/lib/audit/checks/SSH_INIT_1.check +9 -0
  110. data/lib/audit/checks/SSH_INIT_2.check +12 -0
  111. data/lib/audit/checks/SSH_KEYS_1.check +32 -0
  112. data/lib/audit/checks/USERS_INIT_1.check +9 -0
  113. data/lib/audit/checks/USERS_INIT_2.check +5 -0
  114. data/lib/audit/checks/USERS_INIT_3.check +5 -0
  115. data/lib/audit/checks/USERS_INIT_4.check +9 -0
  116. data/lib/audit/checks/USERS_INIT_5.check +10 -0
  117. data/lib/audit/checks/USER_INFORMATION.check +29 -0
  118. data/lib/audit/checks/VARIOUS.group +19 -0
  119. data/lib/audit/checks/VAR_LIST_HOME_DIRECTORIES.check +5 -0
  120. data/lib/audit/checks/benchmark.group +6 -0
  121. data/lib/audit/checks/footer.template +12 -0
  122. data/lib/audit/checks/header.template +10 -0
  123. data/lib/audit/checks/helpers/head.sh +59 -0
  124. data/lib/audit/checks/script_header.template +69 -0
  125. data/lib/audit/create_benchmark.sh +93 -0
  126. data/lib/audit/lib/audit.rb +136 -0
  127. data/lib/audit/lib/audit_facade.rb +5 -0
  128. data/lib/audit/lib/benchmark/audit_benchmark.rb +165 -0
  129. data/lib/audit/lib/benchmark/automatic_dependencies.rb +13 -0
  130. data/lib/audit/lib/benchmark/benchmark_factory.rb +23 -0
  131. data/lib/audit/lib/benchmark/benchmark_result.rb +25 -0
  132. data/lib/audit/lib/benchmark/check.rb +34 -0
  133. data/lib/audit/lib/benchmark/group.rb +30 -0
  134. data/lib/audit/lib/benchmark/item_exception.rb +13 -0
  135. data/lib/audit/lib/benchmark/result_code.rb +11 -0
  136. data/lib/audit/lib/benchmark/rule_result.rb +42 -0
  137. data/lib/audit/lib/benchmark/rule_role.rb +5 -0
  138. data/lib/audit/lib/benchmark/rule_severity.rb +13 -0
  139. data/lib/audit/lib/benchmark/yaml_benchmark.rb +133 -0
  140. data/lib/audit/lib/connection/ami_connection.rb +4 -0
  141. data/lib/audit/lib/connection/connection_factory.rb +27 -0
  142. data/lib/audit/lib/connection/ssh_connection.rb +243 -0
  143. data/lib/audit/lib/ec2_utils.rb +245 -0
  144. data/lib/audit/lib/http_fingerprint.rb +116 -0
  145. data/lib/audit/lib/lazy.rb +37 -0
  146. data/lib/audit/lib/linear_script_generator.rb +31 -0
  147. data/lib/audit/lib/main.rb +13 -0
  148. data/lib/audit/lib/my_option_parser.rb +106 -0
  149. data/lib/audit/lib/nessus_new.rb +290 -0
  150. data/lib/audit/lib/nessus_utils.rb +102 -0
  151. data/lib/audit/lib/parser/command/abstract_command.rb +32 -0
  152. data/lib/audit/lib/parser/command/abstract_command_result.rb +30 -0
  153. data/lib/audit/lib/parser/command/attach_file_command.rb +63 -0
  154. data/lib/audit/lib/parser/command/check_finished_command.rb +45 -0
  155. data/lib/audit/lib/parser/command/cpe_name_command.rb +37 -0
  156. data/lib/audit/lib/parser/command/data_command.rb +43 -0
  157. data/lib/audit/lib/parser/command/listening_port_command.rb +46 -0
  158. data/lib/audit/lib/parser/command/message_command.rb +21 -0
  159. data/lib/audit/lib/parser/command/program_name_command.rb +42 -0
  160. data/lib/audit/lib/parser/parse_exception.rb +2 -0
  161. data/lib/audit/lib/parser/result_type.rb +13 -0
  162. data/lib/audit/lib/parser/script_output_parser.rb +201 -0
  163. data/lib/audit/lib/parser/stdout_line_buffer.rb +43 -0
  164. data/lib/audit/lib/ssh_fingerprint.rb +220 -0
  165. data/lib/audit/lib/ssh_fingerprint2.rb +170 -0
  166. data/lib/audit/lib/ssh_utils.rb +292 -0
  167. data/lib/audit/lib/transformers/web_view_transformer.rb +171 -0
  168. data/lib/audit/lib/transformers/yaml_transformer.rb +50 -0
  169. data/lib/audit/lib/util/random_string.rb +22 -0
  170. data/lib/audit/lib/version.rb +7 -0
  171. data/lib/help/ec2_helper.rb +65 -2
  172. data/lib/help/remote_command_handler.rb +17 -0
  173. data/lib/help/state_transition_helper.rb +8 -0
  174. data/lib/scripts/ec2/open_port_checker.rb +112 -0
  175. data/lib/scripts/ec2/port_range_detector.rb +0 -1
  176. metadata +175 -16
@@ -0,0 +1,245 @@
1
+ require 'AWS'
2
+
3
+ class EC2_Utils
4
+ attr_reader :ec2
5
+
6
+ public
7
+ def initialize(ec2_options)
8
+ @ec2 = AWS::EC2::Base.new(ec2_options)
9
+ end
10
+ # Get public DNS name of an instance.
11
+ # If the instance is not yet started and the DNS name not known, block until the instance is started.
12
+ #
13
+ # @param instance_id Instance ID of the instance that you want to get the DNS from.
14
+ # @param ec2 The AWS::EC2::Base object that is used to access EC2.
15
+ # @return Public DNS name of the instance as String.
16
+ public
17
+ def get_instance_public_dns(instance_id)
18
+ error_count = 0
19
+ begin
20
+ while (true) do
21
+ instances = @ec2.describe_instances(:instance_id => instance_id)
22
+ # protect against nil errors because parts of the structure are not initialized when the DNS is not known
23
+ begin
24
+ dns_name = instances["reservationSet"]["item"][0]["instancesSet"]["item"][0]["dnsName"]
25
+ return dns_name if dns_name
26
+ rescue => err
27
+ end
28
+ sleep(5)
29
+ end
30
+ rescue => err
31
+ error_count += 1
32
+ raise err if error_count > 3
33
+
34
+ sleep(5)
35
+ retry
36
+ end
37
+ end
38
+
39
+ # Get the AMI from a started instance.
40
+ #
41
+ # @param instance_id The instance id that the machine id is retrieved for.
42
+ # @param ec2 The AWS::EC2::Base object that is used to access EC2.
43
+ # @return Machine id of the instance as String.
44
+ public
45
+ def get_image_id(instance_id)
46
+ instances = @ec2.describe_instances(:instance_id => instance_id)
47
+ if instances then
48
+ return instances["reservationSet"]["item"][0]["instancesSet"]["item"][0]["imageId"]
49
+ else
50
+ return "none"
51
+ end
52
+ end
53
+
54
+ public
55
+ def get_instance_states()
56
+ instanceStates = []
57
+ @ec2.describe_instances()['reservationSet']['item'].each do|x|
58
+ x['instancesSet']['item'].each do|y|
59
+ instanceStates << {:instance_id => y['instanceId'],
60
+ :state => y['instanceState']['name'],
61
+ :image_id => y['imageId'],
62
+ :runtime => (DateTime.now() - DateTime.strptime(y['launchTime'], "%Y-%m-%dT%H:%M:%S")) * 24.0}
63
+ end
64
+ end
65
+ return instanceStates
66
+ end
67
+
68
+ public
69
+ def get_cheapest_instance_type(machine_id)
70
+ machines = @ec2.describe_images(:image_id => machine_id)
71
+ begin
72
+ return "t1.micro" if machines['imagesSet']['item'][0]['rootDeviceType'] == "ebs"
73
+ return 'm1.small' if machines['imagesSet']['item'][0]['architecture'] == "i386"
74
+ return "m1.large" if machines['imagesSet']['item'][0]['architecture'] == "x86_64"
75
+ rescue => err
76
+ end
77
+
78
+ puts "ERROR: Finding cheapest instance type in EC2_Utils::get_cheapest_instance_type for machine_id = #{machine_id}"
79
+ return "t1.micro"
80
+ end
81
+
82
+ public
83
+ def start_instance(options)
84
+ raise "Invalid parameters to EC2_Utils::start_instance: :id is missing" unless options[:id]
85
+
86
+ if /^ami-.*$/.match(options[:id]) then
87
+ raise "Invalid parameters to EC2_Utils::start_instance: :ssh_keypair is missing" unless options[:ssh_keypair]
88
+ raise "Invalid parameters to EC2_Utils::start_instance: :instance_type is missing" unless options[:instance_type]
89
+ raise "Invalid parameters to EC2_Utils::start_instance: :security_group is missing" unless options[:security_group]
90
+
91
+ instance_id = false
92
+ if options[:max_price] then
93
+ spot_request = @ec2.request_spot_instances(
94
+ :image_id => options[:id],
95
+ :instance_count => 1,
96
+ :key_name => options[:ssh_keypair],
97
+ :security_group => options[:security_group],
98
+ :disable_api_termination => false,
99
+ :instance_type => options[:instance_type],
100
+ :spot_price => options[:max_price],
101
+ :valid_from => nil,
102
+ :valid_until => nil)
103
+
104
+ spot_request_id = spot_request['spotInstanceRequestSet']['item'][0]['spotInstanceRequestId']
105
+ begin
106
+ spot_reqs = ec2.describe_spot_instance_requests()
107
+ spot_req = spot_reqs['spotInstanceRequestSet']['item'].reject{|x| x['spotInstanceRequestId'] != spot_request_id}
108
+
109
+ raise "Spot request #{spot_request_id} seems to have disappeared" if spot_req.length() != 1
110
+
111
+ if spot_req[0]['instanceId'] then
112
+ instance_id = spot_req[0]['instanceId']
113
+ end
114
+
115
+ sleep(30)
116
+ end until instance_id
117
+ else
118
+ instance = @ec2.run_instances(
119
+ :image_id => options[:id],
120
+ :max_count => 1,
121
+ :key_name => options[:ssh_keypair],
122
+ :security_group => options[:security_group],
123
+ :disable_api_termination => false,
124
+ :instance_type => options[:instance_type])
125
+ instance_id = instance["instancesSet"]["item"][0]["instanceId"]
126
+ end
127
+
128
+ image_id = options[:id]
129
+ elsif /^i-.*$/.match(options[:id]) then
130
+ instance_id = options[:id]
131
+ image_id = get_image_id(instance_id)
132
+ else
133
+ raise "Unknown identifier #{options[:id]}"
134
+ end
135
+
136
+ puts "instance #{instance_id} started, waiting for IP address" if options[:verbose]
137
+ begin
138
+ dns_name = get_instance_public_dns(instance_id)
139
+ rescue => err
140
+ puts "ERROR: During DNS request of AMI" if options[:verbose]
141
+ end
142
+
143
+ if dns_name.nil? || dns_name.empty? then
144
+ puts "ERROR: No DNS name for AMI found" if options[:verbose]
145
+ raise "No DNS name for AMI found"
146
+ end
147
+
148
+ return {:machine_id => image_id,
149
+ :instance_id => instance_id,
150
+ :public_dns => dns_name}
151
+ end
152
+
153
+ public
154
+ def get_instance_volumes(instance_id)
155
+ volumes = []
156
+ instances = @ec2.describe_instances(:instance_id => [instance_id])
157
+
158
+ instances['reservationSet']['item'].each do|reservationSet|
159
+ next unless reservationSet['instancesSet']
160
+
161
+ reservationSet['instancesSet']['item'].each do|instancesSet|
162
+ next unless instancesSet['blockDeviceMapping']
163
+
164
+ instancesSet['blockDeviceMapping']['item'].each do|blockDeviceMapping|
165
+ next unless blockDeviceMapping['ebs']
166
+
167
+ volumes << blockDeviceMapping['ebs']['volumeId']
168
+ end
169
+ end
170
+ end
171
+
172
+ return volumes
173
+ end
174
+
175
+ public
176
+ def terminate_instance(instance_id)
177
+ volumes = get_instance_volumes(instance_id)
178
+
179
+ @ec2.terminate_instances(:instance_id => [instance_id])
180
+
181
+ begin
182
+ #wait till instance is terminated
183
+ begin
184
+ instance_state = @ec2.describe_instances(:instance_id => [instance_id])['reservationSet']['item'][0]['instancesSet']['item'][0]['instanceState']['name']
185
+ end unless instance_state == "terminated"
186
+
187
+ #delete volumes
188
+ volumes.each do|volume|
189
+ begin
190
+ @ec2.detach_volumes(:volume_id => volume)
191
+ rescue => err
192
+ end
193
+
194
+ @ec2.delete_volume(:volume_id => volume)
195
+ end
196
+ rescue => err
197
+ if err.class() == AWS::Error && /The volume 'vol-[0-9a-f]{8}' does not exist/.match(err.message()) then
198
+ #ignore error
199
+ end
200
+ end
201
+ end
202
+
203
+ public
204
+ def get_spot_prices(options = {})
205
+ arg = {:start_time => Time.now() - 1, :end_time => Time.now()}
206
+ arg[:instance_type] = options[:instance_type] if options[:instance_type]
207
+ spot_prices = ec2.describe_spot_price_history(arg)
208
+
209
+ prices = {}
210
+ if spot_prices["spotPriceHistorySet"] then
211
+ spot_prices["spotPriceHistorySet"]["item"].each do|spot_price|
212
+ (prices[spot_price["instanceType"]] ||= {})[spot_price["productDescription"]] = {:price => spot_price["spotPrice"], :timestamp => spot_price["timestamp"]}
213
+ end
214
+ end
215
+
216
+ return prices
217
+ end
218
+ end
219
+
220
+ # taken from https://github.com/grempe/amazon-ec2/blob/master/lib/AWS/EC2/console.rb ------------------------->
221
+ module AWS
222
+ module EC2
223
+ class Base < AWS::Base
224
+
225
+
226
+ # The GetConsoleOutput operation retrieves console output that has been posted for the specified instance.
227
+ #
228
+ # Instance console output is buffered and posted shortly after instance boot, reboot and once the instance
229
+ # is terminated. Only the most recent 64 KB of posted output is available. Console output is available for
230
+ # at least 1 hour after the most recent post.
231
+ #
232
+ # @option options [String] :instance_id ("") an Instance ID
233
+ #
234
+ def get_console_output( options = {} )
235
+ options = {:instance_id => ""}.merge(options)
236
+ raise ArgumentError, "No instance ID provided" if options[:instance_id].nil? || options[:instance_id].empty?
237
+ params = { "InstanceId" => options[:instance_id] }
238
+ return response_generator(:action => "GetConsoleOutput", :params => params)
239
+ end
240
+
241
+
242
+ end
243
+ end
244
+ end
245
+ # <----------------------------------------------------------------------------------------------------------
@@ -0,0 +1,116 @@
1
+ require 'timeout'
2
+ require 'socket'
3
+
4
+ # http://www.apachehaus.com/index.php?option=com_content&view=article&id=119:history-releases-apache&catid=41:catagory-change-logs&Itemid=93
5
+
6
+ #Contains code to take responses to revealing HTTP requests.
7
+ #This code needs Ruby 1.9 for the timeout module.
8
+ module HTTP_FINGERPRINT
9
+ #HTTP request timeout in seconds
10
+ HTTP_REQUEST_TIMEOUT = 10
11
+
12
+ def self.repeat_character(x, y)
13
+ if y == 0 then
14
+ return ""
15
+ else
16
+ return x + repeat_character(x, y - 1)
17
+ end
18
+ end
19
+
20
+ @http_methods = [["GET / HTTP/1.1\r\n", :get_existing],
21
+ ["GET /" + repeat_character("x", 1024) + " HTTP/1.1\r\n", :get_long],
22
+ ["GET /kC8CH9.html HTTP/1.1\r\n", :get_nonexisting],
23
+ ["GET / HTTP/9.8\r\n", :wrong_version],
24
+ ["GET / INVD/1.1\r\n", :wrong_protocol],
25
+ ["HEAD / HTTP/1.1\r\n", :head_existing],
26
+ ["OPTIONS / HTTP/1.1\r\n", :options],
27
+ ["DELETE / HTTP/1.1\r\n", :delete_existing],
28
+ ["GET /etc/passwd?format=%%%&xss=\"><script>alert('xss');" +
29
+ "</script>&traversal=../../&sql='%20OR%201; HTTP/1.1\r\n", :attack_request],
30
+ ["TEST / HTTP/1.1\r\n", :wrong_method],
31
+ ["GET \\ HTTP/1.1\r\n", :get_backslash_resource]]
32
+
33
+ def self.fingerprint_to_xml(fingerprint)
34
+ xml = [
35
+ "<scan_targethost>\n",
36
+ fingerprint[:scan_targethost] + "\n",
37
+ "</scan_targethost>\n",
38
+ "<scan_targetport>\n",
39
+ fingerprint[:scan_targetport].to_s + "\n",
40
+ "</scan_targetport>\n",
41
+ "<scan_targetsecure>\n",
42
+ fingerprint[:scan_targetsecure].to_s + "\n",
43
+ "</scan_targetsecure>\n",
44
+ "<scan_date>\n",
45
+ fingerprint[:scan_timestamp].strftime("%d.%m.%Y") + "\n",
46
+ "</scan_date>\n",
47
+ "<scan_time>\n",
48
+ fingerprint[:scan_timestamp].strftime("%H:%M:%S") + "\n",
49
+ "</scan_time>\n"]
50
+ @http_methods.each do|method|
51
+ xml << ("<" + method[1].to_s + ">\n")
52
+ fingerprint[method[1]].each {|l| xml << l}
53
+ xml << ("</" + method[1].to_s + ">\n")
54
+ end
55
+
56
+ return xml.join
57
+ end
58
+
59
+ public
60
+ def self.fingerprint(host, port = 80, useragent = "(KHTML, like Gecko) " +
61
+ "Ubuntu/10.04 Chromium/8.0.552.224 Chrome/8.0.552.224" +
62
+ " Safari/534.10")
63
+ header_lines = ["User-Agent: " + useragent + "\r\n",
64
+ "Host: " + host + "\r\n",
65
+ "Connection: Close\r\n",
66
+ "Cache-Control: no-cache\r\n",
67
+ "\r\n"]
68
+ http_fingerprints= {
69
+ :scan_targethost => host,
70
+ :scan_targetport => port,
71
+ :scan_targetsecure => 0,
72
+ :scan_timestamp => Time.now}
73
+ # [
74
+ # "<scan_targethost>\n",
75
+ # host + "\n",
76
+ # "</scan_targethost>\n",
77
+ # "<scan_targetport>\n",
78
+ # port.to_s + "\n",
79
+ # "</scan_targetport>\n",
80
+ # "<scan_targetsecure>\n",
81
+ # "0\n",
82
+ # "</scan_targetsecure>\n",
83
+ # "<scan_date>\n",
84
+ # Time.now.strftime("%d.%m.%Y") + "\n",
85
+ # "</scan_date>\n",
86
+ # "<scan_time>\n",
87
+ # Time.now.strftime("%H:%M:%S") + "\n",
88
+ # "</scan_time>\n"]
89
+
90
+ @http_methods.each do|method|
91
+ http_fingerprints[method[1]] = []
92
+ # http_fingerprints << ("<" + method[1] + ">\n")
93
+ begin
94
+ timeout(HTTP_REQUEST_TIMEOUT) do
95
+ socket = TCPSocket.new(host, port)
96
+ socket.puts method[0]
97
+ header_lines.each do|hdr_line|
98
+ socket.puts hdr_line
99
+ end
100
+
101
+ received = socket.readlines
102
+ for i in 0 .. received.length
103
+ if received[i] == "\r\n" || received[i] == "\n" then
104
+ break
105
+ end
106
+ http_fingerprints[method[1]] << received[i]
107
+ end
108
+ end
109
+ rescue Timeout::Error
110
+ http_fingerprints[method[1]] = :TIMEOUT
111
+ end
112
+ # http_fingerprints << ("</" + method[1] + ">\n")
113
+ end
114
+ return http_fingerprints
115
+ end
116
+ end
@@ -0,0 +1,37 @@
1
+ # To change this template, choose Tools | Templates
2
+ # and open the template in the editor.
3
+
4
+ class Lazy
5
+ def initialize(obj, eval_method, *eval_args, &eval_block)
6
+ @obj = obj
7
+ @eval_method = eval_method
8
+ @eval_args = *eval_args
9
+ @eval_block = eval_block
10
+
11
+ #debugging
12
+ raise "Object #{@obj.class.name} does not contain method #{@eval_method}" unless @obj.methods.include? @eval_method
13
+ end
14
+
15
+ def method_missing(method, *args, &block)
16
+ @evaluated = @obj.send(@eval_method, *@eval_args, &@eval_block) if @evaluated.nil?
17
+ @evaluated.send(method, *args, &block)
18
+ end
19
+
20
+ def to_yaml(opts = {})
21
+ @evaluated = @obj.send(@eval_method, *@eval_args, &@eval_block) if @evaluated.nil?
22
+ return @evaluated.to_yaml(opts)
23
+ end
24
+
25
+ def methods()
26
+ @evaluated = @obj.send(@eval_method, *@eval_args, &@eval_block) if @evaluated.nil?
27
+ return @evaluated.methods()
28
+ end
29
+
30
+ def debug_lazy()
31
+ return [@obj, @eval_method, @eval_args, @eval_block]
32
+ end
33
+
34
+ def get()
35
+ return @obj
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ require 'benchmark'
2
+
3
+ class LinearScriptGenerator
4
+
5
+ def self.generate(benchmark)
6
+ retval = ""
7
+ resolved_dependencies = benchmark.execution_order
8
+
9
+ script_header = benchmark.element("script_header.template")
10
+ header = benchmark.element("header.template")
11
+ footer = benchmark.element("footer.template")
12
+
13
+ raise ItemNotFoundException.new("header.template"), "header template missing in benchmark" if header.nil?
14
+ raise ItemNotFoundException.new("footer.template"), "footer template missing in benchmark" if footer.nil?
15
+ raise ItemNotFoundException.new("script_header.template"), "script header template missing in benchmark" if script_header.nil?
16
+
17
+ retval = script_header if script_header
18
+
19
+ resolved_dependencies.flatten.each do|x|
20
+ depends_condition = ""
21
+ x.dependencies.each do|y|
22
+ depends_condition = depends_condition + "-a ${" + y.id + "_EXITCODE} -eq 0 "
23
+ end
24
+
25
+ retval = retval + "\n" + header.gsub(/%%SCRIPT_ID%%/, x.id).gsub(/%%DEPENDS_CONDITION%%/, depends_condition) + "\n"
26
+ retval = retval + (x.script)
27
+ retval = retval + "\n" + footer.gsub(/%%SCRIPT_ID%%/, x.id)
28
+ end
29
+ return retval
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'my_option_parser'
4
+
5
+ # Parsed options from command line
6
+ options = MyOptionParser.new(ARGV).parse()
7
+
8
+ print "Connection type: #{options.connection_type}\n"
9
+ print "SSH Credentials: #{options.ssh_credentials.to_s}\n" if options.connection_type == :ssh
10
+ #print "SSH: #{options[:ssh]}\n" unless options[:ssh].nil?
11
+
12
+
13
+
@@ -0,0 +1,106 @@
1
+ require 'optparse'
2
+
3
+ class MyOptionParser
4
+
5
+ attr_reader :options
6
+
7
+ def initialize(args)
8
+ @args = args
9
+ end
10
+
11
+ def parse()
12
+ @options = {}
13
+
14
+ opts = OptionParser.new do|opts|
15
+ #Banner string displayed at top of help
16
+ opts.banner = "Usage: ./main.rb\t--ssh HOST[:PORT] [--user USERNAME] --key KEYFILE --benchmark BENCHMARK"
17
+ opts.separator "\t\t\t--ami AMI-ID --credentials CREDENTIALS --benchmark BENCHMARK"
18
+
19
+
20
+ @options[:verbose] = false
21
+ opts.on('-v', '--[no-]verbose', 'Output more information') do|v|
22
+ @options[:verbose] = v
23
+ end
24
+
25
+ opts.on('-A', '--ami AMI-ID', String, 'Select this AMI for audit') do|ami|
26
+ @options[:ami] = ami
27
+ end
28
+
29
+ opts.on('-S', '--ssh HOST', String, 'Select this host for audit') do|host|
30
+ @options[:ssh] = host
31
+ end
32
+
33
+ opts.on('-B', '--benchmark BENCHMARK', String, 'Use this benchmark file') do|bm|
34
+ @options[:benchmark] = bm
35
+ end
36
+
37
+ opts.on('-K', '--key KEY', String, 'Use this private key file for authentication') do|key|
38
+ @options[:key] = key
39
+ end
40
+
41
+ opts.on('-P', '--password PASSWORD', String, 'Use this password for authentication') do|pwd|
42
+ @options[:password] = pwd
43
+ end
44
+
45
+ opts.on('-C', '--credentials CREDENTIALS', String, 'Use these Amazon Account credentials to start the AMI') do|cd|
46
+ @options[:credentials] = cd
47
+ end
48
+
49
+ opts.on_tail("-h", "--help", "Show this message") do
50
+ puts opts
51
+ exit
52
+ end
53
+ end
54
+
55
+ opts.parse(@args)
56
+
57
+ if @options[:ssh].nil? and @options[:ami].nil? then
58
+ print "You must specify one of the --ssh or --ami options. Exiting.\n"
59
+ exit 1
60
+ end
61
+
62
+ if not @options[:ssh].nil? and not @options[:ami].nil? then
63
+ print "Options --ssh and --ami are mutually exclusive, but both chosen. Please specify only one of them. Exiting.\n"
64
+ exit 1
65
+ end
66
+
67
+ if @options[:benchmark].nil? then
68
+ print "Option --benchmark is required. Please specify a benchmark file for this audit. Exiting.\n"
69
+ exit 1
70
+ end
71
+
72
+ if not @options[:ssh].nil? and @options[:key].nil? and @options[:password].nil? then
73
+ print "At least one authentication method for SSH is required. Please specify either --key or --password. Exiting.\n"
74
+ exit 1
75
+ end
76
+
77
+ return self
78
+ end
79
+
80
+ def connection_type
81
+ return :ami unless @options[:ami].nil?
82
+ return :ssh unless @options[:ssh].nil?
83
+ return :none
84
+ end
85
+
86
+ def ssh_credentials
87
+ raise "SSH credentials requested although SSH connection method is not chosen" if @options[:ssh].nil?
88
+ raise "No SSH authentication method chosen" if @options[:password].nil? and @options[:key].nil?
89
+
90
+ cred = {:host => @options[:ssh]}
91
+ if @options[:user].nil? then
92
+ cred[:user] = 'root'
93
+ else
94
+ cred[:user] = @options[:user]
95
+ end
96
+ cred[:key_data] = @options[:key] unless @options[:key].nil?
97
+ cred[:password] = @options[:password] unless @options[:password].nil?
98
+
99
+ return cred
100
+ end
101
+
102
+ def benchmark
103
+ raise "No benchmark file specified" if @options[:benchmark].nil?
104
+ return @options[:benchmark]
105
+ end
106
+ end