cif-client 1.0.5 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -1
- data.tar.gz.sig +2 -1
- data/bin/cifcli +104 -104
- data/cif-client.gemspec +19 -19
- data/lib/cif/client.rb +35 -34
- data/lib/cif/client/version.rb +1 -1
- data/test/test_cif-client.rb +19 -19
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b140c16760108b5eb0caf70728504407d85c8a46
|
4
|
+
data.tar.gz: b89b03af6edc6afe611d150e9c23627a4dbcf9cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fe6997c11f8c2bdb5c19f9945c2253b903cb1dc2b8e5fd87039a4f62a7c11a27ef5879af49d48ef82d87dfd66cd5a6c26ee3521ba738041a4fe2b55c9f413e9
|
7
|
+
data.tar.gz: 4c47ecfd3b69151ad8e11b38a58468865104c7c23fa2fca568df74c1b67aeaed1a4ad891f56bcb5fff3c2821630719a1324502921249271f90a3acaf20aeaeaf
|
checksums.yaml.gz.sig
CHANGED
@@ -1 +1,3 @@
|
|
1
|
-
|
1
|
+
RD��2��am
|
2
|
+
~�G���Ef������`��i���E��Ax�990^
|
3
|
+
Ín��iwm;�h��T���o����j��矪;s�D?v<�(� 'B[���V���^�Zutj�z���La�ciР�>��g�}�ka�{=v��r�v��,G*���8�u�N���aV��5�iL���BKF��Y
|
data.tar.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
Q���#��t%a&|֜�F�F��K[q-ʺjt鎯�ph�Q��Ǭ��cN��2����ؒ�a�� �[����i`�
|
2
|
+
(ۥ�(�^bS%����ZqJ�a��8�Z�f�cA�y��mlL���wYJ�G� �l#v�I"i.�y���e�A7[�Ѩ�X�&n��j�io
|
data/bin/cifcli
CHANGED
@@ -9,86 +9,86 @@ require 'snort-rule'
|
|
9
9
|
require 'configparser'
|
10
10
|
|
11
11
|
def usage
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
12
|
+
puts "Usage: #{$0} [-h] [-c <config>] [-s <severity>] [-r <restriction>] [-n] [-x|-j|-y|-t|-o] [-d <delim>] <query> [<query> ...]"
|
13
|
+
puts "-h prints this help"
|
14
|
+
puts "-c <config> specifies a configuration file with the API key and host endpoint"
|
15
|
+
puts "-s <severity> severity: low, medium, or high"
|
16
|
+
puts "-r <restriction> examples: need-to-know and private"
|
17
|
+
puts "-n requests the server to not log the query"
|
18
|
+
puts "-x outputs in XML"
|
19
|
+
puts "-j outputs in JSON"
|
20
|
+
puts "-y outputs in YAML"
|
21
|
+
puts "-o outputs in SNORT formatted rules"
|
22
|
+
puts "-t outputs in ASCII text (broken in 1.0.0)"
|
23
|
+
puts "-d <delimiter> specifies the delimiter for text (default tab)"
|
24
|
+
puts "<query> terms, usually domains, IPs, or CIDRs, that are being queried from the CIF"
|
25
|
+
exit
|
26
26
|
end
|
27
27
|
|
28
28
|
def format_results(results,format,delim)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
29
|
+
return unless results
|
30
|
+
case format
|
31
|
+
when 'xml'
|
32
|
+
results.to_xml
|
33
|
+
when 'json'
|
34
|
+
results.to_json
|
35
|
+
when 'yaml'
|
36
|
+
results.to_yaml
|
37
|
+
when 'text'
|
38
|
+
fields = nil
|
39
|
+
output = ""
|
40
|
+
results['entry'].each do |item|
|
41
|
+
unless fields
|
42
|
+
fields = item.keys
|
43
|
+
output += fields.join(delim)+"\n"
|
44
|
+
end
|
45
|
+
sep = ""
|
46
|
+
fields.each do |field|
|
47
|
+
output += sep
|
48
|
+
output += item[field].chomp if item[field] and item[field].class == String
|
49
|
+
sep = delim
|
50
|
+
end
|
51
|
+
output += "\n"
|
52
|
+
end
|
53
|
+
output
|
54
|
+
when 'snort'
|
55
|
+
sid = 1
|
56
|
+
output = ""
|
57
|
+
results['entry'].each do |item|
|
58
|
+
begin
|
59
|
+
item = item['Incident']
|
60
|
+
next unless item['EventData']['Flow']['System']['Node']['Address']
|
61
|
+
portlist = item['EventData']['Flow']['System']['Service']['Portlist']
|
62
|
+
rule = Snort::Rule.new
|
63
|
+
|
64
|
+
rule.dst = item['EventData']['Flow']['System']['Node']['Address']
|
65
|
+
rule.dport = portlist || 'any'
|
66
|
+
rule.options << Snort::RuleOption.new('msg', "#{item['restriction']} - #{item['description']}") if item['restriction'] and item['description']
|
67
|
+
rule.options << Snort::RuleOption.new('threshold', 'type limit,track by_src,count 1,seconds 3600')
|
68
|
+
rule.options << Snort::RuleOption.new('sid', sid)
|
69
|
+
rule.options << Snort::RuleOption.new('reference', item['AlternativeID']['IncidentID']['content']) if item['AlternativeID']['IncidentID']['content']
|
70
|
+
sid += 1
|
71
|
+
output += rule.to_s + "\n"
|
72
|
+
rescue Exception => e
|
73
|
+
# do nothing
|
74
|
+
end
|
75
|
+
end
|
76
|
+
output
|
77
|
+
end
|
78
78
|
end
|
79
79
|
|
80
80
|
opts = GetoptLong.new(
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
81
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
82
|
+
[ '--config', '-c', GetoptLong::REQUIRED_ARGUMENT ],
|
83
|
+
[ '--severity', '-s', GetoptLong::REQUIRED_ARGUMENT ],
|
84
|
+
[ '--restriction', '-r', GetoptLong::REQUIRED_ARGUMENT ],
|
85
|
+
[ '--nolog', '-n', GetoptLong::NO_ARGUMENT ],
|
86
|
+
[ '--xml', '-x', GetoptLong::NO_ARGUMENT ],
|
87
|
+
[ '--json', '-j', GetoptLong::NO_ARGUMENT ],
|
88
|
+
[ '--yaml', '-y', GetoptLong::NO_ARGUMENT ],
|
89
|
+
[ '--delim', '-d', GetoptLong::REQUIRED_ARGUMENT ],
|
90
|
+
[ '--text', '-t', GetoptLong::NO_ARGUMENT ],
|
91
|
+
[ '--snort', '-o', GetoptLong::NO_ARGUMENT ]
|
92
92
|
)
|
93
93
|
config = "#{ENV['HOME']}/.cif"
|
94
94
|
severity = nil
|
@@ -98,43 +98,43 @@ format = 'text'
|
|
98
98
|
delim = "\t"
|
99
99
|
|
100
100
|
opts.each do |opt, arg|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
101
|
+
case opt
|
102
|
+
when '--help'
|
103
|
+
usage
|
104
|
+
when '--config'
|
105
|
+
config = arg
|
106
|
+
when '--severity'
|
107
|
+
severity = arg
|
108
|
+
when '--restriction'
|
109
|
+
restriction = arg
|
110
|
+
when '--nolog'
|
111
|
+
nolog = true
|
112
|
+
when '--xml'
|
113
|
+
format = 'xml'
|
114
|
+
when '--json'
|
115
|
+
format = 'json'
|
116
|
+
when '--yaml'
|
117
|
+
format = 'yaml'
|
118
|
+
when '--snort'
|
119
|
+
format = 'snort'
|
120
|
+
when '--delim'
|
121
|
+
delim = arg
|
122
|
+
when '--text'
|
123
|
+
format = 'text'
|
124
|
+
else
|
125
|
+
usage
|
126
|
+
end
|
127
127
|
end
|
128
128
|
usage if ARGV.length == 0
|
129
129
|
unless(File.exists?(config))
|
130
|
-
|
131
|
-
|
132
|
-
|
130
|
+
puts "cifcli requires a configuration file to work. It defaults to ~/.cif"
|
131
|
+
puts "please refer to the documentation for more detail"
|
132
|
+
exit
|
133
133
|
end
|
134
134
|
config = ConfigParser.new(config)
|
135
135
|
host = config['client']['host']
|
136
136
|
apikey = config['client']['apikey']
|
137
137
|
client = CIF::Client.new(host,apikey,severity,restriction,nolog)
|
138
138
|
ARGV.each do |query|
|
139
|
-
|
139
|
+
puts format_results(client.query(query),format,delim)
|
140
140
|
end
|
data/cif-client.gemspec
CHANGED
@@ -4,26 +4,26 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'cif/client/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
spec.name = "cif-client"
|
8
|
+
spec.version = CIF::Client::VERSION
|
9
|
+
spec.authors = ["chrislee35"]
|
10
|
+
spec.email = ["rubygems@chrislee.dhs.org"]
|
11
|
+
spec.description = %q{CIF is a cyber threat intelligence management system. CIF allows you to combine known malicious threat information from many sources and use that information for identification (incident response), detection (IDS) and mitigation (null route). The most common types of threat intelligence warehoused in CIF are IP addresses, domains and urls that are observed to be related to malicious activity.}
|
12
|
+
spec.summary = %q{Ruby-based client and library for the Collective Intelligence Framework}
|
13
|
+
spec.homepage = "https://code.google.com/p/collective-intelligence-framework/"
|
14
|
+
spec.license = "MIT"
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
spec.add_runtime_dependency "configparser", "~> 0.1.2"
|
22
|
+
spec.add_runtime_dependency "json", "~> 1.4.3"
|
23
|
+
spec.add_runtime_dependency "snort-rule", "~> 1.0.2"
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
spec.signing_key = "#{File.dirname(__FILE__)}/../gem-private_key.pem"
|
28
|
+
spec.cert_chain = ["#{File.dirname(__FILE__)}/../gem-public_cert.pem"]
|
29
29
|
end
|
data/lib/cif/client.rb
CHANGED
@@ -9,38 +9,39 @@ require 'net/https'
|
|
9
9
|
require 'openssl'
|
10
10
|
|
11
11
|
module CIF
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
12
|
+
class Client
|
13
|
+
attr_accessor :fields
|
14
|
+
attr_writer :severity, :restriction, :fields
|
15
|
+
def initialize(host,apikey,severity=nil,restriction=nil,nolog=false)
|
16
|
+
@host = host
|
17
|
+
@apikey = apikey
|
18
|
+
@severity = severity
|
19
|
+
@nolog = nolog
|
20
|
+
@restriction = restriction
|
21
|
+
end
|
22
|
+
|
23
|
+
def query(q,severity=nil,restriction=nil,nolog=false)
|
24
|
+
params = {'apikey' => @apikey}
|
25
|
+
params['restriction'] = restriction || @restriction if restriction || @restriction
|
26
|
+
params['severity'] = severity || @severity if severity || @severity
|
27
|
+
params['nolog'] = 1 if nolog || @nolog
|
28
|
+
s = "#{@host}/#{q}?"+params.map{|k,v| "#{k}=#{v}"}.join("&")
|
29
|
+
url = URI.parse s
|
30
|
+
http = Net::HTTP.new(url.host, url.port)
|
31
|
+
http.use_ssl = (url.scheme == 'https')
|
32
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
33
|
+
http.verify_depth = 5
|
34
|
+
request = Net::HTTP::Get.new(url.path+"?"+url.query)
|
35
|
+
request.add_field("User-Agent", "Ruby/#{RUBY_VERSION} cif-client v#{CIF::Client::VERSION}")
|
36
|
+
request.add_field("Accept", "application/json")
|
37
|
+
response = http.request(request)
|
38
|
+
doc = response.body
|
39
|
+
data = JSON.parse(doc)
|
40
|
+
@response_code = data['status']
|
41
|
+
if data['data'] and data['data']['feed']
|
42
|
+
feed = data['data']['feed']
|
43
|
+
end
|
44
|
+
feed
|
45
|
+
end
|
46
|
+
end
|
46
47
|
end
|
data/lib/cif/client/version.rb
CHANGED
data/test/test_cif-client.rb
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
unless Kernel.respond_to?(:require_relative)
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Kernel
|
3
|
+
def require_relative(path)
|
4
|
+
require File.join(File.dirname(caller[0]), path.to_str)
|
5
|
+
end
|
6
|
+
end
|
7
7
|
end
|
8
8
|
|
9
9
|
require_relative 'helper'
|
10
10
|
|
11
11
|
class TestCIFClient < Test::Unit::TestCase
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def test_perform_a_query_and_receive_results
|
13
|
+
config = "#{ENV['HOME']}/.cif"
|
14
|
+
severity = nil
|
15
|
+
restriction = nil
|
16
|
+
nolog = false
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
18
|
+
config = ConfigParser.new(config)
|
19
|
+
host = config['client']['host']
|
20
|
+
apikey = config['client']['apikey']
|
21
|
+
query = "64.120.146.250"
|
22
|
+
client = CIF::Client.new(host,apikey,severity,restriction,nolog)
|
23
|
+
results = client.query(query)
|
24
|
+
assert_not_nil(results)
|
25
|
+
puts results
|
26
|
+
end
|
27
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cif-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- chrislee35
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
jLXMQu2ZgISYwXNjNbGVHehut82U7U9oiHoWcrOGazaRUmGO9TXP+aJLH0gw2dcK
|
31
31
|
AfMglXPi
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2014-
|
33
|
+
date: 2014-05-02 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: configparser
|
@@ -66,14 +66,14 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.
|
69
|
+
version: 1.0.2
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: 0.
|
76
|
+
version: 1.0.2
|
77
77
|
- !ruby/object:Gem::Dependency
|
78
78
|
name: bundler
|
79
79
|
requirement: !ruby/object:Gem::Requirement
|
metadata.gz.sig
CHANGED
Binary file
|