pwn 0.4.886 → 0.4.887

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a85fbb128c8c5ba0dafc425373d33839998f866ccc0982b9d0f596ce7ee2411
4
- data.tar.gz: ab8a86d182d5cc69e7509596bd38a0515b2c8c0b532ca61b59675558fb5df554
3
+ metadata.gz: eba0652465ac3cb7e848a84e78412952875ab79a2c47dbcda39068a65e9f5c5b
4
+ data.tar.gz: 2c03fbba16c08c1820d483e744e5e1dd70812081aff632a9f71f0227f582d2a7
5
5
  SHA512:
6
- metadata.gz: d3ef35410455de329014f16c01c6498ce9e7540a1edbf2028b3c181297e47084a4439e7e6344892ce33685868599cd44f3ffb21008bfcd83695f6b1931067a95
7
- data.tar.gz: 0e3155be591274c629fc0dd73a45d94b830261af83bf4a074d05c4579d0eea110815f5efb6ef5adf439c16e171da51f7287f44e032f29ec29b719c8a4c163a9d
6
+ metadata.gz: c9912c9c682b57c711c1a57e09e7ffad70c7018cf8e2689ecf7ff3a0f8fe3e5de9638588fd85c3475f58aaeb51a4892061e9cd4ceca6d1d3a40e5a2be8e88d31
7
+ data.tar.gz: c26189e41c966c8d3ca0e3988d9d901461b420a85e6d49123814b7e9331e8bcb6a7fe2dd2b3fa0d058f8b2b4f3948e3b5131a4ecb21854dc0a018e03f42d9b58
data/README.md CHANGED
@@ -37,7 +37,7 @@ $ rvm use ruby-3.2.2@pwn
37
37
  $ rvm list gemsets
38
38
  $ gem install --verbose pwn
39
39
  $ pwn
40
- pwn[v0.4.886]:001 >>> PWN.help
40
+ pwn[v0.4.887]:001 >>> PWN.help
41
41
  ```
42
42
 
43
43
  [![Installing the pwn Security Automation Framework](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/pwn_install.png)](https://youtu.be/G7iLUY4FzsI)
@@ -52,7 +52,7 @@ $ rvm use ruby-3.2.2@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.4.886]:001 >>> PWN.help
55
+ pwn[v0.4.887]:001 >>> PWN.help
56
56
  ```
57
57
 
