pwn 0.5.708 → 0.5.710

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.
Files changed (450) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/documentation/Installation.md +1 -0
  4. data/etc/default_skills/exploitdev/SKILL.md +38 -0
  5. data/etc/default_skills/pwn/ai/agent/extrospection/osint/bridges/SKILL.md +30 -8
  6. data/etc/default_skills/pwn/ai/agent/extrospection/osint/social/SKILL.md +30 -8
  7. data/etc/default_skills/pwn/ai/agent/extrospection/osint/social/references/urls.md +1 -1
  8. data/etc/default_skills/pwn/ai/agent/extrospection/references/urls.md +0 -1
  9. data/etc/default_skills/pwn/memory_index/SKILL.md +0 -4
  10. data/etc/default_skills/pwn/plugins/aflplusplus/SKILL.md +49 -0
  11. data/etc/default_skills/pwn/plugins/android/SKILL.md +1 -0
  12. data/etc/default_skills/pwn/plugins/artifact_registry/SKILL.md +49 -0
  13. data/etc/default_skills/pwn/plugins/binary_parser/SKILL.md +54 -0
  14. data/etc/default_skills/pwn/plugins/credential_attack/SKILL.md +58 -0
  15. data/etc/default_skills/pwn/plugins/credential_attack/references/urls.md +3 -0
  16. data/etc/default_skills/pwn/plugins/exploit_db/SKILL.md +49 -0
  17. data/etc/default_skills/pwn/plugins/exploit_dev/SKILL.md +63 -0
  18. data/etc/default_skills/pwn/plugins/frida/SKILL.md +51 -0
  19. data/etc/default_skills/pwn/plugins/fuzz/SKILL.md +2 -0
  20. data/etc/default_skills/pwn/plugins/gdb/SKILL.md +53 -0
  21. data/etc/default_skills/pwn/plugins/jobs/SKILL.md +51 -0
  22. data/etc/default_skills/pwn/plugins/k8s/SKILL.md +51 -0
  23. data/etc/default_skills/pwn/plugins/nuclei/SKILL.md +50 -0
  24. data/etc/default_skills/pwn/plugins/preflight_checker/SKILL.md +59 -0
  25. data/etc/default_skills/pwn/plugins/process_tube/SKILL.md +53 -0
  26. data/etc/default_skills/pwn/plugins/radare2/SKILL.md +59 -0
  27. data/etc/default_skills/pwn/plugins/recon/SKILL.md +57 -0
  28. data/etc/default_skills/pwn/plugins/recon/references/urls.md +6 -0
  29. data/etc/default_skills/pwn/plugins/semgrep/SKILL.md +48 -0
  30. data/etc/default_skills/pwn/plugins/sqlmap/SKILL.md +48 -0
  31. data/etc/default_skills/pwn/plugins/transparent_browser/SKILL.md +0 -4
  32. data/etc/default_skills/pwn/plugins/volatility/SKILL.md +49 -0
  33. data/lib/pwn/ai/agent/assembly.rb +4 -1
  34. data/lib/pwn/ai/agent/btc.rb +4 -1
  35. data/lib/pwn/ai/agent/burp_suite.rb +5 -2
  36. data/lib/pwn/ai/agent/curriculum.rb +89 -30
  37. data/lib/pwn/ai/agent/dispatch.rb +27 -16
  38. data/lib/pwn/ai/agent/extrospection/osint/bridges.rb +9 -18
  39. data/lib/pwn/ai/agent/extrospection/osint/social.rb +9 -18
  40. data/lib/pwn/ai/agent/extrospection.rb +185 -60
  41. data/lib/pwn/ai/agent/gqrx.rb +4 -1
  42. data/lib/pwn/ai/agent/hacker_one.rb +5 -2
  43. data/lib/pwn/ai/agent/learning.rb +142 -25
  44. data/lib/pwn/ai/agent/loop.rb +53 -46
  45. data/lib/pwn/ai/agent/metrics.rb +133 -23
  46. data/lib/pwn/ai/agent/mistakes.rb +126 -17
  47. data/lib/pwn/ai/agent/open_goal.rb +25 -9
  48. data/lib/pwn/ai/agent/policy.rb +158 -18
  49. data/lib/pwn/ai/agent/prompt_builder.rb +21 -11
  50. data/lib/pwn/ai/agent/prompt_cache.rb +44 -13
  51. data/lib/pwn/ai/agent/reflect.rb +9 -5
  52. data/lib/pwn/ai/agent/registry.rb +65 -12
  53. data/lib/pwn/ai/agent/result.rb +19 -10
  54. data/lib/pwn/ai/agent/reward.rb +150 -32
  55. data/lib/pwn/ai/agent/sast.rb +4 -1
  56. data/lib/pwn/ai/agent/swarm.rb +72 -36
  57. data/lib/pwn/ai/agent/task_summarizer.rb +165 -36
  58. data/lib/pwn/ai/agent/tool_guard.rb +105 -6
  59. data/lib/pwn/ai/agent/tools/sessions.rb +8 -1
  60. data/lib/pwn/ai/agent/transparent_browser.rb +4 -1
  61. data/lib/pwn/ai/agent/turn_finalizer.rb +41 -21
  62. data/lib/pwn/ai/agent/vuln_gen.rb +6 -3
  63. data/lib/pwn/ai/agent.rb +4 -0
  64. data/lib/pwn/ai/anthropic.rb +41 -7
  65. data/lib/pwn/ai/gemini.rb +21 -11
  66. data/lib/pwn/ai/grok.rb +44 -6
  67. data/lib/pwn/ai/http_retry.rb +40 -12
  68. data/lib/pwn/ai/ollama.rb +19 -10
  69. data/lib/pwn/ai/open_ai.rb +81 -30
  70. data/lib/pwn/ai/open_web_ui.rb +20 -14
  71. data/lib/pwn/ai/red_team/agent_protocol_abuse.rb +7 -1
  72. data/lib/pwn/ai/red_team/data_and_model_poisoning.rb +7 -1
  73. data/lib/pwn/ai/red_team/excessive_agency.rb +7 -1
  74. data/lib/pwn/ai/red_team/hidden_context_exposure.rb +7 -1
  75. data/lib/pwn/ai/red_team/insecure_output_handling.rb +7 -1
  76. data/lib/pwn/ai/red_team/jailbreak.rb +7 -1
  77. data/lib/pwn/ai/red_team/memory_poisoning.rb +7 -1
  78. data/lib/pwn/ai/red_team/multimodal_injection.rb +7 -1
  79. data/lib/pwn/ai/red_team/overreliance.rb +7 -1
  80. data/lib/pwn/ai/red_team/payload_splitting.rb +7 -1
  81. data/lib/pwn/ai/red_team/prompt_injection.rb +7 -1
  82. data/lib/pwn/ai/red_team/rag_poisoning.rb +7 -1
  83. data/lib/pwn/ai/red_team/sensitive_information_disclosure.rb +7 -1
  84. data/lib/pwn/ai/red_team/supply_chain.rb +7 -1
  85. data/lib/pwn/ai/red_team/system_prompt_extraction.rb +7 -1
  86. data/lib/pwn/ai/red_team/test_case_engine.rb +12 -9
  87. data/lib/pwn/ai/red_team/token_smuggling.rb +7 -1
  88. data/lib/pwn/ai/red_team/unbounded_consumption.rb +7 -1
  89. data/lib/pwn/ai/red_team/vector_and_embedding_weaknesses.rb +7 -1
  90. data/lib/pwn/ai/red_team.rb +4 -0
  91. data/lib/pwn/ai.rb +4 -0
  92. data/lib/pwn/aws/acm.rb +5 -2
  93. data/lib/pwn/aws/api_gateway.rb +10 -7
  94. data/lib/pwn/aws/app_stream.rb +5 -2
  95. data/lib/pwn/aws/application_auto_scaling.rb +5 -2
  96. data/lib/pwn/aws/application_discovery_service.rb +5 -2
  97. data/lib/pwn/aws/auto_scaling.rb +5 -2
  98. data/lib/pwn/aws/batch.rb +5 -2
  99. data/lib/pwn/aws/budgets.rb +5 -2
  100. data/lib/pwn/aws/cloud_formation.rb +5 -2
  101. data/lib/pwn/aws/cloud_front.rb +7 -4
  102. data/lib/pwn/aws/cloud_hsm.rb +5 -2
  103. data/lib/pwn/aws/cloud_search.rb +5 -2
  104. data/lib/pwn/aws/cloud_search_domain.rb +5 -2
  105. data/lib/pwn/aws/cloud_trail.rb +5 -2
  106. data/lib/pwn/aws/cloud_watch.rb +5 -2
  107. data/lib/pwn/aws/cloud_watch_events.rb +5 -2
  108. data/lib/pwn/aws/cloud_watch_logs.rb +5 -2
  109. data/lib/pwn/aws/code_build.rb +5 -2
  110. data/lib/pwn/aws/code_commit.rb +5 -2
  111. data/lib/pwn/aws/code_deploy.rb +5 -2
  112. data/lib/pwn/aws/code_pipeline.rb +5 -2
  113. data/lib/pwn/aws/cognito_identity.rb +5 -2
  114. data/lib/pwn/aws/cognito_identity_provider.rb +5 -2
  115. data/lib/pwn/aws/cognito_sync.rb +5 -2
  116. data/lib/pwn/aws/config_service.rb +5 -2
  117. data/lib/pwn/aws/data_pipleline.rb +5 -2
  118. data/lib/pwn/aws/database_migration_service.rb +5 -2
  119. data/lib/pwn/aws/device_farm.rb +5 -2
  120. data/lib/pwn/aws/direct_connect.rb +5 -2
  121. data/lib/pwn/aws/directory_service.rb +5 -2
  122. data/lib/pwn/aws/dynamo_db.rb +5 -2
  123. data/lib/pwn/aws/dynamo_db_streams.rb +5 -2
  124. data/lib/pwn/aws/ec2.rb +5 -2
  125. data/lib/pwn/aws/ecr.rb +5 -2
  126. data/lib/pwn/aws/ecs.rb +5 -2
  127. data/lib/pwn/aws/efs.rb +5 -2
  128. data/lib/pwn/aws/elasti_cache.rb +5 -2
  129. data/lib/pwn/aws/elastic_beanstalk.rb +8 -5
  130. data/lib/pwn/aws/elastic_load_balancing.rb +5 -2
  131. data/lib/pwn/aws/elastic_load_balancing_v2.rb +6 -3
  132. data/lib/pwn/aws/elastic_transcoder.rb +5 -2
  133. data/lib/pwn/aws/elasticsearch_service.rb +5 -2
  134. data/lib/pwn/aws/emr.rb +5 -2
  135. data/lib/pwn/aws/firehose.rb +5 -2
  136. data/lib/pwn/aws/game_lift.rb +5 -2
  137. data/lib/pwn/aws/glacier.rb +6 -3
  138. data/lib/pwn/aws/health.rb +5 -2
  139. data/lib/pwn/aws/iam.rb +10 -4
  140. data/lib/pwn/aws/import_export.rb +5 -2
  141. data/lib/pwn/aws/inspector.rb +5 -2
  142. data/lib/pwn/aws/iot.rb +5 -2
  143. data/lib/pwn/aws/iot_data_plane.rb +5 -2
  144. data/lib/pwn/aws/kinesis.rb +5 -2
  145. data/lib/pwn/aws/kinesis_analytics.rb +5 -2
  146. data/lib/pwn/aws/kms.rb +5 -2
  147. data/lib/pwn/aws/lambda.rb +5 -2
  148. data/lib/pwn/aws/lambda_preview.rb +5 -2
  149. data/lib/pwn/aws/lex.rb +5 -2
  150. data/lib/pwn/aws/lightsail.rb +5 -2
  151. data/lib/pwn/aws/machine_learning.rb +5 -2
  152. data/lib/pwn/aws/marketplace_commerce_analytics.rb +5 -2
  153. data/lib/pwn/aws/marketplace_metering.rb +5 -2
  154. data/lib/pwn/aws/ops_works.rb +5 -2
  155. data/lib/pwn/aws/ops_works_cm.rb +5 -2
  156. data/lib/pwn/aws/pinpoint.rb +5 -2
  157. data/lib/pwn/aws/polly.rb +5 -2
  158. data/lib/pwn/aws/rds.rb +5 -2
  159. data/lib/pwn/aws/redshift.rb +5 -2
  160. data/lib/pwn/aws/rekognition.rb +5 -2
  161. data/lib/pwn/aws/route53.rb +5 -2
  162. data/lib/pwn/aws/route53_domains.rb +5 -2
  163. data/lib/pwn/aws/s3.rb +5 -2
  164. data/lib/pwn/aws/service_catalog.rb +5 -2
  165. data/lib/pwn/aws/ses.rb +5 -2
  166. data/lib/pwn/aws/shield.rb +5 -2
  167. data/lib/pwn/aws/simple_db.rb +5 -2
  168. data/lib/pwn/aws/sms.rb +5 -2
  169. data/lib/pwn/aws/snowball.rb +5 -2
  170. data/lib/pwn/aws/sns.rb +5 -2
  171. data/lib/pwn/aws/sqs.rb +5 -2
  172. data/lib/pwn/aws/ssm.rb +5 -2
  173. data/lib/pwn/aws/states.rb +5 -2
  174. data/lib/pwn/aws/storage_gateway.rb +5 -2
  175. data/lib/pwn/aws/sts.rb +4 -1
  176. data/lib/pwn/aws/support.rb +5 -2
  177. data/lib/pwn/aws/swf.rb +5 -2
  178. data/lib/pwn/aws/waf.rb +5 -2
  179. data/lib/pwn/aws/waf_regional.rb +5 -2
  180. data/lib/pwn/aws/workspaces.rb +5 -2
  181. data/lib/pwn/aws/x_ray.rb +5 -2
  182. data/lib/pwn/aws.rb +4 -0
  183. data/lib/pwn/banner/anon.rb +3 -0
  184. data/lib/pwn/banner/bubble.rb +3 -0
  185. data/lib/pwn/banner/cheshire.rb +3 -0
  186. data/lib/pwn/banner/code_cave.rb +3 -0
  187. data/lib/pwn/banner/dont_panic.rb +3 -0
  188. data/lib/pwn/banner/f_society.rb +3 -0
  189. data/lib/pwn/banner/fork_bomb.rb +3 -0
  190. data/lib/pwn/banner/jmp_esp.rb +3 -0
  191. data/lib/pwn/banner/matrix.rb +5 -1
  192. data/lib/pwn/banner/ninja.rb +3 -0
  193. data/lib/pwn/banner/off_the_air.rb +3 -0
  194. data/lib/pwn/banner/pirate.rb +3 -0
  195. data/lib/pwn/banner/radare2.rb +3 -0
  196. data/lib/pwn/banner/radare2_ai.rb +3 -0
  197. data/lib/pwn/banner/white_rabbit.rb +3 -0
  198. data/lib/pwn/banner.rb +6 -2
  199. data/lib/pwn/blockchain/btc.rb +8 -3
  200. data/lib/pwn/blockchain/eth.rb +10 -3
  201. data/lib/pwn/blockchain.rb +4 -0
  202. data/lib/pwn/bounty/lifecycle_authz_replay.rb +46 -27
  203. data/lib/pwn/bounty.rb +4 -0
  204. data/lib/pwn/config.rb +79 -13
  205. data/lib/pwn/cron.rb +297 -20
  206. data/lib/pwn/driver.rb +2 -18
  207. data/lib/pwn/ffi/adalm_pluto.rb +65 -11
  208. data/lib/pwn/ffi/fftw.rb +31 -6
  209. data/lib/pwn/ffi/hack_rf.rb +59 -8
  210. data/lib/pwn/ffi/liquid.rb +63 -10
  211. data/lib/pwn/ffi/rtl_sdr.rb +35 -5
  212. data/lib/pwn/ffi/soapy_sdr.rb +60 -10
  213. data/lib/pwn/ffi/stdio.rb +7 -8
  214. data/lib/pwn/ffi/volk.rb +36 -7
  215. data/lib/pwn/ffi.rb +12 -0
  216. data/lib/pwn/memory.rb +136 -16
  217. data/lib/pwn/memory_index.rb +34 -19
  218. data/lib/pwn/migrate.rb +34 -24
  219. data/lib/pwn/module_skills.rb +39 -8
  220. data/lib/pwn/plugins/aflplusplus.rb +72 -0
  221. data/lib/pwn/plugins/android.rb +71 -245
  222. data/lib/pwn/plugins/artifact_registry.rb +71 -0
  223. data/lib/pwn/plugins/assembly.rb +9 -4
  224. data/lib/pwn/plugins/authentication_helper.rb +8 -5
  225. data/lib/pwn/plugins/baresip.rb +59 -12
  226. data/lib/pwn/plugins/basic_auth.rb +9 -3
  227. data/lib/pwn/plugins/beef.rb +28 -18
  228. data/lib/pwn/plugins/binary_parser.rb +133 -0
  229. data/lib/pwn/plugins/black_duck_binary_analysis.rb +63 -39
  230. data/lib/pwn/plugins/burp_suite.rb +98 -68
  231. data/lib/pwn/plugins/bus_pirate.rb +15 -8
  232. data/lib/pwn/plugins/char.rb +33 -3
  233. data/lib/pwn/plugins/credential_attack.rb +158 -0
  234. data/lib/pwn/plugins/credit_card.rb +6 -1
  235. data/lib/pwn/plugins/dao_ldap.rb +19 -13
  236. data/lib/pwn/plugins/dao_mongo.rb +11 -5
  237. data/lib/pwn/plugins/dao_postgres.rb +28 -19
  238. data/lib/pwn/plugins/dao_sqlite3.rb +15 -6
  239. data/lib/pwn/plugins/defect_dojo.rb +38 -22
  240. data/lib/pwn/plugins/detect_os.rb +5 -0
  241. data/lib/pwn/plugins/ein.rb +3 -0
  242. data/lib/pwn/plugins/exploit_db.rb +69 -0
  243. data/lib/pwn/plugins/exploit_dev.rb +330 -0
  244. data/lib/pwn/plugins/file_fu.rb +11 -8
  245. data/lib/pwn/plugins/frida.rb +112 -0
  246. data/lib/pwn/plugins/fuzz.rb +42 -6
  247. data/lib/pwn/plugins/gdb.rb +115 -0
  248. data/lib/pwn/plugins/git.rb +19 -14
  249. data/lib/pwn/plugins/github.rb +38 -15
  250. data/lib/pwn/plugins/google_workspace.rb +188 -45
  251. data/lib/pwn/plugins/hacker_one.rb +159 -35
  252. data/lib/pwn/plugins/hunter.rb +6 -3
  253. data/lib/pwn/plugins/ip_info.rb +9 -4
  254. data/lib/pwn/plugins/irc.rb +28 -15
  255. data/lib/pwn/plugins/jenkins.rb +65 -57
  256. data/lib/pwn/plugins/jira_data_center.rb +30 -22
  257. data/lib/pwn/plugins/jobs.rb +110 -0
  258. data/lib/pwn/plugins/json_pathify.rb +9 -5
  259. data/lib/pwn/plugins/k8s.rb +73 -0
  260. data/lib/pwn/plugins/log.rb +113 -13
  261. data/lib/pwn/plugins/mail_agent.rb +87 -79
  262. data/lib/pwn/plugins/metasploit.rb +11 -6
  263. data/lib/pwn/plugins/monkey_patch.rb +3 -0
  264. data/lib/pwn/plugins/msr206.rb +42 -28
  265. data/lib/pwn/plugins/nessus_cloud.rb +44 -4
  266. data/lib/pwn/plugins/nexpose_vuln_scan.rb +40 -24
  267. data/lib/pwn/plugins/nmap_it.rb +14 -34
  268. data/lib/pwn/plugins/nuclei.rb +90 -0
  269. data/lib/pwn/plugins/oauth2.rb +11 -5
  270. data/lib/pwn/plugins/ocr.rb +3 -0
  271. data/lib/pwn/plugins/open_api.rb +5 -2
  272. data/lib/pwn/plugins/openvas.rb +33 -25
  273. data/lib/pwn/plugins/packet.rb +152 -31
  274. data/lib/pwn/plugins/pdf_parse.rb +5 -2
  275. data/lib/pwn/plugins/pony.rb +86 -1
  276. data/lib/pwn/plugins/preflight_checker.rb +166 -0
  277. data/lib/pwn/plugins/process_tube.rb +139 -0
  278. data/lib/pwn/plugins/ps.rb +7 -1
  279. data/lib/pwn/plugins/pwn_logger.rb +6 -2
  280. data/lib/pwn/plugins/rabbit_mq.rb +12 -7
  281. data/lib/pwn/plugins/radare2.rb +253 -0
  282. data/lib/pwn/plugins/recon.rb +196 -0
  283. data/lib/pwn/plugins/repl.rb +122 -1
  284. data/lib/pwn/plugins/scannable_codes.rb +5 -1
  285. data/lib/pwn/plugins/semgrep.rb +61 -0
  286. data/lib/pwn/plugins/serial.rb +24 -14
  287. data/lib/pwn/plugins/shodan.rb +54 -35
  288. data/lib/pwn/plugins/slack_client.rb +11 -6
  289. data/lib/pwn/plugins/sock.rb +17 -8
  290. data/lib/pwn/plugins/spider.rb +5 -2
  291. data/lib/pwn/plugins/sqlmap.rb +49 -0
  292. data/lib/pwn/plugins/ssn.rb +3 -0
  293. data/lib/pwn/plugins/thread_pool.rb +6 -9
  294. data/lib/pwn/plugins/tor.rb +9 -4
  295. data/lib/pwn/plugins/transparent_browser.rb +62 -107
  296. data/lib/pwn/plugins/tty_spinner.rb +16 -2
  297. data/lib/pwn/plugins/twitter_api.rb +6 -2
  298. data/lib/pwn/plugins/uri_scheme.rb +4 -1
  299. data/lib/pwn/plugins/vault.rb +12 -3
  300. data/lib/pwn/plugins/vin.rb +24 -12
  301. data/lib/pwn/plugins/voice.rb +7 -2
  302. data/lib/pwn/plugins/volatility.rb +67 -0
  303. data/lib/pwn/plugins/vsphere.rb +9 -5
  304. data/lib/pwn/plugins/xxd.rb +12 -43
  305. data/lib/pwn/plugins/zaproxy.rb +30 -16
  306. data/lib/pwn/plugins.rb +22 -0
  307. data/lib/pwn/reports/ai_red_team.rb +6 -2
  308. data/lib/pwn/reports/csv.rb +8 -1
  309. data/lib/pwn/reports/fuzz.rb +5 -2
  310. data/lib/pwn/reports/html.rb +8 -1
  311. data/lib/pwn/reports/html_footer.rb +4 -3
  312. data/lib/pwn/reports/html_header.rb +6 -2
  313. data/lib/pwn/reports/json.rb +8 -1
  314. data/lib/pwn/reports/markdown.rb +8 -1
  315. data/lib/pwn/reports/pdf.rb +8 -1
  316. data/lib/pwn/reports/phone.rb +5 -2
  317. data/lib/pwn/reports/sast.rb +6 -2
  318. data/lib/pwn/reports/uri_buster.rb +5 -2
  319. data/lib/pwn/reports/xml.rb +8 -1
  320. data/lib/pwn/reports.rb +19 -0
  321. data/lib/pwn/sast/amqp_connect_as_guest.rb +9 -3
  322. data/lib/pwn/sast/apache_file_system_util_api.rb +9 -3
  323. data/lib/pwn/sast/aws.rb +9 -3
  324. data/lib/pwn/sast/banned_function_calls_c.rb +9 -3
  325. data/lib/pwn/sast/base64.rb +9 -3
  326. data/lib/pwn/sast/beef_hook.rb +9 -3
  327. data/lib/pwn/sast/cmd_execution_go_lang.rb +9 -3
  328. data/lib/pwn/sast/cmd_execution_java.rb +9 -3
  329. data/lib/pwn/sast/cmd_execution_python.rb +9 -3
  330. data/lib/pwn/sast/cmd_execution_ruby.rb +9 -3
  331. data/lib/pwn/sast/cmd_execution_scala.rb +9 -3
  332. data/lib/pwn/sast/csrf.rb +9 -3
  333. data/lib/pwn/sast/deserial_java.rb +9 -3
  334. data/lib/pwn/sast/emoticon.rb +9 -3
  335. data/lib/pwn/sast/eval.rb +9 -3
  336. data/lib/pwn/sast/factory.rb +9 -3
  337. data/lib/pwn/sast/http_authorization_header.rb +9 -3
  338. data/lib/pwn/sast/inner_html.rb +9 -3
  339. data/lib/pwn/sast/keystore.rb +9 -3
  340. data/lib/pwn/sast/local_storage.rb +9 -3
  341. data/lib/pwn/sast/location_hash.rb +9 -3
  342. data/lib/pwn/sast/log4j.rb +9 -3
  343. data/lib/pwn/sast/logger.rb +9 -3
  344. data/lib/pwn/sast/md5.rb +9 -3
  345. data/lib/pwn/sast/outer_html.rb +9 -3
  346. data/lib/pwn/sast/padding_oracle.rb +9 -3
  347. data/lib/pwn/sast/password.rb +9 -3
  348. data/lib/pwn/sast/php_input_mechanisms.rb +9 -3
  349. data/lib/pwn/sast/php_type_juggling.rb +9 -3
  350. data/lib/pwn/sast/pom_version.rb +9 -3
  351. data/lib/pwn/sast/port.rb +9 -3
  352. data/lib/pwn/sast/post_message.rb +9 -3
  353. data/lib/pwn/sast/private_key.rb +9 -3
  354. data/lib/pwn/sast/redirect.rb +9 -3
  355. data/lib/pwn/sast/redos.rb +9 -3
  356. data/lib/pwn/sast/shell.rb +9 -3
  357. data/lib/pwn/sast/signature.rb +9 -3
  358. data/lib/pwn/sast/sql.rb +9 -3
  359. data/lib/pwn/sast/ssl.rb +9 -3
  360. data/lib/pwn/sast/sudo.rb +9 -3
  361. data/lib/pwn/sast/task_tag.rb +9 -3
  362. data/lib/pwn/sast/test_case_engine.rb +11 -7
  363. data/lib/pwn/sast/throw_errors.rb +9 -3
  364. data/lib/pwn/sast/token.rb +9 -3
  365. data/lib/pwn/sast/type_script_type_juggling.rb +9 -3
  366. data/lib/pwn/sast/use_after_free.rb +9 -3
  367. data/lib/pwn/sast/version.rb +9 -3
  368. data/lib/pwn/sast/window_location_hash.rb +9 -3
  369. data/lib/pwn/sast.rb +4 -0
  370. data/lib/pwn/sdr/decoder/adsb.rb +36 -5
  371. data/lib/pwn/sdr/decoder/apt.rb +9 -6
  372. data/lib/pwn/sdr/decoder/base.rb +74 -22
  373. data/lib/pwn/sdr/decoder/bluetooth.rb +17 -5
  374. data/lib/pwn/sdr/decoder/dect.rb +12 -3
  375. data/lib/pwn/sdr/decoder/dsp.rb +229 -39
  376. data/lib/pwn/sdr/decoder/flex.rb +59 -11
  377. data/lib/pwn/sdr/decoder/gps.rb +12 -3
  378. data/lib/pwn/sdr/decoder/gsm.rb +24 -4
  379. data/lib/pwn/sdr/decoder/iridium.rb +12 -3
  380. data/lib/pwn/sdr/decoder/lora.rb +13 -4
  381. data/lib/pwn/sdr/decoder/lte.rb +27 -3
  382. data/lib/pwn/sdr/decoder/morse.rb +12 -3
  383. data/lib/pwn/sdr/decoder/p25.rb +12 -3
  384. data/lib/pwn/sdr/decoder/pager.rb +8 -5
  385. data/lib/pwn/sdr/decoder/pocsag.rb +29 -9
  386. data/lib/pwn/sdr/decoder/rds.rb +14 -8
  387. data/lib/pwn/sdr/decoder/rfid.rb +12 -3
  388. data/lib/pwn/sdr/decoder/rtl433.rb +12 -3
  389. data/lib/pwn/sdr/decoder/rtty.rb +8 -5
  390. data/lib/pwn/sdr/decoder/wifi.rb +12 -3
  391. data/lib/pwn/sdr/decoder/zigbee.rb +12 -3
  392. data/lib/pwn/sdr/decoder.rb +9 -0
  393. data/lib/pwn/sdr/flipper_zero.rb +17 -10
  394. data/lib/pwn/sdr/frequency_allocation.rb +4 -1
  395. data/lib/pwn/sdr/gqrx.rb +178 -119
  396. data/lib/pwn/sdr/rfidler.rb +4 -1
  397. data/lib/pwn/sdr/son_micro_rfid.rb +37 -24
  398. data/lib/pwn/sdr.rb +14 -0
  399. data/lib/pwn/sessions.rb +86 -16
  400. data/lib/pwn/setup.rb +106 -37
  401. data/lib/pwn/version.rb +1 -1
  402. data/lib/pwn/www/app_cobalt_io.rb +11 -5
  403. data/lib/pwn/www/bing.rb +10 -5
  404. data/lib/pwn/www/bug_crowd.rb +11 -5
  405. data/lib/pwn/www/checkip.rb +8 -4
  406. data/lib/pwn/www/coinbase_pro.rb +11 -5
  407. data/lib/pwn/www/duckduckgo.rb +12 -6
  408. data/lib/pwn/www/facebook.rb +11 -5
  409. data/lib/pwn/www/github.rb +11 -5
  410. data/lib/pwn/www/google.rb +11 -5
  411. data/lib/pwn/www/hacker_one.rb +20 -9
  412. data/lib/pwn/www/linkedin.rb +11 -5
  413. data/lib/pwn/www/pandora.rb +11 -5
  414. data/lib/pwn/www/pastebin.rb +9 -4
  415. data/lib/pwn/www/paypal.rb +19 -11
  416. data/lib/pwn/www/synack.rb +11 -5
  417. data/lib/pwn/www/torch.rb +13 -8
  418. data/lib/pwn/www/trading_view.rb +11 -5
  419. data/lib/pwn/www/twitter.rb +11 -5
  420. data/lib/pwn/www/uber.rb +11 -5
  421. data/lib/pwn/www/upwork.rb +11 -5
  422. data/lib/pwn/www/wayback_machine.rb +12 -6
  423. data/lib/pwn/www/youtube.rb +10 -5
  424. data/lib/pwn/www.rb +4 -0
  425. data/spec/conventions_spec.rb +118 -2
  426. data/spec/integration/help_contract_spec.rb +2 -0
  427. data/spec/lib/pwn/ai/agent/reward_spec.rb +9 -0
  428. data/spec/lib/pwn/plugins/aflplusplus_spec.rb +13 -0
  429. data/spec/lib/pwn/plugins/artifact_registry_spec.rb +13 -0
  430. data/spec/lib/pwn/plugins/binary_parser_spec.rb +21 -0
  431. data/spec/lib/pwn/plugins/credential_attack_spec.rb +13 -0
  432. data/spec/lib/pwn/plugins/exploit_db_spec.rb +13 -0
  433. data/spec/lib/pwn/plugins/exploit_dev_spec.rb +23 -0
  434. data/spec/lib/pwn/plugins/frida_spec.rb +13 -0
  435. data/spec/lib/pwn/plugins/gdb_spec.rb +13 -0
  436. data/spec/lib/pwn/plugins/jobs_spec.rb +13 -0
  437. data/spec/lib/pwn/plugins/k8s_spec.rb +13 -0
  438. data/spec/lib/pwn/plugins/nuclei_spec.rb +13 -0
  439. data/spec/lib/pwn/plugins/preflight_checker_spec.rb +23 -0
  440. data/spec/lib/pwn/plugins/process_tube_spec.rb +13 -0
  441. data/spec/lib/pwn/plugins/radare2_spec.rb +13 -0
  442. data/spec/lib/pwn/plugins/recon_spec.rb +26 -0
  443. data/spec/lib/pwn/plugins/semgrep_spec.rb +13 -0
  444. data/spec/lib/pwn/plugins/sqlmap_spec.rb +13 -0
  445. data/spec/lib/pwn/plugins/volatility_spec.rb +13 -0
  446. data/spec/lib/pwn/req_queue_spec.rb +168 -0
  447. data/third_party/pwn_rdoc.jsonl +160 -5
  448. metadata +63 -7
  449. data/etc/default_skills/pwn/memory_index/references/urls.md +0 -4
  450. data/etc/default_skills/pwn/plugins/transparent_browser/references/urls.md +0 -3
