fofa 0.3.17 → 0.4.21

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 (6) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile.lock +2 -2
  3. data/bin/fofacli +103 -22
  4. data/lib/fofa/version.rb +13 -1
  5. data/lib/fofa.rb +59 -23
  6. metadata +7 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c547727d9ed816e3d644f0416cc146bf6e856914
4
- data.tar.gz: 4b972ee2dc95eefadfe1233d4ab01cd912c790d1
2
+ SHA256:
3
+ metadata.gz: 4ba6286e4654e1e55b8b07ba1996edfb64b61139eb9957f03a7e73a35ae93e4a
4
+ data.tar.gz: 0b0c0daa6a59f9c602b5e72c19cf35f539cef73d0a0609d8090d73dd9ecc1676
5
5
  SHA512:
6
- metadata.gz: e3650e6c08280779282fd7865c912d9e2ec152ca3b8aea318e43f7a6e70014ca32308b7a38de9a45edb2b9e27434dc74fba6c9d2811f05648aea9ba7acff7863
7
- data.tar.gz: 2e919a75409e0c1a6fc7ee1eba8f9c094f630c061eaabbfa2d84e56519efe98c9583040177503eb48a701f9bf18c913c0419c5d77908c4249a28a05cba5a79b3
6
+ metadata.gz: 137d9c7252fd91dff2f6ac7d61f01fa43bca086bb716912c8e694aebaca9817970051708e29726f8c0c16920b7bf11e9b4b66334758ee826b24f5d907b2008fa
7
+ data.tar.gz: 0716e3e28ce190378a25aae007308d395ee651fa4ac02dd1ba29d36482f084f69b1a298d362dd4180bc7d6d34b7618db49efc2f598c683287977f45ccc9cad27
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fofa (0.3.16)
4
+ fofa (0.4.20)
5
5
  colorize
6
6
  concurrent-ruby
7
7
 
@@ -38,4 +38,4 @@ DEPENDENCIES
38
38
  rspec (~> 3.0)
39
39
 
40
40
  BUNDLED WITH
41
- 1.15.1
41
+ 1.16.4
data/bin/fofacli CHANGED
@@ -21,7 +21,8 @@ options = {
21
21
  format: 'csv',
22
22
  check_app_category: nil,
23
23
  check_app_application: nil,
24
- check_app_all: false
24
+ check_app_all: false,
25
+ task_id: nil
25
26
  }
26
27
 
27
28
  ARGV.options do |opts|
@@ -42,12 +43,16 @@ ARGV.options do |opts|
42
43
  options[:page] = val.to_i
43
44
  end
44
45
 
45
- opts.on('-m', '--mode=MODE', String, 'Mode, default to [search], -m should be specified when [import_service, query_ip_list, check_app] ') do |val|
46
+ opts.on('-m', '--mode=MODE', String, 'Mode, default to [search], -m should be specified when [import_service, query_ip_list, check_app, ip_tags] ') do |val|
46
47
  options[:mode] = val.to_sym
47
48
  end
48
49
 
49
- opts.on('-f', '--file=FILE', String, 'Used at [import_service] mode') do |val|
50
+ opts.on('-f', '--file=FILE', String, 'Used at [import_service, check_app, ip_tags] mode') do |val|
50
51
  options[:file] = val
52
+ end
53
+
54
+ opts.on('-t', '--task_id=ID', Integer, 'Used at [ip_tags] mode') do |val|
55
+ options[:task_id] = val.to_i
51
56
  end
52
57
 
53
58
  opts.on('-s', '--limit=SIZE', Integer, "Limit size to fetch, default to #{options[:limit]}") do |val|
@@ -80,7 +85,7 @@ ARGV.options do |opts|
80
85
  opts.on('-g', "--category=CATEGORY", String, "Category to check, only used in check_app mode." ) do |val|
81
86
  options[:check_app_category] = val
82
87
  options[:mode] = :check_app
83
- end
88
+ end
84
89
 
