pwn 0.5.708 → 0.5.709

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 (434) hide show
  1. checksums.yaml +4 -4
  2. data/documentation/Installation.md +1 -0
  3. data/etc/default_skills/pwn/ai/agent/extrospection/osint/bridges/SKILL.md +30 -8
  4. data/etc/default_skills/pwn/ai/agent/extrospection/osint/social/SKILL.md +30 -8
  5. data/etc/default_skills/pwn/ai/agent/extrospection/osint/social/references/urls.md +1 -1
  6. data/etc/default_skills/pwn/ai/agent/extrospection/references/urls.md +0 -1
  7. data/etc/default_skills/pwn/memory_index/SKILL.md +0 -4
  8. data/etc/default_skills/pwn/plugins/aflplusplus/SKILL.md +48 -0
  9. data/etc/default_skills/pwn/plugins/android/SKILL.md +1 -0
  10. data/etc/default_skills/pwn/plugins/artifact_registry/SKILL.md +49 -0
  11. data/etc/default_skills/pwn/plugins/binary_parser/SKILL.md +54 -0
  12. data/etc/default_skills/pwn/plugins/credential_attack/SKILL.md +51 -0
  13. data/etc/default_skills/pwn/plugins/doctor/SKILL.md +57 -0
  14. data/etc/default_skills/pwn/plugins/exploit_dev/SKILL.md +61 -0
  15. data/etc/default_skills/pwn/plugins/frida/SKILL.md +49 -0
  16. data/etc/default_skills/pwn/plugins/gdb/SKILL.md +52 -0
  17. data/etc/default_skills/pwn/plugins/jobs/SKILL.md +51 -0
  18. data/etc/default_skills/pwn/plugins/nuclei/SKILL.md +48 -0
  19. data/etc/default_skills/pwn/plugins/process_tube/SKILL.md +52 -0
  20. data/etc/default_skills/pwn/plugins/radare2/SKILL.md +59 -0
  21. data/etc/default_skills/pwn/plugins/recon/SKILL.md +55 -0
  22. data/etc/default_skills/pwn/plugins/recon/references/urls.md +5 -0
  23. data/etc/default_skills/pwn/plugins/sqlmap/SKILL.md +48 -0
  24. data/etc/default_skills/pwn/plugins/transparent_browser/SKILL.md +0 -4
  25. data/etc/default_skills/pwn/plugins/volatility/SKILL.md +48 -0
  26. data/lib/pwn/ai/agent/assembly.rb +4 -1
  27. data/lib/pwn/ai/agent/btc.rb +4 -1
  28. data/lib/pwn/ai/agent/burp_suite.rb +5 -2
  29. data/lib/pwn/ai/agent/curriculum.rb +89 -30
  30. data/lib/pwn/ai/agent/dispatch.rb +27 -16
  31. data/lib/pwn/ai/agent/extrospection/osint/bridges.rb +9 -18
  32. data/lib/pwn/ai/agent/extrospection/osint/social.rb +9 -18
  33. data/lib/pwn/ai/agent/extrospection.rb +185 -60
  34. data/lib/pwn/ai/agent/gqrx.rb +4 -1
  35. data/lib/pwn/ai/agent/hacker_one.rb +5 -2
  36. data/lib/pwn/ai/agent/learning.rb +142 -25
  37. data/lib/pwn/ai/agent/loop.rb +53 -46
  38. data/lib/pwn/ai/agent/metrics.rb +133 -23
  39. data/lib/pwn/ai/agent/mistakes.rb +126 -17
  40. data/lib/pwn/ai/agent/open_goal.rb +25 -9
  41. data/lib/pwn/ai/agent/policy.rb +158 -18
  42. data/lib/pwn/ai/agent/prompt_builder.rb +21 -11
  43. data/lib/pwn/ai/agent/prompt_cache.rb +44 -13
  44. data/lib/pwn/ai/agent/reflect.rb +9 -5
  45. data/lib/pwn/ai/agent/registry.rb +65 -12
  46. data/lib/pwn/ai/agent/result.rb +19 -10
  47. data/lib/pwn/ai/agent/reward.rb +150 -32
  48. data/lib/pwn/ai/agent/sast.rb +4 -1
  49. data/lib/pwn/ai/agent/swarm.rb +72 -36
  50. data/lib/pwn/ai/agent/task_summarizer.rb +165 -36
  51. data/lib/pwn/ai/agent/tool_guard.rb +105 -6
  52. data/lib/pwn/ai/agent/transparent_browser.rb +4 -1
  53. data/lib/pwn/ai/agent/turn_finalizer.rb +41 -21
  54. data/lib/pwn/ai/agent/vuln_gen.rb +6 -3
  55. data/lib/pwn/ai/agent.rb +4 -0
  56. data/lib/pwn/ai/anthropic.rb +41 -7
  57. data/lib/pwn/ai/gemini.rb +21 -11
  58. data/lib/pwn/ai/grok.rb +44 -6
  59. data/lib/pwn/ai/http_retry.rb +40 -12
  60. data/lib/pwn/ai/ollama.rb +19 -10
  61. data/lib/pwn/ai/open_ai.rb +81 -30
  62. data/lib/pwn/ai/open_web_ui.rb +20 -14
  63. data/lib/pwn/ai/red_team/agent_protocol_abuse.rb +7 -1
  64. data/lib/pwn/ai/red_team/data_and_model_poisoning.rb +7 -1
  65. data/lib/pwn/ai/red_team/excessive_agency.rb +7 -1
  66. data/lib/pwn/ai/red_team/hidden_context_exposure.rb +7 -1
  67. data/lib/pwn/ai/red_team/insecure_output_handling.rb +7 -1
  68. data/lib/pwn/ai/red_team/jailbreak.rb +7 -1
  69. data/lib/pwn/ai/red_team/memory_poisoning.rb +7 -1
  70. data/lib/pwn/ai/red_team/multimodal_injection.rb +7 -1
  71. data/lib/pwn/ai/red_team/overreliance.rb +7 -1
  72. data/lib/pwn/ai/red_team/payload_splitting.rb +7 -1
  73. data/lib/pwn/ai/red_team/prompt_injection.rb +7 -1
  74. data/lib/pwn/ai/red_team/rag_poisoning.rb +7 -1
  75. data/lib/pwn/ai/red_team/sensitive_information_disclosure.rb +7 -1
  76. data/lib/pwn/ai/red_team/supply_chain.rb +7 -1
  77. data/lib/pwn/ai/red_team/system_prompt_extraction.rb +7 -1
  78. data/lib/pwn/ai/red_team/test_case_engine.rb +12 -9
  79. data/lib/pwn/ai/red_team/token_smuggling.rb +7 -1
  80. data/lib/pwn/ai/red_team/unbounded_consumption.rb +7 -1
  81. data/lib/pwn/ai/red_team/vector_and_embedding_weaknesses.rb +7 -1
  82. data/lib/pwn/ai/red_team.rb +4 -0
  83. data/lib/pwn/ai.rb +4 -0
  84. data/lib/pwn/aws/acm.rb +5 -2
  85. data/lib/pwn/aws/api_gateway.rb +10 -7
  86. data/lib/pwn/aws/app_stream.rb +5 -2
  87. data/lib/pwn/aws/application_auto_scaling.rb +5 -2
  88. data/lib/pwn/aws/application_discovery_service.rb +5 -2
  89. data/lib/pwn/aws/auto_scaling.rb +5 -2
  90. data/lib/pwn/aws/batch.rb +5 -2
  91. data/lib/pwn/aws/budgets.rb +5 -2
  92. data/lib/pwn/aws/cloud_formation.rb +5 -2
  93. data/lib/pwn/aws/cloud_front.rb +7 -4
  94. data/lib/pwn/aws/cloud_hsm.rb +5 -2
  95. data/lib/pwn/aws/cloud_search.rb +5 -2
  96. data/lib/pwn/aws/cloud_search_domain.rb +5 -2
  97. data/lib/pwn/aws/cloud_trail.rb +5 -2
  98. data/lib/pwn/aws/cloud_watch.rb +5 -2
  99. data/lib/pwn/aws/cloud_watch_events.rb +5 -2
  100. data/lib/pwn/aws/cloud_watch_logs.rb +5 -2
  101. data/lib/pwn/aws/code_build.rb +5 -2
  102. data/lib/pwn/aws/code_commit.rb +5 -2
  103. data/lib/pwn/aws/code_deploy.rb +5 -2
  104. data/lib/pwn/aws/code_pipeline.rb +5 -2
  105. data/lib/pwn/aws/cognito_identity.rb +5 -2
  106. data/lib/pwn/aws/cognito_identity_provider.rb +5 -2
  107. data/lib/pwn/aws/cognito_sync.rb +5 -2
  108. data/lib/pwn/aws/config_service.rb +5 -2
  109. data/lib/pwn/aws/data_pipleline.rb +5 -2
  110. data/lib/pwn/aws/database_migration_service.rb +5 -2
  111. data/lib/pwn/aws/device_farm.rb +5 -2
  112. data/lib/pwn/aws/direct_connect.rb +5 -2
  113. data/lib/pwn/aws/directory_service.rb +5 -2
  114. data/lib/pwn/aws/dynamo_db.rb +5 -2
  115. data/lib/pwn/aws/dynamo_db_streams.rb +5 -2
  116. data/lib/pwn/aws/ec2.rb +5 -2
  117. data/lib/pwn/aws/ecr.rb +5 -2
  118. data/lib/pwn/aws/ecs.rb +5 -2
  119. data/lib/pwn/aws/efs.rb +5 -2
  120. data/lib/pwn/aws/elasti_cache.rb +5 -2
  121. data/lib/pwn/aws/elastic_beanstalk.rb +8 -5
  122. data/lib/pwn/aws/elastic_load_balancing.rb +5 -2
  123. data/lib/pwn/aws/elastic_load_balancing_v2.rb +6 -3
  124. data/lib/pwn/aws/elastic_transcoder.rb +5 -2
  125. data/lib/pwn/aws/elasticsearch_service.rb +5 -2
  126. data/lib/pwn/aws/emr.rb +5 -2
  127. data/lib/pwn/aws/firehose.rb +5 -2
  128. data/lib/pwn/aws/game_lift.rb +5 -2
  129. data/lib/pwn/aws/glacier.rb +6 -3
  130. data/lib/pwn/aws/health.rb +5 -2
  131. data/lib/pwn/aws/iam.rb +10 -4
  132. data/lib/pwn/aws/import_export.rb +5 -2
  133. data/lib/pwn/aws/inspector.rb +5 -2
  134. data/lib/pwn/aws/iot.rb +5 -2
  135. data/lib/pwn/aws/iot_data_plane.rb +5 -2
  136. data/lib/pwn/aws/kinesis.rb +5 -2
  137. data/lib/pwn/aws/kinesis_analytics.rb +5 -2
  138. data/lib/pwn/aws/kms.rb +5 -2
  139. data/lib/pwn/aws/lambda.rb +5 -2
  140. data/lib/pwn/aws/lambda_preview.rb +5 -2
  141. data/lib/pwn/aws/lex.rb +5 -2
  142. data/lib/pwn/aws/lightsail.rb +5 -2
  143. data/lib/pwn/aws/machine_learning.rb +5 -2
  144. data/lib/pwn/aws/marketplace_commerce_analytics.rb +5 -2
  145. data/lib/pwn/aws/marketplace_metering.rb +5 -2
  146. data/lib/pwn/aws/ops_works.rb +5 -2
  147. data/lib/pwn/aws/ops_works_cm.rb +5 -2
  148. data/lib/pwn/aws/pinpoint.rb +5 -2
  149. data/lib/pwn/aws/polly.rb +5 -2
  150. data/lib/pwn/aws/rds.rb +5 -2
  151. data/lib/pwn/aws/redshift.rb +5 -2
  152. data/lib/pwn/aws/rekognition.rb +5 -2
  153. data/lib/pwn/aws/route53.rb +5 -2
  154. data/lib/pwn/aws/route53_domains.rb +5 -2
  155. data/lib/pwn/aws/s3.rb +5 -2
  156. data/lib/pwn/aws/service_catalog.rb +5 -2
  157. data/lib/pwn/aws/ses.rb +5 -2
  158. data/lib/pwn/aws/shield.rb +5 -2
  159. data/lib/pwn/aws/simple_db.rb +5 -2
  160. data/lib/pwn/aws/sms.rb +5 -2
  161. data/lib/pwn/aws/snowball.rb +5 -2
  162. data/lib/pwn/aws/sns.rb +5 -2
  163. data/lib/pwn/aws/sqs.rb +5 -2
  164. data/lib/pwn/aws/ssm.rb +5 -2
  165. data/lib/pwn/aws/states.rb +5 -2
  166. data/lib/pwn/aws/storage_gateway.rb +5 -2
  167. data/lib/pwn/aws/sts.rb +4 -1
  168. data/lib/pwn/aws/support.rb +5 -2
  169. data/lib/pwn/aws/swf.rb +5 -2
  170. data/lib/pwn/aws/waf.rb +5 -2
  171. data/lib/pwn/aws/waf_regional.rb +5 -2
  172. data/lib/pwn/aws/workspaces.rb +5 -2
  173. data/lib/pwn/aws/x_ray.rb +5 -2
  174. data/lib/pwn/aws.rb +4 -0
  175. data/lib/pwn/banner/anon.rb +3 -0
  176. data/lib/pwn/banner/bubble.rb +3 -0
  177. data/lib/pwn/banner/cheshire.rb +3 -0
  178. data/lib/pwn/banner/code_cave.rb +3 -0
  179. data/lib/pwn/banner/dont_panic.rb +3 -0
  180. data/lib/pwn/banner/f_society.rb +3 -0
  181. data/lib/pwn/banner/fork_bomb.rb +3 -0
  182. data/lib/pwn/banner/jmp_esp.rb +3 -0
  183. data/lib/pwn/banner/matrix.rb +5 -1
  184. data/lib/pwn/banner/ninja.rb +3 -0
  185. data/lib/pwn/banner/off_the_air.rb +3 -0
  186. data/lib/pwn/banner/pirate.rb +3 -0
  187. data/lib/pwn/banner/radare2.rb +3 -0
  188. data/lib/pwn/banner/radare2_ai.rb +3 -0
  189. data/lib/pwn/banner/white_rabbit.rb +3 -0
  190. data/lib/pwn/banner.rb +6 -2
  191. data/lib/pwn/blockchain/btc.rb +8 -3
  192. data/lib/pwn/blockchain/eth.rb +10 -3
  193. data/lib/pwn/blockchain.rb +4 -0
  194. data/lib/pwn/bounty/lifecycle_authz_replay.rb +46 -27
  195. data/lib/pwn/bounty.rb +4 -0
  196. data/lib/pwn/config.rb +79 -13
  197. data/lib/pwn/cron.rb +297 -20
  198. data/lib/pwn/driver.rb +2 -18
  199. data/lib/pwn/ffi/adalm_pluto.rb +65 -11
  200. data/lib/pwn/ffi/fftw.rb +31 -6
  201. data/lib/pwn/ffi/hack_rf.rb +59 -8
  202. data/lib/pwn/ffi/liquid.rb +63 -10
  203. data/lib/pwn/ffi/rtl_sdr.rb +35 -5
  204. data/lib/pwn/ffi/soapy_sdr.rb +60 -10
  205. data/lib/pwn/ffi/stdio.rb +5 -8
  206. data/lib/pwn/ffi/volk.rb +36 -7
  207. data/lib/pwn/ffi.rb +12 -0
  208. data/lib/pwn/memory.rb +136 -16
  209. data/lib/pwn/memory_index.rb +34 -19
  210. data/lib/pwn/migrate.rb +34 -24
  211. data/lib/pwn/module_skills.rb +39 -8
  212. data/lib/pwn/plugins/aflplusplus.rb +52 -0
  213. data/lib/pwn/plugins/android.rb +65 -245
  214. data/lib/pwn/plugins/artifact_registry.rb +71 -0
  215. data/lib/pwn/plugins/assembly.rb +9 -4
  216. data/lib/pwn/plugins/authentication_helper.rb +8 -5
  217. data/lib/pwn/plugins/baresip.rb +59 -12
  218. data/lib/pwn/plugins/basic_auth.rb +9 -3
  219. data/lib/pwn/plugins/beef.rb +28 -18
  220. data/lib/pwn/plugins/binary_parser.rb +133 -0
  221. data/lib/pwn/plugins/black_duck_binary_analysis.rb +63 -39
  222. data/lib/pwn/plugins/burp_suite.rb +98 -68
  223. data/lib/pwn/plugins/bus_pirate.rb +15 -8
  224. data/lib/pwn/plugins/char.rb +33 -3
  225. data/lib/pwn/plugins/credential_attack.rb +99 -0
  226. data/lib/pwn/plugins/credit_card.rb +6 -1
  227. data/lib/pwn/plugins/dao_ldap.rb +19 -13
  228. data/lib/pwn/plugins/dao_mongo.rb +11 -5
  229. data/lib/pwn/plugins/dao_postgres.rb +28 -19
  230. data/lib/pwn/plugins/dao_sqlite3.rb +15 -6
  231. data/lib/pwn/plugins/defect_dojo.rb +38 -22
  232. data/lib/pwn/plugins/detect_os.rb +5 -0
  233. data/lib/pwn/plugins/doctor.rb +149 -0
  234. data/lib/pwn/plugins/ein.rb +3 -0
  235. data/lib/pwn/plugins/exploit_dev.rb +264 -0
  236. data/lib/pwn/plugins/file_fu.rb +11 -8
  237. data/lib/pwn/plugins/frida.rb +61 -0
  238. data/lib/pwn/plugins/fuzz.rb +9 -6
  239. data/lib/pwn/plugins/gdb.rb +95 -0
  240. data/lib/pwn/plugins/git.rb +19 -14
  241. data/lib/pwn/plugins/github.rb +38 -15
  242. data/lib/pwn/plugins/google_workspace.rb +188 -45
  243. data/lib/pwn/plugins/hacker_one.rb +159 -35
  244. data/lib/pwn/plugins/hunter.rb +6 -3
  245. data/lib/pwn/plugins/ip_info.rb +9 -4
  246. data/lib/pwn/plugins/irc.rb +28 -15
  247. data/lib/pwn/plugins/jenkins.rb +65 -57
  248. data/lib/pwn/plugins/jira_data_center.rb +30 -22
  249. data/lib/pwn/plugins/jobs.rb +109 -0
  250. data/lib/pwn/plugins/json_pathify.rb +9 -5
  251. data/lib/pwn/plugins/log.rb +113 -13
  252. data/lib/pwn/plugins/mail_agent.rb +87 -79
  253. data/lib/pwn/plugins/metasploit.rb +11 -6
  254. data/lib/pwn/plugins/monkey_patch.rb +3 -0
  255. data/lib/pwn/plugins/msr206.rb +42 -28
  256. data/lib/pwn/plugins/nessus_cloud.rb +44 -4
  257. data/lib/pwn/plugins/nexpose_vuln_scan.rb +40 -24
  258. data/lib/pwn/plugins/nmap_it.rb +14 -34
  259. data/lib/pwn/plugins/nuclei.rb +57 -0
  260. data/lib/pwn/plugins/oauth2.rb +11 -5
  261. data/lib/pwn/plugins/ocr.rb +3 -0
  262. data/lib/pwn/plugins/open_api.rb +5 -2
  263. data/lib/pwn/plugins/openvas.rb +33 -25
  264. data/lib/pwn/plugins/packet.rb +152 -31
  265. data/lib/pwn/plugins/pdf_parse.rb +5 -2
  266. data/lib/pwn/plugins/pony.rb +86 -1
  267. data/lib/pwn/plugins/process_tube.rb +120 -0
  268. data/lib/pwn/plugins/ps.rb +7 -1
  269. data/lib/pwn/plugins/pwn_logger.rb +6 -2
  270. data/lib/pwn/plugins/rabbit_mq.rb +12 -7
  271. data/lib/pwn/plugins/radare2.rb +253 -0
  272. data/lib/pwn/plugins/recon.rb +161 -0
  273. data/lib/pwn/plugins/repl.rb +122 -1
  274. data/lib/pwn/plugins/scannable_codes.rb +5 -1
  275. data/lib/pwn/plugins/serial.rb +24 -14
  276. data/lib/pwn/plugins/shodan.rb +54 -35
  277. data/lib/pwn/plugins/slack_client.rb +11 -6
  278. data/lib/pwn/plugins/sock.rb +16 -8
  279. data/lib/pwn/plugins/spider.rb +5 -2
  280. data/lib/pwn/plugins/sqlmap.rb +49 -0
  281. data/lib/pwn/plugins/ssn.rb +3 -0
  282. data/lib/pwn/plugins/thread_pool.rb +6 -9
  283. data/lib/pwn/plugins/tor.rb +9 -4
  284. data/lib/pwn/plugins/transparent_browser.rb +62 -107
  285. data/lib/pwn/plugins/tty_spinner.rb +16 -2
  286. data/lib/pwn/plugins/twitter_api.rb +6 -2
  287. data/lib/pwn/plugins/uri_scheme.rb +4 -1
  288. data/lib/pwn/plugins/vault.rb +12 -3
  289. data/lib/pwn/plugins/vin.rb +24 -12
  290. data/lib/pwn/plugins/voice.rb +7 -2
  291. data/lib/pwn/plugins/volatility.rb +48 -0
  292. data/lib/pwn/plugins/vsphere.rb +9 -5
  293. data/lib/pwn/plugins/xxd.rb +12 -43
  294. data/lib/pwn/plugins/zaproxy.rb +30 -16
  295. data/lib/pwn/plugins.rb +19 -0
  296. data/lib/pwn/reports/ai_red_team.rb +6 -2
  297. data/lib/pwn/reports/csv.rb +8 -1
  298. data/lib/pwn/reports/fuzz.rb +5 -2
  299. data/lib/pwn/reports/html.rb +8 -1
  300. data/lib/pwn/reports/html_footer.rb +4 -3
  301. data/lib/pwn/reports/html_header.rb +6 -2
  302. data/lib/pwn/reports/json.rb +8 -1
  303. data/lib/pwn/reports/markdown.rb +8 -1
  304. data/lib/pwn/reports/pdf.rb +8 -1
  305. data/lib/pwn/reports/phone.rb +5 -2
  306. data/lib/pwn/reports/sast.rb +6 -2
  307. data/lib/pwn/reports/uri_buster.rb +5 -2
  308. data/lib/pwn/reports/xml.rb +8 -1
  309. data/lib/pwn/reports.rb +19 -0
  310. data/lib/pwn/sast/amqp_connect_as_guest.rb +9 -3
  311. data/lib/pwn/sast/apache_file_system_util_api.rb +9 -3
  312. data/lib/pwn/sast/aws.rb +9 -3
  313. data/lib/pwn/sast/banned_function_calls_c.rb +9 -3
  314. data/lib/pwn/sast/base64.rb +9 -3
  315. data/lib/pwn/sast/beef_hook.rb +9 -3
  316. data/lib/pwn/sast/cmd_execution_go_lang.rb +9 -3
  317. data/lib/pwn/sast/cmd_execution_java.rb +9 -3
  318. data/lib/pwn/sast/cmd_execution_python.rb +9 -3
  319. data/lib/pwn/sast/cmd_execution_ruby.rb +9 -3
  320. data/lib/pwn/sast/cmd_execution_scala.rb +9 -3
  321. data/lib/pwn/sast/csrf.rb +9 -3
  322. data/lib/pwn/sast/deserial_java.rb +9 -3
  323. data/lib/pwn/sast/emoticon.rb +9 -3
  324. data/lib/pwn/sast/eval.rb +9 -3
  325. data/lib/pwn/sast/factory.rb +9 -3
  326. data/lib/pwn/sast/http_authorization_header.rb +9 -3
  327. data/lib/pwn/sast/inner_html.rb +9 -3
  328. data/lib/pwn/sast/keystore.rb +9 -3
  329. data/lib/pwn/sast/local_storage.rb +9 -3
  330. data/lib/pwn/sast/location_hash.rb +9 -3
  331. data/lib/pwn/sast/log4j.rb +9 -3
  332. data/lib/pwn/sast/logger.rb +9 -3
  333. data/lib/pwn/sast/md5.rb +9 -3
  334. data/lib/pwn/sast/outer_html.rb +9 -3
  335. data/lib/pwn/sast/padding_oracle.rb +9 -3
  336. data/lib/pwn/sast/password.rb +9 -3
  337. data/lib/pwn/sast/php_input_mechanisms.rb +9 -3
  338. data/lib/pwn/sast/php_type_juggling.rb +9 -3
  339. data/lib/pwn/sast/pom_version.rb +9 -3
  340. data/lib/pwn/sast/port.rb +9 -3
  341. data/lib/pwn/sast/post_message.rb +9 -3
  342. data/lib/pwn/sast/private_key.rb +9 -3
  343. data/lib/pwn/sast/redirect.rb +9 -3
  344. data/lib/pwn/sast/redos.rb +9 -3
  345. data/lib/pwn/sast/shell.rb +9 -3
  346. data/lib/pwn/sast/signature.rb +9 -3
  347. data/lib/pwn/sast/sql.rb +9 -3
  348. data/lib/pwn/sast/ssl.rb +9 -3
  349. data/lib/pwn/sast/sudo.rb +9 -3
  350. data/lib/pwn/sast/task_tag.rb +9 -3
  351. data/lib/pwn/sast/test_case_engine.rb +11 -7
  352. data/lib/pwn/sast/throw_errors.rb +9 -3
  353. data/lib/pwn/sast/token.rb +9 -3
  354. data/lib/pwn/sast/type_script_type_juggling.rb +9 -3
  355. data/lib/pwn/sast/use_after_free.rb +9 -3
  356. data/lib/pwn/sast/version.rb +9 -3
  357. data/lib/pwn/sast/window_location_hash.rb +9 -3
  358. data/lib/pwn/sast.rb +4 -0
  359. data/lib/pwn/sdr/decoder/adsb.rb +36 -5
  360. data/lib/pwn/sdr/decoder/apt.rb +9 -6
  361. data/lib/pwn/sdr/decoder/base.rb +74 -22
  362. data/lib/pwn/sdr/decoder/bluetooth.rb +17 -5
  363. data/lib/pwn/sdr/decoder/dect.rb +12 -3
  364. data/lib/pwn/sdr/decoder/dsp.rb +229 -39
  365. data/lib/pwn/sdr/decoder/flex.rb +59 -11
  366. data/lib/pwn/sdr/decoder/gps.rb +12 -3
  367. data/lib/pwn/sdr/decoder/gsm.rb +24 -4
  368. data/lib/pwn/sdr/decoder/iridium.rb +12 -3
  369. data/lib/pwn/sdr/decoder/lora.rb +13 -4
  370. data/lib/pwn/sdr/decoder/lte.rb +27 -3
  371. data/lib/pwn/sdr/decoder/morse.rb +12 -3
  372. data/lib/pwn/sdr/decoder/p25.rb +12 -3
  373. data/lib/pwn/sdr/decoder/pager.rb +8 -5
  374. data/lib/pwn/sdr/decoder/pocsag.rb +29 -9
  375. data/lib/pwn/sdr/decoder/rds.rb +14 -8
  376. data/lib/pwn/sdr/decoder/rfid.rb +12 -3
  377. data/lib/pwn/sdr/decoder/rtl433.rb +12 -3
  378. data/lib/pwn/sdr/decoder/rtty.rb +8 -5
  379. data/lib/pwn/sdr/decoder/wifi.rb +12 -3
  380. data/lib/pwn/sdr/decoder/zigbee.rb +12 -3
  381. data/lib/pwn/sdr/decoder.rb +9 -0
  382. data/lib/pwn/sdr/flipper_zero.rb +17 -10
  383. data/lib/pwn/sdr/frequency_allocation.rb +4 -1
  384. data/lib/pwn/sdr/gqrx.rb +178 -119
  385. data/lib/pwn/sdr/rfidler.rb +4 -1
  386. data/lib/pwn/sdr/son_micro_rfid.rb +37 -24
  387. data/lib/pwn/sdr.rb +14 -0
  388. data/lib/pwn/sessions.rb +86 -16
  389. data/lib/pwn/setup.rb +94 -37
  390. data/lib/pwn/version.rb +1 -1
  391. data/lib/pwn/www/app_cobalt_io.rb +11 -5
  392. data/lib/pwn/www/bing.rb +10 -5
  393. data/lib/pwn/www/bug_crowd.rb +11 -5
  394. data/lib/pwn/www/checkip.rb +8 -4
  395. data/lib/pwn/www/coinbase_pro.rb +11 -5
  396. data/lib/pwn/www/duckduckgo.rb +12 -6
  397. data/lib/pwn/www/facebook.rb +11 -5
  398. data/lib/pwn/www/github.rb +11 -5
  399. data/lib/pwn/www/google.rb +11 -5
  400. data/lib/pwn/www/hacker_one.rb +20 -9
  401. data/lib/pwn/www/linkedin.rb +11 -5
  402. data/lib/pwn/www/pandora.rb +11 -5
  403. data/lib/pwn/www/pastebin.rb +9 -4
  404. data/lib/pwn/www/paypal.rb +19 -11
  405. data/lib/pwn/www/synack.rb +11 -5
  406. data/lib/pwn/www/torch.rb +13 -8
  407. data/lib/pwn/www/trading_view.rb +11 -5
  408. data/lib/pwn/www/twitter.rb +11 -5
  409. data/lib/pwn/www/uber.rb +11 -5
  410. data/lib/pwn/www/upwork.rb +11 -5
  411. data/lib/pwn/www/wayback_machine.rb +12 -6
  412. data/lib/pwn/www/youtube.rb +10 -5
  413. data/lib/pwn/www.rb +4 -0
  414. data/spec/conventions_spec.rb +118 -2
  415. data/spec/lib/pwn/ai/agent/reward_spec.rb +9 -0
  416. data/spec/lib/pwn/plugins/aflplusplus_spec.rb +13 -0
  417. data/spec/lib/pwn/plugins/artifact_registry_spec.rb +13 -0
  418. data/spec/lib/pwn/plugins/binary_parser_spec.rb +21 -0
  419. data/spec/lib/pwn/plugins/credential_attack_spec.rb +13 -0
  420. data/spec/lib/pwn/plugins/doctor_spec.rb +23 -0
  421. data/spec/lib/pwn/plugins/exploit_dev_spec.rb +23 -0
  422. data/spec/lib/pwn/plugins/frida_spec.rb +13 -0
  423. data/spec/lib/pwn/plugins/gdb_spec.rb +13 -0
  424. data/spec/lib/pwn/plugins/jobs_spec.rb +13 -0
  425. data/spec/lib/pwn/plugins/nuclei_spec.rb +13 -0
  426. data/spec/lib/pwn/plugins/process_tube_spec.rb +13 -0
  427. data/spec/lib/pwn/plugins/radare2_spec.rb +13 -0
  428. data/spec/lib/pwn/plugins/recon_spec.rb +26 -0
  429. data/spec/lib/pwn/plugins/sqlmap_spec.rb +13 -0
  430. data/spec/lib/pwn/plugins/volatility_spec.rb +13 -0
  431. data/third_party/pwn_rdoc.jsonl +126 -5
  432. metadata +47 -3
  433. data/etc/default_skills/pwn/memory_index/references/urls.md +0 -4
  434. data/etc/default_skills/pwn/plugins/transparent_browser/references/urls.md +0 -3
