pwn 0.5.451 → 0.5.453

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.
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'diffy'
3
4
  require 'em/pure_ruby'
4
5
  require 'faye/websocket'
5
- # require 'openapi3_parser'
6
+ require 'nokogiri'
6
7
  require 'openssl'
7
8
  require 'rest-client'
8
9
  require 'securerandom'
10
+ require 'selenium/devtools/v140'
9
11
  require 'selenium/webdriver'
10
- require 'selenium/devtools'
11
12
  require 'socksify'
12
13
  require 'timeout'
13
14
  require 'watir'
@@ -474,6 +475,8 @@ module PWN
474
475
  case js
475
476
  when 'clear', 'clear;', 'clear()', 'clear();'
476
477
  script = 'console.clear()'
478
+ when 'debugger', 'debugger;', 'debugger()', 'debugger();'
479
+ script = 'debugger'
477
480
  else
478
481
  case return_to.to_s.downcase.to_sym
479
482
  when :stdout
@@ -938,205 +941,387 @@ module PWN
938
941
  end
939
942
 
940
943
  # Supported Method Parameters::
941
- # PWN::Plugins::TransparentBrowser.debugger(
942
- # browser_obj: 'required - browser_obj returned from #open method)',
943
- # action: 'optional - action to take :pause|:resume (Defaults to :pause)',
944
- # url: 'optional - URL to navigate to after pausing debugger (Defaults to nil)'
944
+ # current_dom = PWN::Plugins::TransparentBrowser.dom(
945
+ # browser_obj: 'required - browser_obj returned from #open method)'
945
946
  # )
946
947
 
947
- public_class_method def self.debugger(opts = {})
948
+ public_class_method def self.dom(opts = {})
948
949
  browser_obj = opts[:browser_obj]
949
- supported = %i[chrome headless_chrome]
950
- verified = verify_devtools_browser(browser_obj: browser_obj, supported: supported)
950
+ verified = verify_devtools_browser(browser_obj: browser_obj)
951
951
  puts 'This browser is not supported for DevTools operations.' unless verified
952
952
  return unless verified
953
953
 
954
- action = opts[:action] ||= :pause
955
- url = opts[:url]
956
-
957
- case action.to_s.downcase.to_sym
958
- when :pause
959
- browser_obj[:devtools].send_cmd(
960
- 'EventBreakpoints.setInstrumentationBreakpoint',
961
- eventName: 'scriptFirstStatement'
962
- )
963
- # browser_obj[:devtools].send_cmd('Debugger.enable')
964
- # browser_obj[:devtools].send_cmd(
965
- # 'Debugger.setInstrumentationBreakpoint',
966
- # instrumentation: 'beforeScriptExecution'
967
- # )
968
-
969
- # browser_obj[:devtools].send_cmd(
970
- # 'EventBreakpoints.setInstrumentationBreakpoint',
971
- # eventName: 'load'
972
- # )
973
-
974
- # browser_obj[:devtools].send_cmd(
975
- # 'Debugger.setPauseOnExceptions',
976
- # state: 'all'
977
- # )
954
+ dom_str = console(browser_obj: browser_obj, js: 'document.documentElement.outerHTML', return_to: :stdout)
955
+ raise 'DOM capture failed: returned nil or empty string. Check DevTools connection.' if dom_str.nil? || dom_str.strip.empty?
978
956
 
979
- begin
980
- Timeout.timeout(1) do
981
- browser_obj[:browser].refresh if url.nil?
982
- browser_obj[:browser].goto(url) unless url.nil?
983
- end
984
- rescue Timeout::Error
985
- url
986
- end
987
- when :resume
988
- browser_obj[:devtools].send_cmd(
989
- 'EventBreakpoints.removeInstrumentationBreakpoint',
990
- eventName: 'scriptFirstStatement'
991
- )
992
- browser_obj[:devtools].send_cmd('Debugger.resume')
993
- else
994
- raise 'ERROR: action parameter must be :pause or :resume'
995
- end
957
+ Nokogiri::HTML.parse(dom_str)
996
958
  rescue StandardError => e
997
959
  raise e
998
960
  end
999
961
 
1000
962
  # Supported Method Parameters::
