pwn 0.4.886 → 0.4.888

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: 5c9290a5c2e09f3306dfebf9d4a557f5ee9d63ab0a909650af515c99fccdf7a1
4
+ data.tar.gz: 9ef4d20e21c19bca22c9c678b50dcad41ab00747a09c9a059f06f58ec70d2721
5
5
  SHA512:
6
- metadata.gz: d3ef35410455de329014f16c01c6498ce9e7540a1edbf2028b3c181297e47084a4439e7e6344892ce33685868599cd44f3ffb21008bfcd83695f6b1931067a95
7
- data.tar.gz: 0e3155be591274c629fc0dd73a45d94b830261af83bf4a074d05c4579d0eea110815f5efb6ef5adf439c16e171da51f7287f44e032f29ec29b719c8a4c163a9d
6
+ metadata.gz: 3207380842882ae96d64db682b3f1016963a551aa9757f56c29daa0472a2e7856899f5e1a328409ed88fd6e233fb7f06ba6bb92ccdc58bd2ffa78d969f209a3c
7
+ data.tar.gz: db6d6deac66c00462f27cdb1e89c8a363a01338969489762f5d3d8b3803df66167b606ad78548bf95ebd6eb9eef22235e4d80e491993aacb93a97684ce12777a
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.888]: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.888]: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.888'
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.888
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
@@ -1189,6 +1189,7 @@ executables:
1189
1189
  - pwn_serial_msr206
1190
1190
  - pwn_serial_qualcomm_commands
1191
1191
  - pwn_serial_son_micro_sm132_rfid
1192
+ - pwn_shodan_graphql_introspection
1192
1193
  - pwn_shodan_search
1193
1194
  - pwn_simple_http_server
1194
1195
  - pwn_web_cache_deception
@@ -1255,6 +1256,7 @@ files:
1255
1256
  - bin/pwn_serial_msr206
1256
1257
  - bin/pwn_serial_qualcomm_commands
1257
1258
  - bin/pwn_serial_son_micro_sm132_rfid
1259
+ - bin/pwn_shodan_graphql_introspection
1258
1260
  - bin/pwn_shodan_search
1259
1261
  - bin/pwn_simple_http_server
1260
1262
  - bin/pwn_web_cache_deception