@@ -190,34 +190,43 @@ module PWN
190
190
 
191
191
  public_class_method def self.help
192
192
  puts "USAGE:
193
- pg_conn = #{self}.connect(
194
- host: 'required host or IP',
195
- port: 'optional port (defaults to 5432)',
196
- dbname: 'required database name',
197
- user: 'required username',
198
- password: 'optional (prompts if left blank)',
199
- connect_timeout: 'optional (defaults to 60 seconds)',
200
- options: 'optional postgres options',
201
- tty: 'optional tty',
202
- sslmode: :disable|:allow|:prefer|:require
193
+ # Run connect and return its result
194
+ #{self}.connect(
195
+ host: 'required - required host or IP',
196
+ port: 'optional - optional port (defaults to 5432)',
197
+ dbname: 'required - required database name',
198
+ user: 'required - required username',
199
+ password: 'optional - optional (prompts if left blank)',
200
+ connect_timeout: 'optional - optional (defaults to 60 seconds)',
201
+ options: 'optional - optional postgres options',
202
+ tty: 'optional - optional tty',
203
+ sslmode: 'required - :disable|:allow|:prefer|:require'
203
204
  )
204
205
 
205
- res = #{self}.sql_statement(
206
- pg_conn: pg_conn,
207
- prepared_statement: 'SELECT * FROM tn_users WHERE state = $1',
208
- statement_params: ['Active']
206
+ # Run sql statement and return its result
207
+ #{self}.sql_statement(
208
+ pg_conn: 'optional - pg conn value consumed by #sql_statement',
209
+ prepared_statement: 'optional - SELECT * FROM tn_users WHERE state = $1',
210
+ statement_params: 'required - statement params value consumed by #sql_statement'
209
211
  )