1001
- # current_dom = PWN::Plugins::TransparentBrowser.dom(
963
+ # page_state = PWN::Plugins::TransparentBrowser.get_page_state(
1002
964
  # browser_obj: 'required - browser_obj returned from #open method)'
1003
965
  # )
1004
966
 
1005
- public_class_method def self.dom(opts = {})
967
+ public_class_method def self.get_page_state(opts = {})
1006
968
  browser_obj = opts[:browser_obj]
1007
- supported = %i[chrome headless_chrome]
1008
- verified = verify_devtools_browser(browser_obj: browser_obj, supported: supported)
969
+ verified = verify_devtools_browser(browser_obj: browser_obj)
1009
970
  puts 'This browser is not supported for DevTools operations.' unless verified
1010
971
  return unless verified
1011
972
 
1012
- computed_styles = %i[display color font-size font-family]
1013
- browser_obj[:devtools].send_cmd(
1014
- 'DOMSnapshot.captureSnapshot',
1015
- computedStyles: computed_styles
1016
- ).transform_keys(&:to_sym)
1017
- rescue StandardError => e
1018
- raise e
1019
- end
973
+ js = <<~JS.strip
974
+ (function() {
975
+ try {
976
+ let ls = {};
977
+ for (let i = 0; i < localStorage.length; i++) {
978
+ let key = localStorage.key(i);
979
+ ls[key] = localStorage.getItem(key);
980
+ }
981
+ let ss = {};
982
+ for (let i = 0; i < sessionStorage.length; i++) {
983
+ let key = sessionStorage.key(i);
984
+ ss[key] = sessionStorage.getItem(key);
985
+ }
1020
986
 
1021
- # Supported Method Parameters::
1022
- # PWN::Plugins::TransparentBrowser.step_into(
1023
- # browser_obj: 'required - browser_obj returned from #open method)',
1024
- # steps: 'optional - number of steps taken (Defaults to 1)'
1025
- # )
987
+ let scripts = Array.from(document.scripts).map(s => ({
988
+ src: s.src,
989
+ innerHTML: s.innerHTML
990
+ })).filter(s => s.src || s.innerHTML);
1026
991
 
1027
- public_class_method def self.step_into(opts = {})
1028
- browser_obj = opts[:browser_obj]
1029
- supported = %i[chrome headless_chrome]
1030
- verified = verify_devtools_browser(browser_obj: browser_obj, supported: supported)
1031
- puts 'This browser is not supported for DevTools operations.' unless verified
1032
- return unless verified
992
+ let stylesheets = Array.from(document.querySelectorAll('link[rel="stylesheet"]')).map(l => l.href).filter(h => h);
1033
993
 
1034
- steps = opts[:steps].to_i
1035
- steps = 1 if steps.zero? || steps.negative?
994
+ let inline_styles = Array.from(document.querySelectorAll('style')).map(s => s.innerHTML).filter(c => c);
1036
995
 
1037
- diff_arr = []
1038
- steps.times do |s|
1039
- diff_hash = {}
1040
- step = s + 1
1041
- diff_hash[:step] = step
996
+ let forms = Array.from(document.forms).map(f => ({
997
+ action: f.action,
998
+ method: f.method,
999
+ elements: Array.from(f.elements).map(e => ({
1000
+ name: e.name,
1001
+ type: e.type,
1002
+ value: e.value
1003
+ }))
1004
+ }));
1042
1005
 
1043
- dom_before = dom(browser_obj: browser_obj)
1044
- diff_hash[:dom_before_step] = dom_before
1006
+ let iframes = Array.from(document.querySelectorAll('iframe')).map(i => i.src).filter(s => s);
1045
1007
 
1046
- browser_obj[:devtools].send_cmd('Debugger.stepInto')
1008
+ let csp_meta = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
1009
+ let csp = csp_meta ? csp_meta.content : null;
1047
1010
 
1048
- dom_after = dom(browser_obj: browser_obj)
1049
- diff_hash[:dom_after_step] = dom_after
1011
+ let feature_policy = [];
1012
+ if (document.featurePolicy) {
1013
+ feature_policy = document.featurePolicy.allowedFeatures().sort();
1014
+ }
1050
1015
 
1051
- da = dom_before.to_a - dom_after.to_a
1052
- diff_hash[:diff_dom] = da.to_h.transform_keys(&:to_sym)
1016
+ let is_framed = false;
1017
+ try {
1018
+ if (window.top !== window.self) {
1019
+ is_framed = true;
1020
+ }
1021
+ } catch (e) {
1022
+ is_framed = true;
1023
+ }
1053
1024
 
1054
- diff_arr.push(diff_hash)
1055
- end
1025
+ let resources = window.performance.getEntriesByType('resource').map(e => ({
1026
+ name: e.name,
1027
+ initiatorType: e.initiatorType
1028
+ }));
1029
+
1030
+ // Enhanced globals capture with values
1031
+ let globals = {};
1032
+ let propNames = Object.getOwnPropertyNames(window).sort();
1033
+ const safeStringify = (value, depth = 0) => {
1034
+ if (depth > 5) return '[Max depth exceeded]'; // Prevent deep recursion
1035
+ try {
1036
+ return JSON.stringify(value, (key, val) => {
1037
+ if (typeof val === 'function') {
1038
+ return val.toString(); // Capture function source
1039
+ } else if (typeof val === 'symbol') {
1040
+ return val.toString();
1041
+ } else if (val === window) {
1042
+ return '[Window reference]'; // Avoid circularity
1043
+ } else if (val && typeof val === 'object') {
1044
+ if (depth > 5) return '[Object (depth limit)]';
1045
+ return val; // Let JSON handle, recurse with depth
1046
+ }
1047
+ return val;
1048
+ });
1049
+ } catch (e) {
1050
+ return '[Stringify error: ' + e.message + ']';
1051
+ }
1052
+ };
1053
+
1054
+ for (let name of propNames) {
1055
+ try {
1056
+ let value = window[name];
1057
+ globals[name] = safeStringify(value);
1058
+ } catch (e) {
1059
+ globals[name] = '[Access error: ' + e.message + ']';
1060
+ }
1061
+ }
1056
1062
 
1057
- diff_arr
1063
+ return JSON.stringify({
1064
+ cookies: document.cookie,
1065
+ localStorage: ls,
1066
+ sessionStorage: ss,
1067
+ globals: globals, // Now an object with name: stringified_value
1068
+ scripts: scripts,
1069
+ stylesheets: stylesheets,
1070
+ inline_styles: inline_styles,
1071
+ stack: new Error().stack,
1072
+ location: {
1073
+ href: location.href,
1074
+ origin: location.origin,
1075
+ pathname: location.pathname,
1076
+ search: location.search,
1077
+ hash: location.hash
1078
+ },
1079
+ referrer: document.referrer,
1080
+ userAgent: navigator.userAgent,
1081
+ html_snapshot: document.documentElement.outerHTML,
1082
+ forms: forms,
1083
+ iframes: iframes,
1084
+ csp: csp,
1085
+ feature_policy: feature_policy,
1086
+ is_framed: is_framed,
1087
+ has_service_worker: 'serviceWorker' in navigator,
1088
+ resources: resources
1089
+ });
1090
+ } catch (e) {
1091
+ return JSON.stringify({
1092
+ error: e.message,
1093
+ stack: e.stack
1094
+ });
1095
+ }
1096
+ })()
1097
+ JS
1098
+
1099
+ browser_obj[:devtools].send_cmd('Console.clearMessages')
1100
+ browser_obj[:devtools].send_cmd('Log.clear')
1101
+ console_events = []
1102
+ browser_obj[:browser].driver.on_log_event(:console) { |event| console_events.push(event) }
1103
+
1104
+ # page_state = console(browser_obj: browser_obj, js: js, return_to: :stdout)
1105
+ console_cmd = { expression: js }
1106
+ runtime_resp = browser_obj[:devtools].send_cmd('Runtime.evaluate', **console_cmd)
1107
+ page_state = runtime_resp['result']['result']['value']
1108
+ JSON.parse(page_state, symbolize_names: true)
1109
+ rescue JSON::ParserError => e
1110
+ raise "Failed to parse state JSON: #{e.message}. Raw output: #{state_json.inspect}"
1058
1111
  rescue StandardError => e
