threat_agent 1.0.0.beta.1 → 1.0.0.beta.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/bin/threatagent +21 -16
- data/lib/threat_agent.rb +2 -0
- data/lib/threat_agent/api_client.rb +14 -3
- data/lib/threat_agent/config.rb +33 -0
- data/lib/threat_agent/exceptions.rb +10 -0
- data/lib/threat_agent/exceptions/invalid_yaml.rb +6 -0
- data/lib/threat_agent/exceptions/no_configuration_found.rb +6 -0
- data/lib/threat_agent/tasks/pwnxy.rb +29 -6
- data/lib/threat_agent/version.rb +1 -1
- data/threat_agent.gemspec +5 -1
- metadata +80 -39
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a685a1dc402be9ba1ea49872c431e42373fe3918
|
4
|
+
data.tar.gz: ba030b2aef8d8e48766285b728b8b40e755700bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 55e0b60b26d6468188c4905b5286f981fa0975d85f0ad89b32b8c7c926f01f17e449cc0c303fb2b371c99c49a22466d0b9caf1c9c4d550c205b144b62638a27e
|
7
|
+
data.tar.gz: 4d585124a9412991cd0a02a5b732bd5e92f9db69bb8cdfeddf89c317a6f4dac9c544f335b329629b7a7b0f75dada4fc1b9519596fcf6a4006cf983054be164ee
|
data/.gitignore
CHANGED
data/bin/threatagent
CHANGED
@@ -2,35 +2,40 @@
|
|
2
2
|
# -*- mode: ruby -*-
|
3
3
|
# vi: set ft=ruby :
|
4
4
|
|
5
|
+
require 'cryptic'
|
5
6
|
require 'threat_agent'
|
6
7
|
require 'threat_agent/tasks'
|
7
8
|
require 'thor'
|
8
9
|
|
9
10
|
class ThreatAgentCLI < Thor
|
10
|
-
desc 'breachbot [SUBCOMMAND]', 'Monitor website changes'
|
11
|
-
subcommand :breachbot, ThreatAgent::Tasks::Breachbot
|
11
|
+
# desc 'breachbot [SUBCOMMAND]', 'Monitor website changes'
|
12
|
+
# subcommand :breachbot, ThreatAgent::Tasks::Breachbot
|
12
13
|
|
13
|
-
desc 'drone [SUBCOMMAND]', 'Launch or review Drone security assessments'
|
14
|
-
subcommand :drone, ThreatAgent::Tasks::Drone
|
14
|
+
# desc 'drone [SUBCOMMAND]', 'Launch or review Drone security assessments'
|
15
|
+
# subcommand :drone, ThreatAgent::Tasks::Drone
|
15
16
|
|
16
|
-
desc 'exfiltrate [SUBCOMMAND]', '
|
17
|
-
subcommand :exfiltrate, ThreatAgent::Tasks::Exfiltrate
|
17
|
+
# desc 'exfiltrate [SUBCOMMAND]', 'Check if devices can detect sensitive data'
|
18
|
+
# subcommand :exfiltrate, ThreatAgent::Tasks::Exfiltrate
|
18
19
|
|
19
|
-
desc '
|
20
|
-
|
20
|
+
desc 'keygen [OPTIONS]', 'Generate an RSA keypair'
|
21
|
+
method_option :passphrase, aliases: %w[-P], default: nil, desc: 'The passphrase to give your private key'
|
22
|
+
method_option :path, aliases: %w[-o], default: '.', desc: 'The path to save generated keys to'
|
23
|
+
def keygen
|
24
|
+
keypair = Cryptic::Keypair.generate(options[:passphrase])
|
25
|
+
keypair.save(options[:path])
|
26
|
+
end
|
21
27
|
|
22
|
-
desc '
|
23
|
-
subcommand :
|
28
|
+
# desc 'passision [SUBCOMMAND]', 'Create a locale/organization aware wordlists'
|
29
|
+
# subcommand :passision, ThreatAgent::Tasks::Passision
|
30
|
+
|
31
|
+
# desc 'phishable [SUBCOMMAND]', 'Launch phishing campaigns'
|
32
|
+
# subcommand :phishable, ThreatAgent::Tasks::Phishable
|
24
33
|
|
25
34
|
desc 'pwnxy [SUBCOMMAND]', 'Create a Pwnxy instance'
|
26
35
|
subcommand :pwnxy, ThreatAgent::Tasks::Pwnxy
|
27
36
|
end
|
28
37
|
|
29
|
-
|
30
|
-
|
31
|
-
$threat_agent_client = ThreatAgent::APIClient.new(
|
32
|
-
ENV['THREAT_AGENT_KEY'],
|
33
|
-
ENV['THREAT_AGENT_SUP']
|
34
|
-
)
|
38
|
+
config = ThreatAgent::Config
|
39
|
+
$threat_agent_client = ThreatAgent::APIClient.new(config[:key], config[:sup])
|
35
40
|
|
36
41
|
ThreatAgentCLI.start(ARGV)
|
data/lib/threat_agent.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'net/http'
|
3
|
+
require 'threat_agent'
|
3
4
|
|
4
5
|
module ThreatAgent
|
5
|
-
# The
|
6
|
+
# The APClient object handles most of the interactions with the ThreatAgent
|
6
7
|
# API
|
7
8
|
#
|
8
9
|
# @author Erran Carey <me@errancarey.com>
|
@@ -42,12 +43,22 @@ module ThreatAgent
|
|
42
43
|
# @param [Hash] params parameters to send along with the action to
|
43
44
|
# api.threatagent.com
|
44
45
|
def request(action, params = {})
|
45
|
-
params.merge!({ key: @key, sup: @sup })
|
46
46
|
action = action.to_s.gsub(/-|_/, '/')
|
47
|
+
params.merge!({ key: @key, sup: @sup })
|
47
48
|
encoded_params = URI.encode_www_form(params.keys.zip(params.values))
|
48
|
-
|
49
|
+
|
50
|
+
config = ThreatAgent::Config
|
51
|
+
|
52
|
+
if File.exists?("#{ENV['HOME']}/.threatagent")
|
53
|
+
ThreatAgent::Config.from_file("#{ENV['HOME']}/.threatagent")
|
54
|
+
end
|
55
|
+
|
56
|
+
api_endpoint = "#{config[:endpoint]}/api/#{config[:api_version]}/"
|
57
|
+
uri = URI("#{api_endpoint}#{action}?#{encoded_params}")
|
58
|
+
|
49
59
|
resp = Net::HTTP.get_response(uri)
|
50
60
|
json = resp.body
|
61
|
+
JSON.parse(json)
|
51
62
|
end
|
52
63
|
end
|
53
64
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'mixlib/config'
|
3
|
+
require 'threat_agent/exceptions'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
module ThreatAgent
|
7
|
+
# A class that load's the user's configuration
|
8
|
+
#
|
9
|
+
# @author Erran Carey <me@errancarey.com>
|
10
|
+
class Config
|
11
|
+
extend Mixlib::Config
|
12
|
+
include ThreatAgent::Exceptions
|
13
|
+
|
14
|
+
# Sets the default configuration options
|
15
|
+
configure do |config|
|
16
|
+
config[:endpoint] = ENV['THREAT_AGENT_ENDPOINT'] || 'https://www.threatagent.com'
|
17
|
+
config[:key] = ENV['THREAT_AGENT_KEY']
|
18
|
+
config[:sup] = ENV['THREAT_AGENT_SUP']
|
19
|
+
config[:api_version] = 'v1'
|
20
|
+
end
|
21
|
+
|
22
|
+
# TODO: Add from_json/from_yaml methods to Mixlib::Config or add them here
|
23
|
+
=begin
|
24
|
+
def self.from_json(file)
|
25
|
+
hash = File.exists? ? JSON.parse(file) : {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.from_yaml(file)
|
29
|
+
hash = File.exists? ? YAML.parse(file).to_ruby : {}
|
30
|
+
end
|
31
|
+
=end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'cryptic'
|
3
|
+
require 'colorize'
|
4
|
+
require 'json'
|
1
5
|
require 'thor'
|
2
6
|
require 'threat_agent'
|
3
7
|
|
@@ -15,14 +19,33 @@ module ThreatAgent
|
|
15
19
|
end
|
16
20
|
|
17
21
|
desc 'pwnxy logs [INSTANCE] [OPTIONS]', 'Show logs for a Pwnxy instance'
|
18
|
-
# TODO: Add logs(identifier = :last), add support in the TA API
|
19
|
-
# Support last/first in the TA API. Currently 0 returns first. Use
|
20
|
-
# -1 for last?
|
21
|
-
# TODO: Add support for dropping all logs?
|
22
22
|
def logs(identifier = 0)
|
23
|
-
|
23
|
+
logs = $threat_agent_client.request(:pwnxy_logs, { p: identifier })
|
24
24
|
# TODO: Add a UI class/method.
|
25
|
-
|
25
|
+
# TODO: Return the logs to the user
|
26
|
+
if logs.is_a?(Hash) && logs['error']
|
27
|
+
$stderr.puts "Threat Agent API Error: #{logs['error']}".red
|
28
|
+
exit 255 # This is an API error. Exit with an unspecific code.
|
29
|
+
end
|
30
|
+
|
31
|
+
$stdout.puts decrypt(logs)
|
32
|
+
end
|
33
|
+
|
34
|
+
no_commands do
|
35
|
+
def decrypt(logs)
|
36
|
+
keypair = Cryptic::Keypair.new(ThreatAgent::Config[:private_key])
|
37
|
+
private_key = keypair.private_key
|
38
|
+
|
39
|
+
logs.map do |log|
|
40
|
+
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
|
41
|
+
cipher.decrypt
|
42
|
+
cipher.key = private_key.private_decrypt(Base64.decode64(log['encrypted_key']))
|
43
|
+
cipher.iv = private_key.private_decrypt(Base64.decode64(log['encrypted_iv']))
|
44
|
+
|
45
|
+
decrypted_data = cipher.update(Base64.decode64(log['encrypted_data']))
|
46
|
+
decrypted_data << cipher.final
|
47
|
+
end.to_json
|
48
|
+
end
|
26
49
|
end
|
27
50
|
end
|
28
51
|
end
|
data/lib/threat_agent/version.rb
CHANGED
data/threat_agent.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = 'threat_agent'
|
8
8
|
spec.version = ThreatAgent::VERSION
|
9
9
|
spec.authors = ['Erran Carey']
|
10
|
-
spec.email = ['
|
10
|
+
spec.email = ['e@threatagent.com']
|
11
11
|
spec.description = %q{A gem to interface with the Threat Agent API}
|
12
12
|
spec.summary = %q{Interact with apps from the Threat Agent website}
|
13
13
|
spec.homepage = 'http://developer.threatagent.com'
|
@@ -19,11 +19,15 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_dependency 'colorize'
|
22
|
+
spec.add_dependency 'cryptic'
|
23
|
+
spec.add_dependency 'json'
|
24
|
+
spec.add_dependency 'mixlib-config'
|
22
25
|
spec.add_dependency 'redcarpet'
|
23
26
|
spec.add_dependency 'thor'
|
24
27
|
spec.add_dependency 'yard'
|
25
28
|
|
26
29
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
30
|
+
spec.add_development_dependency 'pry'
|
27
31
|
spec.add_development_dependency 'rake'
|
28
32
|
spec.add_development_dependency 'rspec'
|
29
33
|
end
|
metadata
CHANGED
@@ -1,84 +1,116 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: threat_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.beta.
|
5
|
-
prerelease: 6
|
4
|
+
version: 1.0.0.beta.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Erran Carey
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-09 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: colorize
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: cryptic
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mixlib-config
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
28
67
|
- !ruby/object:Gem::Version
|
29
68
|
version: '0'
|
30
69
|
- !ruby/object:Gem::Dependency
|
31
70
|
name: redcarpet
|
32
71
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
72
|
requirements:
|
35
|
-
- -
|
73
|
+
- - '>='
|
36
74
|
- !ruby/object:Gem::Version
|
37
75
|
version: '0'
|
38
76
|
type: :runtime
|
39
77
|
prerelease: false
|
40
78
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
79
|
requirements:
|
43
|
-
- -
|
80
|
+
- - '>='
|
44
81
|
- !ruby/object:Gem::Version
|
45
82
|
version: '0'
|
46
83
|
- !ruby/object:Gem::Dependency
|
47
84
|
name: thor
|
48
85
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
86
|
requirements:
|
51
|
-
- -
|
87
|
+
- - '>='
|
52
88
|
- !ruby/object:Gem::Version
|
53
89
|
version: '0'
|
54
90
|
type: :runtime
|
55
91
|
prerelease: false
|
56
92
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
93
|
requirements:
|
59
|
-
- -
|
94
|
+
- - '>='
|
60
95
|
- !ruby/object:Gem::Version
|
61
96
|
version: '0'
|
62
97
|
- !ruby/object:Gem::Dependency
|
63
98
|
name: yard
|
64
99
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
100
|
requirements:
|
67
|
-
- -
|
101
|
+
- - '>='
|
68
102
|
- !ruby/object:Gem::Version
|
69
103
|
version: '0'
|
70
104
|
type: :runtime
|
71
105
|
prerelease: false
|
72
106
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
107
|
requirements:
|
75
|
-
- -
|
108
|
+
- - '>='
|
76
109
|
- !ruby/object:Gem::Version
|
77
110
|
version: '0'
|
78
111
|
- !ruby/object:Gem::Dependency
|
79
112
|
name: bundler
|
80
113
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
114
|
requirements:
|
83
115
|
- - ~>
|
84
116
|
- !ruby/object:Gem::Version
|
@@ -86,46 +118,55 @@ dependencies:
|
|
86
118
|
type: :development
|
87
119
|
prerelease: false
|
88
120
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
121
|
requirements:
|
91
122
|
- - ~>
|
92
123
|
- !ruby/object:Gem::Version
|
93
124
|
version: '1.3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
94
139
|
- !ruby/object:Gem::Dependency
|
95
140
|
name: rake
|
96
141
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
142
|
requirements:
|
99
|
-
- -
|
143
|
+
- - '>='
|
100
144
|
- !ruby/object:Gem::Version
|
101
145
|
version: '0'
|
102
146
|
type: :development
|
103
147
|
prerelease: false
|
104
148
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
149
|
requirements:
|
107
|
-
- -
|
150
|
+
- - '>='
|
108
151
|
- !ruby/object:Gem::Version
|
109
152
|
version: '0'
|
110
153
|
- !ruby/object:Gem::Dependency
|
111
154
|
name: rspec
|
112
155
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
156
|
requirements:
|
115
|
-
- -
|
157
|
+
- - '>='
|
116
158
|
- !ruby/object:Gem::Version
|
117
159
|
version: '0'
|
118
160
|
type: :development
|
119
161
|
prerelease: false
|
120
162
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
163
|
requirements:
|
123
|
-
- -
|
164
|
+
- - '>='
|
124
165
|
- !ruby/object:Gem::Version
|
125
166
|
version: '0'
|
126
167
|
description: A gem to interface with the Threat Agent API
|
127
168
|
email:
|
128
|
-
-
|
169
|
+
- e@threatagent.com
|
129
170
|
executables:
|
130
171
|
- threatagent
|
131
172
|
extensions: []
|
@@ -140,6 +181,10 @@ files:
|
|
140
181
|
- bin/threatagent
|
141
182
|
- lib/threat_agent.rb
|
142
183
|
- lib/threat_agent/api_client.rb
|
184
|
+
- lib/threat_agent/config.rb
|
185
|
+
- lib/threat_agent/exceptions.rb
|
186
|
+
- lib/threat_agent/exceptions/invalid_yaml.rb
|
187
|
+
- lib/threat_agent/exceptions/no_configuration_found.rb
|
143
188
|
- lib/threat_agent/tasks.rb
|
144
189
|
- lib/threat_agent/tasks/breachbot.rb
|
145
190
|
- lib/threat_agent/tasks/drone.rb
|
@@ -153,30 +198,26 @@ files:
|
|
153
198
|
homepage: http://developer.threatagent.com
|
154
199
|
licenses:
|
155
200
|
- MIT
|
201
|
+
metadata: {}
|
156
202
|
post_install_message:
|
157
203
|
rdoc_options: []
|
158
204
|
require_paths:
|
159
205
|
- lib
|
160
206
|
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
207
|
requirements:
|
163
|
-
- -
|
208
|
+
- - '>='
|
164
209
|
- !ruby/object:Gem::Version
|
165
210
|
version: '0'
|
166
|
-
segments:
|
167
|
-
- 0
|
168
|
-
hash: -3825142359742865107
|
169
211
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
|
-
none: false
|
171
212
|
requirements:
|
172
|
-
- -
|
213
|
+
- - '>'
|
173
214
|
- !ruby/object:Gem::Version
|
174
215
|
version: 1.3.1
|
175
216
|
requirements: []
|
176
217
|
rubyforge_project:
|
177
|
-
rubygems_version:
|
218
|
+
rubygems_version: 2.0.3
|
178
219
|
signing_key:
|
179
|
-
specification_version:
|
220
|
+
specification_version: 4
|
180
221
|
summary: Interact with apps from the Threat Agent website
|
181
222
|
test_files:
|
182
223
|
- spec/default_spec.rb
|