210
212
 
211
- res = #{self}.list_all_columns_by_table(
212
- pg_conn: pg_conn,
213
- schema: 'required schema name',
214
- table_name: 'required table name'
213
+ # Method Parameters Not Implemented
214
+ #{self}.list_all_columns_by_table(
215
+ pg_conn: 'optional - pg conn value consumed by #list_all_columns_by_table',
216
+ schema: 'required - required schema name',
217
+ table_name: 'required - required table name',
218
+ table_schema: 'optional - table schema value consumed by #list_all_columns_by_table'
215
219
  )
216
220
 
217
- #{self}.disconnect(pg_conn: pg_conn)
221
+ # Run disconnect and return its result
222
+ #{self}.disconnect(
223
+ pg_conn: 'optional - pg conn value consumed by #disconnect'
224
+ )
218
225
 
226
+ # Print the AUTHOR(S) string for this module.
219
227
  #{self}.authors
220
228
  "
229
+ constants.sort
221
230
  end
222
231
  end
223
232
  end
@@ -107,18 +107,27 @@ module PWN
107
107
 
108
108
  public_class_method def self.help
109
109
  puts "USAGE:
110
- sqlite3_conn = #{self}.connect(db_path: 'Required - Path of SQLite3 DB File')
110
+ # Run connect and return its result
111
+ #{self}.connect(
112
+ db_path: 'required - Path of SQLite3 DB File'
113
+ )
111
114
 