1059
1112
  raise e
1060
1113
  end
1061
1114
 
1062
1115
  # Supported Method Parameters::
1063
- # PWN::Plugins::TransparentBrowser.step_out(
1064
- # browser_obj: 'required - browser_obj returned from #open method)',
1065
- # steps: 'optional - number of steps taken (Defaults to 1)'
1116
+ # messages = PWN::Plugins::TransparentBrowser.devtools_websocket_messages(
1117
+ # browser_obj: 'required - browser_obj returned from #open method)'
1066
1118
  # )
1067
1119
 
1068
- public_class_method def self.step_out(opts = {})
1120
+ public_class_method def self.devtools_websocket_messages(opts = {})
1069
1121
  browser_obj = opts[:browser_obj]
1070
- supported = %i[chrome headless_chrome]
1071
- verified = verify_devtools_browser(browser_obj: browser_obj, supported: supported)
1122
+ verified = verify_devtools_browser(browser_obj: browser_obj)
1072
1123
  puts 'This browser is not supported for DevTools operations.' unless verified
1073
1124
  return unless verified
1074
1125
 
1075
- steps = opts[:steps].to_i
1076
- steps = 1 if steps.zero? || steps.negative?
1077
-
1078
- diff_arr = []
1079
- steps.times do |s|
1080
- diff_hash = {}
1081
- step = s + 1
1082
- diff_hash[:step] = step
1126
+ devtools = browser_obj[:devtools]
1127
+ websocket = devtools.instance_variable_get(:@ws)
1128
+ websocket.instance_variable_get(:@messages)[nil]
1129
+ rescue StandardError => e
1130
+ raise e
1131
+ end
1083
1132
 