@@ -0,0 +1,330 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ module PWN
6
+ module Plugins
7
+ # p8/p16/p32/p64, cyclic, flat, fmt writes, gadget search.
8
+ module ExploitDev
9
+ CYCLIC_ALPHA = (('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a).freeze
10
+
11
+ public_class_method def self.required_bins
12
+ []
13
+ end
14
+
15
+ public_class_method def self.p8(opts = {})
16
+ pack_int(value: opts[:value] || opts[:n], bytes: 1, endian: opts[:endian])
17
+ end
18
+
19
+ public_class_method def self.p16(opts = {})
20
+ pack_int(value: opts[:value] || opts[:n], bytes: 2, endian: opts[:endian])
21
+ end
22
+
23
+ public_class_method def self.p32(opts = {})
24
+ pack_int(value: opts[:value] || opts[:n], bytes: 4, endian: opts[:endian])
25
+ end
26
+
27
+ public_class_method def self.p64(opts = {})
28
+ pack_int(value: opts[:value] || opts[:n], bytes: 8, endian: opts[:endian])
29
+ end
30
+
31
+ public_class_method def self.u8(opts = {})
32
+ unpack_int(buf: opts[:buf] || opts[:data], bytes: 1, endian: opts[:endian])
33
+ end
34
+
35
+ public_class_method def self.u16(opts = {})
36
+ unpack_int(buf: opts[:buf] || opts[:data], bytes: 2, endian: opts[:endian])
37
+ end
38
+
39
+ public_class_method def self.u32(opts = {})
40
+ unpack_int(buf: opts[:buf] || opts[:data], bytes: 4, endian: opts[:endian])
41
+ end
42
+
43
+ public_class_method def self.u64(opts = {})
44
+ unpack_int(buf: opts[:buf] || opts[:data], bytes: 8, endian: opts[:endian])
45
+ end
46
+
47
+ public_class_method def self.cyclic(opts = {})
48
+ n = (opts[:length] || 100).to_i
49
+ width = (opts[:width] || opts[:n] || 4).to_i
50
+ width = 4 if width < 2
51
+ out = +''
52
+ i = 0
53
+ while out.length < n
54
+ chunk = []
55
+ v = i
56
+ width.times do
57
+ chunk.unshift(CYCLIC_ALPHA[v % CYCLIC_ALPHA.length])
58
+ v /= CYCLIC_ALPHA.length
59
+ end
60
+ out << chunk.join
61
+ i += 1
62
+ end
63
+ out[0, n]
64
+ end
65
+
66
+ public_class_method def self.cyclic_find(opts = {})
67
+ needle = opts[:value] || opts[:subseq]
68
+ hay = cyclic(length: (opts[:length] || 8_192).to_i, n: (opts[:n] || 4).to_i)
69
+ blob = needle.is_a?(Integer) ? p32(value: needle, endian: opts[:endian]) : needle.to_s
70
+ hay.index(blob)
71
+ end
72
+
73
+ public_class_method def self.flat(opts = {})
74
+ parts = Array(opts[:parts] || opts[:values] || opts[:arr])
75
+ endian = opts[:endian]
76
+ parts.map do |p|
77
+ case p
78
+ when Integer then p32(value: p, endian: endian)
79
+ when Array then p32(value: p[0], endian: endian) * p[1].to_i
80
+ else p.to_s
81
+ end
82
+ end.join
83
+ end
84
+
85
+ public_class_method def self.shellcode(opts = {})
86
+ arch = (opts[:arch] || 'x86_64').to_s
87
+ kind = (opts[:kind] || opts[:payload] || 'nop').to_s
88
+ return execve_bin_sh_bytes(arch: arch) if kind == 'execve_bin_sh'
89
+
90
+ asm = case kind
91
+ when 'nop' then 'nop'
92
+ when 'ret' then 'ret'
93
+ else opts[:asm].to_s
94
+ end
95
+ raise 'ERROR: asm is required for custom shellcode' if asm.empty?
96
+
97
+ PWN::Plugins::Assembly.asm_to_opcodes(asm: asm, arch: arch, endian: opts[:endian])
98
+ end
99
+
100
+ public_class_method def self.one_gadget(opts = {})
101
+ path = (opts[:path] || opts[:libc]).to_s
102
+ raise 'ERROR: path is required' if path.empty?
103
+
104
+ return { error: 'one_gadget missing', hint: 'pwn setup --profile re', path: path } unless PWN::Plugins::PreflightChecker.bin?(name: 'one_gadget')
105
+
106
+ stdout, stderr, status = Open3.capture3('one_gadget', path)
107
+ {
108
+ path: path,
109
+ stdout: stdout,
110
+ stderr: stderr,
111
+ exit: status.exitstatus,
112
+ gadgets: stdout.scan(/0x[0-9a-fA-F]+/)
113
+ }
114
+ end
115
+
116
+ public_class_method def self.libc_offsets(opts = {})
117
+ path = opts[:path].to_s
118
+ raise 'ERROR: path is required' if path.empty?
119
+
120
+ wanted = Array(opts[:names] || %w[system execve __libc_start_main])
121
+ syms = PWN::Plugins::BinaryParser.symbols(path: path, limit: 20_000)
122
+ map = {}
123
+ Array(syms).each do |s|
124
+ n = s[:name].to_s
125
+ next if n.empty?
126
+
127
+ wanted.each do |w|
128
+ map[w.to_s] = s[:value] if n == w.to_s || n.end_with?(w.to_s)
129
+ end
130
+ end
131
+ { path: path, symbols: map }
132
+ end
133
+
134
+ public_class_method def self.fmt_writes(opts = {})
135
+ addr = (opts[:addr] || 0).to_i
136
+ value = (opts[:value] || 0).to_i
137
+ offset = (opts[:offset] || 6).to_i
138
+ {
139
+ payload: "#{p32(value: addr)}%#{value}x%#{offset}$n",
140
+ addr: addr,
141
+ value: value,
142
+ offset: offset
143
+ }
144
+ end
145
+
146
+ public_class_method def self.gadgets(opts = {})
147
+ path = opts[:path].to_s
148
+ raise 'ERROR: path is required' if path.empty?
149
+
150
+ if PWN::Plugins::PreflightChecker.bin?(name: 'r2')
151
+ sid = PWN::Plugins::Radare2.open(path: path)
152
+ begin
153
+ PWN::Plugins::Radare2.cmd(session: sid, cmd: '/R')
154
+ ensure
155
+ PWN::Plugins::Radare2.close(session: sid)
156
+ end
157
+ elsif PWN::Plugins::PreflightChecker.bin?(name: 'ROPgadget')
158
+ `ROPgadget --binary #{path}`.to_s
159
+ else
160
+ { error: 'r2 and ROPgadget missing', hint: 'pwn setup --profile re' }
161
+ end
162
+ end
163
+
164
+ public_class_method def self.authors
165
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n"
166
+ end
167
+
168
+ public_class_method def self.help
169
+ puts "USAGE:
170
+ # List host binaries this module expects to be installed.
171
+ #{self}.required_bins
172
+
173
+ # Run p8 and return its result
174
+ #{self}.p8(
175
+ value: 'optional - integer or string to pack/encode',
176
+ n: 'optional - count, width, or size',
177
+ endian: 'optional - :little or :big byte order'
178
+ )
179
+
180
+ # Run p16 and return its result
181
+ #{self}.p16(
182
+ value: 'optional - integer or string to pack/encode',
183
+ n: 'optional - count, width, or size',
184
+ endian: 'optional - :little or :big byte order'
185
+ )
186
+
187
+ # Run p32 and return its result
188
+ #{self}.p32(
189
+ value: 'optional - integer or string to pack/encode',
190
+ n: 'optional - count, width, or size',
191
+ endian: 'optional - :little or :big byte order'
192
+ )
193
+
194
+ # Run p64 and return its result
195
+ #{self}.p64(
196
+ value: 'optional - integer or string to pack/encode',
197
+ n: 'optional - count, width, or size',
198
+ endian: 'optional - :little or :big byte order'
199
+ )
200
+
201
+ # Run u8 and return its result
202
+ #{self}.u8(
203
+ buf: 'optional - buf value consumed by #u8',
204
+ data: 'optional - data value consumed by #u8',
205
+ endian: 'optional - :little or :big byte order'
206
+ )
207
+
208
+ # Run u16 and return its result
209
+ #{self}.u16(
210
+ buf: 'optional - buf value consumed by #u16',
211
+ data: 'optional - data value consumed by #u16',
212
+ endian: 'optional - :little or :big byte order'
213
+ )
214
+
215
+ # Run u32 and return its result
216
+ #{self}.u32(
217
+ buf: 'optional - buf value consumed by #u32',
218
+ data: 'optional - data value consumed by #u32',
219
+ endian: 'optional - :little or :big byte order'
220
+ )
221
+
222
+ # Run u64 and return its result
223
+ #{self}.u64(
224
+ buf: 'optional - buf value consumed by #u64',
225
+ data: 'optional - data value consumed by #u64',
226
+ endian: 'optional - :little or :big byte order'
227
+ )
228
+
229
+ # Run cyclic and return its result
230
+ #{self}.cyclic(
231
+ length: 'optional - number of bytes or characters to generate',
232
+ width: 'optional - cyclic de Bruijn sequence width in bytes',
233
+ n: 'optional - count, width, or size'
234
+ )
235
+
236
+ # Run cyclic find and return its result
237
+ #{self}.cyclic_find(
238
+ value: 'optional - integer or string to pack/encode (defaults to opts[:subseq])',
239
+ subseq: 'optional - subseq value consumed by #cyclic_find',
240
+ length: 'optional - number of bytes or characters to generate',
241
+ n: 'optional - count, width, or size',
242
+ endian: 'optional - :little or :big byte order'
243
+ )
244
+
245
+ # Run flat and return its result
246
+ #{self}.flat(
247
+ parts: 'optional - parts value consumed by #flat',
248
+ values: 'optional - values value consumed by #flat',
249
+ arr: 'optional - arr value consumed by #flat',
250
+ endian: 'optional - :little or :big byte order'
251
+ )
252
+
253
+ # Run shellcode and return its result
254
+ #{self}.shellcode(
255
+ arch: 'optional - architecture string (as from objdump --info)',
256
+ kind: 'optional - kind value consumed by #shellcode',
257
+ payload: 'optional - payload value consumed by #shellcode',
258
+ asm: 'required - assembly source (one instruction per line)',
259
+ endian: 'optional - :little or :big byte order'
260
+ )
261
+
262
+ # Run fmt writes and return its result
263
+ #{self}.fmt_writes(
264
+ addr: 'optional - address or flag (e.g. main or 0x401000)',
265
+ value: 'optional - integer or string to pack/encode',
266
+ offset: 'optional - offset value consumed by #fmt_writes'
267
+ )
268
+
269
+ # Run gadgets and return its result
270
+ #{self}.gadgets(
271
+ path: 'required - filesystem path of the binary to search for gadgets'
272
+ )
273
+
274
+ # Resolve one_gadget offsets in a libc (needs the one_gadget gem/bin).
275
+ #{self}.one_gadget(
276
+ path: 'required - filesystem path to libc.so',
277
+ libc: 'optional - alias for path'
278
+ )
279
+
280
+ # Map named libc symbols to virtual addresses via BinaryParser.
281
+ #{self}.libc_offsets(
282
+ path: 'required - filesystem path to libc or any ELF',
283
+ names: 'optional - Array of symbol names (defaults to system, execve, __libc_start_main)'
284
+ )
285
+
286
+ # Print the AUTHOR(S) string for this module.
287
+ #{self}.authors
288
+ "
289
+ constants.sort
290
+ end
291
+
292
+ private_class_method def self.pack_int(opts = {})
293
+ v = opts[:value].to_i
294
+ bytes = opts[:bytes].to_i
295
+ little = opts[:endian].to_s != 'big'
296
+ template = {
297
+ 1 => 'C',
298
+ 2 => little ? 'v' : 'n',
299
+ 4 => little ? 'V' : 'N',
300
+ 8 => little ? 'Q<' : 'Q>'
301
+ }[bytes]
302
+ [v].pack(template)
303
+ end
304
+
305
+ private_class_method def self.unpack_int(opts = {})
306
+ buf = opts[:buf].to_s
307
+ bytes = opts[:bytes].to_i
308
+ little = opts[:endian].to_s != 'big'
309
+ template = { 1 => 'C', 2 => little ? 'v' : 'n', 4 => little ? 'V' : 'N', 8 => little ? 'Q<' : 'Q>' }[bytes]
310
+ buf.unpack1(template)
311
+ end
312
+
313
+ private_class_method def self.execve_bin_sh_bytes(opts = {})
314
+ arch = opts[:arch].to_s
315
+ if arch.match?(/64|amd64/i)
316
+ return [
317
+ 0x48, 0x31, 0xd2, 0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e,
318
+ 0x2f, 0x73, 0x68, 0x00, 0x53, 0x48, 0x89, 0xe7, 0x50,
319
+ 0x57, 0x48, 0x89, 0xe6, 0xb0, 0x3b, 0x0f, 0x05
320
+ ].pack('C*')
321
+ end
322
+
323
+ [
324
+ 0x31, 0xc0, 0x50, 0x68, 0x2f, 0x2f, 0x73, 0x68, 0x68, 0x2f, 0x62, 0x69, 0x6e,
325
+ 0x89, 0xe3, 0x50, 0x53, 0x89, 0xe1, 0xb0, 0x0b, 0xcd, 0x80
326
+ ].pack('C*')
327
+ end
328
+ end
329
+ end
330
+ end
@@ -116,27 +116,30 @@ module PWN
116
116
 