112
- res = #{self}.sql_statement(
113
- sqlite3_conn: sqlite3_conn,
114
- prepared_statement: 'SELECT * FROM tn_users WHERE state = ?;',
115
- statement_params: ['Active']
115
+ # Run sql statement and return its result
116
+ #{self}.sql_statement(
117
+ sqlite3_conn: 'optional - sqlite3 conn value consumed by #sql_statement',
118
+ prepared_statement: 'optional - SELECT * FROM tn_users WHERE state = ?;',
119
+ statement_params: 'required - statement params value consumed by #sql_statement'
116
120
  )
117
121
 
118
- #{self}.disconnect(:sqlite3_conn => sqlite3_conn)
122
+ # Run disconnect and return its result
123
+ #{self}.disconnect(
124
+ sqlite3_conn: 'optional - sqlite3 conn value consumed by #disconnect'
125
+ )
119
126
 
127
+ # Print the AUTHOR(S) string for this module.
120
128
  #{self}.authors
121
129
  "
130
+ constants.sort
122
131
  end
123
132
  end
124
133
  end
@@ -738,7 +738,8 @@ module PWN
738
738
 
739
739
  public_class_method def self.help
740
740
  puts "USAGE:
741
- dd_obj = #{self}.login(
741
+ # Run login and return its result
742
+ #{self}.login(
742
743
  url: 'required - url of DefectDojo Server',