1084
- dom_before = dom(browser_obj: browser_obj)
1085
- diff_hash[:pre_step] = dom_before
1133
+ # Supported Method Parameters::
1134
+ # PWN::Plugins::TransparentBrowser.debugger(
1135
+ # browser_obj: 'required - browser_obj returned from #open method)',
1136
+ # action: 'optional - action to take :enable|:pause|:resume|:disable (Defaults to :enable)',
1137
+ # )
1086
1138
 
1087
- browser_obj[:devtools].send_cmd('Debugger.stepOut')
1139
+ public_class_method def self.debugger(opts = {})
1140
+ browser_obj = opts[:browser_obj]
1141
+ verified = verify_devtools_browser(browser_obj: browser_obj)
1142
+ puts 'This browser is not supported for DevTools operations.' unless verified
1143
+ return unless verified
1088
1144
 
1089
- dom_after = dom(browser_obj: browser_obj, step_sum: step_sum)
1090
- diff_hash[:post_step] = dom_after
1145
+ valid_actions = %i[enable pause resume disable]
1146
+ action = opts[:action] ||= :enable
1147
+ action = action.to_s.downcase.to_sym
1148
+ raise 'ERROR: action parameter must be :enable|:pause|:resume|:disable' unless valid_actions.include?(action)
1091
1149
 
1092
- da = dom_before.to_a - dom_after.to_a
1093
- diff_hash[:diff] = da.to_h.transform_keys(&:to_sym)
1150
+ devtools = browser_obj[:devtools]
1151
+ debugger_state = devtools.instance_variable_get(:@debugger_state)
1094
1152
 
1095
- diff_arr.push(diff_hash)
1153
+ case action
1154
+ when :enable
1155
+ if debugger_state.is_a?(Hash)
1156
+ debugger_state = devtools.instance_variable_get(:@debugger_state)
1157
+ devtools.remove_instance_variable(:@debugger_state) if debugger_state.is_a?(Hash)
1158
+ devtools.debugger.disable
1159
+ end
1160
+ debugger_state = {}
1161
+ breakpoint_arr = []
1162
+
1163
+ # breakpoint = devtools.debugger.set_instrumentation_breakpoint(instrumentation: 'beforeScriptExecution')
1164
+ bcmd = 'EventBreakpoints.setInstrumentationBreakpoint'
1165
+ event = 'load'
1166
+ breakpoint = devtools.send_cmd(bcmd, eventName: event)
1167
+ breakpoint['result']['breakpointId'] = "#{bcmd}.#{event}.#{SecureRandom.uuid}"
1168
+ breakpoint_arr.push(breakpoint)
1169
+ debugger_state[:breakpoints] = breakpoint_arr
1170
+
1171
+ devtools.runtime.disable
1172
+ devtools.log.disable
1173
+ devtools.network.disable
1174
+ devtools.page.disable
1175
+ devtools.debugger.enable
1176
+ when :pause
1177
+ devtools.debugger.pause
1178
+ Timeout.timeout(5) { browser_obj[:browser].refresh }
1179
+ when :resume
1180
+ devtools.debugger.resume
1181
+ when :disable
1182
+ debugger_state = devtools.instance_variable_get(:@debugger_state)
1183
+ devtools.remove_instance_variable(:@debugger_state) if debugger_state.is_a?(Hash)
1184
+ devtools.debugger.disable
1096
1185
  end