117
117
  public_class_method def self.help
118
118
  puts "USAGE:
119
+ # Run recurse in dir and return its result
119
120
  #{self}.recurse_in_dir(
120
- dir_path: 'optional path to dir defaults to .',
121
- include_extensions: 'optional - array of file extensions to search for in scan (e.g. ['.js', '.php'])',
122
- exclude_extensions: 'optional - array of file extensions to exclude from scan (e.g. ['.log', '.txt', '.spec'])'
123
- ) do |entry|
124
- puts entry
125
- end
121
+ dir_path: 'optional - optional path to dir defaults to .',
122
+ include_extensions: 'optional - array of file extensions to search for in scan (e.g. [.js, .php])',
123
+ exclude_extensions: 'optional - array of file extensions to exclude from scan (e.g. [.log, .txt, .spec])'
124
+ )
126
125
 
126
+ # Run untar gz file and return its result
127
127
  #{self}.untar_gz_file(
128
128
  tar_gz_file: 'required - path to .tar.gz file',
129
129
  destination: 'required - destination folder to save extracted contents'
130
130
  )
131
131
 
132
+ # Run shift file up and return its result
132
133
  #{self}.shift_file_up(
133
134
  path: 'required - path to file to shift up',
134
- bytes: 'required - number of bytes to shift up',
135
- buffer_size: 'optional - buffer size to use when shifting file up (default: 256 * 1024 / i.e 256KB)'
135
+ bytes: 'required - number of bytes to shift up (remove from beginning)',
136
+ buffer_size: 'optional - buffer size to use when shifting (default: 256KB)'
136
137
  )
