-
Notifications
You must be signed in to change notification settings - Fork 2
/
2040-http-ruby-environment.nse
161 lines (134 loc) · 5.99 KB
/
2040-http-ruby-environment.nse
1
2
3
4
5
6
7
8
9
10
11
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
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
-- The Head Section --
description = [[
Sample script to detect the presence of a Ruby on Rails rack-mini-profiler gem that is used to provide performance metrics
for Rails applications. This simple detection script finds the environment variables page and looks for exposed API keys
and other sensitive data such as credentials at '?pp=env' appended to default host URL. It is possible that Rails
developers can expose environment variables through the gem without fully understanding their implications.
The 'rack-mini-profiler' is a performance gem utilized by Ruby on Rails developers to better understand performance details
of Rails applications. For more information:
[1] https://github.com/MiniProfiler/rack-mini-profiler
[2] https://www.speedshop.co/2015/08/05/rack-mini-profiler-the-secret-weapon.html
[3] https://stackify.com/rack-mini-profiler-a-complete-guide-on-rails-performance/
A demo project named 'Hammer' that demonstrates a mis-configured Rails app with this vulnerability:
[4] https://github.com/iknowjason/hammer
A gentle introduction to the 'Hammer' project:
[5] https://medium.com/@iknowjason/building-a-vulnerable-rails-application-for-learning-2a1de8cf98d5
]]
---
-- @usage
-- nmap --script http-ruby-environment <target>
-- @output
-- PORT STATE SERVICE
-- 443/tcp open https
-- | http-ruby-environment:
-- | VULNERABLE:
-- | Detected Rack-mini-profiler Environment Variables
-- | State: LIKELY VULNERABLE
-- | Manually investigate for issues
-- | Extra information:
-- | URI: https://preprod.rtcfingroup.com/?pp=env
-- |
-- | Sensitive Data: S3_ACCESS_KEY_ID
-- | State: VULNERABLE
-- | String Found: S3_ACCESS_KEY_ID: kDgvmKEFKZsT9CAgJdKy
-- | Extra information:
-- | URI: https://preprod.rtcfingroup.com/?pp=env
-- |_
author = "Jason Ostrom"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"default", "safe", "vuln"}
--- Requirements
local shortport = require "shortport"
local http = require "http"
local string = require "string"
local stdnse = require "stdnse"
local vulns = require "vulns"
-- The Rule Section --
portrule = shortport.http
-- The Action Section --
action = function(host, port)
local report = vulns.Report:new(SCRIPT_NAME, host, port)
--- helper function to check if data contains sensitive API keys or any credentials
local function check_sensitive(response_body, key, value, rhost, ruri)
---print("Checking: "..key)
local retval = ""
retval = string.match(response_body, value)
if retval == nil then
--- do nothing
else
--- strip off the last '\n'
retval = retval:sub(1,-2)
---print("Found: "..retval)
local tmp_vuln_table = {
title = "Sensitive Data: "..key,
state = vulns.STATE.VULN, --default
description = "String Found: "..retval,
extra_info = "URI: https://" .. rhost .. ruri
}
---Need to add this information to vulnerability table
local status, ret = report:add_vulns(tmp_vuln_table)
end
end
--- Define table for sensitive API key and data searches
local sensitive = {}
sensitive["MONGOID_HOST"] = "MONGOID_%u+_HOST.-\n"
sensitive["MONGOID_USER"] = "MONGOID_%u+_USER:.-\n"
sensitive["MONGOID_PASS"] = "MONGOID_%u+_PASS:.-\n"
sensitive["MYSQL_USER"] = "MYSQL_%u+_USER:.-\n"
sensitive["MYSQL_PASS"] = "MYSQL_%u+_PASS:.-\n"
sensitive["MYSQL_DATABASE_NAME"] = "MYSQL_%u+_DATABASE_.-\n"
sensitive["AWS_ACCESS_KEY_ID"] = "AWS_ACCESS_KEY_ID:.-\n"
sensitive["S3_ACCESS_KEY_ID"] = "S3_ACCESS_KEY_ID:.-\n"
sensitive["AWS_SECRET_ACCESS_KEY"] = "AWS_SECRET_ACCESS_KEY:.-\n"
sensitive["S3_SECRET_ACCESS_KEY"] = "S3_SECRET_ACCESS_KEY:.-\n"
sensitive["S3_BUCKET"] = "S3_BUCKET:.-\n"
sensitive["LINKEDIN_APP_ID"] = "LINKEDIN_APP_ID:.-\n"
sensitive["LINKEDIN_SECRET_KEY"] = "LINKEDIN_SECRET_KEY:.-\n"
sensitive["FACEBOOK_APP_ID"] = "FACEBOOK_APP_ID:.-\n"
sensitive["FACEBOOK_SECRET_KEY"] = "FACEBOOK_SECRET_KEY:.-\n"
sensitive["TWITTER_APP_ID"] = "TWITTER_APP_ID:.-\n"
sensitive["TWITTER_SECRET_KEY"] = "TWITTER_SECRET_KEY:.-\n"
sensitive["GOOGLE_APP_ID"] = "GOOGLE_APP_ID:.-\n"
sensitive["GOOGLE_SECRET_KEY"] = "GOOGLE_SECRET_KEY:.-\n"
sensitive["GOOGLE_MAPS_API_KEY"] = "GOOGLE_MAPS_API_KEY:.-\n"
sensitive["SALESFORCE_CLIENT_ID"] = "SALESFORCE_CLIENT_ID:.-\n"
sensitive["SALESFORCE_CLIENT_SECRET"] = "SALESFORCE_CLIENT_SECRET:.-\n"
sensitive["SALESFORCE_USERNAME"] = "SALESFORCE_USERNAME:.-\n"
sensitive["SALESFORCE_PASSWORD_TOKEN"] = "SALESFORCE_PASSWORD_TOKEN:.-\n"
sensitive["SALESFORCE_HOST"] = "SALESFORCE_HOST:.-\n"
sensitive["EBAY_AUTH_TOKEN"] = "EBAY_AUTH_TOKEN:.-\n"
sensitive["EBAY_DEV_ID"] = "EBAY_DEV_ID:.-\n"
sensitive["EBAY_APP_ID"] = "EBAY_APP_ID:.-\n"
sensitive["EBAY_CERT_ID"] = "EBAY_CERT_ID:.-\n"
--- uri variable for rack-mini-profiler Ruby on Rails gem
local uri = "/?pp=env"
--- declaring the myhost variable
local myhost = ""
--- use hostname or IP address
if host["targetname"] == nil then
myhost = host["ip"]
else
myhost = host["targetname"]
end
--- Vuln Definition Table for presence of rack-mini-profiler gem---
local vuln_table = {
title = "Detected Rack-mini-profiler Environment Variables",
state = vulns.STATE.NOT_VULN, --default
description = "Manually investigate for issues",
extra_info = "URI: https://" .. myhost .. uri
}
--- get the body response
local response = http.get(host, port, uri)
--- if this is True, then the URL exists of https://<HOST>/?pp=env and returns a 200 OK
if ( response.status == 200) then
vuln_table.state = vulns.STATE.LIKELY_VULN
local status, ret = report:add_vulns(vuln_table)
--- loop through and check for sensitive data in response.body
for key, value in pairs(sensitive) do
retval = check_sensitive(response.body, key, value, myhost, uri)
end
else
vuln_table.state = vulns.STATE.NOT_VULN
end
return report:make_output()
end