1097
1186
 
1098
- diff_arr
1187
+ devtools_websocket_messages = devtools_websocket_messages(browser_obj: browser_obj)
1188
+ debugger_state[:method] = devtools_websocket_messages['method']
1189
+ devtools.instance_variable_set(:@debugger_state, debugger_state)
1190
+ devtools
1191
+ rescue Timeout::Error
1192
+ devtools
1193
+ rescue Selenium::WebDriver::Error::WebDriverError => e
1194
+ puts e.message
1099
1195
  rescue StandardError => e
1100
1196
  raise e
1101
1197
  end
1102
1198
 
1103
1199
  # Supported Method Parameters::
1104
- # PWN::Plugins::TransparentBrowser.step_over(
1200
+ # page_state_arr = PWN::Plugins::TransparentBrowser.step(
1105
1201
  # browser_obj: 'required - browser_obj returned from #open method)',
1202
+ # action: 'optional - action to take :into|:out|:over (Defaults to :into)',
1106
1203
  # steps: 'optional - number of steps taken (Defaults to 1)'
1107
1204
  # )
1108
1205
 
1109
- public_class_method def self.step_over(opts = {})
1206
+ public_class_method def self.step(opts = {})
1110
1207
  browser_obj = opts[:browser_obj]
1111
1208
  supported = %i[chrome headless_chrome]
1112
1209
  verified = verify_devtools_browser(browser_obj: browser_obj, supported: supported)
1113
1210
  puts 'This browser is not supported for DevTools operations.' unless verified
1114
1211
  return unless verified
1115
1212
 
1213
+ valid_actions = %i[into out over]
1214
+ action = opts[:action] ||= :into
1215
+ action = action.to_s.downcase.to_sym
1216
+ raise 'ERROR: action parameter must be :into|:out|:over' unless valid_actions.include?(action)
1217
+
1116
1218
  steps = opts[:steps].to_i
1117
1219
  steps = 1 if steps.zero? || steps.negative?
1118
1220
 
1119
- diff_arr = []
1120
- steps.times do |s|
1121
- diff_hash = {}
1122
- step = s + 1
1123
- diff_hash[:step] = step
1221
+ devtools = browser_obj[:devtools]
1222
+ debugger_state = devtools.instance_variable_get(:@debugger_state)
1223
+ method = debugger_state[:method]
1224
+ if method != 'Debugger.paused'
1225
+ puts 'The debugger must be paused before stepping. Pausing now...'
1226
+ return devtools
1227
+ end
1124
1228
 
1125
- dom_before = dom(browser_obj: browser_obj)
1126
- diff_hash[:dom_before_step] = dom_before
1229
+ page_state_arr = []
1230
+ steps.times do |s|
1231
+ step_num = s + 1
1232
+ puts "Stepping #{action} (step #{step_num}/#{steps})..."
1233
+
1234
+ # before = get_page_state(browser_obj: browser_obj)
1235
+ # puts before.inspect
1236
+ before = devtools_websocket_messages(browser_obj: browser_obj)
1237
+ method = before['method']
1238
+ # puts before
1239
+ puts "\n"
1240
+
1241
+ if method == 'Debugger.paused'
1242
+ before_location = before['params']['callFrames'].first['location']
1243
+ start_location = before['params']['callFrames'].first['scopeChain'].first['startLocation']
1244
+ before_script_id = start_location['scriptId']
1245
+ from_line_num = start_location['lineNumber']
1246
+ from_column_num = start_location['columnNumber']
1247
+
1248
+ end_location = before['params']['callFrames'].first['scopeChain'].first['endLocation']
1249
+ to_line_num = end_location['lineNumber']
1250
+ to_column_num = end_location['columnNumber']
1251
+
1252
+ source_obj = devtools.debugger.get_script_source(script_id: before_script_id)
1253
+ source_code = source_obj['result']['scriptSource']
1254
+ # puts source_code
1255
+ # gets
1256
+
1257
+ source_lines = source_code.split("\n")
1258
+ source_lines_str = source_lines[from_line_num..to_line_num].join("\n")
1259
+ source_to_review = source_lines_str[from_column_num..to_column_num]
1260
+
1261
+ puts source_to_review
1262
+ request = source_lines_str[from_column_num..to_column_num]
1263
+ ai_analysis = PWN::AI::Introspection.reflect_on(request: request)
1264
+ puts "^^^ #{ai_analysis}" unless ai_analysis.nil?
1265
+ # gets
1266
+ end
1127
1267
 