743
744
  api_version: 'required - api version to use v1 || v2',
744
745
  username: 'required - username to AuthN w/ api v1)',
@@ -746,18 +747,21 @@ module PWN
746
747
  proxy: 'optional - proxy all traffic through MITM proxy (defaults to nil)'
747
748
  )
748
749
 
749
- product_list = #{self}.product_list(
750
- dd_obj: 'required dd_obj returned from #login_v1 method',
750
+ # Run product list and return its result
751
+ #{self}.product_list(
752
+ dd_obj: 'required - required dd_obj returned from #login method',
751
753
  id: 'optional - retrieve single product by id, otherwise return all'
752
754
  )
753
755
 
754
- engagement_list = #{self}.engagement_list(
755
- dd_obj: 'required dd_obj returned from #login_v1 method',
756
+ # Run engagement list and return its result
757
+ #{self}.engagement_list(
758
+ dd_obj: 'required - required dd_obj returned from #login method',
756
759
  id: 'optional - retrieve single engagement by id, otherwise return all'
757
760
  )
758
761
 
759
- engagement_create_response = #{self}.engagement_create(
760
- dd_obj: 'required - dd_obj returned from #login_v1 method',
762
+ # Run engagement create and return its result
763
+ #{self}.engagement_create(
764
+ dd_obj: 'required - dd_obj returned from #login method',
761
765
  name: 'required - name of the engagement',
