aikido-zen 1.0.1.beta.4-arm64-linux → 1.0.1.beta.5-arm64-linux
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.
- checksums.yaml +4 -4
- data/lib/aikido/zen/sinks/async_http.rb +40 -42
- data/lib/aikido/zen/sinks/curb.rb +56 -58
- data/lib/aikido/zen/sinks/em_http.rb +27 -29
- data/lib/aikido/zen/sinks/excon.rb +62 -65
- data/lib/aikido/zen/sinks/file.rb +66 -70
- data/lib/aikido/zen/sinks/http.rb +26 -28
- data/lib/aikido/zen/sinks/httpclient.rb +27 -29
- data/lib/aikido/zen/sinks/httpx.rb +27 -29
- data/lib/aikido/zen/sinks/kernel.rb +11 -12
- data/lib/aikido/zen/sinks/mysql2.rb +10 -12
- data/lib/aikido/zen/sinks/net_http.rb +25 -27
- data/lib/aikido/zen/sinks/patron.rb +56 -58
- data/lib/aikido/zen/sinks/pg.rb +23 -25
- data/lib/aikido/zen/sinks/resolv.rb +21 -21
- data/lib/aikido/zen/sinks/socket.rb +10 -12
- data/lib/aikido/zen/sinks/sqlite3.rb +18 -21
- data/lib/aikido/zen/sinks/trilogy.rb +10 -12
- data/lib/aikido/zen/sinks.rb +1 -4
- data/lib/aikido/zen/sinks_dsl.rb +27 -15
- data/lib/aikido/zen/version.rb +1 -1
- data/lib/aikido/zen.rb +1 -1
- metadata +2 -2
@@ -6,14 +6,6 @@ require_relative "../outbound_connection_monitor"
|
|
6
6
|
module Aikido::Zen
|
7
7
|
module Sinks
|
8
8
|
module HTTP
|
9
|
-
def self.load_sinks!
|
10
|
-
if Aikido::Zen.satisfy "http", ">= 1.0"
|
11
|
-
require "http"
|
12
|
-
|
13
|
-
::HTTP::Client.prepend(ClientExtensions)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
9
|
SINK = Sinks.add("http", scanners: [
|
18
10
|
Scanners::SSRFScanner,
|
19
11
|
OutboundConnectionMonitor
|
@@ -59,33 +51,39 @@ module Aikido::Zen
|
|
59
51
|
end
|
60
52
|
end
|
61
53
|
|
62
|
-
|
63
|
-
|
54
|
+
def self.load_sinks!
|
55
|
+
if Aikido::Zen.satisfy "http", ">= 1.0"
|
56
|
+
require "http"
|
64
57
|
|
65
|
-
|
66
|
-
|
58
|
+
::HTTP::Client.class_eval do
|
59
|
+
extend Sinks::DSL
|
67
60
|
|
68
|
-
|
69
|
-
|
70
|
-
if context
|
71
|
-
prev_request = context["ssrf.request"]
|
72
|
-
context["ssrf.request"] = wrapped_request
|
73
|
-
end
|
61
|
+
sink_around :perform do |original_call, req|
|
62
|
+
wrapped_request = Helpers.wrap_request(req)
|
74
63
|
|
75
|
-
|
64
|
+
# Store the request information so the DNS sinks can pick it up.
|
65
|
+
context = Aikido::Zen.current_context
|
66
|
+
if context
|
67
|
+
prev_request = context["ssrf.request"]
|
68
|
+
context["ssrf.request"] = wrapped_request
|
69
|
+
end
|
76
70
|
|
77
|
-
|
71
|
+
connection = Helpers.build_outbound(req)
|
78
72
|
|
79
|
-
|
73
|
+
Helpers.scan(wrapped_request, connection, "request")
|
80
74
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
75
|
+
response = original_call.call
|
76
|
+
|
77
|
+
Scanners::SSRFScanner.track_redirects(
|
78
|
+
request: wrapped_request,
|
79
|
+
response: Helpers.wrap_response(response)
|
80
|
+
)
|
85
81
|
|
86
|
-
|
87
|
-
|
88
|
-
|
82
|
+
response
|
83
|
+
ensure
|
84
|
+
context["ssrf.request"] = prev_request if context
|
85
|
+
end
|
86
|
+
end
|
89
87
|
end
|
90
88
|
end
|
91
89
|
end
|
@@ -6,14 +6,6 @@ require_relative "../outbound_connection_monitor"
|
|
6
6
|
module Aikido::Zen
|
7
7
|
module Sinks
|
8
8
|
module HTTPClient
|
9
|
-
def self.load_sinks!
|
10
|
-
if Aikido::Zen.satisfy "httpclient", ">= 2.0"
|
11
|
-
require "httpclient"
|
12
|
-
|
13
|
-
::HTTPClient.prepend(HTTPClient::HTTPClientExtensions)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
9
|
SINK = Sinks.add("httpclient", scanners: [
|
18
10
|
Scanners::SSRFScanner,
|
19
11
|
OutboundConnectionMonitor
|
@@ -66,28 +58,34 @@ module Aikido::Zen
|
|
66
58
|
end
|
67
59
|
end
|
68
60
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
sink_around :do_get_block do |super_call, req|
|
75
|
-
Helpers.sink(req, &super_call)
|
76
|
-
end
|
77
|
-
|
78
|
-
sink_around :do_get_stream do |super_call, req|
|
79
|
-
Helpers.sink(req, &super_call)
|
80
|
-
end
|
61
|
+
def self.load_sinks!
|
62
|
+
if Aikido::Zen.satisfy "httpclient", ">= 2.0"
|
63
|
+
require "httpclient"
|
81
64
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
65
|
+
::HTTPClient.class_eval do
|
66
|
+
extend Sinks::DSL
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
sink_around :do_get_block do |original_call, req|
|
71
|
+
Helpers.sink(req, &original_call)
|
72
|
+
end
|
73
|
+
|
74
|
+
sink_around :do_get_stream do |original_call, req|
|
75
|
+
Helpers.sink(req, &original_call)
|
76
|
+
end
|
77
|
+
|
78
|
+
sink_after :do_get_header do |_result, req, res, _sess|
|
79
|
+
# Code coverage is disabled here because `do_get_header` is not called,
|
80
|
+
# because WebMock does not mock it.
|
81
|
+
# :nocov:
|
82
|
+
Scanners::SSRFScanner.track_redirects(
|
83
|
+
request: Helpers.wrap_request(req),
|
84
|
+
response: Helpers.wrap_response(res)
|
85
|
+
)
|
86
|
+
# :nocov:
|
87
|
+
end
|
88
|
+
end
|
91
89
|
end
|
92
90
|
end
|
93
91
|
end
|
@@ -6,14 +6,6 @@ require_relative "../outbound_connection_monitor"
|
|
6
6
|
module Aikido::Zen
|
7
7
|
module Sinks
|
8
8
|
module HTTPX
|
9
|
-
def self.load_sinks!
|
10
|
-
if Aikido::Zen.satisfy "httpx", ">= 1.1.3"
|
11
|
-
require "httpx"
|
12
|
-
|
13
|
-
::HTTPX::Session.prepend(HTTPX::SessionExtensions)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
9
|
SINK = Sinks.add("httpx", scanners: [
|
18
10
|
Scanners::SSRFScanner,
|
19
11
|
OutboundConnectionMonitor
|
@@ -44,33 +36,39 @@ module Aikido::Zen
|
|
44
36
|
end
|
45
37
|
end
|
46
38
|
|
47
|
-
|
48
|
-
|
39
|
+
def self.load_sinks!
|
40
|
+
if Aikido::Zen.satisfy "httpx", ">= 1.1.3"
|
41
|
+
require "httpx"
|
49
42
|
|
50
|
-
|
51
|
-
|
43
|
+
::HTTPX::Session.class_eval do
|
44
|
+
extend Sinks::DSL
|
52
45
|
|
53
|
-
|
54
|
-
|
55
|
-
if context
|
56
|
-
prev_request = context["ssrf.request"]
|
57
|
-
context["ssrf.request"] = wrapped_request
|
58
|
-
end
|
46
|
+
sink_around :send_request do |original_call, request|
|
47
|
+
wrapped_request = Helpers.wrap_request(request)
|
59
48
|
|
60
|
-
|
49
|
+
# Store the request information so the DNS sinks can pick it up.
|
50
|
+
context = Aikido::Zen.current_context
|
51
|
+
if context
|
52
|
+
prev_request = context["ssrf.request"]
|
53
|
+
context["ssrf.request"] = wrapped_request
|
54
|
+
end
|
61
55
|
|
62
|
-
|
56
|
+
connection = OutboundConnection.from_uri(request.uri)
|
63
57
|
|
64
|
-
|
65
|
-
|
66
|
-
request:
|
67
|
-
|
68
|
-
|
69
|
-
|
58
|
+
Helpers.scan(wrapped_request, connection, "request")
|
59
|
+
|
60
|
+
request.on(:response) do |response|
|
61
|
+
Scanners::SSRFScanner.track_redirects(
|
62
|
+
request: wrapped_request,
|
63
|
+
response: Helpers.wrap_response(response)
|
64
|
+
)
|
65
|
+
end
|
70
66
|
|
71
|
-
|
72
|
-
|
73
|
-
|
67
|
+
original_call.call
|
68
|
+
ensure
|
69
|
+
context["ssrf.request"] = prev_request if context
|
70
|
+
end
|
71
|
+
end
|
74
72
|
end
|
75
73
|
end
|
76
74
|
end
|
@@ -3,11 +3,6 @@
|
|
3
3
|
module Aikido::Zen
|
4
4
|
module Sinks
|
5
5
|
module Kernel
|
6
|
-
def self.load_sinks!
|
7
|
-
::Kernel.singleton_class.prepend(KernelExtensions)
|
8
|
-
::Kernel.prepend(KernelExtensions)
|
9
|
-
end
|
10
|
-
|
11
6
|
SINK = Sinks.add("Kernel", scanners: [Scanners::ShellInjectionScanner])
|
12
7
|
|
13
8
|
module Helpers
|
@@ -16,14 +11,18 @@ module Aikido::Zen
|
|
16
11
|
end
|
17
12
|
end
|
18
13
|
|
19
|
-
|
20
|
-
|
14
|
+
def self.load_sinks!
|
15
|
+
[::Kernel.singleton_class, ::Kernel].each do |klass|
|
16
|
+
klass.class_eval do
|
17
|
+
extend Sinks::DSL
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
%i[system spawn].each do |method_name|
|
20
|
+
sink_before method_name do |*args|
|
21
|
+
# Remove the optional environment argument before the command-line.
|
22
|
+
args.shift if args.first.is_a?(Hash)
|
23
|
+
Helpers.scan(args.first, method_name)
|
24
|
+
end
|
25
|
+
end
|
27
26
|
end
|
28
27
|
end
|
29
28
|
end
|
@@ -3,14 +3,6 @@
|
|
3
3
|
module Aikido::Zen
|
4
4
|
module Sinks
|
5
5
|
module Mysql2
|
6
|
-
def self.load_sinks!
|
7
|
-
if Aikido::Zen.satisfy "mysql2"
|
8
|
-
require "mysql2"
|
9
|
-
|
10
|
-
::Mysql2::Client.prepend(ClientExtensions)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
6
|
SINK = Sinks.add("mysql2", scanners: [Scanners::SQLInjectionScanner])
|
15
7
|
|
16
8
|
module Helpers
|
@@ -19,11 +11,17 @@ module Aikido::Zen
|
|
19
11
|
end
|
20
12
|
end
|
21
13
|
|
22
|
-
|
23
|
-
|
14
|
+
def self.load_sinks!
|
15
|
+
if Aikido::Zen.satisfy "mysql2"
|
16
|
+
require "mysql2"
|
17
|
+
|
18
|
+
::Mysql2::Client.class_eval do
|
19
|
+
extend Sinks::DSL
|
24
20
|
|
25
|
-
|
26
|
-
|
21
|
+
sink_before :query do |sql|
|
22
|
+
Helpers.scan(sql, "query")
|
23
|
+
end
|
24
|
+
end
|
27
25
|
end
|
28
26
|
end
|
29
27
|
end
|
@@ -7,13 +7,6 @@ module Aikido::Zen
|
|
7
7
|
module Sinks
|
8
8
|
module Net
|
9
9
|
module HTTP
|
10
|
-
def self.load_sinks!
|
11
|
-
# In stdlib but not always required
|
12
|
-
require "net/http"
|
13
|
-
|
14
|
-
::Net::HTTP.prepend(Net::HTTP::HTTPExtensions)
|
15
|
-
end
|
16
|
-
|
17
10
|
SINK = Sinks.add("net-http", scanners: [
|
18
11
|
Scanners::SSRFScanner,
|
19
12
|
OutboundConnectionMonitor
|
@@ -66,33 +59,38 @@ module Aikido::Zen
|
|
66
59
|
end
|
67
60
|
end
|
68
61
|
|
69
|
-
|
70
|
-
|
62
|
+
def self.load_sinks!
|
63
|
+
# In stdlib but not always required
|
64
|
+
require "net/http"
|
71
65
|
|
72
|
-
|
73
|
-
|
66
|
+
::Net::HTTP.class_eval do
|
67
|
+
extend Sinks::DSL
|
74
68
|
|
75
|
-
|
76
|
-
|
77
|
-
if context
|
78
|
-
prev_request = context["ssrf.request"]
|
79
|
-
context["ssrf.request"] = wrapped_request
|
80
|
-
end
|
69
|
+
sink_around :request do |original_call, req|
|
70
|
+
wrapped_request = Helpers.wrap_request(req, self)
|
81
71
|
|
82
|
-
|
72
|
+
# Store the request information so the DNS sinks can pick it up.
|
73
|
+
context = Aikido::Zen.current_context
|
74
|
+
if context
|
75
|
+
prev_request = context["ssrf.request"]
|
76
|
+
context["ssrf.request"] = wrapped_request
|
77
|
+
end
|
83
78
|
|
84
|
-
|
79
|
+
connection = Helpers.build_outbound(self)
|
85
80
|
|
86
|
-
|
81
|
+
Helpers.scan(wrapped_request, connection, "request")
|
87
82
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
83
|
+
response = original_call.call
|
84
|
+
|
85
|
+
Scanners::SSRFScanner.track_redirects(
|
86
|
+
request: wrapped_request,
|
87
|
+
response: Helpers.wrap_response(response)
|
88
|
+
)
|
92
89
|
|
93
|
-
|
94
|
-
|
95
|
-
|
90
|
+
response
|
91
|
+
ensure
|
92
|
+
context["ssrf.request"] = prev_request if context
|
93
|
+
end
|
96
94
|
end
|
97
95
|
end
|
98
96
|
end
|
@@ -6,14 +6,6 @@ require_relative "../outbound_connection_monitor"
|
|
6
6
|
module Aikido::Zen
|
7
7
|
module Sinks
|
8
8
|
module Patron
|
9
|
-
def self.load_sinks!
|
10
|
-
if Aikido::Zen.satisfy "patron", ">= 0.6.4"
|
11
|
-
require "patron"
|
12
|
-
|
13
|
-
::Patron::Session.prepend(SessionExtensions)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
9
|
SINK = Sinks.add("patron", scanners: [
|
18
10
|
Scanners::SSRFScanner,
|
19
11
|
OutboundConnectionMonitor
|
@@ -44,58 +36,64 @@ module Aikido::Zen
|
|
44
36
|
end
|
45
37
|
end
|
46
38
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
sink_around :handle_request do |super_call, request|
|
51
|
-
wrapped_request = Scanners::SSRFScanner::Request.new(
|
52
|
-
verb: request.action,
|
53
|
-
uri: URI(request.url),
|
54
|
-
headers: request.headers
|
55
|
-
)
|
56
|
-
|
57
|
-
# Store the request information so the DNS sinks can pick it up.
|
58
|
-
context = Aikido::Zen.current_context
|
59
|
-
if context
|
60
|
-
prev_request = context["ssrf.request"]
|
61
|
-
context["ssrf.request"] = wrapped_request
|
62
|
-
end
|
63
|
-
|
64
|
-
connection = OutboundConnection.from_uri(URI(request.url))
|
65
|
-
|
66
|
-
Helpers.scan(wrapped_request, connection, "request")
|
67
|
-
|
68
|
-
response = super_call.call
|
69
|
-
|
70
|
-
Scanners::SSRFScanner.track_redirects(
|
71
|
-
request: wrapped_request,
|
72
|
-
response: Helpers.wrap_response(request, response)
|
73
|
-
)
|
74
|
-
|
75
|
-
# When libcurl has follow_location set, it will handle redirections
|
76
|
-
# internally, and expose the response.url as the URI that was last
|
77
|
-
# requested in the redirect chain.
|
78
|
-
#
|
79
|
-
# In this case, we can't actually stop the request from happening, but
|
80
|
-
# we can scan again (now that we know another request happened), to
|
81
|
-
# stop the response from being exposed to the user. This downgrades
|
82
|
-
# the SSRF into a blind SSRF, which is better than doing nothing.
|
83
|
-
if request.url != response.url && !response.url.to_s.empty?
|
84
|
-
last_effective_request = Scanners::SSRFScanner::Request.new(
|
85
|
-
verb: request.action,
|
86
|
-
uri: URI(response.url),
|
87
|
-
headers: request.headers
|
88
|
-
)
|
89
|
-
context["ssrf.request"] = last_effective_request if context
|
90
|
-
|
91
|
-
connection = OutboundConnection.from_uri(URI(response.url))
|
39
|
+
def self.load_sinks!
|
40
|
+
if Aikido::Zen.satisfy "patron", ">= 0.6.4"
|
41
|
+
require "patron"
|
92
42
|
|
93
|
-
|
43
|
+
::Patron::Session.class_eval do
|
44
|
+
extend Sinks::DSL
|
45
|
+
|
46
|
+
sink_around :handle_request do |original_call, request|
|
47
|
+
wrapped_request = Scanners::SSRFScanner::Request.new(
|
48
|
+
verb: request.action,
|
49
|
+
uri: URI(request.url),
|
50
|
+
headers: request.headers
|
51
|
+
)
|
52
|
+
|
53
|
+
# Store the request information so the DNS sinks can pick it up.
|
54
|
+
context = Aikido::Zen.current_context
|
55
|
+
if context
|
56
|
+
prev_request = context["ssrf.request"]
|
57
|
+
context["ssrf.request"] = wrapped_request
|
58
|
+
end
|
59
|
+
|
60
|
+
connection = OutboundConnection.from_uri(URI(request.url))
|
61
|
+
|
62
|
+
Helpers.scan(wrapped_request, connection, "request")
|
63
|
+
|
64
|
+
response = original_call.call
|
65
|
+
|
66
|
+
Scanners::SSRFScanner.track_redirects(
|
67
|
+
request: wrapped_request,
|
68
|
+
response: Helpers.wrap_response(request, response)
|
69
|
+
)
|
70
|
+
|
71
|
+
# When libcurl has follow_location set, it will handle redirections
|
72
|
+
# internally, and expose the response.url as the URI that was last
|
73
|
+
# requested in the redirect chain.
|
74
|
+
#
|
75
|
+
# In this case, we can't actually stop the request from happening, but
|
76
|
+
# we can scan again (now that we know another request happened), to
|
77
|
+
# stop the response from being exposed to the user. This downgrades
|
78
|
+
# the SSRF into a blind SSRF, which is better than doing nothing.
|
79
|
+
if request.url != response.url && !response.url.to_s.empty?
|
80
|
+
last_effective_request = Scanners::SSRFScanner::Request.new(
|
81
|
+
verb: request.action,
|
82
|
+
uri: URI(response.url),
|
83
|
+
headers: request.headers
|
84
|
+
)
|
85
|
+
context["ssrf.request"] = last_effective_request if context
|
86
|
+
|
87
|
+
connection = OutboundConnection.from_uri(URI(response.url))
|
88
|
+
|
89
|
+
Helpers.scan(last_effective_request, connection, "request")
|
90
|
+
end
|
91
|
+
|
92
|
+
response
|
93
|
+
ensure
|
94
|
+
context["ssrf.request"] = prev_request if context
|
95
|
+
end
|
94
96
|
end
|
95
|
-
|
96
|
-
response
|
97
|
-
ensure
|
98
|
-
context["ssrf.request"] = prev_request if context
|
99
97
|
end
|
100
98
|
end
|
101
99
|
end
|
data/lib/aikido/zen/sinks/pg.rb
CHANGED
@@ -3,14 +3,6 @@
|
|
3
3
|
module Aikido::Zen
|
4
4
|
module Sinks
|
5
5
|
module PG
|
6
|
-
def self.load_sinks!
|
7
|
-
if Aikido::Zen.satisfy "pg", ">= 1.0"
|
8
|
-
require "pg"
|
9
|
-
|
10
|
-
::PG::Connection.prepend(PG::ConnectionExtensions)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
6
|
SINK = Sinks.add("pg", scanners: [Scanners::SQLInjectionScanner])
|
15
7
|
|
16
8
|
module Helpers
|
@@ -43,26 +35,32 @@ module Aikido::Zen
|
|
43
35
|
end
|
44
36
|
end
|
45
37
|
|
46
|
-
|
47
|
-
|
38
|
+
def self.load_sinks!
|
39
|
+
if Aikido::Zen.satisfy "pg", ">= 1.0"
|
40
|
+
require "pg"
|
48
41
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
42
|
+
::PG::Connection.class_eval do
|
43
|
+
extend Sinks::DSL
|
44
|
+
|
45
|
+
%i[
|
46
|
+
send_query exec sync_exec async_exec
|
47
|
+
send_query_params exec_params sync_exec_params async_exec_params
|
48
|
+
].each do |method_name|
|
49
|
+
presafe_sink_before method_name do |query|
|
50
|
+
Helpers.safe do
|
51
|
+
Helpers.scan(query, method_name)
|
52
|
+
end
|
53
|
+
end
|
56
54
|
end
|
57
|
-
end
|
58
|
-
end
|
59
55
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
56
|
+
%i[
|
57
|
+
send_prepare prepare async_prepare sync_prepare
|
58
|
+
].each do |method_name|
|
59
|
+
presafe_sink_before method_name do |_, query|
|
60
|
+
Helpers.safe do
|
61
|
+
Helpers.scan(query, method_name)
|
62
|
+
end
|
63
|
+
end
|
66
64
|
end
|
67
65
|
end
|
68
66
|
end
|
@@ -6,13 +6,6 @@ require_relative "../scanners/ssrf_scanner"
|
|
6
6
|
module Aikido::Zen
|
7
7
|
module Sinks
|
8
8
|
module Resolv
|
9
|
-
def self.load_sinks!
|
10
|
-
# In stdlib but not always required
|
11
|
-
require "resolv"
|
12
|
-
|
13
|
-
::Resolv.prepend(ResolvExtensions)
|
14
|
-
end
|
15
|
-
|
16
9
|
SINK = Sinks.add("resolv", scanners: [
|
17
10
|
Scanners::StoredSSRFScanner,
|
18
11
|
Scanners::SSRFScanner
|
@@ -35,23 +28,30 @@ module Aikido::Zen
|
|
35
28
|
end
|
36
29
|
end
|
37
30
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# is applicable.
|
31
|
+
def self.load_sinks!
|
32
|
+
# In stdlib but not always required
|
33
|
+
require "resolv"
|
42
34
|
|
43
|
-
|
35
|
+
::Resolv.class_eval do
|
36
|
+
alias_method :each_address__internal_for_aikido_zen, :each_address
|
44
37
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
38
|
+
def each_address(*args, **kwargs, &blk)
|
39
|
+
# each_address is defined "manually" because no sink method pattern
|
40
|
+
# is applicable.
|
41
|
+
|
42
|
+
name, = args
|
43
|
+
|
44
|
+
addresses = []
|
45
|
+
each_address__internal_for_aikido_zen(*args, **kwargs) do |address|
|
46
|
+
addresses << address
|
47
|
+
blk.call(address)
|
48
|
+
end
|
49
|
+
ensure
|
50
|
+
# Ensure partial results are scanned.
|
52
51
|
|
53
|
-
|
54
|
-
|
52
|
+
Sinks::DSL.safe do
|
53
|
+
Helpers.scan(name, addresses, "lookup")
|
54
|
+
end
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -10,10 +10,6 @@ module Aikido::Zen
|
|
10
10
|
# there's no way to access the internal DNS resolution that happens in C
|
11
11
|
# when using the socket primitives.
|
12
12
|
module Socket
|
13
|
-
def self.load_sinks!
|
14
|
-
::IPSocket.singleton_class.prepend(Socket::IPSocketExtensions)
|
15
|
-
end
|
16
|
-
|
17
13
|
SINK = Sinks.add("socket", scanners: [
|
18
14
|
Scanners::StoredSSRFScanner,
|
19
15
|
Scanners::SSRFScanner
|
@@ -62,15 +58,17 @@ module Aikido::Zen
|
|
62
58
|
end
|
63
59
|
end
|
64
60
|
|
65
|
-
|
66
|
-
|
61
|
+
def self.load_sinks!
|
62
|
+
::IPSocket.singleton_class.class_eval do
|
63
|
+
extend Sinks::DSL
|
67
64
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
65
|
+
sink_after :open do |socket, remote_host|
|
66
|
+
# Code coverage is disabled here because the tests are contrived and
|
67
|
+
# intentionally do not call open.
|
68
|
+
# :nocov:
|
69
|
+
Helpers.scan(remote_host, socket, "open")
|
70
|
+
# :nocov:
|
71
|
+
end
|
74
72
|
end
|
75
73
|
end
|
76
74
|
end
|