1128
- browser_obj[:devtools].send_cmd('Debugger.stepOver')
1268
+ case action
1269
+ when :into
1270
+ devtools.debugger.step_into
1271
+ when :out
1272
+ devtools.debugger.step_out
1273
+ when :over
1274
+ devtools.debugger.step_over
1275
+ end
1129
1276
 
1130
- dom_after = dom(browser_obj: browser_obj, step_sum: step_sum)
1131
- diff_hash[:dom_after_step] = dom_after
1277
+ puts "\n" * 3
1278
+ after = devtools_websocket_messages(browser_obj: browser_obj)
1279
+ method = after['method']
1280
+ # puts after
1281
+ puts "\n"
1282
+
1283
+ if method == 'Debugger.paused'
1284
+ after_location = after['params']['callFrames'].first['scopeChain'].first['object']
1285
+ start_location = after['params']['callFrames'].first['scopeChain'].first['startLocation']
1286
+ after_script_id = start_location['scriptId']
1287
+ from_line_num = start_location['lineNumber']
1288
+ from_column_num = start_location['columnNumber']
1289
+
1290
+ end_location = after['params']['callFrames'].first['scopeChain'].first['endLocation']
1291
+ to_line_num = end_location['lineNumber']
1292
+ to_column_num = end_location['columnNumber']
1293
+
1294
+ source_obj = devtools.debugger.get_script_source(script_id: after_script_id)
1295
+ source_code = source_obj['result']['scriptSource']
1296
+ # puts source_code
1297
+ # gets
1298
+
1299
+ source_lines = source_code.split("\n")
1300
+ source_lines_str = source_lines[from_line_num..to_line_num].join("\n")
1301
+ source_to_review = source_lines_str[from_column_num..to_column_num]
1302
+
1303
+ puts source_to_review
1304
+ request = source_lines_str[from_column_num..to_column_num]
1305
+ ai_analysis = PWN::AI::Introspection.reflect_on(request: request)
1306
+ puts "^^^ #{ai_analysis}" unless ai_analysis.nil?
1307
+ # gets
1308
+ end
1309
+ puts "\n" * 6
1132
1310
 
1133
- da = dom_before.to_a - dom_after.to_a
1134
- diff_hash[:diff_dom] = da.to_h.transform_keys(&:to_sym)
1311
+ # step_hash = {
1312
+ # step: step_num,
1313
+ # action: action,
1314
+ # before: before,
1315
+ # after: after,
1316
+ # diff: diff.to_s(:text)
1317
+ # }
1135
1318
 
1136
- diff_arr.push(diff_hash)
1319
+ # page_state_arr.push(step_hash)
1137
1320
  end
1138
1321
 
1139
- diff_arr
1322
+ devtools
1323
+ rescue Selenium::WebDriver::Error::WebDriverError
1324
+ devtools
1140
1325
  rescue StandardError => e
1141
1326
  raise e
1142
1327
  end
@@ -1399,28 +1584,22 @@ module PWN
1399
1584
  keyword: 'optional - keyword in title or url used to close tabs (defaults to closing active tab)'
1400
1585
  )
1401
1586
 
1402
- #{self}.debugger(
1403
- browser_obj: 'required - browser_obj returned from #open method)',
1404
- action: 'optional - action to take :pause|:resume (Defaults to :pause)',
1405
- url: 'optional - URL to navigate to after pausing debugger (Defaults to nil)'
1406
- )
1407
-
1408
1587
  current_dom = #{self}.dom(
1409
1588
  browser_obj: 'required - browser_obj returned from #open method)'
1410
1589
  )
1411
1590
 
1412
- #{self}.step_into(
1413
- browser_obj: 'required - browser_obj returned from #open method)',
1414
- steps: 'optional - number of steps taken (Defaults to 1)'
1591
+ page_state = #{self}.get_page_state(
1592
+ browser_obj: 'required - browser_obj returned from #open method)'
1415
1593
  )
1416
1594
 
1417
- #{self}.step_out(
1595
+ #{self}.debugger(
1418
1596
  browser_obj: 'required - browser_obj returned from #open method)',
1419
- steps: 'optional - number of steps taken (Defaults to 1)'
1597
+ action: 'optional - action to take :enable|:pause|:resume|:disable (Defaults to :enable)'
1420
1598
  )
1421
1599
 
1422
- #{self}.step_over(
1600
+ #{self}.step(
1423
1601
  browser_obj: 'required - browser_obj returned from #open method)',
1602
+ action: 'optional - action to take :into|:out|:over (Defaults to :into)',
1424
1603
  steps: 'optional - number of steps taken (Defaults to 1)'
1425
1604
  )
1426
1605
 
@@ -22,61 +22,8 @@ module PWN
22
22
  report_name: HTMLEntities.new.encode(report_name.to_s.scrub.strip.chomp),
23
23
  data: []
24
24
  }
25
- report_name = opts[:report_name] ||= File.basename(Dir.pwd)
26
25
 
27
- # Calculate percentage of AI analysis based on the number of entries
28
- # total_entries = results_hash[:data].sum { |entry| entry[:line_no_and_contents].size }
29
- # puts "Total entries to analyze: #{total_entries}" if engine
30
-
31
- # percent_complete = 0.0
32
- # entry_count = 0
33
- # spin = TTY::Spinner.new(
34
- # '[:spinner] Report Generation Progress: :percent_complete :entry_count of :total_entries',
35
- # format: :dots,
36
- # hide_cursor: true
37
- # )
38
- # spin.auto_spin
39
-
40
- # ai_instrospection = PWN::Env[:ai][:introspection]
41
- # puts "Analyzing source code using AI engine: #{engine}\nModel: #{model}\nSystem Role Content: #{system_role_content}\nTemperature: #{temp}" if ai_instrospection
42
-
43
- # results_hash[:data].each do |hash_line|
44
- # git_repo_root_uri = hash_line[:filename][:git_repo_root_uri]
45
- # filename = hash_line[:filename][:entry]
46
- # hash_line[:line_no_and_contents].each do |src_detail|
47
- # entry_count += 1
48
- # percent_complete = (entry_count.to_f / total_entries * 100).round(2)
49
- # line_no = src_detail[:line_no]
50
- # source_code_snippet = src_detail[:contents]
51
- # author = src_detail[:author].to_s.scrub.chomp.strip
52
- # response = nil
53
- # if ai_instrospection
54
- # request = {
55
- # scm_uri: "#{git_repo_root_uri}/#{filename}",
56
- # line: line_no,
57
- # source_code_snippet: source_code_snippet
58
- # }.to_json
59
- # response = PWN::AI::Introspection.reflect(request: request)
60
- # end
61
- # ai_analysis = nil
62
- # if response.is_a?(Hash)
63
- # ai_analysis = response[:choices].last[:text] if response[:choices].last.keys.include?(:text)
64
- # ai_analysis = response[:choices].last[:content] if response[:choices].last.keys.include?(:content)
65
- # puts "AI Analysis Progress: #{percent_complete}% Line: #{line_no} | Author: #{author} | AI Analysis: #{ai_analysis}\n\n\n" if ai_analysis
66
- # end
67
- # src_detail[:ai_analysis] = ai_analysis.to_s.scrub.chomp.strip
68
- # spin.update(
69
- # percent_complete: "#{percent_complete}%",
70
- # entry_count: entry_count,
71
- # total_entries: total_entries
72
- # )
73
- # end
74
- # end
75
-
76
- # JSON object Completion
77
- # File.open("#{dir_path}/pwn_scan_git_source.json", 'w') do |f|
78
- # f.print(results_hash.to_json)
79
- # end
26
+ report_name = opts[:report_name] ||= File.basename(Dir.pwd)
80
27
  File.write(
81
28
  "#{dir_path}/#{report_name}.json",
82
29
  JSON.pretty_generate(results_hash)