137
138
 
139
+ # Print the AUTHOR(S) string for this module.
138
140
  #{self}.authors
139
141
  "
142
+ constants.sort
140
143
  end
141
144
  end
142
145
  end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ module PWN
6
+ module Plugins
7
+ # Frida attach/spawn + script injection.
8
+ module Frida
9
+ SSL_PINNING = <<~JS
10
+ Java.perform(function () {
11
+ try {
12
+ var TrustManager = Java.use('javax.net.ssl.X509TrustManager');
13
+ var SSLContext = Java.use('javax.net.ssl.SSLContext');
14
+ var TrustManagers = [Java.registerClass({
15
+ name: 'pwn.TrustAll',
16
+ implements: [TrustManager],
17
+ methods: {
18
+ checkClientTrusted: function () {},
19
+ checkServerTrusted: function () {},
20
+ getAcceptedIssuers: function () { return []; }
21
+ }
22
+ }).$new()];
23
+ var ctx = SSLContext.getInstance('TLS');
24
+ ctx.init(null, TrustManagers, null);
25
+ SSLContext.getDefault.implementation = function () { return ctx; };
26
+ } catch (e) {}
27
+ });
28
+ JS
29
+
30
+ public_class_method def self.required_bins
31
+ %w[frida]
32
+ end
33
+
34
+ public_class_method def self.ps(opts = {})
35
+ PWN::Plugins::PreflightChecker.require_bin!(name: 'frida')
36
+ stdout, stderr, status = Open3.capture3('frida-ps', *Array(opts[:extra]))
37
+ { stdout: stdout, stderr: stderr, exit: status.exitstatus }
38
+ end
39
+
40
+ public_class_method def self.attach(opts = {})
41
+ PWN::Plugins::PreflightChecker.require_bin!(name: 'frida')
42
+ target = opts[:target] || opts[:name]
43
+ script = opts[:script].to_s
44
+ raise 'ERROR: target is required' if target.to_s.empty?
45
+
46
+ cmd = ['frida', '-n', target.to_s]
47
+ cmd += ['-l', opts[:script_path].to_s] if opts[:script_path]
48
+ cmd += ['-e', script] unless script.empty?
49
+ stdout, stderr, status = Open3.capture3(*cmd)
50
+ { stdout: stdout, stderr: stderr, exit: status.exitstatus }
51
+ end
52
+
53
+ public_class_method def self.spawn(opts = {})
54
+ PWN::Plugins::PreflightChecker.require_bin!(name: 'frida')
55
+ path = (opts[:path] || opts[:file]).to_s
56
+ raise 'ERROR: path is required' if path.empty?
57
+
58
+ cmd = ['frida', '-f', path]
59
+ cmd += ['-l', opts[:script_path].to_s] if opts[:script_path]
60
+ cmd += ['-e', opts[:script].to_s] unless opts[:script].to_s.empty?
61
+ stdout, stderr, status = Open3.capture3(*cmd)
62
+ { stdout: stdout, stderr: stderr, exit: status.exitstatus }
63
+ end
64
+
65
+ public_class_method def self.ssl_pinning_script(opts = {})
66
+ opts[:android]
67
+ SSL_PINNING
68
+ end
69
+
70
+ public_class_method def self.authors
71
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n"
72
+ end
73
+
74
+ public_class_method def self.help
75
+ puts "USAGE:
76
+ # List host binaries this module expects to be installed.
77
+ #{self}.required_bins
78
+
79
+ # List processes via frida-ps.
80
+ #{self}.ps(
81
+ extra: 'optional - extra frida-ps argv'
82
+ )
83
+
84
+ # Attach to a running process and optionally inject a script.
85
+ #{self}.attach(
86
+ target: 'required - process name (defaults to opts[:name])',
87
+ name: 'optional - alias for target',
88
+ script: 'optional - JavaScript source to pass with -e',
89
+ script_path: 'optional - path to a .js file for -l'
90
+ )
91
+
92
+ # Spawn a binary under Frida and inject a script.
93
+ #{self}.spawn(
94
+ path: 'required - filesystem path to the binary',
95
+ file: 'optional - alias for path',
96
+ script: 'optional - JavaScript source to pass with -e',
97
+ script_path: 'optional - path to a .js file for -l'
98
+ )
99
+
100
+ # Return an SSL-pinning bypass JavaScript template.
101
+ #{self}.ssl_pinning_script(
102
+ android: 'optional - currently always returns the Java TrustManager template'
103
+ )
104
+
105
+ # Print the AUTHOR(S) string for this module.
106
+ #{self}.authors
107
+ "
108
+ constants.sort
109
+ end
110
+ end
111
+ end
112
+ end
@@ -171,6 +171,25 @@ module PWN
171
171
  sock_obj = PWN::Plugins::Sock.disconnect(sock_obj: sock_obj) unless sock_obj.nil?
