timing_attack 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b6f971fe9e7eb6b8aa282dffbd7c0eea3a2f009
4
- data.tar.gz: e05deb06b3c31be39f128c7906ef3534abad6d09
3
+ metadata.gz: 8bdfcbf107fd5fffba64e424a8cce2d85a31ee8b
4
+ data.tar.gz: b6f3b3eed4f88b493e676d651c9b3a8a669c8c56
5
5
  SHA512:
6
- metadata.gz: c0e1f43f47fafd477678072023fcba97c6db2dbe12f6d09f6c1face92feed5fe6a17f2a16e79bb692e0db1b4e912f7136f5cd47d3f07e66dabafbf52ab293df3
7
- data.tar.gz: 8977b5ddbea3da6e3511c1e9b0c9921d194a99e1cfabe7cbe104882579a949a562458fcc17adf72ded2ddb8cbc08e51cf4950349fe30046f9e342f85d5743e73
6
+ metadata.gz: 663c64fb49012a9ba42836eecc1a4974983a65c578599ad71c6e7fb43654e855503f5d2dc8dd0469ca2916eb01e10935463ad32899e6be78eddee58b74085918
7
+ data.tar.gz: 1411e2f1eb5f1e565314ad20c9eeee2258b530fc2c87686fde4df078ec6bc52d85573637aca5f6efa8587f29f2dfab5cb011c385cb88fb360d4cbdc809a35b5f
data/README.md CHANGED
@@ -14,17 +14,20 @@ discrepancies in the application's response time.
14
14
  ```
15
15
  timing_attack [options] -u <target> <inputs>
16
16
  -u, --url URL URL of endpoint to profile
17
- -n, --number NUM Requests per input
18
- -t, --threshold NUM Minimum threshold, in seconds, for meaningfulness (default: 0.05)
17
+ -n, --number NUM Requests per input (default: 50)
18
+ -c, --concurrency NUM Number of concurrent requests (default: 15)
19
+ -t, --threshold NUM Minimum threshold, in seconds, for meaningfulness (default: 0.025)
19
20
  -p, --post Use POST, not GET
20
21
  -q, --quiet Quiet mode (don't display progress bars)
22
+ --percentile N Use Nth percentile for calculations (default: 3)
21
23
  --mean Use mean for calculations
22
24
  --median Use median for calculations
23
- --percentile N Use Nth percentile for calculations
24
25
  -v, --version Print version information
25
26
  -h, --help Display this screen
26
27
  ```
27
28
 