58
58
 
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'faker'
5
+ require 'json'
6
+ require 'optparse'
7
+ require 'pwn'
8
+
9
+ opts = {}
10
+ OptionParser.new do |options|
11
+ options.on('-jFILE', '--json-results=FILE', 'Required - JSON results file from pwn_shodan_search driver') do |j|
12
+ opts[:json_results] = j
13
+ end
14
+ end.parse!
15
+
16
+ if opts.empty?
17
+ puts `#{$PROGRAM_NAME} --help`
18
+ exit 1
19
+ end
20
+
21
+ json_results_path = opts[:json_results]
22
+ raise "ERROR: Shodan JSON Results File #{json_results_path} Does Not Exist." unless File.exist?(json_results_path)
23
+
24
+ search_results = JSON.parse(
25
+ File.read(json_results_path),
26
+ symbolize_names: true
27
+ )
28
+
29
+ print 'Extracting URIs from Shodan search results...'
30
+ uri_arr = PWN::Plugins::Shodan.get_uris(search_results: search_results)
31
+ puts 'complete.'
32
+
33
+ print "Extracting GraphQL URIs from #{uri_arr.count} URIs..."
34
+ graphql_uris = uri_arr.uniq.select do |uri|
35
+ uri if uri =~ %r{.+/graphql/?$} ||
36
+ uri =~ %r{.+/graphiql/?$} ||
37
+ uri =~ %r{.+/playground/?$} ||
38
+ uri =~ %r{.+/console/?$} ||
39
+ uri =~ %r{.+/query/?$} ||
40
+ uri =~ %r{.+/gql/?$} ||
41
+ uri =~ %r{.+/index.php?graphql$}
42
+ end
43
+ puts 'complete.'
44
+
45
+ browser_obj = PWN::Plugins::TransparentBrowser.open(browser_type: :rest)
46
+ rest_client = browser_obj[:browser]::Request
47
+
48
+ graphql_payloads_arr = []
49
+
50
+ graphql_schema_payload = '{ "query": "{ __schema { types { name } } }" }'
51
+ graphql_payloads_arr.push(graphql_schema_payload)
52
+
53
+ graphql_introspection_payload1 = <<-END_OF_PAYLOAD
54
+ {
55
+ query IntrospectionQuery {
56
+ __schema {
57
+
58
+ queryType { name }
59
+ mutationType { name }
60
+ subscriptionType { name }
61
+ types { ...FullType }
62
+ directives {
63
+ name
64
+ description
65
+ locations
66
+ args { ...InputValue }
67
+ }
68
+ }
69
+ }
70
+
71
+ fragment FullType on __Type {
72
+ kind
73
+ name
74
+ description
75
+ fields(includeDeprecated: true) {
76
+ name
77
+ description
78
+ args { ...InputValue }
79
+ type { ...TypeRef }
80
+ isDeprecated
81
+ deprecationReason
82
+ }
83
+ inputFields {
84
+ ...InputValue
85
+ }
86
+ interfaces {
87
+ ...TypeRef
88
+ }
89
+ enumValues(includeDeprecated: true) {
90
+ name
91
+ description
92
+ isDeprecated
93
+ deprecationReason
94
+ }
95
+ possibleTypes {
96
+ ...TypeRef
97
+ }
98
+ }
99
+
100
+ fragment InputValue on __InputValue {
101
+ name
102
+ description
103
+ type { ...TypeRef }
104
+ defaultValue
105
+ }
106
+
107
+ fragment TypeRef on __Type {
108
+ kind
109
+ name
110
+ ofType {
111
+ kind
112
+ name
113
+ ofType {
114
+ kind
115
+ name
116
+ ofType {
117
+ kind
118
+ name
119
+ ofType {
120
+ kind
121
+ name
122
+ ofType {
123
+ kind
124
+ name
125
+ ofType {
126
+ kind
127
+ name
128
+ ofType {
129
+ kind
130
+ name
131
+ }
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+ END_OF_PAYLOAD
141
+ graphql_payloads_arr.push(graphql_introspection_payload1)
142
+
143
+ graphql_introspection_payload2 = <<-END_OF_PAYLOAD
144
+ {
145
+ "operationName":"IntrospectionQuery",
146
+ "variables":{},
147
+ "query":"
148
+ fragment FullType on __Type {
149
+ kind
150
+ name
151
+ description
152
+ fields(includeDeprecated: true) {
153
+ name
154
+ description
155
+ args { ...InputValue }
156
+ type { ...TypeRef }
157
+ isDeprecated deprecationReason
158
+ }
159
+ inputFields { ...InputValue }
160
+ interfaces { ...TypeRef }
161
+ enumValues(includeDeprecated: true) {
162
+ name
163
+ description
164
+ isDeprecated
165
+ deprecationReason
166
+ }
167
+ possibleTypes { ...TypeRef }
168
+ }
169
+
170
+ fragment InputValue on __InputValue {
171
+ name
172
+ description
173
+ type { ...TypeRef }
174
+ defaultValue
175
+ }
176
+
177
+ fragment TypeRef on __Type {
178
+ kind
179
+ name
180
+ ofType {
181
+ kind
182
+ name
183
+ ofType {
184
+ kind
185
+ name
186
+ ofType {
187
+ kind
188
+ name
189
+ ofType {
190
+ kind
191
+ name
192
+ ofType {
193
+ kind
194
+ name
195
+ ofType {
196
+ kind
197
+ name
198
+ ofType {
199
+ kind
200
+ name
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }
209
+
210
+ query IntrospectionQuery {
211
+ __schema {
212
+ queryType { name }
213
+ mutationType { name }
214
+ types { ...FullType }
215
+ directives {
216
+ name
217
+ description
218
+ locations
219
+ args { ...InputValue }
220
+ }
221
+ }
222
+ }"
223
+ }
224
+ END_OF_PAYLOAD
225
+ graphql_payloads_arr.push(graphql_introspection_payload2)
226
+
227
+ # Math Part
228
+ graphql_uri_tot = graphql_uris.length
229
+ payload_tot = graphql_payloads_arr.length
230
+ request_tot = payload_tot * graphql_uri_tot
231
+
232
+ puts "Sending #{payload_tot} payloads to #{graphql_uris.count} GraphQL URIs..."
233
+ puts "Total HTTP Requests: #{request_tot}"
234
+
235
+ user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
236
+ introspection_arr_of_hashes = []
237
+ graphql_uris.each do |this_uri|
238
+ puts "IN PROGRESS: #{this_uri}..."
239
+ graphql_payloads_arr.each_with_index do |this_payload, payload_index|
240
+ # user_agent = Faker::Internet.user_agent
241
+ timestamp = Time.now.strftime('%Y-%m-%d_%H:%M:%S')
242
+ introspection_hash = {
243
+ time: timestamp,
244
+ uri: this_uri,
245
+ payload_index: payload_index,
246
+ response_code: nil,
247
+ response_headers: nil,
248
+ response: nil
249
+ }
250
+ resp = rest_client.execute(
251
+ method: :post,
252
+ url: this_uri,
253
+ headers: {
254
+ content_type: 'application/json; charset=UTF-8',
255
+ user_agent: user_agent
256
+ },
257
+ payload: this_payload,
258
+ verify_ssl: false,
259
+ timeout: 3.0,
260
+ max_redirects: 3
261
+ )
262
+ introspection_hash[:response_code] = resp.code
263
+ introspection_hash[:response_headers] = resp.headers
264
+ json_resp = JSON.parse(
265
+ resp.body,
266
+ symbolize_names: true
267
+ )
268
+
269
+ introspection_hash[:response] = json_resp
270
+ rescue Errno::ECONNREFUSED,
271
+ Errno::ENETUNREACH,
272
+ JSON::ParserError,
273
+ OpenSSL::SSL::SSLError,
274
+ SocketError => e
275
+
276
+ introspection_hash[:response_code] = "#{e.class}: #{e.message}"
277
+
278
+ next
279
+ rescue RestClient::ExceptionWithResponse => e
280
+ introspection_hash[:response_code] = "#{e.class}: #{e.message}" if e.response.nil?
281
+
282
+ if e.response
283
+ introspection_hash[:response_code] = e.response.code
284
+ introspection_hash[:response_headers] = e.response.headers
285
+ introspection_hash[:response] = e.response.body
286
+ end
287
+
288
+ next
289
+ ensure
290
+ introspection_arr_of_hashes.push(introspection_hash)
291
+ end
292
+ end
293
+ puts 'complete.'
294
+
295
+ timestamp = Time.now.strftime('%Y-%m-%d_%H:%M:%S')
296
+ print 'Saving Introspection Results...'
297
+ File.write(
298
+ "graphql_results-#{timestamp}-ALL.json",
299
+ JSON.pretty_generate(introspection_arr_of_hashes)
300
+ )
301
+
302
+ vulnerable_uris = introspection_arr_of_hashes.select do |h|
303
+ h if (h[:response].is_a?(Hash) && h[:response].keys.first.to_sym == :data) ||
304
+ (h[:response].is_a?(Integer) && h[:response_code] == 415) ||
305
+ (h[:response].is_a?(Integer) && h[:response_code] >= 500)
306
+ end
307
+ File.write(
308
+ "graphql_results-#{timestamp}-VULNERABLE.json",
309
+ JSON.pretty_generate(vulnerable_uris)
310
+ )
311
+ puts 'complete.'
data/lib/pwn/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.4.886'
4
+ VERSION = '0.4.887'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.886
4
+ version: 0.4.887
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
@@ -1167,6 +1167,7 @@ executables:
1167
1167
  - pwn_diff_csv_files_w_column_exclude
1168
1168
  - pwn_domain_reversewhois
1169
1169
  - pwn_fuzz_net_app_proto
1170
+ - pwn_graphql_introspection_detector
1170
1171
  - pwn_ibm_appscan_enterprise
1171
1172
  - pwn_jenkins_create_job
1172
1173
  - pwn_jenkins_create_view
@@ -1233,6 +1234,7 @@ files:
1233
1234
  - bin/pwn_diff_csv_files_w_column_exclude
1234
1235
  - bin/pwn_domain_reversewhois
1235
1236
  - bin/pwn_fuzz_net_app_proto
1237
+ - bin/pwn_graphql_introspection_detector
1236
1238
  - bin/pwn_ibm_appscan_enterprise
1237
1239
  - bin/pwn_jenkins_create_job
1238
1240
  - bin/pwn_jenkins_create_view