172
172
  end
173
173
 
174
+ public_class_method def self.http(opts = {})
175
+ template = opts[:request].to_s
176
+ raise 'ERROR: request is required' if template.empty?
177
+
178
+ token = (opts[:token] || 'FUZZ').to_s
179
+ Array(opts[:dictionary] || opts[:payloads] || ['A']).map do |p|
180
+ template.gsub(token, p.to_s)
181
+ end
182
+ end
183
+
184
+ public_class_method def self.file_format(opts = {})
185
+ path = opts[:path].to_s
186
+ raise 'ERROR: path is required' if path.empty?
187
+
188
+ seed = File.binread(path)
189
+ dict = Array(opts[:dictionary] || ["\xff"])
190
+ dict.map { |blob| seed + blob.to_s }
191
+ end
192
+
174
193
  # Author(s):: 0day Inc. <support@0dayinc.com>
175
194
 
176
195
  public_class_method def self.authors
@@ -183,13 +202,14 @@ module PWN
183
202
 
184
203
  public_class_method def self.help
185
204
  puts "USAGE:
186
- socket_fuzz_results_arr = #{self}.socket(
187
- target: 'required = target host or ip',
188
- port: 'required => target port',
189
- protocol: 'optional => :tcp || :udp (defaults to tcp)',
205
+ # Run socket and return its result
206
+ #{self}.socket(
207
+ target: 'required - target host or ip',
208
+ port: 'required - target port',
209
+ protocol: 'optional - :tcp || :udp (defaults to tcp)',
190
210
  tls: 'optional - boolean connect to target socket using TLS (defaults to false)',
