ronin-app 0.1.0.rc1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/ChangeLog.md +1 -1
- data/Gemfile +2 -0
- data/README.md +14 -14
- data/app.rb +23 -0
- data/gemspec.yml +13 -12
- data/lib/ronin/app/validations/http_params.rb +126 -0
- data/lib/ronin/app/version.rb +1 -1
- data/public/stylesheets/app.css +9 -0
- data/views/exploits/show.erb +10 -0
- data/views/layout.erb +9 -1
- data/views/network/http.erb +303 -0
- data/views/payloads/show.erb +4 -1
- metadata +44 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 254cf151b2f2725f6e24fa6acb4465c86f4071448e8fefcbe662b65e0565a676
|
4
|
+
data.tar.gz: 97cb3bc2fbbeaf8935f04d8907d3e248e6fda3d58216e1655f6a9409952951f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '062801f6bdfe086e94d87f292ce0c87f02187289033f465ef1f016d52c9328687885ba4c9f33f570d561cba5d8f8544d358e2a34ab20ababe0a888e2b1c54bd7'
|
7
|
+
data.tar.gz: 62c3aadce32eb5044a218350bd5301aa058f69eb872c2a5016c7c93b20c239d7559b8a5548935f38e4690ae43394f25a22766cc24a1722de3b998af51ee32665
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-3.
|
1
|
+
ruby-3.3
|
data/ChangeLog.md
CHANGED
data/Gemfile
CHANGED
@@ -38,11 +38,13 @@ gem 'sidekiq', require: false
|
|
38
38
|
|
39
39
|
group :development do
|
40
40
|
gem 'rake', require: false
|
41
|
+
gem 'rack-test', '~> 2.1', require: false
|
41
42
|
|
42
43
|
gem 'rubygems-tasks', '~> 0.2'
|
43
44
|
|
44
45
|
gem 'rspec', '~> 3.0', require: false
|
45
46
|
gem 'simplecov', '~> 0.20', require: false
|
47
|
+
gem 'capybara', '~> 3.40', require: false
|
46
48
|
|
47
49
|
gem 'kramdown', '~> 2.0', require: false
|
48
50
|
gem 'kramdown-man', '~> 1.0', require: false
|
data/README.md
CHANGED
@@ -35,48 +35,48 @@ user. It provides a web interface to [ronin-support], [ronin-repos], [ronin-db],
|
|
35
35
|
<tbody>
|
36
36
|
<tr>
|
37
37
|
<td>
|
38
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
38
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_scanning_nmap.svg" />
|
39
39
|
</td>
|
40
40
|
<td>
|
41
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
41
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_scanning_masscan.svg" />
|
42
42
|
</td>
|
43
43
|
<td>
|
44
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
44
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_scanning_recon.svg" />
|
45
45
|
</td>
|
46
46
|
<td>
|
47
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
47
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_scanning_spider.svg" />
|
48
48
|
</td>
|
49
49
|
<td>
|
50
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
50
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_scanning_vulns.svg" />
|
51
51
|
</td>
|
52
52
|
<td>
|
53
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
53
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_db.svg" />
|
54
54
|
</td>
|
55
55
|
<td>
|
56
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
56
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_db_ip_address.svg" />
|
57
57
|
</td>
|
58
58
|
</tr>
|
59
59
|
<tr>
|
60
60
|
<td>
|
61
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
61
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_repos.svg" />
|
62
62
|
</td>
|
63
63
|
<td>
|
64
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
64
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_repos_show.svg" />
|
65
65
|
</td>
|
66
66
|
<td>
|
67
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
67
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_payloads.svg" />
|
68
68
|
</td>
|
69
69
|
<td>
|
70
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
70
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_payloads_show.svg" />
|
71
71
|
</td>
|
72
72
|
<td>
|
73
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
73
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_payloads_build.svg" />
|
74
74
|
</td>
|
75
75
|
<td>
|
76
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
76
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_exploits.svg" />
|
77
77
|
</td>
|
78
78
|
<td>
|
79
|
-
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/
|
79
|
+
<img src="https://raw.githubusercontent.com/ronin-rb/ronin-app/main/screenshots/ronin_app_exploits_show.svg" />
|
80
80
|
</td>
|
81
81
|
</tr>
|
82
82
|
</tbody>
|
data/app.rb
CHANGED
@@ -39,6 +39,7 @@ require 'ronin/support/encoding'
|
|
39
39
|
# param validations
|
40
40
|
require 'ronin/app/validations/install_repo_params'
|
41
41
|
require 'ronin/app/validations/import_params'
|
42
|
+
require 'ronin/app/validations/http_params'
|
42
43
|
|
43
44
|
# schema builders
|
44
45
|
require 'ronin/app/schemas/payloads/encoders/encode_schema'
|
@@ -354,6 +355,28 @@ class App < Sinatra::Base
|
|
354
355
|
erb :queue
|
355
356
|
end
|
356
357
|
|
358
|
+
get '/network/http' do
|
359
|
+
erb :"network/http"
|
360
|
+
end
|
361
|
+
|
362
|
+
post '/network/http' do
|
363
|
+
result = Validations::HTTPParams.call(params)
|
364
|
+
|
365
|
+
if result.success?
|
366
|
+
kwargs = result.to_h
|
367
|
+
method = kwargs.delete(:method)
|
368
|
+
url = kwargs.delete(:url)
|
369
|
+
|
370
|
+
@http_response = Ronin::Support::Network::HTTP.request(method,url,**kwargs)
|
371
|
+
|
372
|
+
erb :"network/http"
|
373
|
+
else
|
374
|
+
@params = params
|
375
|
+
@errors = result.errors
|
376
|
+
halt 400, erb(:"network/http")
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
357
380
|
private
|
358
381
|
|
359
382
|
#
|
data/gemspec.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
name: ronin-app
|
2
2
|
summary: A local web interface for Ronin
|
3
3
|
description: |
|
4
|
-
|
4
|
+
ronin-app is a small web application that is meant to be ran locally by the
|
5
5
|
user. It provides a web interface to ronin-support, ronin-repos, ronin-db,
|
6
6
|
ronin-payloads, ronin-exploits, as well as automating
|
7
7
|
ronin-nmap, ronin-masscan, ronin-web-spider, ronin-recon, and ronin-vulns.
|
@@ -39,17 +39,18 @@ dependencies:
|
|
39
39
|
sidekiq: ~> 7.0
|
40
40
|
puma: ~> 6.0
|
41
41
|
# Ronin dependencies:
|
42
|
-
ronin-support: ~> 1.1
|
43
|
-
ronin-core: ~> 0.2
|
44
|
-
ronin-
|
45
|
-
ronin-db: ~> 0.2
|
46
|
-
ronin-
|
47
|
-
ronin-
|
48
|
-
ronin-
|
49
|
-
ronin-
|
50
|
-
ronin-
|
51
|
-
ronin-
|
52
|
-
ronin-
|
42
|
+
ronin-support: ~> 1.1
|
43
|
+
ronin-core: ~> 0.2
|
44
|
+
ronin-repos: ~> 0.2
|
45
|
+
ronin-db-activerecord: ~> 0.2
|
46
|
+
ronin-db: ~> 0.2
|
47
|
+
ronin-payloads: ~> 0.2
|
48
|
+
ronin-exploits: ~> 1.1
|
49
|
+
ronin-vulns: ~> 0.2
|
50
|
+
ronin-web-spider: ~> 0.2
|
51
|
+
ronin-nmap: ~> 0.1
|
52
|
+
ronin-masscan: ~> 0.1
|
53
|
+
ronin-recon: ~> 0.1
|
53
54
|
|
54
55
|
development_dependencies:
|
55
56
|
bundler: ~> 2.0
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# ronin-app - a local web app for Ronin.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
|
6
|
+
#
|
7
|
+
# ronin-app is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# ronin-app is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with ronin-app. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'dry/validation'
|
22
|
+
|
23
|
+
module Ronin
|
24
|
+
module App
|
25
|
+
module Validations
|
26
|
+
#
|
27
|
+
# Validations for the form params submitted to `POST /network/http`.
|
28
|
+
#
|
29
|
+
class HTTPParams < Dry::Validation::Contract
|
30
|
+
|
31
|
+
HTTPMethods = Types::Symbol.enum(
|
32
|
+
copy: 'COPY',
|
33
|
+
delete: 'DELETE',
|
34
|
+
get: 'GET',
|
35
|
+
head: 'HEAD',
|
36
|
+
lock: 'LOCK',
|
37
|
+
mkcol: 'MKCOL',
|
38
|
+
move: 'MOVE',
|
39
|
+
options: 'OPTIONS',
|
40
|
+
patch: 'PATCH',
|
41
|
+
post: 'POST',
|
42
|
+
propfind: 'PROPFIND',
|
43
|
+
proppatch: 'PROPPATCH',
|
44
|
+
put: 'PUT',
|
45
|
+
trace: 'TRACE',
|
46
|
+
unlock: 'UNLOCK'
|
47
|
+
)
|
48
|
+
|
49
|
+
Versions = (Types::Float | Types::Integer).enum(
|
50
|
+
1 => '1.0',
|
51
|
+
1.1 => '1.1',
|
52
|
+
1.2 => '1.2'
|
53
|
+
)
|
54
|
+
|
55
|
+
VerificationModes = Types::Symbol.enum(
|
56
|
+
none: 'none',
|
57
|
+
peer: 'peer',
|
58
|
+
fail_if_no_peer_cert: 'fail_if_no_peer_cert'
|
59
|
+
)
|
60
|
+
|
61
|
+
Headers = Types::Hash.constructor do |input,type|
|
62
|
+
if input.is_a?(String)
|
63
|
+
headers = {}
|
64
|
+
|
65
|
+
input.strip.each_line(chomp: true) do |line|
|
66
|
+
name, value = line.split(/:\s*/,2)
|
67
|
+
|
68
|
+
case (previous_value = headers[name])
|
69
|
+
when nil # no value yet
|
70
|
+
headers[name] = value
|
71
|
+
when String # previous value
|
72
|
+
headers[name] = [previous_value, value]
|
73
|
+
when Array # multiple previous values
|
74
|
+
previous_value << value
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
headers unless headers.empty?
|
79
|
+
elsif type.valid?(input)
|
80
|
+
input
|
81
|
+
else
|
82
|
+
type.call(input)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
params do
|
87
|
+
required(:method).filled(HTTPMethods)
|
88
|
+
required(:url).filled(:string)
|
89
|
+
|
90
|
+
optional(:body).maybe(:string)
|
91
|
+
optional(:headers).maybe(Headers)
|
92
|
+
|
93
|
+
optional(:proxy).maybe(:string)
|
94
|
+
optional(:user_agent).maybe(:string)
|
95
|
+
optional(:user).maybe(:string)
|
96
|
+
optional(:password).maybe(:string)
|
97
|
+
optional(:cookie).maybe(:string)
|
98
|
+
|
99
|
+
optional(:ssl).hash do
|
100
|
+
optional(:timeout).maybe(:integer)
|
101
|
+
optional(:version).maybe(Versions)
|
102
|
+
optional(:min_version).maybe(Versions)
|
103
|
+
optional(:max_version).maybe(Versions)
|
104
|
+
optional(:verify).maybe(VerificationModes)
|
105
|
+
optional(:verify_depth).maybe(:integer)
|
106
|
+
optional(:verify_hostname).maybe(:bool)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Initializes and calls the validation contract.
|
112
|
+
#
|
113
|
+
# @param [Hash{String => Object}] params
|
114
|
+
# The HTTP params to validate.
|
115
|
+
#
|
116
|
+
# @return [Dry::Validation::Result]
|
117
|
+
# The validation result.
|
118
|
+
#
|
119
|
+
def self.call(params)
|
120
|
+
new.call(params)
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/ronin/app/version.rb
CHANGED
data/public/stylesheets/app.css
CHANGED
@@ -167,6 +167,10 @@ main > nav.breadcrumb a {
|
|
167
167
|
text-decoration: none;
|
168
168
|
}
|
169
169
|
|
170
|
+
.content .tabs ul li a:hover {
|
171
|
+
background-color: var(--fg-color);
|
172
|
+
}
|
173
|
+
|
170
174
|
.content .content-tab {
|
171
175
|
display: none;
|
172
176
|
}
|
@@ -214,3 +218,8 @@ body.dark-mode main strong,
|
|
214
218
|
body.dark-mode main a {
|
215
219
|
color: var(--dark-mode-fg-color);
|
216
220
|
}
|
221
|
+
|
222
|
+
body.dark-mode .content .tabs ul li a:hover {
|
223
|
+
color: var(--dark-mode-bg-color);
|
224
|
+
background-color: var(--dark-mode-fg-color);
|
225
|
+
}
|
data/views/exploits/show.erb
CHANGED
@@ -90,6 +90,16 @@
|
|
90
90
|
</td>
|
91
91
|
</tr>
|
92
92
|
|
93
|
+
<% if defined?(Ronin::Exploits::Metadata::Shouts) &&
|
94
|
+
@exploit.include?(Ronin::Exploits::Metadata::Shouts) %>
|
95
|
+
<tr>
|
96
|
+
<td><strong>Shouts:</strong></td>
|
97
|
+
<td>
|
98
|
+
<p><%=h @exploit.shouts.join(', ') %></p>
|
99
|
+
</td>
|
100
|
+
</tr>
|
101
|
+
<% end %>
|
102
|
+
|
93
103
|
<tr>
|
94
104
|
<td><strong>Params:</strong></td>
|
95
105
|
<td>
|
data/views/layout.erb
CHANGED
@@ -60,6 +60,14 @@
|
|
60
60
|
</div>
|
61
61
|
</div>
|
62
62
|
|
63
|
+
<div class="navbar-item has-dropdown is-hoverable">
|
64
|
+
<a class="navbar-item">network</a>
|
65
|
+
|
66
|
+
<div class="navbar-dropdown">
|
67
|
+
<a href="/network/http" class="navbar-item">http</a>
|
68
|
+
</div>
|
69
|
+
</div>
|
70
|
+
|
63
71
|
<a href="/queue" class="navbar-item">queue</a>
|
64
72
|
<a href="/about" class="navbar-item">about</a>
|
65
73
|
</div>
|
@@ -89,7 +97,7 @@
|
|
89
97
|
<div class="container">
|
90
98
|
<div class="columns">
|
91
99
|
<div class="column is-full">
|
92
|
-
<span>(c) 2023 Hal Brodigan</span>
|
100
|
+
<span>(c) 2023-<%= Date.today.year %> Hal Brodigan</span>
|
93
101
|
</div>
|
94
102
|
</div>
|
95
103
|
</div>
|
@@ -0,0 +1,303 @@
|
|
1
|
+
<script type="text/javascript" src="/javascript/tabs.js"></script>
|
2
|
+
<h1>HTTP</h1>
|
3
|
+
|
4
|
+
<form action="/network/http" method="post">
|
5
|
+
<div class="field">
|
6
|
+
<label class="label is-required">URL</label>
|
7
|
+
|
8
|
+
<div class="control">
|
9
|
+
<% if @errors && @errors[:url] %>
|
10
|
+
<input class="input is-danger" type="text" name="url" value="<%=hattr params[:url] %>">
|
11
|
+
|
12
|
+
<% @errors[:url].each do |error| %>
|
13
|
+
<p class="help is-danger"><%=h error %></p>
|
14
|
+
<% end %>
|
15
|
+
<% else %>
|
16
|
+
<input class="input" type="text" name="url" placeholder="https://www.example.com" value="<%=hattr params[:url] %>">
|
17
|
+
<% end %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<div class="field">
|
22
|
+
<label class="has-text-weight-semibold">HTTP Method:</label>
|
23
|
+
|
24
|
+
<% if @errors && @errors[:method] %>
|
25
|
+
<select class="select is-danger" name="method">
|
26
|
+
<option value="">
|
27
|
+
<option value="COPY"<%= ' selected' if params[:http_method] == 'COPY' %>>COPY</option>
|
28
|
+
<option value="DELETE"<%= ' selected' if params[:http_method] == 'DELETE' %>>DELETE</option>
|
29
|
+
<option value="GET"<%= ' selected' if params[:http_method] == 'GET' %>>GET</option>
|
30
|
+
<option value="HEAD"<%= ' selected' if params[:http_method] == 'HEAD' %>>HEAD</option>
|
31
|
+
<option value="LOCK"<%= ' selected' if params[:http_method] == 'LOCK' %>>LOCK</option>
|
32
|
+
<option value="MKCOL"<%= ' selected' if params[:http_method] == 'MKCOL' %>>MKCOL</option>
|
33
|
+
<option value="MOVE"<%= ' selected' if params[:http_method] == 'MOVE' %>>MOVE</option>
|
34
|
+
<option value="OPTIONS"<%= ' selected' if params[:http_method] == 'OPTIONS' %>>OPTIONS</option>
|
35
|
+
<option value="PATCH"<%= ' selected' if params[:http_method] == 'PATCH' %>>PATCH</option>
|
36
|
+
<option value="POST"<%= ' selected' if params[:http_method] == 'POST' %>>POST</option>
|
37
|
+
<option value="PROPFIND"<%= ' selected' if params[:http_method] == 'PROPFIND' %>>PROPFIND</option>
|
38
|
+
<option value="PROPPATCH"<%= ' selected' if params[:http_method] == 'PROPPATCH' %>>PROPPATCH</option>
|
39
|
+
<option value="PUT"<%= ' selected' if params[:http_method] == 'PUT' %>>PUT</option>
|
40
|
+
<option value="TRACE"<%= ' selected' if params[:http_method] == 'TRACE' %>>TRACE</option>
|
41
|
+
<option value="UNLOCK"<%= ' selected' if params[:http_method] == 'UNLOCK' %>>UNLOCK</option>
|
42
|
+
</select>
|
43
|
+
|
44
|
+
<% @errors[:method].each do |error| %>
|
45
|
+
<p class="help is-danger"><%=h error %></p>
|
46
|
+
<% end %>
|
47
|
+
<% else %>
|
48
|
+
<select class="select" name="method">
|
49
|
+
<option value="">
|
50
|
+
<option value="COPY"<%= ' selected' if params[:http_method] == 'COPY' %>>COPY</option>
|
51
|
+
<option value="DELETE"<%= ' selected' if params[:http_method] == 'DELETE' %>>DELETE</option>
|
52
|
+
<option value="GET"<%= ' selected' if params[:http_method] == 'GET' %>>GET</option>
|
53
|
+
<option value="HEAD"<%= ' selected' if params[:http_method] == 'HEAD' %>>HEAD</option>
|
54
|
+
<option value="LOCK"<%= ' selected' if params[:http_method] == 'LOCK' %>>LOCK</option>
|
55
|
+
<option value="MKCOL"<%= ' selected' if params[:http_method] == 'MKCOL' %>>MKCOL</option>
|
56
|
+
<option value="MOVE"<%= ' selected' if params[:http_method] == 'MOVE' %>>MOVE</option>
|
57
|
+
<option value="OPTIONS"<%= ' selected' if params[:http_method] == 'OPTIONS' %>>OPTIONS</option>
|
58
|
+
<option value="PATCH"<%= ' selected' if params[:http_method] == 'PATCH' %>>PATCH</option>
|
59
|
+
<option value="POST"<%= ' selected' if params[:http_method] == 'POST' %>>POST</option>
|
60
|
+
<option value="PROPFIND"<%= ' selected' if params[:http_method] == 'PROPFIND' %>>PROPFIND</option>
|
61
|
+
<option value="PROPPATCH"<%= ' selected' if params[:http_method] == 'PROPPATCH' %>>PROPPATCH</option>
|
62
|
+
<option value="PUT"<%= ' selected' if params[:http_method] == 'PUT' %>>PUT</option>
|
63
|
+
<option value="TRACE"<%= ' selected' if params[:http_method] == 'TRACE' %>>TRACE</option>
|
64
|
+
<option value="UNLOCK"<%= ' selected' if params[:http_method] == 'UNLOCK' %>>UNLOCK</option>
|
65
|
+
</select>
|
66
|
+
<% end %>
|
67
|
+
</div>
|
68
|
+
|
69
|
+
<div class="field">
|
70
|
+
<button type="submit" class="button is-primary">Send</button>
|
71
|
+
</div>
|
72
|
+
|
73
|
+
<div class="tabs is-centered">
|
74
|
+
<ul>
|
75
|
+
<li class="is-active"><a data-tab-id="general">General</a></li>
|
76
|
+
<li><a data-tab-id="ssl">SSL</a></li>
|
77
|
+
</ul>
|
78
|
+
</div>
|
79
|
+
|
80
|
+
<div class="tabs-content">
|
81
|
+
<div id="general" class="content-tab is-active">
|
82
|
+
<div class="field">
|
83
|
+
<label class="has-text-weight-semibold">Proxy:</label>
|
84
|
+
|
85
|
+
<div class="control">
|
86
|
+
<% if @errors && @errors[:proxy] %>
|
87
|
+
<input class="input is-danger" type="text" name="proxy" value="<%=hattr params[:proxy] %>">
|
88
|
+
|
89
|
+
<% @errors[:proxy].each do |error| %>
|
90
|
+
<p class="help is-danger"><%=h error %></p>
|
91
|
+
<% end %>
|
92
|
+
<% else %>
|
93
|
+
<input class="input" type="text" name="proxy" value="<%=hattr params[:proxy] %>">
|
94
|
+
<% end %>
|
95
|
+
</div>
|
96
|
+
</div>
|
97
|
+
|
98
|
+
<div class="field">
|
99
|
+
<label class="has-text-weight-semibold">Headers:</label>
|
100
|
+
|
101
|
+
<div class="control">
|
102
|
+
<% if @errors && @errors[:headers] %>
|
103
|
+
<textarea class="textarea is-danger" name="headers" placeholder="Content-Type: application/x-www-form-urlencoded, Connection: keep-alive" value="<%=hattr params[:headers] %>"></textarea>
|
104
|
+
|
105
|
+
<% @errors[:headers].each do |error| %>
|
106
|
+
<p class="help is-danger"><%=h error %></p>
|
107
|
+
<% end %>
|
108
|
+
<% else %>
|
109
|
+
<textarea class="textarea" name="headers" placeholder="Content-Type: application/x-www-form-urlencoded, Connection: keep-alive" value="<%=hattr params[:headers] %>"></textarea>
|
110
|
+
<% end %>
|
111
|
+
</div>
|
112
|
+
</div>
|
113
|
+
|
114
|
+
<div class="field">
|
115
|
+
<label class="has-text-weight-semibold">User Agent:</label>
|
116
|
+
|
117
|
+
<div class="control">
|
118
|
+
<% if @errors && @errors[:user_agent] %>
|
119
|
+
<input class="input is-danger" type="text" name="user_agent" value="<%=hattr params[:user_agent] %>">
|
120
|
+
|
121
|
+
<% @errors[:user_agent].each do |error| %>
|
122
|
+
<p class="help is-danger"><%=h error %></p>
|
123
|
+
<% end %>
|
124
|
+
<% else %>
|
125
|
+
<input class="input" type="text" name="user_agent" value="<%=hattr params[:user_agent] %>">
|
126
|
+
<% end %>
|
127
|
+
</div>
|
128
|
+
</div>
|
129
|
+
|
130
|
+
<div class="field">
|
131
|
+
<label class="has-text-weight-semibold">User:</label>
|
132
|
+
|
133
|
+
<div class="control">
|
134
|
+
<% if @errors && @errors[:user] %>
|
135
|
+
<input class="input is-danger" type="text" name="user" value="<%=hattr params[:user] %>">
|
136
|
+
|
137
|
+
<% @errors[:user].each do |error| %>
|
138
|
+
<p class="help is-danger"><%=h error %></p>
|
139
|
+
<% end %>
|
140
|
+
<% else %>
|
141
|
+
<input class="input" type="text" name="user" value="<%=hattr params[:user] %>">
|
142
|
+
<% end %>
|
143
|
+
</div>
|
144
|
+
</div>
|
145
|
+
|
146
|
+
<div class="field">
|
147
|
+
<label class="has-text-weight-semibold">Password:</label>
|
148
|
+
|
149
|
+
<div class="control">
|
150
|
+
<% if @errors && @errors[:password] %>
|
151
|
+
<input class="input is-danger" type="text" name="password" value="<%=hattr params[:password] %>">
|
152
|
+
|
153
|
+
<% @errors[:password].each do |error| %>
|
154
|
+
<p class="help is-danger"><%=h error %></p>
|
155
|
+
<% end %>
|
156
|
+
<% else %>
|
157
|
+
<input class="input" type="text" name="password" value="<%=hattr params[:password] %>">
|
158
|
+
<% end %>
|
159
|
+
</div>
|
160
|
+
</div>
|
161
|
+
|
162
|
+
<div class="field">
|
163
|
+
<label class="has-text-weight-semibold">Cookie:</label>
|
164
|
+
|
165
|
+
<div class="control">
|
166
|
+
<% if @errors && @errors[:cookie] %>
|
167
|
+
<input class="input is-danger" type="text" name="cookie" value="<%=hattr params[:cookie] %>">
|
168
|
+
|
169
|
+
<% @errors[:cookie].each do |error| %>
|
170
|
+
<p class="help is-danger"><%=h error %></p>
|
171
|
+
<% end %>
|
172
|
+
<% else %>
|
173
|
+
<input class="input" type="text" name="cookie" value="<%=hattr params[:cookie] %>">
|
174
|
+
<% end %>
|
175
|
+
</div>
|
176
|
+
</div>
|
177
|
+
|
178
|
+
<div class="field">
|
179
|
+
<label class="has-text-weight-semibold">Body:</label>
|
180
|
+
|
181
|
+
<div class="control">
|
182
|
+
<% if @errors && @errors[:body] %>
|
183
|
+
<textarea class="textarea is-danger" type="text" name="body" value="<%=hattr params[:body] %>"></textarea>
|
184
|
+
|
185
|
+
<% @errors[:body].each do |error| %>
|
186
|
+
<p class="help is-danger"><%=h error %></p>
|
187
|
+
<% end %>
|
188
|
+
<% else %>
|
189
|
+
<textarea class="textarea" type="text" name="body" value="<%=hattr params[:body] %>"></textarea>
|
190
|
+
<% end %>
|
191
|
+
</div>
|
192
|
+
</div>
|
193
|
+
</div>
|
194
|
+
|
195
|
+
<div id="ssl" class="content-tab">
|
196
|
+
<div class="field">
|
197
|
+
<label class="has-text-weight-semibold">Timeout:</label>
|
198
|
+
|
199
|
+
<div class="control">
|
200
|
+
<% if @errors && @errors[:ssl]&.dig(:timeout) %>
|
201
|
+
<input class="input is-danger" type="number" name="ssl[timeout]" value="<%=hattr params[:timeout] %>">
|
202
|
+
|
203
|
+
<% @errors[:ssl][:timeout].each do |error| %>
|
204
|
+
<p class="help is-danger"><%=h error %></p>
|
205
|
+
<% end %>
|
206
|
+
<% else %>
|
207
|
+
<input class="input" type="number" name="ssl[timeout]" value="<%=hattr params[:timeout] %>">
|
208
|
+
<% end %>
|
209
|
+
</div>
|
210
|
+
</div>
|
211
|
+
|
212
|
+
<div class="field">
|
213
|
+
<label class="has-text-weight-semibold">Version:</label>
|
214
|
+
<select class="select" name="ssl[version]">
|
215
|
+
<option value="">
|
216
|
+
<option value="1.0"<%= ' selected' if params[:ssl]&.dig(:version) == '1.0' %>>1.0</option>
|
217
|
+
<option value="1.1"<%= ' selected' if params[:ssl]&.dig(:version) == '1.1' %>>1.1</option>
|
218
|
+
<option value="1.2"<%= ' selected' if params[:ssl]&.dig(:version) == '1.2' %>>1.2</option>
|
219
|
+
</select>
|
220
|
+
</div>
|
221
|
+
|
222
|
+
<div class="field">
|
223
|
+
<label class="has-text-weight-semibold">Min Version:</label>
|
224
|
+
<select class="select" name="ssl[min_version]">
|
225
|
+
<option value="">
|
226
|
+
<option value="1.0"<%= ' selected' if params[:ssl]&.dig(:version) == '1.0' %>>1.0</option>
|
227
|
+
<option value="1.1"<%= ' selected' if params[:ssl]&.dig(:version) == '1.1' %>>1.1</option>
|
228
|
+
<option value="1.2"<%= ' selected' if params[:ssl]&.dig(:version) == '1.2' %>>1.2</option>
|
229
|
+
</select>
|
230
|
+
</div>
|
231
|
+
|
232
|
+
<div class="field">
|
233
|
+
<label class="has-text-weight-semibold">Max Version:</label>
|
234
|
+
<select class="select" name="ssl[max_version]">
|
235
|
+
<option value="">
|
236
|
+
<option value="1.0"<%= ' selected' if params[:ssl]&.dig(:version) == '1.0' %>>1.0</option>
|
237
|
+
<option value="1.1"<%= ' selected' if params[:ssl]&.dig(:version) == '1.1' %>>1.1</option>
|
238
|
+
<option value="1.2"<%= ' selected' if params[:ssl]&.dig(:version) == '1.2' %>>1.2</option>
|
239
|
+
</select>
|
240
|
+
</div>
|
241
|
+
|
242
|
+
<div class="field">
|
243
|
+
<label class="has-text-weight-semibold">Verify:</label>
|
244
|
+
<select class="select" name="ssl[verify]">
|
245
|
+
<option value="">
|
246
|
+
<option value="none"<%= ' selected' if params[:verify] == 'none' %>>None</option>
|
247
|
+
<option value="peer"<%= ' selected' if params[:verify] == 'peer' %>>Peer</option>
|
248
|
+
<option value="fail_if_no_peer_cert"<%= ' selected' if params[:verify] == 'fail_if_no_peer_cert' %>>Fail if no peer cert</option>
|
249
|
+
</select>
|
250
|
+
</div>
|
251
|
+
|
252
|
+
<div class="field">
|
253
|
+
<label class="has-text-weight-semibold">Verify Depth:</label>
|
254
|
+
|
255
|
+
<div class="control">
|
256
|
+
<% if @errors && @errors[:ssl]&.dig(:verify_depth) %>
|
257
|
+
<input class="input is-danger" type="number" name="ssl[verify_depth]" value="<%=hattr params[:verify_depth] %>">
|
258
|
+
|
259
|
+
<% @errors[:ssl][:verify_depth].each do |error| %>
|
260
|
+
<p class="help is-danger"><%=h error %></p>
|
261
|
+
<% end %>
|
262
|
+
<% else %>
|
263
|
+
<input class="input" type="number" name="ssl[verify_depth]" value="<%=hattr params[:verify_depth] %>">
|
264
|
+
<% end %>
|
265
|
+
</div>
|
266
|
+
</div>
|
267
|
+
|
268
|
+
<div class="field">
|
269
|
+
<label class="has-text-weight-semibold">Verify Hostname:</label>
|
270
|
+
|
271
|
+
<div class="control">
|
272
|
+
<% if @errors && @errors[:ssl]&.dig(:verify_hostname) %>
|
273
|
+
<input class="checkbox is-danger" type="checkbox" name="ssl[verify_hostname]" value="<%=hattr params[:verify_hostname] %>">
|
274
|
+
|
275
|
+
<% @errors[:ssl][:verify_hostname].each do |error| %>
|
276
|
+
<p class="help is-danger"><%=h error %></p>
|
277
|
+
<% end %>
|
278
|
+
<% else %>
|
279
|
+
<input class="checkbox is-danger" type="checkbox" name="ssl[verify_hostname]" value="<%=hattr params[:verify_hostname] %>">
|
280
|
+
<% end %>
|
281
|
+
</div>
|
282
|
+
</div>
|
283
|
+
</div>
|
284
|
+
</div>
|
285
|
+
</div>
|
286
|
+
|
287
|
+
<% if @http_response %>
|
288
|
+
<div>
|
289
|
+
<pre>
|
290
|
+
<%=h @http_response.code %> <%= @http_response.message %>
|
291
|
+
</pre>
|
292
|
+
|
293
|
+
<pre>
|
294
|
+
<% @http_response.each_capitalized do |name, value| %>
|
295
|
+
<%=h name%>: <%=h value %>
|
296
|
+
<% end %>
|
297
|
+
</pre>
|
298
|
+
|
299
|
+
<pre>
|
300
|
+
<%=h @http_response.body %>
|
301
|
+
</pre>
|
302
|
+
</div>
|
303
|
+
<% end %>
|
data/views/payloads/show.erb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
<
|
1
|
+
<div class="is-flex is-justify-content-space-between">
|
2
|
+
<h1>Payload: <%=h @payload.id %></h1>
|
3
|
+
<a href="/payloads/build/<%=hattr @payload.id %>" class="button is-primary">Build</a>
|
4
|
+
</div>
|
2
5
|
|
3
6
|
<table class="table">
|
4
7
|
<tbody>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ronin-app
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Postmodern
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-schema
|
@@ -170,154 +170,168 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - "~>"
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: 1.1
|
173
|
+
version: '1.1'
|
174
174
|
type: :runtime
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: 1.1
|
180
|
+
version: '1.1'
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
182
|
name: ronin-core
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
185
|
- - "~>"
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version: 0.2
|
187
|
+
version: '0.2'
|
188
188
|
type: :runtime
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
192
|
- - "~>"
|
193
193
|
- !ruby/object:Gem::Version
|
194
|
-
version: 0.2
|
194
|
+
version: '0.2'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: ronin-repos
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0.2'
|
202
|
+
type: :runtime
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0.2'
|
195
209
|
- !ruby/object:Gem::Dependency
|
196
210
|
name: ronin-db-activerecord
|
197
211
|
requirement: !ruby/object:Gem::Requirement
|
198
212
|
requirements:
|
199
213
|
- - "~>"
|
200
214
|
- !ruby/object:Gem::Version
|
201
|
-
version: 0.2
|
215
|
+
version: '0.2'
|
202
216
|
type: :runtime
|
203
217
|
prerelease: false
|
204
218
|
version_requirements: !ruby/object:Gem::Requirement
|
205
219
|
requirements:
|
206
220
|
- - "~>"
|
207
221
|
- !ruby/object:Gem::Version
|
208
|
-
version: 0.2
|
222
|
+
version: '0.2'
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: ronin-db
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
212
226
|
requirements:
|
213
227
|
- - "~>"
|
214
228
|
- !ruby/object:Gem::Version
|
215
|
-
version: 0.2
|
229
|
+
version: '0.2'
|
216
230
|
type: :runtime
|
217
231
|
prerelease: false
|
218
232
|
version_requirements: !ruby/object:Gem::Requirement
|
219
233
|
requirements:
|
220
234
|
- - "~>"
|
221
235
|
- !ruby/object:Gem::Version
|
222
|
-
version: 0.2
|
236
|
+
version: '0.2'
|
223
237
|
- !ruby/object:Gem::Dependency
|
224
238
|
name: ronin-payloads
|
225
239
|
requirement: !ruby/object:Gem::Requirement
|
226
240
|
requirements:
|
227
241
|
- - "~>"
|
228
242
|
- !ruby/object:Gem::Version
|
229
|
-
version: 0.2
|
243
|
+
version: '0.2'
|
230
244
|
type: :runtime
|
231
245
|
prerelease: false
|
232
246
|
version_requirements: !ruby/object:Gem::Requirement
|
233
247
|
requirements:
|
234
248
|
- - "~>"
|
235
249
|
- !ruby/object:Gem::Version
|
236
|
-
version: 0.2
|
250
|
+
version: '0.2'
|
237
251
|
- !ruby/object:Gem::Dependency
|
238
252
|
name: ronin-exploits
|
239
253
|
requirement: !ruby/object:Gem::Requirement
|
240
254
|
requirements:
|
241
255
|
- - "~>"
|
242
256
|
- !ruby/object:Gem::Version
|
243
|
-
version: 1.1
|
257
|
+
version: '1.1'
|
244
258
|
type: :runtime
|
245
259
|
prerelease: false
|
246
260
|
version_requirements: !ruby/object:Gem::Requirement
|
247
261
|
requirements:
|
248
262
|
- - "~>"
|
249
263
|
- !ruby/object:Gem::Version
|
250
|
-
version: 1.1
|
264
|
+
version: '1.1'
|
251
265
|
- !ruby/object:Gem::Dependency
|
252
266
|
name: ronin-vulns
|
253
267
|
requirement: !ruby/object:Gem::Requirement
|
254
268
|
requirements:
|
255
269
|
- - "~>"
|
256
270
|
- !ruby/object:Gem::Version
|
257
|
-
version: 0.2
|
271
|
+
version: '0.2'
|
258
272
|
type: :runtime
|
259
273
|
prerelease: false
|
260
274
|
version_requirements: !ruby/object:Gem::Requirement
|
261
275
|
requirements:
|
262
276
|
- - "~>"
|
263
277
|
- !ruby/object:Gem::Version
|
264
|
-
version: 0.2
|
278
|
+
version: '0.2'
|
265
279
|
- !ruby/object:Gem::Dependency
|
266
280
|
name: ronin-web-spider
|
267
281
|
requirement: !ruby/object:Gem::Requirement
|
268
282
|
requirements:
|
269
283
|
- - "~>"
|
270
284
|
- !ruby/object:Gem::Version
|
271
|
-
version: 0.2
|
285
|
+
version: '0.2'
|
272
286
|
type: :runtime
|
273
287
|
prerelease: false
|
274
288
|
version_requirements: !ruby/object:Gem::Requirement
|
275
289
|
requirements:
|
276
290
|
- - "~>"
|
277
291
|
- !ruby/object:Gem::Version
|
278
|
-
version: 0.2
|
292
|
+
version: '0.2'
|
279
293
|
- !ruby/object:Gem::Dependency
|
280
294
|
name: ronin-nmap
|
281
295
|
requirement: !ruby/object:Gem::Requirement
|
282
296
|
requirements:
|
283
297
|
- - "~>"
|
284
298
|
- !ruby/object:Gem::Version
|
285
|
-
version: 0.1
|
299
|
+
version: '0.1'
|
286
300
|
type: :runtime
|
287
301
|
prerelease: false
|
288
302
|
version_requirements: !ruby/object:Gem::Requirement
|
289
303
|
requirements:
|
290
304
|
- - "~>"
|
291
305
|
- !ruby/object:Gem::Version
|
292
|
-
version: 0.1
|
306
|
+
version: '0.1'
|
293
307
|
- !ruby/object:Gem::Dependency
|
294
308
|
name: ronin-masscan
|
295
309
|
requirement: !ruby/object:Gem::Requirement
|
296
310
|
requirements:
|
297
311
|
- - "~>"
|
298
312
|
- !ruby/object:Gem::Version
|
299
|
-
version: 0.1
|
313
|
+
version: '0.1'
|
300
314
|
type: :runtime
|
301
315
|
prerelease: false
|
302
316
|
version_requirements: !ruby/object:Gem::Requirement
|
303
317
|
requirements:
|
304
318
|
- - "~>"
|
305
319
|
- !ruby/object:Gem::Version
|
306
|
-
version: 0.1
|
320
|
+
version: '0.1'
|
307
321
|
- !ruby/object:Gem::Dependency
|
308
322
|
name: ronin-recon
|
309
323
|
requirement: !ruby/object:Gem::Requirement
|
310
324
|
requirements:
|
311
325
|
- - "~>"
|
312
326
|
- !ruby/object:Gem::Version
|
313
|
-
version: 0.1
|
327
|
+
version: '0.1'
|
314
328
|
type: :runtime
|
315
329
|
prerelease: false
|
316
330
|
version_requirements: !ruby/object:Gem::Requirement
|
317
331
|
requirements:
|
318
332
|
- - "~>"
|
319
333
|
- !ruby/object:Gem::Version
|
320
|
-
version: 0.1
|
334
|
+
version: '0.1'
|
321
335
|
- !ruby/object:Gem::Dependency
|
322
336
|
name: bundler
|
323
337
|
requirement: !ruby/object:Gem::Requirement
|
@@ -334,9 +348,9 @@ dependencies:
|
|
334
348
|
version: '2.0'
|
335
349
|
description: |
|
336
350
|
ronin-app is a small web application that is meant to be ran locally by the
|
337
|
-
|
338
|
-
|
339
|
-
|
351
|
+
user. It provides a web interface to ronin-support, ronin-repos, ronin-db,
|
352
|
+
ronin-payloads, ronin-exploits, as well as automating
|
353
|
+
ronin-nmap, ronin-masscan, ronin-web-spider, ronin-recon, and ronin-vulns.
|
340
354
|
email: postmodern.mod3@gmail.com
|
341
355
|
executables:
|
342
356
|
- ronin-app
|
@@ -392,6 +406,7 @@ files:
|
|
392
406
|
- lib/ronin/app/types/nmap.rb
|
393
407
|
- lib/ronin/app/types/spider.rb
|
394
408
|
- lib/ronin/app/types/vulns.rb
|
409
|
+
- lib/ronin/app/validations/http_params.rb
|
395
410
|
- lib/ronin/app/validations/import_params.rb
|
396
411
|
- lib/ronin/app/validations/install_repo_params.rb
|
397
412
|
- lib/ronin/app/validations/masscan_params.rb
|
@@ -482,6 +497,7 @@ files:
|
|
482
497
|
- views/index.erb
|
483
498
|
- views/layout.erb
|
484
499
|
- views/masscan.erb
|
500
|
+
- views/network/http.erb
|
485
501
|
- views/nmap.erb
|
486
502
|
- views/payloads/build.erb
|
487
503
|
- views/payloads/encoders/encode.erb
|
@@ -531,7 +547,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
531
547
|
- !ruby/object:Gem::Version
|
532
548
|
version: '0'
|
533
549
|
requirements: []
|
534
|
-
rubygems_version: 3.
|
550
|
+
rubygems_version: 3.5.11
|
535
551
|
signing_key:
|
536
552
|
specification_version: 4
|
537
553
|
summary: A local web interface for Ronin
|