762
766
  description: 'optional - description of engagement',
763
767
  engagement_type: 'optional - type of engagement Interactive||CI/CD (defaults to CI/CD)',
@@ -774,16 +778,19 @@ module PWN
774
778
  check_list: 'optional - boolean to set an engagement as a checkbox assessment (defaults to false)',
775
779
  first_contacted: 'optional - date of engagement request e.g. 2018-06-18 (Defaults to current day)',
776
780
  target_start: 'optional - date to start enagement e.g. 2018-06-19 (Defaults to current day)',
777
- target_end: 'optional - date of engagement completion e.g. 2018-06-20 (Defaults to current day)'
781
+ target_end: 'optional - date of engagement completion e.g. 2018-06-20 (Defaults to current day)',
782
+ engagment_type: 'optional - engagment type value consumed by #engagement_create'
778
783
  )
779
784
 
780
- test_list = #{self}.test_list(
781
- dd_obj: 'required dd_obj returned from #login_v1 method',
785
+ # Run test list and return its result
786
+ #{self}.test_list(
787
+ dd_obj: 'required - required dd_obj returned from #login method',
782
788
  id: 'optional - retrieve single test by id, otherwise return all'
783
789
  )
784
790
 
785
- importscan_response = #{self}.importscan(
786
- dd_obj: 'required - dd_obj returned from #login_v1 method',
791
+ # Run importscan and return its result
792
+ #{self}.importscan(
793
+ dd_obj: 'required - dd_obj returned from #login method',
787
794
  engagement_name: 'required - name of engagement to associate w/ scan',
788
795
  scan_type: 'required - type of scan importing (see <DEFECTDOJO_URL>/admin/dojo/test_type/ for listing)',
789
796
  file: 'required - path of scan results file',
@@ -795,11 +802,14 @@ module PWN
795
802
  create_finding_groups: 'optional - flag to create finding groups (defaults to false)',
796
803
  close_old_findings_product_scope: 'optional - flag to close old findings from engagement (defaults to false)',
797
804
  close_old_findings: 'optional - flag to close old findings, regardless of engagement (defaults to false)',
798
- push_to_jira: 'optional - flag to push findings to JIRA (defaults to false)'
805
+ push_to_jira: 'optional - flag to push findings to JIRA (defaults to false)',
806
+ test_title: 'optional - test title value consumed by #importscan',
807
+ group_by: 'required - group by value consumed by #importscan'
799
808
  )
800
809
 
801
- reimportscan_response = #{self}.reimportscan(
802
- dd_obj: 'required - dd_obj returned from #login_v1 method',
810
+ # Run reimportscan and return its result
811
+ #{self}.reimportscan(
812
+ dd_obj: 'required - dd_obj returned from #login method',
803
813
  engagement_name: 'required - name of engagement to associate w/ scan',
804
814
  scan_type: 'required - type of scan importing (see <DEFECTDOJO_URL>/admin/dojo/test_type/ for listing)',
805
815
  file: 'required - path of scan results file',
@@ -814,27 +824,33 @@ module PWN
814
824
  push_to_jira: 'optional - flag to push findings to JIRA (defaults to false)'
815
825
  )
816
826
 
817
- finding_list = #{self}.finding_list(
818
- dd_obj: 'required dd_obj returned from #login_v1 method',
827
+ # Run finding list and return its result
828
+ #{self}.finding_list(
829
+ dd_obj: 'required - required dd_obj returned from #login method',
819
830
  id: 'optional - retrieve single finding by id, otherwise return all'
820
831
  )
821
832
 
822
- user_list = #{self}.user_list(
823
- dd_obj: 'required dd_obj returned from #login_v1 method',
833
+ # Run user list and return its result
834
+ #{self}.user_list(
835
+ dd_obj: 'required - required dd_obj returned from #login method',
824
836
  id: 'optional - retrieve single user by id, otherwise return all'
825
837
  )
826
838
 
827
- tool_configuration_list = #{self}.tool_configuration_list(
828
- dd_obj: 'required dd_obj returned from #login_v1 method',
839
+ # Run tool configuration list and return its result
840
+ #{self}.tool_configuration_list(
841
+ dd_obj: 'required - required dd_obj returned from #login method',
829
842
  id: 'optional - retrieve single test by id, otherwise return all'
830
843
  )
831
844
 
845
+ # Run logout and return its result
832
846
  #{self}.logout(
833
- dd_obj: 'required dd_obj returned from #login_v1 or #login_v2 method'
847
+ dd_obj: 'required - required dd_obj returned from #login method'
834
848
  )
835
849
 
850
+ # Print the AUTHOR(S) string for this module.
836
851
  #{self}.authors
837
852
  "
853
+ constants.sort
838
854
  end
839
855
  end
840
856
  end
@@ -57,14 +57,19 @@ module PWN
57
57
 
58
58
  public_class_method def self.help
59
59
  puts "USAGE:
60
+ # Run type and return its result
60
61
  #{self}.type
61
62
 
63
+ # Run arch and return its result
62
64
  #{self}.arch
63
65
 
66
+ # Run endian and return its result
64
67
  #{self}.endian
65
68
 
69
+ # Print the AUTHOR(S) string for this module.
66
70
  #{self}.authors
67
71
  "
72
+ constants.sort
68
73
  end
69
74
  end