29
+ Note that setting concurrency too high can add significant jitter to your results. If you know that your inputs contain elements in both long and short response groups but your results are bogus, try backing off on concurrency. The default value of 15 is a good starting place for robust remote targets, but you might need to dial it back to as far as 1 (especially if you're attacking a single-threaded server)
30
+
28
31
  ### An example
29
32
 
30
33
  Consider that we we want to gather information from a Rails server running
data/exe/timing_attack CHANGED
@@ -7,15 +7,20 @@ opt_parser = OptionParser.new do |opts|
7
7
  opts.program_name = File.basename(__FILE__)
8
8
  opts.banner = "#{opts.program_name} [options] -u <target> <inputs>"
9
9
  opts.on("-u URL", "--url URL", "URL of endpoint to profile") { |str| options[:url] = str }
10
- opts.on("-n NUM", "--number NUM", "Requests per input (default: 0.025)") { |num| options[:iterations] = num.to_i }
10
+ opts.on("-n NUM", "--number NUM", "Requests per input (default: 50)") do |num|
11
+ options[:iterations] = num.to_i
12
+ end
13
+ opts.on("-c NUM", "--concurrency NUM", "Number of concurrent requests (default: 15)") do |num|
14
+ options[:concurrency] = num.to_i
15
+ end
11
16
  opts.on("-t NUM", "--threshold NUM", "Minimum threshold, in seconds, for meaningfulness (default: 0.025)") do |num|
12
17
  options[:threshold] = num.to_f
13
18
  end
14
19
  opts.on("-p", "--post", "Use POST, not GET") { |bool| options[:method] = bool ? :post : :get }
15
20
  opts.on("-q", "--quiet", "Quiet mode (don't display progress bars)") { |bool| options[:verbose] = !bool }
21
+ opts.on("--percentile N", "Use Nth percentile for calculations (default: 3)") { |num| options[:percentile] = num.to_i }
16
22
  opts.on("--mean", "Use mean for calculations") { |bool| options[:mean] = bool }
17
23
  opts.on("--median", "Use median for calculations") { |bool| options[:median] = bool }
18
- opts.on("--percentile N", "Use Nth percentile for calculations (default: 10)") { |num| options[:percentile] = num.to_i }
19
24
  opts.on_tail("-v", "--version", "Print version information") do
20
25
  gem = Gem::Specification.find_by_name('timing_attack')
21
26
  puts "#{gem.name} #{gem.version}"
@@ -13,7 +13,6 @@ module TimingAttack
13
13
 
14
14
  def run!
15
15
  puts "Target: #{url}" if verbose?
16
- warmup!
17
16
  attack!
18
17
  puts report
19
18
  end
@@ -38,20 +37,19 @@ module TimingAttack
38
37
  ret
39
38
  end
40
39
 
41
- def warmup!
42
- 2.times do
43
- warmup = TestCase.new(input: attacks.sample.input, options: options)
44
- warmup.test!
45
- end
46
- end
47
-
48
40
  def attack!
41
+ hydra = Typhoeus::Hydra.new(max_concurrency: concurrency)
49
42
  iterations.times do
50
43
  attacks.each do |attack|
51
- attack.test!
52
- attack_bar.increment
44
+ req = attack.generate_hydra_request!
45
+ req.on_complete do |response|
46
+ attack_bar.increment
47
+ end
48
+ hydra.queue req
53
49
  end
54
50
  end
51
+ hydra.run
52
+ attacks.each(&:process!)
55
53
  end
56
54
 
57
55
  def grouper
@@ -89,7 +87,7 @@ module TimingAttack
89
87
  @null_bar ||= @null_bar_klass.new
90
88
  end
91
89
 
92
- %i(iterations url verbose width method mean percentile threshold).each do |sym|
90
+ %i(iterations url verbose width method mean percentile threshold concurrency).each do |sym|
93
91
  define_method(sym) { options.fetch sym }
94
92
  end
95
93
  alias_method :verbose?, :verbose
@@ -97,10 +95,11 @@ module TimingAttack
97
95
  DEFAULT_OPTIONS = {
98
96
  verbose: false,
99
97
  method: :get,
100
- iterations: 5,
98
+ iterations: 50,
101
99
  mean: false,
102
100
  threshold: 0.025,
103
- percentile: 10
101
+ percentile: 3,
102
+ concurrency: 15
104
103
  }.freeze
105
104
  end
106
105
  end
@@ -6,20 +6,29 @@ module TimingAttack
6
6
  @options = options
7
7
  @times = []
8
8
  @percentiles = []
9
+ @hydra_requests = []
9
10
  end
10
11
 
11
- def test!
12
- httparty_opts = {
13
- body: {
12
+ def generate_hydra_request!
13
+ req = Typhoeus::Request.new(
14
+ options.fetch(:url),
15
+ method: options.fetch(:method),
16
+ params: {
14
17
  login: input,
15
18
  password: "test" * 1000
16
19
  },
17
- timeout: 5
18
- }
19
- before = Time.now
20
- HTTParty.send(options.fetch(:method), options.fetch(:url), httparty_opts)
21
- diff = (Time.now - before)
22
- times.push(diff)
20
+ followlocation: true
21
+ )
22
+ @hydra_requests.push req
23
+ req
24
+ end
25
+
26
+ def process!
27
+ @hydra_requests.each do |request|
28
+ response = request.response
29
+ diff = response.time - response.namelookup_time
30
+ @times.push(diff)
31
+ end
23
32
  end
24
33
 
25
34
  def mean
@@ -1,3 +1,3 @@
1
1
  module TimingAttack
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/timing_attack.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'httparty'
1
+ require 'typhoeus'
2
2
  require 'ruby-progressbar'
3
3
  require "timing_attack/version"
4
4
  require "timing_attack/grouper"
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.licenses = %q(MIT)
21
21
 
22
22
  spec.add_runtime_dependency "ruby-progressbar", "~> 1.8"
23
- spec.add_runtime_dependency "httparty", "~> 0.13.3"
23
+ spec.add_runtime_dependency "typhoeus", "~> 1.1"
24
24
  spec.add_development_dependency "bundler", "~> 1.12"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "rspec", "~> 3.0"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timing_attack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Forrest Fleming
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.8'
27
27
  - !ruby/object:Gem::Dependency
28
- name: httparty
28
+ name: typhoeus
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.13.3
33
+ version: '1.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.13.3
40
+ version: '1.1'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement