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 +4 -4
- data/README.md +6 -3
- data/exe/timing_attack +7 -2
- data/lib/timing_attack/cli_attacker.rb +12 -13
- data/lib/timing_attack/test_case.rb +18 -9
- data/lib/timing_attack/version.rb +1 -1
- data/lib/timing_attack.rb +1 -1
- data/timing_attack.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bdfcbf107fd5fffba64e424a8cce2d85a31ee8b
|
4
|
+
data.tar.gz: b6f3b3eed4f88b493e676d651c9b3a8a669c8c56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
-
|
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:
|
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.
|
52
|
-
|
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:
|
98
|
+
iterations: 50,
|
101
99
|
mean: false,
|
102
100
|
threshold: 0.025,
|
103
|
-
percentile:
|
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
|
12
|
-
|
13
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
data/lib/timing_attack.rb
CHANGED
data/timing_attack.gemspec
CHANGED
@@ -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 "
|
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.
|
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:
|
28
|
+
name: typhoeus
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
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:
|
40
|
+
version: '1.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|