70
75
  end
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PWN
4
+ module Plugins
5
+ # Plugin/binary/capability preflight. Plugins declare required_bins /
6
+ # required_caps; HOST summaries list degraded modules without autoloading
7
+ # the whole plugin tree.
8
+ module Doctor
9
+ class MissingBinary < StandardError; end
10
+ class MissingCapability < StandardError; end
11
+
12
+ PLUGIN_DEPS = {
13
+ 'PWN::Plugins::Radare2' => { bins: %w[r2] },
14
+ 'PWN::Plugins::GDB' => { bins: %w[gdb] },
15
+ 'PWN::Plugins::Nuclei' => { bins: %w[nuclei] },
16
+ 'PWN::Plugins::Sqlmap' => { bins: %w[sqlmap] },
17
+ 'PWN::Plugins::Frida' => { bins: %w[frida] },
18
+ 'PWN::Plugins::AFLplusplus' => { bins: %w[afl-fuzz] },
19
+ 'PWN::Plugins::Volatility' => { bins: %w[vol] },
20
+ 'PWN::Plugins::NmapIt' => { bins: %w[nmap] },
21
+ 'PWN::Plugins::Metasploit' => { bins: %w[msfconsole] },
22
+ 'PWN::Plugins::BurpSuite' => { bins: %w[burpsuite] },
23
+ 'PWN::Plugins::Zaproxy' => { bins: %w[zaproxy] },
24
+ 'PWN::Plugins::Packet' => { bins: [], caps: %w[CAP_NET_RAW] }
25
+ }.freeze
26
+
27
+ public_class_method def self.required_bins
28
+ []
29
+ end
30
+
31
+ public_class_method def self.bin?(opts = {})
32
+ name = opts[:name].to_s
33
+ return false if name.empty?
34
+
35
+ ENV['PATH'].to_s.split(File::PATH_SEPARATOR).any? do |dir|
36
+ File.executable?(File.join(dir, name))
37
+ end
38
+ end
39
+
40
+ public_class_method def self.require_bin!(opts = {})
41
+ name = opts[:name].to_s
42
+ return true if bin?(name: name)
43
+
44
+ raise MissingBinary, "ERROR: required binary missing: #{name}. Install via pwn setup --profile re (or the plugin profile)."
45
+ end
46
+
47
+ public_class_method def self.cap_net_raw?(opts = {})
48
+ return true unless File.readable?('/proc/self/status')
49
+
50
+ line = File.readlines('/proc/self/status').find { |l| l.start_with?('CapEff:') }
51
+ return false unless line
52
+
53
+ hex = line.split.last.to_s
54
+ hex.to_i(16).anybits?(1 << 13)
55
+ rescue StandardError
56
+ opts[:default] == true
57
+ end
58
+
59
+ public_class_method def self.require_cap_net_raw!(opts = {})
60
+ return true if cap_net_raw?(opts)
61
+
62
+ raise MissingCapability,
63
+ 'ERROR: CAP_NET_RAW is missing. Packet.send cannot inject L2 frames. ' \
64
+ 'Hint: sudo setcap cap_net_raw,cap_net_admin+ep "$(readlink -f "$(command -v ruby)")" ' \
65
+ 'or run as root. Fallback: PWN::Plugins::Sock.connect (no raw).'
66
+ end
67
+
68
+ public_class_method def self.check(opts = {})
69
+ deps = PLUGIN_DEPS
70
+ if opts[:names]
71
+ want = Array(opts[:names]).map(&:to_s)
72
+ deps = deps.slice(*want)
73
+ end
74
+ deps.map do |plugin, dep|
75
+ bins = Array(dep[:bins])
76
+ caps = Array(dep[:caps])
77
+ missing_bins = bins.reject { |b| bin?(name: b) }
78
+ missing_caps = []
79
+ missing_caps << 'CAP_NET_RAW' if caps.include?('CAP_NET_RAW') && !cap_net_raw?
80
+ status = if missing_bins.empty? && missing_caps.empty?
81
+ :ok
82
+ elsif bins.any? && missing_bins.length == bins.length
83
+ :dead
84
+ else
85
+ :degraded
86
+ end
87
+ { plugin: plugin, status: status, missing_bins: missing_bins, missing_caps: missing_caps }
88
+ end
89
+ end
90
+
91
+ public_class_method def self.host_summary(opts = {})
92
+ rows = check(names: opts[:names])
93
+ cap = (opts[:limit] || 12).to_i
94
+ dead = rows.select { |r| r[:status] == :dead }
95
+ degraded = rows.select { |r| r[:status] == :degraded }
96
+ lines = ["HOST plugins ok=#{rows.count { |r| r[:status] == :ok }} degraded=#{degraded.length} dead=#{dead.length}"]
97
+ (degraded + dead).first(cap).each do |r|
98
+ miss = (r[:missing_bins] + r[:missing_caps]).join(',')
99
+ lines << " #{r[:status]} #{r[:plugin]} missing=#{miss}"
100
+ end
101
+ lines.join("\n")
102
+ end
103
+
104
+ public_class_method def self.authors
105
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n"
106
+ end
107
+
108
+ public_class_method def self.help
109
+ puts "USAGE:
110
+ # List host binaries this module expects to be installed.
111
+ #{self}.required_bins
112
+
113
+ # Run bin and return its result
114
+ #{self}.bin?(
115
+ name: 'required - binary or identifier name'
116
+ )
117
+
118
+ # Run require bin and return its result
119
+ #{self}.require_bin!(
120
+ name: 'required - binary or identifier name'
121
+ )
122
+
123
+ # Run cap net raw and return its result
124
+ #{self}.cap_net_raw?(
125
+ default: 'optional - default value consumed by #cap_net_raw?'
126
+ )
127
+
128
+ # Run require cap net raw and return its result
129
+ #{self}.require_cap_net_raw!
130
+
131
+ # Run check and return its result
132
+ #{self}.check(
133
+ names: 'optional - Array names value consumed by #check'
134
+ )
135
+
136
+ # Run host summary and return its result
137
+ #{self}.host_summary(
138
+ names: 'optional - names value consumed by #host_summary',
139
+ limit: 'optional - limit value consumed by #host_summary'
140
+ )
141
+
142
+ # Print the AUTHOR(S) string for this module.
143
+ #{self}.authors
144
+ "
145
+ constants.sort
146
+ end
147
+ end
148
+ end
149
+ end
@@ -129,12 +129,15 @@ module PWN
129
129
 
130
130
  public_class_method def self.help
131
131
  puts "USAGE:
132
+ # Run generate and return its result
132
133
  #{self}.generate(
133
134
  count: 'required - number of EIN numbers to generate'
134
135
  )
135
136
 
137
+ # Print the AUTHOR(S) string for this module.
136
138
  #{self}.authors
137
139
  "
140
+ constants.sort
138
141
  end
139
142
  end
140
143
  end