191
- fuzz_delimeter: \"optional - fuzz delimeter used in request to specify where payloads should reside (defaults to \u2665)\",
192
- request: \"required - String object of socket request w/ \u2665 as fuzz delimeter (e.g. '\"GET /\u2665\u2665 HTTP/1.1\\r\\nHost: \u2665127.0.0.1\u2665\\r\\n\\r\\n\"')\",
211
+ fuzz_delimeter: 'optional - fuzz delimeter used in request to specify where payloads should reside (defaults to \\u2665)',
212
+ request: 'required - String object of socket request w/ \\u001A as fuzz delimeter (e.g. GET /\\u001A\\u001A HTTP/1.1\\r\\nHost: \\u001A127..0.0.1\\u001A\\r\\n\\r\\n)',
193
213
  payload: 'required - payload string',
194
214
  response_timeout: 'optional - float (defaults to 0.9)',
195
215
  request_rate_limit: 'optional - float (defaults to 0.3)',
@@ -198,8 +218,24 @@ module PWN
198
218
  char_encoding: 'optional - character encoding returned by PWN::Plugins::Char.list_encoders (defaults to UTF-8)'
199
219
  )
200
220
 
221
+ # Expand an HTTP request template by substituting FUZZ with dictionary payloads.
222
+ #{self}.http(
223
+ request: 'required - HTTP request template containing FUZZ (or token:)',
224
+ dictionary: 'optional - Array of payload strings',
225
+ payloads: 'optional - alias for dictionary',
226
+ token: 'optional - placeholder to replace (defaults to FUZZ)'
227
+ )
228
+
229
+ # Append dictionary blobs to a seed file for coverage-guided or dumb file fuzzing.
230
+ #{self}.file_format(
231
+ path: 'required - filesystem path to the seed file',
232
+ dictionary: 'optional - Array of binary/string mutations'
233
+ )
234
+
235
+ # Print the AUTHOR(S) string for this module.
201
236
  #{self}.authors