85
90
  opts.separator "Common Options:"
86
91
 
@@ -97,9 +102,14 @@ ARGV.options do |opts|
97
102
  options[:verbose] = true
98
103
  end
99
104
 
105
+ opts.on( "-V", "--version", "Display version" ) do
106
+ puts "Version: #{Fofa::VERSION}"
107
+ exit(0)
108
+ end
109
+
100
110
  opts.on( nil, "--check_app_all", "Check all applications, only used in check_app mode." ) do
101
111
  options[:check_app_all] = true
102
- end
112
+ end
103
113
 
104
114
 
105
115
 
@@ -110,6 +120,9 @@ ARGV.options do |opts|
110
120
  opts.separator "\t fofacli -e aaa@bbb.com -a xxx --query_file /tmp/fofaquery"
111
121
  opts.separator "\t fofacli -e aaa@bbb.com -a xxx -d ip,domain,title,port,protocol -m query_ip_list -f ip.txt"
112
122
  opts.separator %Q@\t cat vapps.txt | xargs -I{} -n 1 sh -c 'fofacli "app=$1" -d host,ip,port,country,province,city -s 1000 -o json -v > "$1.txt"' -- {}@
123
+ opts.separator "\t fofacli -m check_app --app \"Coremail\" mail.tsinghua.edu.cn"
124
+ opts.separator "\t fofacli -e aaa@bbb.com -a xxx -m ip_tags -f ./ip.txt"
125
+ opts.separator "\t fofacli -e aaa@bbb.com -a xxx -m ip_tags -t 1"
113
126
 
114
127
  begin
115
128
  opts.parse!
@@ -139,17 +152,17 @@ def log_record(options, r)
139
152
  case options[:format]
140
153
  when 'json'
141
154
  if r.kind_of?(Array)
142
- puts Hash[options[:fields].split(',').zip r].to_json
155
+ STDOUT.puts Hash[options[:fields].split(',').zip r].to_json
143
156
  elsif r.kind_of?(Hash)
144
- puts r.to_json
157
+ STDOUT.puts r.to_json
145
158
  else
146
- puts %Q|{"id":"#{r}"}|
159
+ STDOUT.puts %Q|{"id":"#{r}"}|
147
160
  end
148
161
  when 'csv'
149
162
  if r.kind_of?(Array)
150
- puts r.map{|v| v}.join("\t")
163
+ STDOUT.puts r.map{|v| v}.join("\t")
151
164
  else
152
- puts r
165
+ STDOUT.puts r
153
166
  end
154
167
 
155
168
  end
@@ -163,7 +176,7 @@ case options[:mode]
163
176
  exit -1
164
177
  end
165
178
  query = options[:query] || ARGV.join(' ')
166
- puts "Query: '#{query}'"
179
+ STDERR.puts "Query: '#{query}'"
167
180
  if options[:page] #search one page
168
181
  Fofa::API.new(options[:email], options[:apikey], {debug:options[:verbose]})