@@ -0,0 +1,264 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PWN
4
+ module Plugins
5
+ # p8/p16/p32/p64, cyclic, flat, fmt writes, gadget search.
6
+ module ExploitDev
7
+ CYCLIC_ALPHA = (('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a).freeze
8
+
9
+ public_class_method def self.required_bins
10
+ []
11
+ end
12
+
13
+ public_class_method def self.p8(opts = {})
14
+ pack_int(value: opts[:value] || opts[:n], bytes: 1, endian: opts[:endian])
15
+ end
16
+
17
+ public_class_method def self.p16(opts = {})
18
+ pack_int(value: opts[:value] || opts[:n], bytes: 2, endian: opts[:endian])
19
+ end
20
+
21
+ public_class_method def self.p32(opts = {})
22
+ pack_int(value: opts[:value] || opts[:n], bytes: 4, endian: opts[:endian])
23
+ end
24
+
25
+ public_class_method def self.p64(opts = {})
26
+ pack_int(value: opts[:value] || opts[:n], bytes: 8, endian: opts[:endian])
27
+ end
28
+
29
+ public_class_method def self.u8(opts = {})
30
+ unpack_int(buf: opts[:buf] || opts[:data], bytes: 1, endian: opts[:endian])
31
+ end
32
+
33
+ public_class_method def self.u16(opts = {})
34
+ unpack_int(buf: opts[:buf] || opts[:data], bytes: 2, endian: opts[:endian])
35
+ end
36
+
37
+ public_class_method def self.u32(opts = {})
38
+ unpack_int(buf: opts[:buf] || opts[:data], bytes: 4, endian: opts[:endian])
39
+ end
40
+
41
+ public_class_method def self.u64(opts = {})
42
+ unpack_int(buf: opts[:buf] || opts[:data], bytes: 8, endian: opts[:endian])
43
+ end
44
+
45
+ public_class_method def self.cyclic(opts = {})
46
+ n = (opts[:length] || 100).to_i
47
+ width = (opts[:width] || opts[:n] || 4).to_i
48
+ width = 4 if width < 2
49
+ out = +''
50
+ i = 0
51
+ while out.length < n
52
+ chunk = []
53
+ v = i
54
+ width.times do
55
+ chunk.unshift(CYCLIC_ALPHA[v % CYCLIC_ALPHA.length])
56
+ v /= CYCLIC_ALPHA.length
57
+ end
58
+ out << chunk.join
59
+ i += 1
60
+ end
61
+ out[0, n]
62
+ end
63
+
64
+ public_class_method def self.cyclic_find(opts = {})
65
+ needle = opts[:value] || opts[:subseq]
66
+ hay = cyclic(length: (opts[:length] || 8_192).to_i, n: (opts[:n] || 4).to_i)
67
+ blob = needle.is_a?(Integer) ? p32(value: needle, endian: opts[:endian]) : needle.to_s
68
+ hay.index(blob)
69
+ end
70
+
71
+ public_class_method def self.flat(opts = {})
72
+ parts = Array(opts[:parts] || opts[:values] || opts[:arr])
73
+ endian = opts[:endian]
74
+ parts.map do |p|
75
+ case p
76
+ when Integer then p32(value: p, endian: endian)
77
+ when Array then p32(value: p[0], endian: endian) * p[1].to_i
78
+ else p.to_s
79
+ end
80
+ end.join
81
+ end
82
+
83
+ public_class_method def self.shellcode(opts = {})
84
+ arch = (opts[:arch] || 'x86_64').to_s
85
+ kind = (opts[:kind] || opts[:payload] || 'nop').to_s
86
+ asm = case kind
87
+ when 'nop' then 'nop'
88
+ when 'ret' then 'ret'
89
+ else opts[:asm].to_s
90
+ end
91
+ raise 'ERROR: asm is required for custom shellcode' if asm.empty?
92
+
93
+ PWN::Plugins::Assembly.asm_to_opcodes(asm: asm, arch: arch, endian: opts[:endian])
94
+ end
95
+
96
+ public_class_method def self.fmt_writes(opts = {})
97
+ addr = (opts[:addr] || 0).to_i
98
+ value = (opts[:value] || 0).to_i
99
+ offset = (opts[:offset] || 6).to_i
100
+ {
101
+ payload: "#{p32(value: addr)}%#{value}x%#{offset}$n",
102
+ addr: addr,
103
+ value: value,
104
+ offset: offset
105
+ }
106
+ end
107
+
108
+ public_class_method def self.gadgets(opts = {})
109
+ path = opts[:path].to_s
110
+ raise 'ERROR: path is required' if path.empty?
111
+
112
+ if PWN::Plugins::Doctor.bin?(name: 'r2')
113
+ sid = PWN::Plugins::Radare2.open(path: path)
114
+ begin
115
+ PWN::Plugins::Radare2.cmd(session: sid, cmd: '/R')
116
+ ensure
117
+ PWN::Plugins::Radare2.close(session: sid)
118
+ end
119
+ elsif PWN::Plugins::Doctor.bin?(name: 'ROPgadget')
120
+ `ROPgadget --binary #{path}`.to_s
121
+ else
122
+ { error: 'r2 and ROPgadget missing', hint: 'pwn setup --profile re' }
123
+ end
124
+ end
125
+
126
+ public_class_method def self.authors
127
+ "AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n"
128
+ end
129
+
130
+ public_class_method def self.help
131
+ puts "USAGE:
132
+ # List host binaries this module expects to be installed.
133
+ #{self}.required_bins
134
+
135
+ # Run p8 and return its result
136
+ #{self}.p8(
137
+ value: 'optional - integer or string to pack/encode',
138
+ n: 'optional - count, width, or size',
139
+ endian: 'optional - :little or :big byte order'
140
+ )
141
+
142
+ # Run p16 and return its result
143
+ #{self}.p16(
144
+ value: 'optional - integer or string to pack/encode',
145
+ n: 'optional - count, width, or size',
146
+ endian: 'optional - :little or :big byte order'
147
+ )
148
+
149
+ # Run p32 and return its result
150
+ #{self}.p32(
151
+ value: 'optional - integer or string to pack/encode',
152
+ n: 'optional - count, width, or size',
153
+ endian: 'optional - :little or :big byte order'
154
+ )
155
+
156
+ # Run p64 and return its result
157
+ #{self}.p64(
158
+ value: 'optional - integer or string to pack/encode',
159
+ n: 'optional - count, width, or size',
160
+ endian: 'optional - :little or :big byte order'
161
+ )
162
+
163
+ # Run u8 and return its result
164
+ #{self}.u8(
165
+ buf: 'optional - buf value consumed by #u8',
166
+ data: 'optional - data value consumed by #u8',
167
+ endian: 'optional - :little or :big byte order'
168
+ )
169
+
170
+ # Run u16 and return its result
171
+ #{self}.u16(
172
+ buf: 'optional - buf value consumed by #u16',
173
+ data: 'optional - data value consumed by #u16',
174
+ endian: 'optional - :little or :big byte order'
175
+ )
176
+
177
+ # Run u32 and return its result
178
+ #{self}.u32(
179
+ buf: 'optional - buf value consumed by #u32',
180
+ data: 'optional - data value consumed by #u32',
181
+ endian: 'optional - :little or :big byte order'
182
+ )
183
+
184
+ # Run u64 and return its result
185
+ #{self}.u64(
186
+ buf: 'optional - buf value consumed by #u64',
187
+ data: 'optional - data value consumed by #u64',
188
+ endian: 'optional - :little or :big byte order'
189
+ )
190
+
191
+ # Run cyclic and return its result
192
+ #{self}.cyclic(
193
+ length: 'optional - number of bytes or characters to generate',
194
+ width: 'optional - cyclic de Bruijn sequence width in bytes',
195
+ n: 'optional - count, width, or size'
196
+ )
197
+
198
+ # Run cyclic find and return its result
199
+ #{self}.cyclic_find(
200
+ value: 'optional - integer or string to pack/encode (defaults to opts[:subseq])',
201
+ subseq: 'optional - subseq value consumed by #cyclic_find',
202
+ length: 'optional - number of bytes or characters to generate',
203
+ n: 'optional - count, width, or size',
204
+ endian: 'optional - :little or :big byte order'
205
+ )
206
+
207
+ # Run flat and return its result
208
+ #{self}.flat(
209
+ parts: 'optional - parts value consumed by #flat',
210
+ values: 'optional - values value consumed by #flat',
211
+ arr: 'optional - arr value consumed by #flat',
212
+ endian: 'optional - :little or :big byte order'
213
+ )
214
+
215
+ # Run shellcode and return its result
216
+ #{self}.shellcode(
217
+ arch: 'optional - architecture string (as from objdump --info)',
218
+ kind: 'optional - kind value consumed by #shellcode',
219
+ payload: 'optional - payload value consumed by #shellcode',
220
+ asm: 'required - assembly source (one instruction per line)',
221
+ endian: 'optional - :little or :big byte order'
222
+ )
223
+
224
+ # Run fmt writes and return its result
225
+ #{self}.fmt_writes(
226
+ addr: 'optional - address or flag (e.g. main or 0x401000)',
227
+ value: 'optional - integer or string to pack/encode',
228
+ offset: 'optional - offset value consumed by #fmt_writes'
229
+ )
230
+
231
+ # Run gadgets and return its result
232
+ #{self}.gadgets(
233
+ path: 'required - filesystem path to read or write'
234
+ )
235
+
236
+ # Print the AUTHOR(S) string for this module.
237
+ #{self}.authors
238
+ "
239
+ constants.sort
240
+ end
241
+
242
+ private_class_method def self.pack_int(opts = {})
243
+ v = opts[:value].to_i
244
+ bytes = opts[:bytes].to_i
245
+ little = opts[:endian].to_s != 'big'
246
+ template = {
247
+ 1 => 'C',
248
+ 2 => little ? 'v' : 'n',
249
+ 4 => little ? 'V' : 'N',
250
+ 8 => little ? 'Q<' : 'Q>'
251
+ }[bytes]
252
+ [v].pack(template)
253
+ end
254
+
255
+ private_class_method def self.unpack_int(opts = {})
256
+ buf = opts[:buf].to_s
257
+ bytes = opts[:bytes].to_i
258
+ little = opts[:endian].to_s != 'big'
259
+ template = { 1 => 'C', 2 => little ? 'v' : 'n', 4 => little ? 'V' : 'N', 8 => little ? 'Q<' : 'Q>' }[bytes]
260
+ buf.unpack1(template)
261
+ end
262
+ end
263
+ end
264
+ end