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.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/documentation/Installation.md +1 -0
- data/etc/default_skills/exploitdev/SKILL.md +38 -0
- data/etc/default_skills/pwn/ai/agent/extrospection/osint/bridges/SKILL.md +30 -8
- data/etc/default_skills/pwn/ai/agent/extrospection/osint/social/SKILL.md +30 -8
- data/etc/default_skills/pwn/ai/agent/extrospection/osint/social/references/urls.md +1 -1
- data/etc/default_skills/pwn/ai/agent/extrospection/references/urls.md +0 -1
- data/etc/default_skills/pwn/memory_index/SKILL.md +0 -4
- data/etc/default_skills/pwn/plugins/aflplusplus/SKILL.md +49 -0
- data/etc/default_skills/pwn/plugins/android/SKILL.md +1 -0
- data/etc/default_skills/pwn/plugins/artifact_registry/SKILL.md +49 -0
- data/etc/default_skills/pwn/plugins/binary_parser/SKILL.md +54 -0
- data/etc/default_skills/pwn/plugins/credential_attack/SKILL.md +58 -0
- data/etc/default_skills/pwn/plugins/credential_attack/references/urls.md +3 -0
- data/etc/default_skills/pwn/plugins/exploit_db/SKILL.md +49 -0
- data/etc/default_skills/pwn/plugins/exploit_dev/SKILL.md +63 -0
- data/etc/default_skills/pwn/plugins/frida/SKILL.md +51 -0
- data/etc/default_skills/pwn/plugins/fuzz/SKILL.md +2 -0
- data/etc/default_skills/pwn/plugins/gdb/SKILL.md +53 -0
- data/etc/default_skills/pwn/plugins/jobs/SKILL.md +51 -0
- data/etc/default_skills/pwn/plugins/k8s/SKILL.md +51 -0
- data/etc/default_skills/pwn/plugins/nuclei/SKILL.md +50 -0
- data/etc/default_skills/pwn/plugins/preflight_checker/SKILL.md +59 -0
- data/etc/default_skills/pwn/plugins/process_tube/SKILL.md +53 -0
- data/etc/default_skills/pwn/plugins/radare2/SKILL.md +59 -0
- data/etc/default_skills/pwn/plugins/recon/SKILL.md +57 -0
- data/etc/default_skills/pwn/plugins/recon/references/urls.md +6 -0
- data/etc/default_skills/pwn/plugins/semgrep/SKILL.md +48 -0
- data/etc/default_skills/pwn/plugins/sqlmap/SKILL.md +48 -0
- data/etc/default_skills/pwn/plugins/transparent_browser/SKILL.md +0 -4
- data/etc/default_skills/pwn/plugins/volatility/SKILL.md +49 -0
- data/lib/pwn/ai/agent/assembly.rb +4 -1
- data/lib/pwn/ai/agent/btc.rb +4 -1
- data/lib/pwn/ai/agent/burp_suite.rb +5 -2
- data/lib/pwn/ai/agent/curriculum.rb +89 -30
- data/lib/pwn/ai/agent/dispatch.rb +27 -16
- data/lib/pwn/ai/agent/extrospection/osint/bridges.rb +9 -18
- data/lib/pwn/ai/agent/extrospection/osint/social.rb +9 -18
- data/lib/pwn/ai/agent/extrospection.rb +185 -60
- data/lib/pwn/ai/agent/gqrx.rb +4 -1
- data/lib/pwn/ai/agent/hacker_one.rb +5 -2
- data/lib/pwn/ai/agent/learning.rb +142 -25
- data/lib/pwn/ai/agent/loop.rb +53 -46
- data/lib/pwn/ai/agent/metrics.rb +133 -23
- data/lib/pwn/ai/agent/mistakes.rb +126 -17
- data/lib/pwn/ai/agent/open_goal.rb +25 -9
- data/lib/pwn/ai/agent/policy.rb +158 -18
- data/lib/pwn/ai/agent/prompt_builder.rb +21 -11
- data/lib/pwn/ai/agent/prompt_cache.rb +44 -13
- data/lib/pwn/ai/agent/reflect.rb +9 -5
- data/lib/pwn/ai/agent/registry.rb +65 -12
- data/lib/pwn/ai/agent/result.rb +19 -10
- data/lib/pwn/ai/agent/reward.rb +150 -32
- data/lib/pwn/ai/agent/sast.rb +4 -1
- data/lib/pwn/ai/agent/swarm.rb +72 -36
- data/lib/pwn/ai/agent/task_summarizer.rb +165 -36
- data/lib/pwn/ai/agent/tool_guard.rb +105 -6
- data/lib/pwn/ai/agent/tools/sessions.rb +8 -1
- data/lib/pwn/ai/agent/transparent_browser.rb +4 -1
- data/lib/pwn/ai/agent/turn_finalizer.rb +41 -21
- data/lib/pwn/ai/agent/vuln_gen.rb +6 -3
- data/lib/pwn/ai/agent.rb +4 -0
- data/lib/pwn/ai/anthropic.rb +41 -7
- data/lib/pwn/ai/gemini.rb +21 -11
- data/lib/pwn/ai/grok.rb +44 -6
- data/lib/pwn/ai/http_retry.rb +40 -12
- data/lib/pwn/ai/ollama.rb +19 -10
- data/lib/pwn/ai/open_ai.rb +81 -30
- data/lib/pwn/ai/open_web_ui.rb +20 -14
- data/lib/pwn/ai/red_team/agent_protocol_abuse.rb +7 -1
- data/lib/pwn/ai/red_team/data_and_model_poisoning.rb +7 -1
- data/lib/pwn/ai/red_team/excessive_agency.rb +7 -1
- data/lib/pwn/ai/red_team/hidden_context_exposure.rb +7 -1
- data/lib/pwn/ai/red_team/insecure_output_handling.rb +7 -1
- data/lib/pwn/ai/red_team/jailbreak.rb +7 -1
- data/lib/pwn/ai/red_team/memory_poisoning.rb +7 -1
- data/lib/pwn/ai/red_team/multimodal_injection.rb +7 -1
- data/lib/pwn/ai/red_team/overreliance.rb +7 -1
- data/lib/pwn/ai/red_team/payload_splitting.rb +7 -1
- data/lib/pwn/ai/red_team/prompt_injection.rb +7 -1
- data/lib/pwn/ai/red_team/rag_poisoning.rb +7 -1
- data/lib/pwn/ai/red_team/sensitive_information_disclosure.rb +7 -1
- data/lib/pwn/ai/red_team/supply_chain.rb +7 -1
- data/lib/pwn/ai/red_team/system_prompt_extraction.rb +7 -1
- data/lib/pwn/ai/red_team/test_case_engine.rb +12 -9
- data/lib/pwn/ai/red_team/token_smuggling.rb +7 -1
- data/lib/pwn/ai/red_team/unbounded_consumption.rb +7 -1
- data/lib/pwn/ai/red_team/vector_and_embedding_weaknesses.rb +7 -1
- data/lib/pwn/ai/red_team.rb +4 -0
- data/lib/pwn/ai.rb +4 -0
- data/lib/pwn/aws/acm.rb +5 -2
- data/lib/pwn/aws/api_gateway.rb +10 -7
- data/lib/pwn/aws/app_stream.rb +5 -2
- data/lib/pwn/aws/application_auto_scaling.rb +5 -2
- data/lib/pwn/aws/application_discovery_service.rb +5 -2
- data/lib/pwn/aws/auto_scaling.rb +5 -2
- data/lib/pwn/aws/batch.rb +5 -2
- data/lib/pwn/aws/budgets.rb +5 -2
- data/lib/pwn/aws/cloud_formation.rb +5 -2
- data/lib/pwn/aws/cloud_front.rb +7 -4
- data/lib/pwn/aws/cloud_hsm.rb +5 -2
- data/lib/pwn/aws/cloud_search.rb +5 -2
- data/lib/pwn/aws/cloud_search_domain.rb +5 -2
- data/lib/pwn/aws/cloud_trail.rb +5 -2
- data/lib/pwn/aws/cloud_watch.rb +5 -2
- data/lib/pwn/aws/cloud_watch_events.rb +5 -2
- data/lib/pwn/aws/cloud_watch_logs.rb +5 -2
- data/lib/pwn/aws/code_build.rb +5 -2
- data/lib/pwn/aws/code_commit.rb +5 -2
- data/lib/pwn/aws/code_deploy.rb +5 -2
- data/lib/pwn/aws/code_pipeline.rb +5 -2
- data/lib/pwn/aws/cognito_identity.rb +5 -2
- data/lib/pwn/aws/cognito_identity_provider.rb +5 -2
- data/lib/pwn/aws/cognito_sync.rb +5 -2
- data/lib/pwn/aws/config_service.rb +5 -2
- data/lib/pwn/aws/data_pipleline.rb +5 -2
- data/lib/pwn/aws/database_migration_service.rb +5 -2
- data/lib/pwn/aws/device_farm.rb +5 -2
- data/lib/pwn/aws/direct_connect.rb +5 -2
- data/lib/pwn/aws/directory_service.rb +5 -2
- data/lib/pwn/aws/dynamo_db.rb +5 -2
- data/lib/pwn/aws/dynamo_db_streams.rb +5 -2
- data/lib/pwn/aws/ec2.rb +5 -2
- data/lib/pwn/aws/ecr.rb +5 -2
- data/lib/pwn/aws/ecs.rb +5 -2
- data/lib/pwn/aws/efs.rb +5 -2
- data/lib/pwn/aws/elasti_cache.rb +5 -2
- data/lib/pwn/aws/elastic_beanstalk.rb +8 -5
- data/lib/pwn/aws/elastic_load_balancing.rb +5 -2
- data/lib/pwn/aws/elastic_load_balancing_v2.rb +6 -3
- data/lib/pwn/aws/elastic_transcoder.rb +5 -2
- data/lib/pwn/aws/elasticsearch_service.rb +5 -2
- data/lib/pwn/aws/emr.rb +5 -2
- data/lib/pwn/aws/firehose.rb +5 -2
- data/lib/pwn/aws/game_lift.rb +5 -2
- data/lib/pwn/aws/glacier.rb +6 -3
- data/lib/pwn/aws/health.rb +5 -2
- data/lib/pwn/aws/iam.rb +10 -4
- data/lib/pwn/aws/import_export.rb +5 -2
- data/lib/pwn/aws/inspector.rb +5 -2
- data/lib/pwn/aws/iot.rb +5 -2
- data/lib/pwn/aws/iot_data_plane.rb +5 -2
- data/lib/pwn/aws/kinesis.rb +5 -2
- data/lib/pwn/aws/kinesis_analytics.rb +5 -2
- data/lib/pwn/aws/kms.rb +5 -2
- data/lib/pwn/aws/lambda.rb +5 -2
- data/lib/pwn/aws/lambda_preview.rb +5 -2
- data/lib/pwn/aws/lex.rb +5 -2
- data/lib/pwn/aws/lightsail.rb +5 -2
- data/lib/pwn/aws/machine_learning.rb +5 -2
- data/lib/pwn/aws/marketplace_commerce_analytics.rb +5 -2
- data/lib/pwn/aws/marketplace_metering.rb +5 -2
- data/lib/pwn/aws/ops_works.rb +5 -2
- data/lib/pwn/aws/ops_works_cm.rb +5 -2
- data/lib/pwn/aws/pinpoint.rb +5 -2
- data/lib/pwn/aws/polly.rb +5 -2
- data/lib/pwn/aws/rds.rb +5 -2
- data/lib/pwn/aws/redshift.rb +5 -2
- data/lib/pwn/aws/rekognition.rb +5 -2
- data/lib/pwn/aws/route53.rb +5 -2
- data/lib/pwn/aws/route53_domains.rb +5 -2
- data/lib/pwn/aws/s3.rb +5 -2
- data/lib/pwn/aws/service_catalog.rb +5 -2
- data/lib/pwn/aws/ses.rb +5 -2
- data/lib/pwn/aws/shield.rb +5 -2
- data/lib/pwn/aws/simple_db.rb +5 -2
- data/lib/pwn/aws/sms.rb +5 -2
- data/lib/pwn/aws/snowball.rb +5 -2
- data/lib/pwn/aws/sns.rb +5 -2
- data/lib/pwn/aws/sqs.rb +5 -2
- data/lib/pwn/aws/ssm.rb +5 -2
- data/lib/pwn/aws/states.rb +5 -2
- data/lib/pwn/aws/storage_gateway.rb +5 -2
- data/lib/pwn/aws/sts.rb +4 -1
- data/lib/pwn/aws/support.rb +5 -2
- data/lib/pwn/aws/swf.rb +5 -2
- data/lib/pwn/aws/waf.rb +5 -2
- data/lib/pwn/aws/waf_regional.rb +5 -2
- data/lib/pwn/aws/workspaces.rb +5 -2
- data/lib/pwn/aws/x_ray.rb +5 -2
- data/lib/pwn/aws.rb +4 -0
- data/lib/pwn/banner/anon.rb +3 -0
- data/lib/pwn/banner/bubble.rb +3 -0
- data/lib/pwn/banner/cheshire.rb +3 -0
- data/lib/pwn/banner/code_cave.rb +3 -0
- data/lib/pwn/banner/dont_panic.rb +3 -0
- data/lib/pwn/banner/f_society.rb +3 -0
- data/lib/pwn/banner/fork_bomb.rb +3 -0
- data/lib/pwn/banner/jmp_esp.rb +3 -0
- data/lib/pwn/banner/matrix.rb +5 -1
- data/lib/pwn/banner/ninja.rb +3 -0
- data/lib/pwn/banner/off_the_air.rb +3 -0
- data/lib/pwn/banner/pirate.rb +3 -0
- data/lib/pwn/banner/radare2.rb +3 -0
- data/lib/pwn/banner/radare2_ai.rb +3 -0
- data/lib/pwn/banner/white_rabbit.rb +3 -0
- data/lib/pwn/banner.rb +6 -2
- data/lib/pwn/blockchain/btc.rb +8 -3
- data/lib/pwn/blockchain/eth.rb +10 -3
- data/lib/pwn/blockchain.rb +4 -0
- data/lib/pwn/bounty/lifecycle_authz_replay.rb +46 -27
- data/lib/pwn/bounty.rb +4 -0
- data/lib/pwn/config.rb +79 -13
- data/lib/pwn/cron.rb +297 -20
- data/lib/pwn/driver.rb +2 -18
- data/lib/pwn/ffi/adalm_pluto.rb +65 -11
- data/lib/pwn/ffi/fftw.rb +31 -6
- data/lib/pwn/ffi/hack_rf.rb +59 -8
- data/lib/pwn/ffi/liquid.rb +63 -10
- data/lib/pwn/ffi/rtl_sdr.rb +35 -5
- data/lib/pwn/ffi/soapy_sdr.rb +60 -10
- data/lib/pwn/ffi/stdio.rb +7 -8
- data/lib/pwn/ffi/volk.rb +36 -7
- data/lib/pwn/ffi.rb +12 -0
- data/lib/pwn/memory.rb +136 -16
- data/lib/pwn/memory_index.rb +34 -19
- data/lib/pwn/migrate.rb +34 -24
- data/lib/pwn/module_skills.rb +39 -8
- data/lib/pwn/plugins/aflplusplus.rb +72 -0
- data/lib/pwn/plugins/android.rb +71 -245
- data/lib/pwn/plugins/artifact_registry.rb +71 -0
- data/lib/pwn/plugins/assembly.rb +9 -4
- data/lib/pwn/plugins/authentication_helper.rb +8 -5
- data/lib/pwn/plugins/baresip.rb +59 -12
- data/lib/pwn/plugins/basic_auth.rb +9 -3
- data/lib/pwn/plugins/beef.rb +28 -18
- data/lib/pwn/plugins/binary_parser.rb +133 -0
- data/lib/pwn/plugins/black_duck_binary_analysis.rb +63 -39
- data/lib/pwn/plugins/burp_suite.rb +98 -68
- data/lib/pwn/plugins/bus_pirate.rb +15 -8
- data/lib/pwn/plugins/char.rb +33 -3
- data/lib/pwn/plugins/credential_attack.rb +158 -0
- data/lib/pwn/plugins/credit_card.rb +6 -1
- data/lib/pwn/plugins/dao_ldap.rb +19 -13
- data/lib/pwn/plugins/dao_mongo.rb +11 -5
- data/lib/pwn/plugins/dao_postgres.rb +28 -19
- data/lib/pwn/plugins/dao_sqlite3.rb +15 -6
- data/lib/pwn/plugins/defect_dojo.rb +38 -22
- data/lib/pwn/plugins/detect_os.rb +5 -0
- data/lib/pwn/plugins/ein.rb +3 -0
- data/lib/pwn/plugins/exploit_db.rb +69 -0
- data/lib/pwn/plugins/exploit_dev.rb +330 -0
- data/lib/pwn/plugins/file_fu.rb +11 -8
- data/lib/pwn/plugins/frida.rb +112 -0
- data/lib/pwn/plugins/fuzz.rb +42 -6
- data/lib/pwn/plugins/gdb.rb +115 -0
- data/lib/pwn/plugins/git.rb +19 -14
- data/lib/pwn/plugins/github.rb +38 -15
- data/lib/pwn/plugins/google_workspace.rb +188 -45
- data/lib/pwn/plugins/hacker_one.rb +159 -35
- data/lib/pwn/plugins/hunter.rb +6 -3
- data/lib/pwn/plugins/ip_info.rb +9 -4
- data/lib/pwn/plugins/irc.rb +28 -15
- data/lib/pwn/plugins/jenkins.rb +65 -57
- data/lib/pwn/plugins/jira_data_center.rb +30 -22
- data/lib/pwn/plugins/jobs.rb +110 -0
- data/lib/pwn/plugins/json_pathify.rb +9 -5
- data/lib/pwn/plugins/k8s.rb +73 -0
- data/lib/pwn/plugins/log.rb +113 -13
- data/lib/pwn/plugins/mail_agent.rb +87 -79
- data/lib/pwn/plugins/metasploit.rb +11 -6
- data/lib/pwn/plugins/monkey_patch.rb +3 -0
- data/lib/pwn/plugins/msr206.rb +42 -28
- data/lib/pwn/plugins/nessus_cloud.rb +44 -4
- data/lib/pwn/plugins/nexpose_vuln_scan.rb +40 -24
- data/lib/pwn/plugins/nmap_it.rb +14 -34
- data/lib/pwn/plugins/nuclei.rb +90 -0
- data/lib/pwn/plugins/oauth2.rb +11 -5
- data/lib/pwn/plugins/ocr.rb +3 -0
- data/lib/pwn/plugins/open_api.rb +5 -2
- data/lib/pwn/plugins/openvas.rb +33 -25
- data/lib/pwn/plugins/packet.rb +152 -31
- data/lib/pwn/plugins/pdf_parse.rb +5 -2
- data/lib/pwn/plugins/pony.rb +86 -1
- data/lib/pwn/plugins/preflight_checker.rb +166 -0
- data/lib/pwn/plugins/process_tube.rb +139 -0
- data/lib/pwn/plugins/ps.rb +7 -1
- data/lib/pwn/plugins/pwn_logger.rb +6 -2
- data/lib/pwn/plugins/rabbit_mq.rb +12 -7
- data/lib/pwn/plugins/radare2.rb +253 -0
- data/lib/pwn/plugins/recon.rb +196 -0
- data/lib/pwn/plugins/repl.rb +122 -1
- data/lib/pwn/plugins/scannable_codes.rb +5 -1
- data/lib/pwn/plugins/semgrep.rb +61 -0
- data/lib/pwn/plugins/serial.rb +24 -14
- data/lib/pwn/plugins/shodan.rb +54 -35
- data/lib/pwn/plugins/slack_client.rb +11 -6
- data/lib/pwn/plugins/sock.rb +17 -8
- data/lib/pwn/plugins/spider.rb +5 -2
- data/lib/pwn/plugins/sqlmap.rb +49 -0
- data/lib/pwn/plugins/ssn.rb +3 -0
- data/lib/pwn/plugins/thread_pool.rb +6 -9
- data/lib/pwn/plugins/tor.rb +9 -4
- data/lib/pwn/plugins/transparent_browser.rb +62 -107
- data/lib/pwn/plugins/tty_spinner.rb +16 -2
- data/lib/pwn/plugins/twitter_api.rb +6 -2
- data/lib/pwn/plugins/uri_scheme.rb +4 -1
- data/lib/pwn/plugins/vault.rb +12 -3
- data/lib/pwn/plugins/vin.rb +24 -12
- data/lib/pwn/plugins/voice.rb +7 -2
- data/lib/pwn/plugins/volatility.rb +67 -0
- data/lib/pwn/plugins/vsphere.rb +9 -5
- data/lib/pwn/plugins/xxd.rb +12 -43
- data/lib/pwn/plugins/zaproxy.rb +30 -16
- data/lib/pwn/plugins.rb +22 -0
- data/lib/pwn/reports/ai_red_team.rb +6 -2
- data/lib/pwn/reports/csv.rb +8 -1
- data/lib/pwn/reports/fuzz.rb +5 -2
- data/lib/pwn/reports/html.rb +8 -1
- data/lib/pwn/reports/html_footer.rb +4 -3
- data/lib/pwn/reports/html_header.rb +6 -2
- data/lib/pwn/reports/json.rb +8 -1
- data/lib/pwn/reports/markdown.rb +8 -1
- data/lib/pwn/reports/pdf.rb +8 -1
- data/lib/pwn/reports/phone.rb +5 -2
- data/lib/pwn/reports/sast.rb +6 -2
- data/lib/pwn/reports/uri_buster.rb +5 -2
- data/lib/pwn/reports/xml.rb +8 -1
- data/lib/pwn/reports.rb +19 -0
- data/lib/pwn/sast/amqp_connect_as_guest.rb +9 -3
- data/lib/pwn/sast/apache_file_system_util_api.rb +9 -3
- data/lib/pwn/sast/aws.rb +9 -3
- data/lib/pwn/sast/banned_function_calls_c.rb +9 -3
- data/lib/pwn/sast/base64.rb +9 -3
- data/lib/pwn/sast/beef_hook.rb +9 -3
- data/lib/pwn/sast/cmd_execution_go_lang.rb +9 -3
- data/lib/pwn/sast/cmd_execution_java.rb +9 -3
- data/lib/pwn/sast/cmd_execution_python.rb +9 -3
- data/lib/pwn/sast/cmd_execution_ruby.rb +9 -3
- data/lib/pwn/sast/cmd_execution_scala.rb +9 -3
- data/lib/pwn/sast/csrf.rb +9 -3
- data/lib/pwn/sast/deserial_java.rb +9 -3
- data/lib/pwn/sast/emoticon.rb +9 -3
- data/lib/pwn/sast/eval.rb +9 -3
- data/lib/pwn/sast/factory.rb +9 -3
- data/lib/pwn/sast/http_authorization_header.rb +9 -3
- data/lib/pwn/sast/inner_html.rb +9 -3
- data/lib/pwn/sast/keystore.rb +9 -3
- data/lib/pwn/sast/local_storage.rb +9 -3
- data/lib/pwn/sast/location_hash.rb +9 -3
- data/lib/pwn/sast/log4j.rb +9 -3
- data/lib/pwn/sast/logger.rb +9 -3
- data/lib/pwn/sast/md5.rb +9 -3
- data/lib/pwn/sast/outer_html.rb +9 -3
- data/lib/pwn/sast/padding_oracle.rb +9 -3
- data/lib/pwn/sast/password.rb +9 -3
- data/lib/pwn/sast/php_input_mechanisms.rb +9 -3
- data/lib/pwn/sast/php_type_juggling.rb +9 -3
- data/lib/pwn/sast/pom_version.rb +9 -3
- data/lib/pwn/sast/port.rb +9 -3
- data/lib/pwn/sast/post_message.rb +9 -3
- data/lib/pwn/sast/private_key.rb +9 -3
- data/lib/pwn/sast/redirect.rb +9 -3
- data/lib/pwn/sast/redos.rb +9 -3
- data/lib/pwn/sast/shell.rb +9 -3
- data/lib/pwn/sast/signature.rb +9 -3
- data/lib/pwn/sast/sql.rb +9 -3
- data/lib/pwn/sast/ssl.rb +9 -3
- data/lib/pwn/sast/sudo.rb +9 -3
- data/lib/pwn/sast/task_tag.rb +9 -3
- data/lib/pwn/sast/test_case_engine.rb +11 -7
- data/lib/pwn/sast/throw_errors.rb +9 -3
- data/lib/pwn/sast/token.rb +9 -3
- data/lib/pwn/sast/type_script_type_juggling.rb +9 -3
- data/lib/pwn/sast/use_after_free.rb +9 -3
- data/lib/pwn/sast/version.rb +9 -3
- data/lib/pwn/sast/window_location_hash.rb +9 -3
- data/lib/pwn/sast.rb +4 -0
- data/lib/pwn/sdr/decoder/adsb.rb +36 -5
- data/lib/pwn/sdr/decoder/apt.rb +9 -6
- data/lib/pwn/sdr/decoder/base.rb +74 -22
- data/lib/pwn/sdr/decoder/bluetooth.rb +17 -5
- data/lib/pwn/sdr/decoder/dect.rb +12 -3
- data/lib/pwn/sdr/decoder/dsp.rb +229 -39
- data/lib/pwn/sdr/decoder/flex.rb +59 -11
- data/lib/pwn/sdr/decoder/gps.rb +12 -3
- data/lib/pwn/sdr/decoder/gsm.rb +24 -4
- data/lib/pwn/sdr/decoder/iridium.rb +12 -3
- data/lib/pwn/sdr/decoder/lora.rb +13 -4
- data/lib/pwn/sdr/decoder/lte.rb +27 -3
- data/lib/pwn/sdr/decoder/morse.rb +12 -3
- data/lib/pwn/sdr/decoder/p25.rb +12 -3
- data/lib/pwn/sdr/decoder/pager.rb +8 -5
- data/lib/pwn/sdr/decoder/pocsag.rb +29 -9
- data/lib/pwn/sdr/decoder/rds.rb +14 -8
- data/lib/pwn/sdr/decoder/rfid.rb +12 -3
- data/lib/pwn/sdr/decoder/rtl433.rb +12 -3
- data/lib/pwn/sdr/decoder/rtty.rb +8 -5
- data/lib/pwn/sdr/decoder/wifi.rb +12 -3
- data/lib/pwn/sdr/decoder/zigbee.rb +12 -3
- data/lib/pwn/sdr/decoder.rb +9 -0
- data/lib/pwn/sdr/flipper_zero.rb +17 -10
- data/lib/pwn/sdr/frequency_allocation.rb +4 -1
- data/lib/pwn/sdr/gqrx.rb +178 -119
- data/lib/pwn/sdr/rfidler.rb +4 -1
- data/lib/pwn/sdr/son_micro_rfid.rb +37 -24
- data/lib/pwn/sdr.rb +14 -0
- data/lib/pwn/sessions.rb +86 -16
- data/lib/pwn/setup.rb +106 -37
- data/lib/pwn/version.rb +1 -1
- data/lib/pwn/www/app_cobalt_io.rb +11 -5
- data/lib/pwn/www/bing.rb +10 -5
- data/lib/pwn/www/bug_crowd.rb +11 -5
- data/lib/pwn/www/checkip.rb +8 -4
- data/lib/pwn/www/coinbase_pro.rb +11 -5
- data/lib/pwn/www/duckduckgo.rb +12 -6
- data/lib/pwn/www/facebook.rb +11 -5
- data/lib/pwn/www/github.rb +11 -5
- data/lib/pwn/www/google.rb +11 -5
- data/lib/pwn/www/hacker_one.rb +20 -9
- data/lib/pwn/www/linkedin.rb +11 -5
- data/lib/pwn/www/pandora.rb +11 -5
- data/lib/pwn/www/pastebin.rb +9 -4
- data/lib/pwn/www/paypal.rb +19 -11
- data/lib/pwn/www/synack.rb +11 -5
- data/lib/pwn/www/torch.rb +13 -8
- data/lib/pwn/www/trading_view.rb +11 -5
- data/lib/pwn/www/twitter.rb +11 -5
- data/lib/pwn/www/uber.rb +11 -5
- data/lib/pwn/www/upwork.rb +11 -5
- data/lib/pwn/www/wayback_machine.rb +12 -6
- data/lib/pwn/www/youtube.rb +10 -5
- data/lib/pwn/www.rb +4 -0
- data/spec/conventions_spec.rb +118 -2
- data/spec/integration/help_contract_spec.rb +2 -0
- data/spec/lib/pwn/ai/agent/reward_spec.rb +9 -0
- data/spec/lib/pwn/plugins/aflplusplus_spec.rb +13 -0
- data/spec/lib/pwn/plugins/artifact_registry_spec.rb +13 -0
- data/spec/lib/pwn/plugins/binary_parser_spec.rb +21 -0
- data/spec/lib/pwn/plugins/credential_attack_spec.rb +13 -0
- data/spec/lib/pwn/plugins/exploit_db_spec.rb +13 -0
- data/spec/lib/pwn/plugins/exploit_dev_spec.rb +23 -0
- data/spec/lib/pwn/plugins/frida_spec.rb +13 -0
- data/spec/lib/pwn/plugins/gdb_spec.rb +13 -0
- data/spec/lib/pwn/plugins/jobs_spec.rb +13 -0
- data/spec/lib/pwn/plugins/k8s_spec.rb +13 -0
- data/spec/lib/pwn/plugins/nuclei_spec.rb +13 -0
- data/spec/lib/pwn/plugins/preflight_checker_spec.rb +23 -0
- data/spec/lib/pwn/plugins/process_tube_spec.rb +13 -0
- data/spec/lib/pwn/plugins/radare2_spec.rb +13 -0
- data/spec/lib/pwn/plugins/recon_spec.rb +26 -0
- data/spec/lib/pwn/plugins/semgrep_spec.rb +13 -0
- data/spec/lib/pwn/plugins/sqlmap_spec.rb +13 -0
- data/spec/lib/pwn/plugins/volatility_spec.rb +13 -0
- data/spec/lib/pwn/req_queue_spec.rb +168 -0
- data/third_party/pwn_rdoc.jsonl +160 -5
- metadata +63 -7
- data/etc/default_skills/pwn/memory_index/references/urls.md +0 -4
- 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
|
data/lib/pwn/plugins/file_fu.rb
CHANGED
|
@@ -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. [
|
|
122
|
-
exclude_extensions: 'optional - array of file extensions to exclude from scan (e.g. [
|
|
123
|
-
)
|
|
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
|
|
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
|
data/lib/pwn/plugins/fuzz.rb
CHANGED
|
@@ -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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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:
|
|
192
|
-
request:
|
|
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
|