169
182
  .search(query, {
@@ -205,7 +218,7 @@ case options[:mode]
205
218
  require 'concurrent'
206
219
  semaphore = Concurrent::Semaphore.new(1)
207
220
  pool = Concurrent::FixedThreadPool.new(10)
208
- $stdout.sync = true
221
+ $STDOUT.sync = true
209
222
  File.open(options[:file]){|f|
210
223
  fields = options[:fields].split(',')
211
224
  f.each_line{|line|
@@ -248,16 +261,84 @@ case options[:mode]
248
261
  pool.wait_for_termination
249
262
  when :check_app
250
263
  query = options[:query] || ARGV.join(' ')
251
- res = Fofa::API.new(options[:email], options[:apikey], {debug:options[:verbose]})
252
- .check_app(query, {
253
- category:options[:check_app_category],
254
- application:options[:check_app_application],
255
- all:options[:all],
256
- })
257
-
258
- res.each{|r|
259
- log_record(options, r)
260
- }
264
+ fofa = Fofa::API.new(options[:email], options[:apikey], {debug:options[:verbose]})
265
+ if options[:file]
266
+ File.open(options[:file]){|f|
267
+ f.each_line{|line|
268
+ query = line.strip
269
+ res = fofa.check_app(query, {
270
+ category:options[:check_app_category],
271
+ application:options[:check_app_application],
272
+ all:options[:all],
273
+ })
274
+
275
+ if res && res.size>0
276
+ res.each{|r|
277
+ log_record(options, [query, r])
278
+ }
279
+ else
280
+ log_record(options, [query, nil])
281
+ end
282
+
283
+ }
284
+ }
285
+ else
286
+ res = fofa.check_app(query, {
287
+ category:options[:check_app_category],
288
+ application:options[:check_app_application],
289
+ all:options[:all],
290
+ })
291
+
292
+ if res && res.size>0
293
+ res.each{|r|
294
+ log_record(options, r)
295
+ }
296
+ else
297
+ $stderr.puts "[WARNING] No result!"
298
+ end
299
+
300
+ end
301
+ when :ip_tags
302
+ fofa = Fofa::API.new(options[:email], options[:apikey], {debug:options[:verbose]})
303
+ if options[:task_id]
304
+ task_id = options[:task_id]
305
+ else
306
+ unless options[:file]
307
+ puts "File not specified.".red
308
+ puts ARGV.options
309
+ exit -1
310
+ end
311
+ puts "Import ip and get tags from '#{options[:file]}'"
312
+ result = fofa.ip_tags(options[:file])
313
+ if result['error']
314
+ puts result
315
+ exit -1
316
+ end
317
+ puts result
318
+ task_id = result['task_id']
319
+ end
320
+
321
+ if task_id
322
+ get_info = -> (fofa, id) { fofa.tag_info(id) }
323
+ puts "Checking progress!"
324
+ sleep(2)
325
+
326
+ loop do
327
+ info = get_info.call(fofa, task_id)
328
+ if info['error']
329
+ puts info
330
+ break
331
+ elsif info['progress'].to_i == 100
332
+ puts "state: #{info['state']}; progress: #{info['progress']}."
333
+ puts info['download_url']
334
+ break
335
+ else
336
+ puts "state: #{info['state']}; progress: #{info['progress']}."
337
+ sleep(10)
338
+ end
339
+ end
340
+
341
+ end
261
342
 
262
343
  end
263
344
 
data/lib/fofa/version.rb CHANGED
@@ -1,3 +1,15 @@
1
+ # 0.4.21
2
+ # split result to stdout
3
+ #
4
+ # 0.4.20
5
+ # add -V option, and ip_tags method need to upgrade major version
6
+ #
7
+ # 0.3.19
8
+ # add feature: ip_tags, tag_info
9
+ #
10
+ # 0.3.18
11
+ # add feature: check applications from file
12
+ #
1
13
  # 0.3.17
2
14
  # add checkapp api call
3
15
  #
@@ -28,5 +40,5 @@
28
40
  # 0.3.6
29
41
  # add fields
30
42
  module Fofa
31
- VERSION = "0.3.17"
43
+ VERSION = "0.4.21"
32
44
  end
data/lib/fofa.rb CHANGED
@@ -153,31 +153,67 @@ module Fofa
153
153
  req = Net::HTTP::Get.new(uri.request_uri)
154
154
  resp = http.request(req)
155
155
  JSON.parse(resp.body)
156
+ rescue => e
157
+ {"error"=>"Error: #{e.to_s}"}
158
+ end
159
+
160
+ # Import ip and get tags
161
+ #
162
+ # Example:
163
+ # >> Fofa::API.new(email,apikey).ip_tags('./ips.txt')
164
+ # => {"task_id"=>1}
165
+ #
166
+ # Arguments:
167
+ # file: (String) ip file
168
+ def ip_tags(file)
169
+ url = "#{@api_server}/api/v1/ip_tags?key=#{@apikey}&email=#{@email}"
170
+ puts url if @options[:debug]
171
+
172
+ # Token used to terminate the file in the post body. Make sure it is not
173
+ # present in the file you're uploading.
174
+ # You might want to use `SecureRandom` class to generate this random strings
175
+ boundary = "AaB03x"
176
+ uri = URI.parse(url)
177
+
178
+ post_body = []
179
+ post_body << "--#{boundary}\r\n"
180
+ post_body << "Content-Disposition: form-data; name=\"file\"; filename=\"#{File.basename(file)}\"\r\n"
181
+ post_body << "Content-Type: text/plain\r\n"
182
+ post_body << "\r\n"
183
+ post_body << File.read(file)
184
+ post_body << "\r\n--#{boundary}--\r\n"
185
+
186
+ http = http_new(uri)
187
+ req = Net::HTTP::Post.new(uri.request_uri)
188
+ req.body = post_body.join
189
+ req["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
190
+
191
+ resp = http.request(req)
192
+ puts resp if @options[:debug]
193
+ JSON.parse(resp.body)
194
+ rescue => e
195
+ {"error"=>"Error: #{e.to_s}"}
196
+ end
197
+
198
+ # Check ip_tags's task state, progress, and download_url
199
+ #
200
+ # Example:
201
+ # >> Fofa::API.new(email,apikey).tag_info(1)
202
+ # => {"state"=>"success", "progress"=>100, "download_url"=>"https://host/xxx/56af409c1c55762a7b9e9a39a801f80d.json"}
203
+ #
204
+ # Arguments:
205
+ # task_id: (Integer) task id
206
+ def tag_info(task_id)
207
+ url = "#{@api_server}/api/v1/ip_tags/info?key=#{@apikey}&email=#{@email}&task_id=#{task_id}"
208
+ puts url if @options[:debug]
209
+ uri = URI.parse(url)
210
+ http = http_new(uri)
211
+ req = Net::HTTP::Get.new(uri.request_uri)
156
212
 
157
- # File.open(file) do |f|
158
- # results = []
159
- # f.each_line.lazy.each_with_index do |line, i|
160
- #
161
- # line = line.strip
162
- # if m = /Discovered open port (?<port>.*?)\/tcp on (?<host>.*?)$/.match(line)
163
- # hostinfo = "#{m[:host]}:#{m[:port]}"
164
- # elsif line.include?(':')
165
- # hostinfo = line
166
- # else
167
- # hostinfo = "#{line}:#{options[:port]}"
168
- # end
169
- #
170
- # results << line
171
- # if i % split_size == 0
172
- # req = Net::HTTP::Post.new(uri.request_uri)
173
- # req.body = results.join("\n")
174
- # resp = http.request(req)
175
- # puts resp if @options[:debug]
176
- # results = []
177
- # end
178
- # end
179
- # end
213
+ resp = http.request(req)
214
+ JSON.parse(resp.body)
180
215
  rescue => e
216
+ $stderr.puts "[WARNING]: #{e.to_s}"
181
217
  {"error"=>"Error: #{e.to_s}"}
182
218
  end
183
219
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fofa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.17
4
+ version: 0.4.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - fofa
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-08 00:00:00.000000000 Z
11
+ date: 2021-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -106,7 +106,7 @@ homepage: https://fofa.so
106
106
  licenses:
107
107
  - MIT
108
108
  metadata: {}
109
- post_install_message:
109
+ post_install_message:
110
110
  rdoc_options: []
111
111
  require_paths:
112
112
  - lib
@@ -121,9 +121,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0'
123
123
  requirements: []
124
- rubyforge_project:
125
- rubygems_version: 2.6.12
126
- signing_key:
124
+ rubyforge_project:
125
+ rubygems_version: 2.7.7
126
+ signing_key:
127
127
  specification_version: 4
128
128
  summary: A Ruby library to interact with the FOFA API. https://fofa.so
129
129
  test_files: []