202
237
  "
238
+ constants.sort
203
239
  end
204
240
  end
205
241
  end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ module PWN
6
+ module Plugins
7
+ # gdb/MI batch driver: run-to-crash, registers, mitigations, core dumps.
8
+ module GDB
9
+ public_class_method def self.required_bins
10
+ %w[gdb]
11
+ end
12
+
13
+ public_class_method def self.batch(opts = {})
14
+ PWN::Plugins::PreflightChecker.require_bin!(name: 'gdb')
15
+ binary = opts[:binary].to_s
16
+ cmds = Array(opts[:commands] || opts[:cmds])
17
+ args = Array(opts[:args])
18
+ mi = ['gdb', '--batch', '--quiet']
19
+ mi += ['-ex', 'set pagination off']
20
+ cmds.each { |c| mi += ['-ex', c.to_s] }
21
+ mi << '--args' if !binary.empty? || args.any?
22
+ mi << binary unless binary.empty?
23
+ mi.concat(args.map(&:to_s))
24
+ stdout, stderr, status = Open3.capture3(*mi)
25
+ { stdout: stdout, stderr: stderr, exit: status.exitstatus }
26
+ end
27
+
28
+ public_class_method def self.run_to_crash(opts = {})
29
+ cmds = ['run', 'bt', 'info registers']
30
+ batch(opts.merge(commands: cmds))
31
+ end
32
+
33
+ public_class_method def self.registers(opts = {})
34
+ batch(opts.merge(commands: ['info registers']))
35
+ end
36
+
37
+ public_class_method def self.mitigations(opts = {})
38
+ batch(opts.merge(commands: ['checksec']))
39
+ rescue StandardError
40
+ path = opts[:binary].to_s
41
+ return { error: 'gdb missing' } unless PWN::Plugins::PreflightChecker.bin?(name: 'gdb')
42
+
43
+ { hint: 'pwndbg/gef checksec not loaded', binary: path }
44
+ end
45
+
46
+ public_class_method def self.core(opts = {})
47
+ core = opts[:core].to_s
48
+ binary = opts[:binary].to_s
49
+ raise 'ERROR: core is required' if core.empty?
50
+
51
+ PWN::Plugins::PreflightChecker.require_bin!(name: 'gdb')
52
+ binary = opts[:binary].to_s
53
+ argv = ['gdb', '--batch', '--quiet', '-c', core, '-ex', 'set pagination off', '-ex', 'bt', '-ex', 'info registers']
54
+ argv << binary unless binary.empty?
55
+ stdout, stderr, status = Open3.capture3(*argv)
56
+ { stdout: stdout, stderr: stderr, exit: status.exitstatus }
57
+ end
58
+
59
+ public_class_method def self.breakpoints(opts = {})
60
+ bps = Array(opts[:breakpoints] || opts[:bp])
61
+ cmds = bps.map { |b| "break #{b}" } + Array(opts[:commands]) + %w[run bt]
62
+ batch(opts.merge(commands: cmds))
63
+ end
64
+
65
+ public_class_method def self.authors
66
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n"
67
+ end
68
+
69
+ public_class_method def self.help
70
+ puts "USAGE:
71
+ # List host binaries this module expects to be installed.
72
+ #{self}.required_bins
73
+
74
+ # Run batch and return its result
75
+ #{self}.batch(
76
+ binary: 'required - binary value consumed by #batch',
77
+ commands: 'optional - commands value consumed by #batch',
78
+ cmds: 'optional - cmds value consumed by #batch',
79
+ args: 'required - Array args value consumed by #batch'
80
+ )
81
+
82
+ # Run run to crash and return its result
83
+ #{self}.run_to_crash
84
+
85
+ # Run registers and return its result
86
+ #{self}.registers
87
+
88
+ # Run mitigations and return its result
89
+ #{self}.mitigations(
90
+ binary: 'optional - binary value consumed by #mitigations'
91
+ )
92
+
93
+ # Run core and return its result
94
+ #{self}.core(
95
+ core: 'required - filesystem path to the core dump',
96
+ binary: 'optional - matching binary for symbols'
97
+ )
98
+
99
+ # Plant breakpoints then run and dump a backtrace.
100
+ #{self}.breakpoints(
101
+ binary: 'optional - binary to debug',
102
+ breakpoints: 'optional - Array of break specs (e.g. main or *0x401000)',
103
+ bp: 'optional - alias for breakpoints',
104
+ commands: 'optional - extra gdb commands after the breaks',
105
+ args: 'optional - Array of inferior argv'
106
+ )
107
+
108
+ # Print the AUTHOR(S) string for this module.
109
+ #{self}.authors
110
+ "
111
+ constants.sort
112
+ end
113
+ end
114
+ end
115
+ end