intrigue-ident 0.9.9 → 0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +3 -10
- data/Gemfile.lock +20 -35
- data/ident.rb +346 -0
- data/intrigue-ident.gemspec +7 -8
- data/lib/check_factory.rb +22 -0
- data/lib/checks/akamai.rb +22 -0
- data/lib/checks/amazon.rb +26 -0
- data/lib/checks/aruba.rb +20 -0
- data/lib/checks/asp_net.rb +70 -0
- data/lib/checks/atlassian.rb +55 -0
- data/lib/checks/base.rb +13 -0
- data/lib/checks/chef.rb +31 -0
- data/lib/checks/cisco.rb +33 -0
- data/lib/checks/citrix.rb +24 -0
- data/lib/checks/cloudflare.rb +59 -0
- data/lib/checks/cloudfront.rb +41 -0
- data/lib/checks/cpanel.rb +23 -0
- data/lib/checks/django.rb +22 -0
- data/lib/checks/drupal.rb +26 -0
- data/lib/checks/f5.rb +24 -0
- data/lib/checks/fastly.rb +22 -0
- data/lib/checks/generic.rb +23 -0
- data/lib/checks/gitlab.rb +22 -0
- data/lib/checks/google.rb +23 -0
- data/lib/checks/grafana.rb +22 -0
- data/lib/checks/jenkins.rb +40 -0
- data/lib/checks/joomla.rb +23 -0
- data/lib/checks/limesuvey.rb +22 -0
- data/lib/checks/lithium.rb +30 -0
- data/lib/checks/magento.rb +22 -0
- data/lib/checks/mcafee.rb +22 -0
- data/lib/checks/mediawiki.rb +38 -0
- data/lib/checks/microsoft.rb +69 -0
- data/lib/checks/nagios.rb +22 -0
- data/lib/checks/oracle.rb +38 -0
- data/lib/checks/palo_alto.rb +23 -0
- data/lib/checks/pardot.rb +22 -0
- data/lib/checks/pfsense.rb +25 -0
- data/lib/checks/phpmyadmin.rb +22 -0
- data/lib/checks/rabbitmq.rb +29 -0
- data/lib/checks/spring.rb +31 -0
- data/lib/checks/team_city.rb +22 -0
- data/lib/checks/telerik.rb +25 -0
- data/lib/checks/tomcat.rb +22 -0
- data/lib/checks/varnish.rb +27 -0
- data/lib/checks/wordpress.rb +120 -0
- data/lib/checks/wp_engine.rb +22 -0
- metadata +55 -487
- data/.circleci/config.yml +0 -21
- data/.gitignore +0 -3
- data/.ruby-version +0 -1
- data/Dockerfile +0 -39
- data/LICENSE.md +0 -12
- data/README.md +0 -79
- data/checks/ftp/base.rb +0 -15
- data/checks/ftp/filezilla.rb +0 -28
- data/checks/ftp/microsoft.rb +0 -27
- data/checks/ftp/proftp.rb +0 -28
- data/checks/ftp/pureftpd.rb +0 -27
- data/checks/ftp/vsftp.rb +0 -28
- data/checks/http/123reg.rb +0 -31
- data/checks/http/acme.rb +0 -28
- data/checks/http/acquia.rb +0 -28
- data/checks/http/adeptia.rb +0 -30
- data/checks/http/adobe.rb +0 -168
- data/checks/http/advantshop.rb +0 -33
- data/checks/http/afrihost.rb +0 -29
- data/checks/http/aftermarketpl.rb +0 -46
- data/checks/http/agility.rb +0 -34
- data/checks/http/akamai.rb +0 -88
- data/checks/http/alkacon.rb +0 -30
- data/checks/http/allegro.rb +0 -28
- data/checks/http/almuba.rb +0 -30
- data/checks/http/amazon.rb +0 -263
- data/checks/http/amirocms.rb +0 -30
- data/checks/http/anelectron.rb +0 -29
- data/checks/http/anquanbao.rb +0 -32
- data/checks/http/aol.rb +0 -29
- data/checks/http/apache.rb +0 -358
- data/checks/http/appdynamics.rb +0 -43
- data/checks/http/arris.rb +0 -30
- data/checks/http/artifactory.rb +0 -30
- data/checks/http/aruba.rb +0 -27
- data/checks/http/atlassian.rb +0 -152
- data/checks/http/auth0.rb +0 -44
- data/checks/http/automattic.rb +0 -292
- data/checks/http/axinom.rb +0 -30
- data/checks/http/axios.rb +0 -29
- data/checks/http/axis.rb +0 -27
- data/checks/http/axway.rb +0 -33
- data/checks/http/backdrop.rb +0 -30
- data/checks/http/banu.rb +0 -30
- data/checks/http/barracuda.rb +0 -99
- data/checks/http/base.rb +0 -139
- data/checks/http/beehive.rb +0 -30
- data/checks/http/bigcartel.rb +0 -33
- data/checks/http/bigcommerce.rb +0 -33
- data/checks/http/binarysec.rb +0 -47
- data/checks/http/bitly.rb +0 -40
- data/checks/http/blackboard.rb +0 -44
- data/checks/http/blueimp.rb +0 -27
- data/checks/http/bomgar.rb +0 -27
- data/checks/http/bootstrap.rb +0 -27
- data/checks/http/bower.rb +0 -28
- data/checks/http/broadcom.rb +0 -29
- data/checks/http/brocade.rb +0 -39
- data/checks/http/browsermedia.rb +0 -29
- data/checks/http/bsm.rb +0 -29
- data/checks/http/bynder.rb +0 -31
- data/checks/http/calibre.rb +0 -33
- data/checks/http/centos.rb +0 -28
- data/checks/http/cerberus.rb +0 -28
- data/checks/http/charity_engine.rb +0 -27
- data/checks/http/checkpoint.rb +0 -56
- data/checks/http/cherokee.rb +0 -29
- data/checks/http/cisco.rb +0 -134
- data/checks/http/citrix.rb +0 -137
- data/checks/http/cloud_city.rb +0 -30
- data/checks/http/cloudflare.rb +0 -219
- data/checks/http/cmsimple.rb +0 -30
- data/checks/http/codeigniter.rb +0 -26
- data/checks/http/communigate.rb +0 -32
- data/checks/http/concrete5.rb +0 -30
- data/checks/http/contenido.rb +0 -33
- data/checks/http/content/analytics.rb +0 -40
- data/checks/http/content/authentication.rb +0 -111
- data/checks/http/content/content.rb +0 -92
- data/checks/http/content/security_headers.rb +0 -70
- data/checks/http/cpanel.rb +0 -56
- data/checks/http/cradlepoint.rb +0 -30
- data/checks/http/craft.rb +0 -42
- data/checks/http/crazydomains.rb +0 -31
- data/checks/http/crowdstrike.rb +0 -27
- data/checks/http/dan.rb +0 -30
- data/checks/http/danneo.rb +0 -30
- data/checks/http/day.rb +0 -31
- data/checks/http/debian.rb +0 -27
- data/checks/http/dell.rb +0 -43
- data/checks/http/dev_php.rb +0 -30
- data/checks/http/discourse.rb +0 -30
- data/checks/http/discuz!.rb +0 -30
- data/checks/http/distil.rb +0 -27
- data/checks/http/django.rb +0 -27
- data/checks/http/dmanager.rb +0 -29
- data/checks/http/dns_made_easy.rb +0 -29
- data/checks/http/docuwiki.rb +0 -27
- data/checks/http/docverify.rb +0 -29
- data/checks/http/domain_parking_ru.rb +0 -31
- data/checks/http/domainname_shop.rb +0 -30
- data/checks/http/dosarrest.rb +0 -29
- data/checks/http/dreamhost.rb +0 -31
- data/checks/http/drupal.rb +0 -91
- data/checks/http/duo.rb +0 -45
- data/checks/http/dyn.rb +0 -41
- data/checks/http/dynamicweb.rb +0 -29
- data/checks/http/dynatrace.rb +0 -40
- data/checks/http/easyname.rb +0 -44
- data/checks/http/eclipse.rb +0 -64
- data/checks/http/enservio.rb +0 -29
- data/checks/http/envoy.rb +0 -26
- data/checks/http/epiccom.rb +0 -31
- data/checks/http/ergon.rb +0 -31
- data/checks/http/expressjs.rb +0 -27
- data/checks/http/ezproxy.rb +0 -28
- data/checks/http/f5.rb +0 -122
- data/checks/http/facebook.rb +0 -27
- data/checks/http/fastly.rb +0 -67
- data/checks/http/first_domains.rb +0 -31
- data/checks/http/flywheel.rb +0 -30
- data/checks/http/forgerock.rb +0 -43
- data/checks/http/fortinet.rb +0 -29
- data/checks/http/fresh_service.rb +0 -30
- data/checks/http/frontify.rb +0 -29
- data/checks/http/generic.rb +0 -272
- data/checks/http/github.rb +0 -40
- data/checks/http/gitlab.rb +0 -30
- data/checks/http/glimpse.rb +0 -32
- data/checks/http/globalscape.rb +0 -27
- data/checks/http/goahead.rb +0 -31
- data/checks/http/godaddy.rb +0 -31
- data/checks/http/google.rb +0 -164
- data/checks/http/google_cloud.rb +0 -27
- data/checks/http/grafana.rb +0 -27
- data/checks/http/gunicorn.rb +0 -30
- data/checks/http/haskell.rb +0 -31
- data/checks/http/heroku.rb +0 -77
- data/checks/http/hikvision.rb +0 -29
- data/checks/http/hp.rb +0 -27
- data/checks/http/hubspot.rb +0 -104
- data/checks/http/ibm.rb +0 -182
- data/checks/http/icewarp.rb +0 -29
- data/checks/http/impresspages.rb +0 -30
- data/checks/http/imunify360.rb +0 -28
- data/checks/http/incapsula.rb +0 -54
- data/checks/http/ingram_micro.rb +0 -28
- data/checks/http/innovative_interfaces_inc.rb +0 -27
- data/checks/http/inside_sales.rb +0 -27
- data/checks/http/instra.rb +0 -61
- data/checks/http/intercom.rb +0 -27
- data/checks/http/ivanti.rb +0 -28
- data/checks/http/jamf.rb +0 -31
- data/checks/http/jekyll.rb +0 -31
- data/checks/http/jenkins.rb +0 -59
- data/checks/http/jetbrains.rb +0 -27
- data/checks/http/jetty.rb +0 -27
- data/checks/http/jforum.rb +0 -27
- data/checks/http/jitbit.rb +0 -30
- data/checks/http/jive.rb +0 -27
- data/checks/http/joomla.rb +0 -43
- data/checks/http/jquery.rb +0 -58
- data/checks/http/jupyter.rb +0 -28
- data/checks/http/kentico.rb +0 -27
- data/checks/http/kerio.rb +0 -34
- data/checks/http/kibana.rb +0 -56
- data/checks/http/kong.rb +0 -32
- data/checks/http/kubernetes.rb +0 -66
- data/checks/http/laravel.rb +0 -27
- data/checks/http/lastpass.rb +0 -27
- data/checks/http/lcn.rb +0 -27
- data/checks/http/leadpages.rb +0 -29
- data/checks/http/lighttpd.rb +0 -31
- data/checks/http/limelight_networks.rb +0 -43
- data/checks/http/limesuvey.rb +0 -27
- data/checks/http/link1.rb +0 -31
- data/checks/http/linksys.rb +0 -38
- data/checks/http/litespeed.rb +0 -29
- data/checks/http/lithium.rb +0 -43
- data/checks/http/lotus.rb +0 -55
- data/checks/http/magento.rb +0 -96
- data/checks/http/magnolia.rb +0 -27
- data/checks/http/mailchimp.rb +0 -27
- data/checks/http/manage_engine.rb +0 -27
- data/checks/http/markmonitor.rb +0 -27
- data/checks/http/mbf_bioscience.rb +0 -29
- data/checks/http/mcafee.rb +0 -27
- data/checks/http/media_temple.rb +0 -27
- data/checks/http/mediawiki.rb +0 -54
- data/checks/http/mhcsoftwareinc.rb +0 -29
- data/checks/http/microsoft.rb +0 -1325
- data/checks/http/mikrotik.rb +0 -44
- data/checks/http/modwsgi.rb +0 -30
- data/checks/http/mojolicious.rb +0 -32
- data/checks/http/moodle.rb +0 -28
- data/checks/http/mura.rb +0 -30
- data/checks/http/nagios.rb +0 -27
- data/checks/http/namesilo.rb +0 -31
- data/checks/http/nationbuilder.rb +0 -30
- data/checks/http/nec.rb +0 -32
- data/checks/http/netlify.rb +0 -40
- data/checks/http/netobjects_inc.rb +0 -30
- data/checks/http/netscape.rb +0 -29
- data/checks/http/neustar.rb +0 -29
- data/checks/http/new_relic.rb +0 -27
- data/checks/http/nexicom.rb +0 -44
- data/checks/http/nginx.rb +0 -82
- data/checks/http/nisource.rb +0 -29
- data/checks/http/nodejs.rb +0 -79
- data/checks/http/okta.rb +0 -53
- data/checks/http/ookla.rb +0 -28
- data/checks/http/openbsd.rb +0 -30
- data/checks/http/openresty.rb +0 -41
- data/checks/http/openscholar.rb +0 -27
- data/checks/http/opensolution.rb +0 -46
- data/checks/http/openssl.rb +0 -43
- data/checks/http/opentext.rb +0 -46
- data/checks/http/openvpn.rb +0 -27
- data/checks/http/opscode.rb +0 -43
- data/checks/http/oracle.rb +0 -335
- data/checks/http/orion_technology.rb +0 -30
- data/checks/http/ovh.rb +0 -46
- data/checks/http/palo_alto.rb +0 -27
- data/checks/http/pantheon.rb +0 -54
- data/checks/http/papercut.rb +0 -29
- data/checks/http/parallels.rb +0 -44
- data/checks/http/pardot.rb +0 -44
- data/checks/http/parkingcrew.rb +0 -47
- data/checks/http/pbworks.rb +0 -27
- data/checks/http/perfectsense.rb +0 -28
- data/checks/http/perl.rb +0 -62
- data/checks/http/pfsense.rb +0 -27
- data/checks/http/php.rb +0 -72
- data/checks/http/phpmyadmin.rb +0 -40
- data/checks/http/phpwind.rb +0 -30
- data/checks/http/phusion.rb +0 -59
- data/checks/http/ping_identity.rb +0 -28
- data/checks/http/pivotal_software.rb +0 -97
- data/checks/http/pjax.rb +0 -40
- data/checks/http/plesk.rb +0 -58
- data/checks/http/porkbun.rb +0 -31
- data/checks/http/progress.rb +0 -30
- data/checks/http/proofpoint.rb +0 -30
- data/checks/http/pulsesecure.rb +0 -91
- data/checks/http/python.rb +0 -30
- data/checks/http/qnap.rb +0 -43
- data/checks/http/qualys.rb +0 -69
- data/checks/http/rapid7.rb +0 -27
- data/checks/http/rbs.rb +0 -30
- data/checks/http/readmeio.rb +0 -28
- data/checks/http/red_hat.rb +0 -95
- data/checks/http/redmine.rb +0 -38
- data/checks/http/restlet.rb +0 -30
- data/checks/http/ritecms.rb +0 -30
- data/checks/http/roadiz.rb +0 -30
- data/checks/http/rock.rb +0 -30
- data/checks/http/rollbar.rb +0 -27
- data/checks/http/roundcube.rb +0 -42
- data/checks/http/ruby.rb +0 -92
- data/checks/http/ruckus_wireless.rb +0 -26
- data/checks/http/sailpoint.rb +0 -30
- data/checks/http/salesforce.rb +0 -28
- data/checks/http/sap.rb +0 -149
- data/checks/http/seamless_cms.rb +0 -30
- data/checks/http/securi.rb +0 -54
- data/checks/http/sedo.rb +0 -63
- data/checks/http/segment.rb +0 -27
- data/checks/http/sencha.rb +0 -31
- data/checks/http/sentry.rb +0 -27
- data/checks/http/serendipity.rb +0 -30
- data/checks/http/shopfactory.rb +0 -30
- data/checks/http/sip.rb +0 -29
- data/checks/http/sitecore.rb +0 -39
- data/checks/http/smartling.rb +0 -27
- data/checks/http/smf.rb +0 -30
- data/checks/http/snews.rb +0 -30
- data/checks/http/software_ag.rb +0 -47
- data/checks/http/soha.rb +0 -66
- data/checks/http/solarwinds.rb +0 -41
- data/checks/http/sonatype.rb +0 -43
- data/checks/http/sonicwall.rb +0 -63
- data/checks/http/sophos.rb +0 -40
- data/checks/http/southriver.rb +0 -43
- data/checks/http/splash.rb +0 -29
- data/checks/http/splunk.rb +0 -27
- data/checks/http/springfox.rb +0 -43
- data/checks/http/squarespace.rb +0 -41
- data/checks/http/stackpath.rb +0 -29
- data/checks/http/stibo_systems.rb +0 -35
- data/checks/http/subrion.rb +0 -29
- data/checks/http/symantec.rb +0 -27
- data/checks/http/synacor.rb +0 -26
- data/checks/http/tableau_software.rb +0 -42
- data/checks/http/telerik.rb +0 -46
- data/checks/http/tengine.rb +0 -29
- data/checks/http/tibco.rb +0 -57
- data/checks/http/townnews.rb +0 -33
- data/checks/http/tridium.rb +0 -28
- data/checks/http/twiki.rb +0 -27
- data/checks/http/typo3.rb +0 -27
- data/checks/http/uberflip.rb +0 -28
- data/checks/http/ucoz.rb +0 -31
- data/checks/http/umbraco.rb +0 -29
- data/checks/http/unbounce.rb +0 -28
- data/checks/http/united_domains.rb +0 -27
- data/checks/http/vanilla_forums.rb +0 -27
- data/checks/http/varnish.rb +0 -79
- data/checks/http/vbulletin.rb +0 -66
- data/checks/http/verizon.rb +0 -27
- data/checks/http/vmware.rb +0 -53
- data/checks/http/vue_js.rb +0 -27
- data/checks/http/webflow.rb +0 -44
- data/checks/http/webgui.rb +0 -30
- data/checks/http/webmin.rb +0 -44
- data/checks/http/webpagetest_project.rb +0 -30
- data/checks/http/wftpserver.rb +0 -28
- data/checks/http/wildfly.rb +0 -29
- data/checks/http/wix.rb +0 -28
- data/checks/http/woltlab_gmbh.rb +0 -30
- data/checks/http/wordpress/ithemes.rb +0 -50
- data/checks/http/wordpress/john_godley.rb +0 -29
- data/checks/http/wordpress/pixelcraft.rb +0 -31
- data/checks/http/wordpress/rocklobster.rb +0 -29
- data/checks/http/wordpress/team_heateor.rb +0 -31
- data/checks/http/wordpress/w3_total_cache.rb +0 -30
- data/checks/http/wordpress/wp_fastest_cache.rb +0 -30
- data/checks/http/wordpress/wp_super_cache.rb +0 -46
- data/checks/http/wordpress/wpbakery.rb +0 -30
- data/checks/http/world4you.rb +0 -46
- data/checks/http/wp_engine.rb +0 -57
- data/checks/http/xcms.rb +0 -30
- data/checks/http/xelion.rb +0 -27
- data/checks/http/xerox.rb +0 -27
- data/checks/http/xmb.rb +0 -30
- data/checks/http/xtec.rb +0 -30
- data/checks/http/yaf.rb +0 -30
- data/checks/http/yaws.rb +0 -30
- data/checks/http/yoast.rb +0 -31
- data/checks/http/zeit.rb +0 -30
- data/checks/http/zendesk.rb +0 -41
- data/checks/http/zengenti.rb +0 -30
- data/checks/http/zoho.rb +0 -69
- data/checks/http/zscaler.rb +0 -30
- data/checks/smtp/base.rb +0 -16
- data/checks/smtp/exim.rb +0 -30
- data/checks/snmp/base.rb +0 -15
- data/checks/snmp/cisco.rb +0 -59
- data/checks/ssh/array_networks.rb +0 -28
- data/checks/ssh/base.rb +0 -16
- data/checks/ssh/openssh.rb +0 -26
- data/checks/telnet/base.rb +0 -16
- data/checks/telnet/huawei.rb +0 -26
- data/data/logos/acquia.png +0 -0
- data/data/logos/amazon_cloudfront.png +0 -0
- data/data/logos/apache_coyote.png +0 -0
- data/data/logos/apache_tomcat.png +0 -0
- data/data/logos/atlassian_bamboo.png +0 -0
- data/data/logos/atlassian_bitbucket.png +0 -0
- data/data/logos/atlassian_confluence.png +0 -0
- data/data/logos/atlassian_crowd.png +0 -0
- data/data/logos/atlassian_crucible.png +0 -0
- data/data/logos/atlassian_fisheye.png +0 -0
- data/data/logos/atlassian_jira.png +0 -0
- data/data/logos/atlassian_sourcetree.png +0 -0
- data/data/logos/automattic_wordpress.png +0 -0
- data/data/logos/calibre.png +0 -0
- data/data/logos/cisco_ssl_vpn.png +0 -0
- data/data/logos/citrix_netscaler_gateway.png +0 -0
- data/data/logos/cloudflare_cdn.png +0 -0
- data/data/logos/drupal.png +0 -0
- data/data/logos/f5_big-ip.png +0 -0
- data/data/logos/f5_big-ip_apm.png +0 -0
- data/data/logos/fastly.png +0 -0
- data/data/logos/generic.png +0 -0
- data/data/logos/gitlab.png +0 -0
- data/data/logos/ibm_axway_securetransport.png +0 -0
- data/data/logos/lithium.png +0 -0
- data/data/logos/microsoft_asp.net.png +0 -0
- data/data/logos/microsoft_iis.png +0 -0
- data/data/logos/microsoft_outlook_web_access.png +0 -0
- data/data/logos/microsoft_sharepoint.png +0 -0
- data/data/logos/microtik_routeros.png +0 -0
- data/data/logos/mikrotik_routeros.png +0 -0
- data/data/logos/newrelic.png +0 -0
- data/data/logos/nginx.png +0 -0
- data/data/logos/okta.png +0 -0
- data/data/logos/oracle_glassfish.png +0 -0
- data/data/logos/oracle_java_application_server.png +0 -0
- data/data/logos/oracle_java_server_pages.png +0 -0
- data/data/logos/oracle_weblogic.png +0 -0
- data/data/logos/phpmyadmin.png +0 -0
- data/data/logos/tableau.png +0 -0
- data/data/logos/vmware_esxi.png +0 -0
- data/data/logos/vmware_horizon.png +0 -0
- data/data/logos/zendesk.png +0 -0
- data/data/logos/zimbra_server.png +0 -0
- data/data/microsoft_sharepoint_versions.csv +0 -224
- data/lib/banner_helpers.rb +0 -36
- data/lib/ftp/check_factory.rb +0 -24
- data/lib/ftp/content.rb +0 -13
- data/lib/ftp/ftp.rb +0 -52
- data/lib/ftp/matchers.rb +0 -26
- data/lib/http/browser.rb +0 -260
- data/lib/http/check_factory.rb +0 -47
- data/lib/http/content.rb +0 -45
- data/lib/http/http.rb +0 -463
- data/lib/http/matchers.rb +0 -132
- data/lib/ident.rb +0 -263
- data/lib/recog_wrapper.rb +0 -70
- data/lib/simple_socket.rb +0 -41
- data/lib/smtp/check_factory.rb +0 -24
- data/lib/smtp/content.rb +0 -13
- data/lib/smtp/matchers.rb +0 -28
- data/lib/smtp/smtp.rb +0 -53
- data/lib/snmp/check_factory.rb +0 -24
- data/lib/snmp/content.rb +0 -13
- data/lib/snmp/matchers.rb +0 -25
- data/lib/snmp/snmp.rb +0 -55
- data/lib/ssh/check_factory.rb +0 -24
- data/lib/ssh/content.rb +0 -13
- data/lib/ssh/matchers.rb +0 -26
- data/lib/ssh/ssh.rb +0 -52
- data/lib/telnet/check_factory.rb +0 -24
- data/lib/telnet/content.rb +0 -13
- data/lib/telnet/matchers.rb +0 -26
- data/lib/telnet/telnet.rb +0 -52
- data/lib/utils.rb +0 -19
- data/lib/version.rb +0 -3
- data/lib/vulndb_client.rb +0 -43
- data/util/console.rb +0 -9
- data/util/docker.sh +0 -2
- data/util/ident.rb +0 -375
- data/util/list_paths.rb +0 -12
- data/util/tags.rb +0 -36
- data/utils.rb +0 -19
data/lib/ftp/matchers.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module Intrigue
|
2
|
-
module Ident
|
3
|
-
module Ftp
|
4
|
-
module Matchers
|
5
|
-
|
6
|
-
require_relative 'ftp'
|
7
|
-
include Intrigue::Ident::Ftp
|
8
|
-
|
9
|
-
require_relative 'content'
|
10
|
-
include Intrigue::Ident::Ftp::Content
|
11
|
-
|
12
|
-
def match_ftp_response_hash(check,response_hash)
|
13
|
-
|
14
|
-
if check[:type] == "fingerprint"
|
15
|
-
if check[:match_type] == :content_banner
|
16
|
-
puts "Banner: #{_banner(response_hash)}"
|
17
|
-
match = _construct_match_response(check,response_hash) if (_banner(response_hash) =~ check[:match_content])
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/lib/http/browser.rb
DELETED
@@ -1,260 +0,0 @@
|
|
1
|
-
###
|
2
|
-
### Please note - these methods may be used inside task modules, or inside libraries within
|
3
|
-
### Intrigue. An attempt has been made to make them abstract enough to use anywhere inside the
|
4
|
-
### application, but they are primarily designed as helpers for tasks. This is why you'll see
|
5
|
-
### references to @task_result in these methods. We do need to check to make sure it's available before
|
6
|
-
### writing to it.
|
7
|
-
###
|
8
|
-
|
9
|
-
# This module exists for common web functionality - inside a web browser
|
10
|
-
module Intrigue
|
11
|
-
module Ident
|
12
|
-
module HttpBrowser
|
13
|
-
|
14
|
-
def ident_create_browser_session
|
15
|
-
|
16
|
-
# first check if we're allowed to create a session by the global config
|
17
|
-
return nil unless Intrigue::Config::GlobalConfig.config["browser_enabled"]
|
18
|
-
|
19
|
-
# start a new session
|
20
|
-
args = ['headless', 'disable-gpu', 'disable-dev-shm-usage',
|
21
|
-
'ignore-certificate-errors', 'disable-popup-blocking', 'disable-translate']
|
22
|
-
|
23
|
-
# configure the driver to run in headless mode
|
24
|
-
options = Selenium::WebDriver::Chrome::Options.new(args: args)
|
25
|
-
|
26
|
-
# create a driver
|
27
|
-
driver = Selenium::WebDriver.for :chrome, { options: options }
|
28
|
-
|
29
|
-
# set size
|
30
|
-
driver.manage.window.size = Selenium::WebDriver::Dimension.new(1280, 1024)
|
31
|
-
|
32
|
-
# set a default timeout
|
33
|
-
driver.manage.timeouts.implicit_wait = 20 # seconds
|
34
|
-
|
35
|
-
driver
|
36
|
-
end
|
37
|
-
|
38
|
-
def ident_destroy_browser_session(session)
|
39
|
-
|
40
|
-
return false unless session
|
41
|
-
|
42
|
-
# get the full group id (driver + browser)
|
43
|
-
begin
|
44
|
-
|
45
|
-
# HACK HACK HACK- get the chromedriver process before we quit
|
46
|
-
#driver_pid = session.driver.browser.instance_variable_get(:@service).instance_variable_get(:@process).pid
|
47
|
-
|
48
|
-
# attempt to quit gracefully...
|
49
|
-
session.close
|
50
|
-
|
51
|
-
#pgid = Process.getpgid(driver_pid)
|
52
|
-
|
53
|
-
# violent delights have violent ends
|
54
|
-
#Process.kill('KILL', -pgid )
|
55
|
-
#Process.kill('KILL', driver_pid )
|
56
|
-
rescue Selenium::WebDriver::Error::UnknownError => e
|
57
|
-
_log_error "Error trying to kill our browser session #{e}"
|
58
|
-
rescue Errno::ESRCH => e
|
59
|
-
# already dead
|
60
|
-
_log_error "Error trying to kill our browser session #{e}"
|
61
|
-
rescue Net::ReadTimeout => e
|
62
|
-
_log_error "Timed out trying to close our session.. #{e}"
|
63
|
-
end
|
64
|
-
|
65
|
-
true
|
66
|
-
end
|
67
|
-
|
68
|
-
def ident_safe_browser_action
|
69
|
-
begin
|
70
|
-
|
71
|
-
results = yield
|
72
|
-
|
73
|
-
rescue Errno::EMFILE => e
|
74
|
-
_log_error "Too many open files: #{e}" if @task_result
|
75
|
-
rescue Addressable::URI::InvalidURIError => e
|
76
|
-
_log_error "Invalid URI: #{e}" if @task_result
|
77
|
-
rescue Net::ReadTimeout => e
|
78
|
-
_log_error "Timed out, moving on" if @task_result
|
79
|
-
rescue Selenium::WebDriver::Error::WebDriverError => e
|
80
|
-
# skip simple errors where we're testing JS libs
|
81
|
-
unless ("#{e}" =~ /is not defined/ || "#{e}" =~ /Cannot read property/)
|
82
|
-
_log_error "Webdriver issue #{e}" if @task_result
|
83
|
-
end
|
84
|
-
rescue Selenium::WebDriver::Error::NoSuchWindowError => e
|
85
|
-
_log_error "Lost our window #{e}" if @task_result
|
86
|
-
rescue Selenium::WebDriver::Error::UnknownError => e
|
87
|
-
# skip simple errors where we're testing JS libs
|
88
|
-
unless ("#{e}" =~ /is not defined/ || "#{e}" =~ /Cannot read property/)
|
89
|
-
_log_error "#{e}" if @task_result
|
90
|
-
end
|
91
|
-
rescue Selenium::WebDriver::Error::UnhandledAlertError => e
|
92
|
-
_log_error "Unhandled alert open: #{e}" if @task_result
|
93
|
-
rescue Selenium::WebDriver::Error::NoSuchElementError
|
94
|
-
_log_error "No such element #{e}, moving on" if @task_result
|
95
|
-
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
96
|
-
_log_error "No such element ref #{e}, moving on" if @task_result
|
97
|
-
end
|
98
|
-
results
|
99
|
-
end
|
100
|
-
|
101
|
-
def ident_capture_document(session, uri)
|
102
|
-
return nil unless session # always make sure the session is real
|
103
|
-
|
104
|
-
# browse to our target
|
105
|
-
safe_browser_action do
|
106
|
-
# visit the page
|
107
|
-
session.navigate.to(uri)
|
108
|
-
# Capture Title
|
109
|
-
page_title = session.title
|
110
|
-
# Capture Body Text
|
111
|
-
page_contents = session.page_source
|
112
|
-
# Capture DOM
|
113
|
-
rendered_page = session.execute_script("return document.documentElement.innerHTML")
|
114
|
-
|
115
|
-
# return our hash
|
116
|
-
return { :title => page_title, :contents => page_contents, :rendered => rendered_page }
|
117
|
-
end
|
118
|
-
nil
|
119
|
-
end
|
120
|
-
|
121
|
-
def ident_capture_screenshot(session, uri)
|
122
|
-
return nil unless session # always make sure the session is real
|
123
|
-
|
124
|
-
# browse to our target
|
125
|
-
safe_browser_action do
|
126
|
-
session.navigate.to(uri)
|
127
|
-
end
|
128
|
-
|
129
|
-
#
|
130
|
-
# Capture a screenshot
|
131
|
-
#
|
132
|
-
base64_image_contents = nil
|
133
|
-
safe_browser_action do
|
134
|
-
tempfile = Tempfile.new(['screenshot', '.png'])
|
135
|
-
session.save_screenshot(tempfile.path)
|
136
|
-
_log "Saved Screenshot to #{tempfile.path}"
|
137
|
-
# open and read the file's contents, and base64 encode them
|
138
|
-
base64_image_contents = Base64.encode64(File.read(tempfile.path))
|
139
|
-
# cleanup
|
140
|
-
tempfile.close
|
141
|
-
tempfile.unlink
|
142
|
-
end
|
143
|
-
|
144
|
-
base64_image_contents
|
145
|
-
end
|
146
|
-
|
147
|
-
def ident_gather_javascript_libraries(session, uri)
|
148
|
-
return nil unless session # always make sure the session is real
|
149
|
-
|
150
|
-
# Test site: https://www.jetblue.com/plan-a-trip/#/
|
151
|
-
# Examples: https://builtwith.angularjs.org/
|
152
|
-
# Examples: https://www.madewithangular.com/
|
153
|
-
|
154
|
-
safe_browser_action do
|
155
|
-
session.navigate.to(uri)
|
156
|
-
end
|
157
|
-
|
158
|
-
libraries = []
|
159
|
-
|
160
|
-
checks = [
|
161
|
-
{ library: "Angular", script: 'angular.version.full' },
|
162
|
-
# Backbone
|
163
|
-
# Test site: https://app.casefriend.com/
|
164
|
-
# Examples: https://github.com/jashkenas/backbone/wiki/projects-and-companies-using-backbone
|
165
|
-
{ library: "Backbone", script: 'Backbone.VERSION' },
|
166
|
-
# D3
|
167
|
-
# Test site: https://d3js.org/
|
168
|
-
# Examples: https://kartoweb.itc.nl/kobben/D3tests/index.html
|
169
|
-
{ library: "D3", script: 'd3.version' },
|
170
|
-
# Dojo
|
171
|
-
# Test site: http://demos.dojotoolkit.org/demos/mobileCharting/demo.html
|
172
|
-
# Examples: http://demos.dojotoolkit.org/demos/
|
173
|
-
{ library: "Dojo", script: 'dojo.version' },
|
174
|
-
# Ember
|
175
|
-
# Test site: https://secure.ally.com/
|
176
|
-
# Examples: http://builtwithember.io/
|
177
|
-
{ library: "Ember", script: 'Ember.VERSION' },
|
178
|
-
|
179
|
-
# Honeybadger
|
180
|
-
{ library: "Honeybadger", script: 'Honeybadger.getVersion()' },
|
181
|
-
|
182
|
-
# Intercom
|
183
|
-
# Examples: https://bugcrowd.com
|
184
|
-
{ library: "Intercom", script: 'Intercom("version")' },
|
185
|
-
|
186
|
-
# Jquery
|
187
|
-
# Test site: http://www.eddiebauer.com/
|
188
|
-
# Test site: https://www.underarmour.com
|
189
|
-
{ library: "jQuery", script: 'jQuery.fn.jquery' },
|
190
|
-
# Jquery tools
|
191
|
-
# Test site: http://www.eddiebauer.com/
|
192
|
-
{ library: "jQuery Tools", script: 'jQuery.tools.version' },
|
193
|
-
# Jquery UI
|
194
|
-
# Test site: http://www.eddiebauer.com/
|
195
|
-
# Test site: https://www.underarmour.com
|
196
|
-
{ library: "jQuery UI", script: 'jQuery.ui.version' },
|
197
|
-
|
198
|
-
# Test site:
|
199
|
-
# Examples: http://knockoutjs.com/examples/
|
200
|
-
#version = session.evaluate_script('knockout.version')
|
201
|
-
# { :product => "Knockout", check: 'knockout.version' }
|
202
|
-
|
203
|
-
# Modernizr
|
204
|
-
{ library: "Modernizr", script: 'Modernizr._version' },
|
205
|
-
|
206
|
-
# Paper.js
|
207
|
-
# Test site: http://paperjs.org/examples/boolean-operations
|
208
|
-
# Examples: http://paperjs.org/examples
|
209
|
-
|
210
|
-
# Prototype
|
211
|
-
# Test site:
|
212
|
-
# Examples:
|
213
|
-
# version = session.evaluate_script('Prototype.version')
|
214
|
-
# { product: "Prototype", check: 'Prototype.version' },
|
215
|
-
|
216
|
-
{ library: "Paper", script: 'paper.version' },
|
217
|
-
|
218
|
-
# React
|
219
|
-
# Test site: https://weather.com/
|
220
|
-
# Examples: https://react.rocks/
|
221
|
-
{ library: "React", script: 'React.version' },
|
222
|
-
|
223
|
-
# RequireJS
|
224
|
-
# Test site: https://www.homedepot.com
|
225
|
-
{ library: "RequireJS", script: 'requirejs.version' },
|
226
|
-
|
227
|
-
# Underscore
|
228
|
-
# Test site: https://app.casefriend.com/#sessions/login
|
229
|
-
# Test site: https://store.dji.com/
|
230
|
-
{ library: "Underscore", script: '_.VERSION' },
|
231
|
-
|
232
|
-
# YUI
|
233
|
-
# Test site: https://yuilibrary.com/yui/docs/event/basic-example.html
|
234
|
-
# Examples: https://yuilibrary.com/yui/docs/examples/
|
235
|
-
{ library: "YUI", script: 'YUI().version' }
|
236
|
-
]
|
237
|
-
|
238
|
-
checks.each do |check|
|
239
|
-
|
240
|
-
hacky_javascript = "return #{check[:script]};"
|
241
|
-
|
242
|
-
# run our script in a browser
|
243
|
-
version = safe_browser_action do
|
244
|
-
session.execute_script(hacky_javascript)
|
245
|
-
end
|
246
|
-
|
247
|
-
if version
|
248
|
-
_log_good "Detected #{check[:library]} #{version}" if @task_result
|
249
|
-
libraries << {"library" => "#{check[:library]}", "version" => "#{version}" }
|
250
|
-
end
|
251
|
-
|
252
|
-
end
|
253
|
-
|
254
|
-
libraries
|
255
|
-
end
|
256
|
-
|
257
|
-
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
data/lib/http/check_factory.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
module Intrigue
|
2
|
-
module Ident
|
3
|
-
module Http
|
4
|
-
class CheckFactory
|
5
|
-
|
6
|
-
#
|
7
|
-
# Register a new handler
|
8
|
-
#
|
9
|
-
def self.register(klass)
|
10
|
-
@checks = [] unless @checks
|
11
|
-
@checks << klass if klass
|
12
|
-
end
|
13
|
-
|
14
|
-
#
|
15
|
-
# Provide the full list of checks
|
16
|
-
#
|
17
|
-
def self.checks
|
18
|
-
@checks
|
19
|
-
end
|
20
|
-
|
21
|
-
#
|
22
|
-
# Provide the full list of checks
|
23
|
-
#
|
24
|
-
def self.generate_initial_checks(url)
|
25
|
-
@checks.map{ |x| x.new.generate_checks("#{url}") }.flatten.compact.select{|x| x[:require_product] == nil }
|
26
|
-
end
|
27
|
-
|
28
|
-
#
|
29
|
-
# Provide the full list of checks
|
30
|
-
#
|
31
|
-
def self.generate_checks_for_product(url,product)
|
32
|
-
@checks.map{ |x| x.new.generate_checks("#{url}") }.flatten.compact.select{|x| x[:require_product] == "#{product}" }
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
# Provide the full list of checks
|
38
|
-
#
|
39
|
-
def self.configuration_checks
|
40
|
-
@checks.map{ |x| x.new.generate_checks("") }.flatten.compact.select{|x| x[:type] == "content" }
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
data/lib/http/content.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
module Intrigue
|
2
|
-
module Ident
|
3
|
-
module Content
|
4
|
-
module Http
|
5
|
-
|
6
|
-
def _body(content)
|
7
|
-
_body_rendered(content) || _body_raw(content)
|
8
|
-
end
|
9
|
-
|
10
|
-
def _body_raw(content)
|
11
|
-
content["details"]["hidden_response_data"]
|
12
|
-
end
|
13
|
-
|
14
|
-
def _body_rendered(content)
|
15
|
-
content["details"]["hidden_response_data_rendered"]
|
16
|
-
end
|
17
|
-
|
18
|
-
def _body_raw_checksum(content)
|
19
|
-
Digest::MD5.hexdigest("#{_body_raw(content)}")
|
20
|
-
end
|
21
|
-
|
22
|
-
def _body_rendered_checksum(content)
|
23
|
-
Digest::MD5.hexdigest("#{_body_rendered(content)}")
|
24
|
-
end
|
25
|
-
|
26
|
-
def _generator(content)
|
27
|
-
content["details"]["generator"]
|
28
|
-
end
|
29
|
-
|
30
|
-
def _title(content)
|
31
|
-
content["details"]["title"]
|
32
|
-
end
|
33
|
-
|
34
|
-
def _headers(content)
|
35
|
-
(content["details"]["headers"] || []).join("\n")
|
36
|
-
end
|
37
|
-
|
38
|
-
def _cookies(content)
|
39
|
-
content["details"]["cookies"]
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/lib/http/http.rb
DELETED
@@ -1,463 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Intrigue
|
4
|
-
module Ident
|
5
|
-
module Http
|
6
|
-
|
7
|
-
require_relative 'browser'
|
8
|
-
include Intrigue::Ident::HttpBrowser
|
9
|
-
|
10
|
-
# gives us the recog http matchers
|
11
|
-
include Intrigue::Ident::RecogWrapper::Http
|
12
|
-
|
13
|
-
# Used by intrigue-core... note that this will currently fail unless
|
14
|
-
def generate_http_requests_and_check(url, opts={})
|
15
|
-
|
16
|
-
dom_checks = opts[:enable_browser] || false
|
17
|
-
debug = opts[:debug] || false
|
18
|
-
only_base = opts[:'only-check-base-url']
|
19
|
-
|
20
|
-
# gather all fingeprints for each product
|
21
|
-
# this will look like an array of checks, each with a uri and a set of checks
|
22
|
-
initial_checks = Intrigue::Ident::Http::CheckFactory.generate_initial_checks("#{url}")
|
23
|
-
|
24
|
-
#####
|
25
|
-
##### Sanity check!
|
26
|
-
#####
|
27
|
-
failing_checks = initial_checks.select{|x| x if !x[:paths] }
|
28
|
-
if failing_checks.compact.count > 0
|
29
|
-
puts "FATAL! Unable to continue, the following checks are invalid, missing a path!"
|
30
|
-
puts failing_checks.inspect
|
31
|
-
return
|
32
|
-
end
|
33
|
-
|
34
|
-
###
|
35
|
-
### Initial Checks
|
36
|
-
###
|
37
|
-
|
38
|
-
# In order to ensure we check all urls associated with a check, we need to
|
39
|
-
# group them up by each path, which is annoying because they're stored in
|
40
|
-
# an array on each check. This line handles that. (take all the checks []
|
41
|
-
# with each of their paths [], flatten and group by them
|
42
|
-
initial_checks_by_path = initial_checks.map{|c| c[:paths].map{ |p|
|
43
|
-
c.merge({:unique_path => p})} }.flatten
|
44
|
-
|
45
|
-
# now we have them organized by a single path, group them up so we only
|
46
|
-
# have to make a single request per unique path
|
47
|
-
grouped_initial_checks = initial_checks_by_path.group_by{|x| x[:unique_path] }
|
48
|
-
|
49
|
-
# allow us to only select the base path (speeds things up)
|
50
|
-
if only_base
|
51
|
-
grouped_initial_checks = grouped_initial_checks.select{|x,y| x == url}
|
52
|
-
end
|
53
|
-
|
54
|
-
# Run'm!!!
|
55
|
-
initial_results = run_grouped_http_checks(url, grouped_initial_checks, dom_checks, debug)
|
56
|
-
|
57
|
-
###
|
58
|
-
### APPLY THE RECOG (ONLY FIRST PAGE)!
|
59
|
-
###
|
60
|
-
# now run recog against the current grab
|
61
|
-
recog_results = []
|
62
|
-
first_response = initial_results["responses"].first
|
63
|
-
if first_response
|
64
|
-
server_headers = first_response[:response_headers].select{|x| x =~ /^server:.*$/i }
|
65
|
-
if server_headers.count > 0
|
66
|
-
recog_results << recog_match_http_server_banner(server_headers.first)
|
67
|
-
end
|
68
|
-
|
69
|
-
cookies_headers = first_response[:response_headers].select{|x| x =~ /^set-cookie:.*$/i }
|
70
|
-
if cookies_headers.count > 0
|
71
|
-
recog_results << recog_match_http_cookies(cookies_headers.first)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
###
|
76
|
-
### Follow-on Checks
|
77
|
-
###
|
78
|
-
|
79
|
-
### Okay so, now we have a set of detected products, let's figure out our follown checks
|
80
|
-
followon_checks = []
|
81
|
-
detected_products = initial_results["fingerprint"].map{|x| x["product"] }.uniq
|
82
|
-
detected_products.each do |prod|
|
83
|
-
followon_checks.concat(Intrigue::Ident::Http::CheckFactory.generate_checks_for_product("#{url}", prod))
|
84
|
-
#puts "Getting checks for product: #{prod} ... #{followon_checks.count}" if debug
|
85
|
-
end
|
86
|
-
|
87
|
-
# group them up by path (there can be multiple paths)
|
88
|
-
followon_checks_by_path = followon_checks.map{|c| c[:paths].map{ |p|
|
89
|
-
c.merge({:unique_path => p})} }.flatten
|
90
|
-
|
91
|
-
# group'm as needed to run the checks
|
92
|
-
grouped_followon_checks = followon_checks_by_path.group_by{|x| x[:unique_path] }
|
93
|
-
|
94
|
-
# allow us to only select the base path (speeds things up)
|
95
|
-
if only_base
|
96
|
-
grouped_followon_checks = grouped_followon_checks.select{|x,y| x == url}
|
97
|
-
end
|
98
|
-
|
99
|
-
### OKAY NOW WE HAVE a set of output that we can run product-specific checks on, run'm
|
100
|
-
if grouped_followon_checks
|
101
|
-
followon_results = run_grouped_http_checks(url, grouped_followon_checks, dom_checks, debug)
|
102
|
-
else
|
103
|
-
followon_results = {
|
104
|
-
"fingerprint" => [],
|
105
|
-
"content" => [],
|
106
|
-
"responses" => [],
|
107
|
-
"check_count" => []
|
108
|
-
}
|
109
|
-
end
|
110
|
-
|
111
|
-
###
|
112
|
-
### Generate output
|
113
|
-
###
|
114
|
-
out = {
|
115
|
-
"url" => initial_results["url"], # same
|
116
|
-
"fingerprint" => (initial_results["fingerprint"] + followon_results["fingerprint"] + recog_results.flatten).uniq,
|
117
|
-
"content" => initial_results["content"].concat(followon_results["content"]),
|
118
|
-
"responses" => initial_results["responses"].concat(followon_results["responses"]),
|
119
|
-
"initial_checks" => initial_results["check_count"],
|
120
|
-
"followon_checks" => followon_results["check_count"]
|
121
|
-
}
|
122
|
-
|
123
|
-
out
|
124
|
-
end
|
125
|
-
|
126
|
-
private
|
127
|
-
|
128
|
-
def run_grouped_http_checks(url, grouped_generated_checks, dom_checks, debug)
|
129
|
-
|
130
|
-
# shove results into an array
|
131
|
-
results = []
|
132
|
-
|
133
|
-
# keep an array of the request / response details
|
134
|
-
responses = []
|
135
|
-
|
136
|
-
# keep track of timeouts
|
137
|
-
timeout_count = 0
|
138
|
-
|
139
|
-
# call the check on each uri
|
140
|
-
grouped_generated_checks.each do |ggc|
|
141
|
-
|
142
|
-
target_url = ggc.first
|
143
|
-
|
144
|
-
if timeout_count > 2
|
145
|
-
puts "Skipping #{target_url}, too many timeouts" if debug
|
146
|
-
next
|
147
|
-
end
|
148
|
-
|
149
|
-
# get the response using a normal http request
|
150
|
-
# TODO - collect redirects here
|
151
|
-
puts "Getting #{target_url}" if debug
|
152
|
-
response_hash = ident_http_request :get, "#{target_url}"
|
153
|
-
|
154
|
-
if response_hash[:timeout]
|
155
|
-
puts "ERROR timed out on #{target_url}" if debug
|
156
|
-
timeout_count += 1
|
157
|
-
end
|
158
|
-
|
159
|
-
responses << response_hash
|
160
|
-
|
161
|
-
# Only if we are running browser checks
|
162
|
-
if dom_checks
|
163
|
-
# get the dom via a browser
|
164
|
-
if ggc.last.map{|c| c[:match_type] }.include?(:content_dom)
|
165
|
-
#puts "We have a check for #{target_url} that requires the DOM, firing a browser"
|
166
|
-
session = ident_create_browser_session
|
167
|
-
browser_response = ident_capture_document(session,"#{target_url}")
|
168
|
-
|
169
|
-
# save the response to our list of responses
|
170
|
-
# TODO - collect redirects here
|
171
|
-
# https://michaeltroutt.com/using-headless-chrome-to-find-link-redirects/
|
172
|
-
responses << browser_response
|
173
|
-
|
174
|
-
ident_destroy_browser_session session
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
puts "matching" if debug
|
179
|
-
|
180
|
-
# Go ahead and match it up if we got a response!
|
181
|
-
if response_hash || browser_response
|
182
|
-
|
183
|
-
# call each check, collecting the product if it's a match
|
184
|
-
###
|
185
|
-
### APPLY THE IDENT!
|
186
|
-
###
|
187
|
-
ggc.last.each do |check|
|
188
|
-
|
189
|
-
# if we have a check that should match the dom, run it
|
190
|
-
if (check[:match_type] == :content_dom)
|
191
|
-
results << match_browser_response_hash(check,browser_response) if dom_checks
|
192
|
-
else #otherwise use the normal flow
|
193
|
-
results << match_http_response_hash(check,response_hash)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
return nil unless results
|
201
|
-
|
202
|
-
# Return all matches, minus the nils (non-matches), and grouped by check type
|
203
|
-
out = results.compact.group_by{|x| x["type"] }
|
204
|
-
|
205
|
-
# make sure we have an empty fingerprints array if we didnt' have any Matches
|
206
|
-
out["check_count"] = grouped_generated_checks.map{|x| {"url" => x.first, "count" => x.last.count } }
|
207
|
-
out["fingerprint"] = [] unless out["fingerprint"]
|
208
|
-
out["content"] = [] unless out["content"]
|
209
|
-
|
210
|
-
# only return unique results
|
211
|
-
out["fingerprint"] = out["fingerprint"].uniq
|
212
|
-
out["content"] = out["content"].uniq
|
213
|
-
out["url"] = url
|
214
|
-
|
215
|
-
# attach the responses
|
216
|
-
out["responses"] = responses
|
217
|
-
|
218
|
-
out
|
219
|
-
end
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
#require_relative 'content_helpers'
|
225
|
-
#include Intrigue::Ident::Content::HttpHelpers
|
226
|
-
|
227
|
-
def ident_encode(string)
|
228
|
-
string.force_encoding('ISO-8859-1').encode('UTF-8')
|
229
|
-
end
|
230
|
-
|
231
|
-
###
|
232
|
-
### XXX - significant updates made to zlib, determine whether to
|
233
|
-
### move this over to RestClient: https://github.com/ruby/ruby/commit/3cf7d1b57e3622430065f6a6ce8cbd5548d3d894
|
234
|
-
###
|
235
|
-
def ident_http_request(method, uri_string, credentials=nil, headers={}, data=nil, limit = 3, open_timeout=15, read_timeout=15)
|
236
|
-
|
237
|
-
response = nil
|
238
|
-
begin
|
239
|
-
|
240
|
-
# set user agent
|
241
|
-
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"
|
242
|
-
headers["User-Agent"] = user_agent
|
243
|
-
|
244
|
-
attempts=0
|
245
|
-
max_attempts=limit
|
246
|
-
found = false
|
247
|
-
timeout = false
|
248
|
-
|
249
|
-
uri = URI.parse uri_string
|
250
|
-
|
251
|
-
# keep track of redirects
|
252
|
-
response_urls = ["#{uri}"]
|
253
|
-
|
254
|
-
unless uri
|
255
|
-
_log error "Unable to parse URI from: #{uri_string}"
|
256
|
-
return
|
257
|
-
end
|
258
|
-
|
259
|
-
until( found || attempts >= max_attempts)
|
260
|
-
|
261
|
-
attempts+=1
|
262
|
-
|
263
|
-
if $global_config
|
264
|
-
if $global_config.config["http_proxy"]
|
265
|
-
proxy_config = $global_config.config["http_proxy"]
|
266
|
-
proxy_addr = $global_config.config["http_proxy"]["host"]
|
267
|
-
proxy_port = $global_config.config["http_proxy"]["port"]
|
268
|
-
proxy_user = $global_config.config["http_proxy"]["user"]
|
269
|
-
proxy_pass = $global_config.config["http_proxy"]["pass"]
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
# set options
|
274
|
-
opts = {}
|
275
|
-
if uri.instance_of? URI::HTTPS
|
276
|
-
opts[:use_ssl] = true
|
277
|
-
opts[:verify_mode] = OpenSSL::SSL::VERIFY_NONE
|
278
|
-
end
|
279
|
-
|
280
|
-
http = Net::HTTP.start(uri.host, uri.port, proxy_addr, proxy_port, opts)
|
281
|
-
http.open_timeout = open_timeout
|
282
|
-
http.read_timeout = read_timeout
|
283
|
-
|
284
|
-
path = "#{uri.path}"
|
285
|
-
path = "/" if path==""
|
286
|
-
|
287
|
-
# add in the query parameters
|
288
|
-
if uri.query
|
289
|
-
path += "?#{uri.query}"
|
290
|
-
end
|
291
|
-
|
292
|
-
### ALLOW DIFFERENT VERBS HERE
|
293
|
-
if method == :get
|
294
|
-
request = Net::HTTP::Get.new(uri)
|
295
|
-
elsif method == :post
|
296
|
-
# see: https://coderwall.com/p/c-mu-a/http-posts-in-ruby
|
297
|
-
request = Net::HTTP::Post.new(uri)
|
298
|
-
request.body = data
|
299
|
-
elsif method == :head
|
300
|
-
request = Net::HTTP::Head.new(uri)
|
301
|
-
elsif method == :propfind
|
302
|
-
request = Net::HTTP::Propfind.new(uri.request_uri)
|
303
|
-
request.body = "Here's the body." # Set your body (data)
|
304
|
-
request["Depth"] = "1" # Set your headers: one header per line.
|
305
|
-
elsif method == :options
|
306
|
-
request = Net::HTTP::Options.new(uri.request_uri)
|
307
|
-
elsif method == :trace
|
308
|
-
request = Net::HTTP::Trace.new(uri.request_uri)
|
309
|
-
request.body = "blah blah"
|
310
|
-
end
|
311
|
-
### END VERBS
|
312
|
-
|
313
|
-
# set the headers
|
314
|
-
headers.each do |k,v|
|
315
|
-
request[k] = v
|
316
|
-
end
|
317
|
-
|
318
|
-
# handle credentials
|
319
|
-
if credentials
|
320
|
-
request.basic_auth(credentials[:username],credentials[:password])
|
321
|
-
end
|
322
|
-
|
323
|
-
# USE THIS TO PRINT HTTP REQUEST
|
324
|
-
#request.each_header{|h| puts "#{h}: #{request[h]}" }
|
325
|
-
# END USE THIS TO PRINT HTTP REQUEST
|
326
|
-
|
327
|
-
# get the response
|
328
|
-
response = http.request(request)
|
329
|
-
|
330
|
-
###
|
331
|
-
### Handle redirects
|
332
|
-
###
|
333
|
-
location_header = response.header['location'] || response.header['Location']
|
334
|
-
if location_header != nil
|
335
|
-
# location header redirect
|
336
|
-
#puts "Following redirect: #{location_header}"
|
337
|
-
|
338
|
-
newuri=URI.parse(location_header)
|
339
|
-
|
340
|
-
# handle relative uri
|
341
|
-
if(newuri.relative?)
|
342
|
-
newuri=URI.parse("#{uri}#{location_header}")
|
343
|
-
end
|
344
|
-
|
345
|
-
response_urls << ident_encode(newuri.to_s)
|
346
|
-
uri=newuri
|
347
|
-
|
348
|
-
elsif response.body =~ /META HTTP-EQUIV=\"?Refresh/i # meta refresh
|
349
|
-
# meta refresh redirect
|
350
|
-
|
351
|
-
# get the URL
|
352
|
-
metaurl = URI.parse(response.body.scan(/META HTTP-EQUIV=Refresh CONTENT=.*; URL=(.*)"/i).first)
|
353
|
-
|
354
|
-
if metaurl
|
355
|
-
newuri = metaurl.first
|
356
|
-
else # unable to parse
|
357
|
-
puts "ERROR Unable to parse redirection!!"
|
358
|
-
found = true
|
359
|
-
break
|
360
|
-
end
|
361
|
-
|
362
|
-
# handle relative uri
|
363
|
-
if(newuri.relative?)
|
364
|
-
newuri=URI.parse("#{uri}/#{newuri}")
|
365
|
-
end
|
366
|
-
|
367
|
-
response_urls << ident_encode(newuri.to_s)
|
368
|
-
uri=newuri
|
369
|
-
|
370
|
-
else
|
371
|
-
|
372
|
-
found = true
|
373
|
-
break
|
374
|
-
|
375
|
-
end #end redirect handling
|
376
|
-
|
377
|
-
end #until
|
378
|
-
|
379
|
-
###
|
380
|
-
### Done Handling Redirects, proactively set final_url
|
381
|
-
###
|
382
|
-
final_url = uri.to_s
|
383
|
-
|
384
|
-
### TODO - create a global $debug config option
|
385
|
-
|
386
|
-
#rescue ArgumentError => e
|
387
|
-
#puts "Unable to connect #{uri}: #{e}"
|
388
|
-
rescue Net::OpenTimeout => e
|
389
|
-
#puts "Unable to connect #{uri}: #{e}"
|
390
|
-
timeout = true
|
391
|
-
rescue Net::ReadTimeout => e
|
392
|
-
#puts "Unable to connect #{uri}: #{e}"
|
393
|
-
timeout = true
|
394
|
-
rescue Errno::ENETDOWN => e
|
395
|
-
#puts "Unable to connect #{uri}: #{e}"
|
396
|
-
rescue Errno::ETIMEDOUT => e
|
397
|
-
#puts "Unable to connect #{uri}: #{e}"
|
398
|
-
timeout = true
|
399
|
-
rescue Errno::EINVAL => e
|
400
|
-
#puts "Unable to connect #{uri}: #{e}"
|
401
|
-
rescue Errno::ENETUNREACH => e
|
402
|
-
#puts "Unable to connect #{uri}: #{e}"
|
403
|
-
rescue Errno::EHOSTUNREACH => e
|
404
|
-
#puts "Unable to connect #{uri}: #{e}"
|
405
|
-
rescue URI::InvalidURIError => e
|
406
|
-
#
|
407
|
-
# XXX - This is an issue. We should catch this and ensure it's not
|
408
|
-
# due to an underscore / other acceptable character in the URI
|
409
|
-
# http://stackoverflow.com/questions/5208851/is-there-a-workaround-to-open-urls-containing-underscores-in-ruby
|
410
|
-
#
|
411
|
-
#puts "Unable to connect #{uri}: #{e}"
|
412
|
-
rescue OpenSSL::SSL::SSLError => e
|
413
|
-
#puts "Unable to connect #{uri}: #{e}"
|
414
|
-
rescue Errno::ECONNREFUSED => e
|
415
|
-
#puts "Unable to connect #{uri}: #{e}"
|
416
|
-
rescue Errno::ECONNRESET => e
|
417
|
-
#puts "Unable to connect #{uri}: #{e}"
|
418
|
-
rescue Net::HTTPBadResponse => e
|
419
|
-
#puts "Unable to connect #{uri}: #{e}"
|
420
|
-
rescue Zlib::BufError => e
|
421
|
-
#puts "Unable to connect #{uri}: #{e}"
|
422
|
-
rescue Zlib::DataError => e # "incorrect header check - may be specific to ruby 2.0"
|
423
|
-
#puts "Unable to connect #{uri}: #{e}"
|
424
|
-
rescue EOFError => e
|
425
|
-
#puts "Unable to connect #{uri}: #{e}"
|
426
|
-
rescue SocketError => e
|
427
|
-
#puts "Unable to connect #{uri}: #{e}"
|
428
|
-
rescue Encoding::InvalidByteSequenceError => e
|
429
|
-
#puts "Encoding issue #{uri}: #{e}"
|
430
|
-
rescue Encoding::UndefinedConversionError => e
|
431
|
-
#puts "Encoding issue #{uri}: #{e}"
|
432
|
-
end
|
433
|
-
|
434
|
-
# generate our output
|
435
|
-
out = {
|
436
|
-
:timeout => timeout,
|
437
|
-
:start_url => uri_string,
|
438
|
-
:final_url => final_url,
|
439
|
-
:request_type => :ruby,
|
440
|
-
:request_method => method,
|
441
|
-
:request_credentials => credentials,
|
442
|
-
:request_headers => headers,
|
443
|
-
:request_data => data,
|
444
|
-
:request_attempts_limit => limit,
|
445
|
-
:request_attempts_used => attempts,
|
446
|
-
:request_user_agent => user_agent,
|
447
|
-
:request_proxy => proxy_config,
|
448
|
-
:response_urls => response_urls,
|
449
|
-
:response_object => response
|
450
|
-
}
|
451
|
-
|
452
|
-
# verify we have a response before adding these
|
453
|
-
if response
|
454
|
-
out[:response_headers] = response.each_header.map{|x| ident_encode "#{x}: #{response[x]}" }
|
455
|
-
out[:response_body] = ident_encode(response.body)
|
456
|
-
end
|
457
|
-
|
458
|
-
out
|
459
|
-
end
|
460
|
-
|
461
|
-
end
|
462
|
-
end
|
463
|
-
end
|