Module: Aikido::Zen::AttackWave::Helpers

Defined in:
lib/aikido/zen/attack_wave/helpers.rb

Constant Summary collapse

SUSPICIOUS_METHODS =
[
  "BADMETHOD",
  "BADHTTPMETHOD",
  "BADDATA",
  "BADMTHD",
  "BDMTHD"
].map(&:downcase).freeze
SUSPICIOUS_DIRECTORY_NAMES =
[
  ".",
  "..",
  ".anydesk",
  ".aptitude",
  ".aws",
  ".azure",
  ".cache",
  ".circleci",
  ".config",
  ".dbus",
  ".docker",
  ".drush",
  ".TODO: gem",
  ".git",
  ".github",
  ".gnupg",
  ".gsutil",
  ".hg",
  ".idea",
  ".java",
  ".kube",
  ".lftp",
  ".minikube",
  ".npm",
  ".nvm",
  ".pki",
  ".snap",
  ".ssh",
  ".subversion",
  ".svn",
  ".tconn",
  ".thunderbird",
  ".tor",
  ".vagrant.d",
  ".vidalia",
  ".vim",
  ".vmware",
  ".vscode",
  "apache",
  "apache2",
  "grub",
  "System32",
  "tmp",
  "xampp",
  "cgi-bin",
  "%systemroot%"
].map(&:downcase).freeze
SUSPICIOUS_FILE_NAMES =
[
  ".addressbook",
  ".atom",
  ".bashrc",
  ".boto",
  ".config",
  ".config.json",
  ".config.xml",
  ".config.yaml",
  ".config.yml",
  ".envrc",
  ".eslintignore",
  ".fbcindex",
  ".forward",
  ".gitattributes",
  ".gitconfig",
  ".gitignore",
  ".gitkeep",
  ".gitlab-ci.yaml",
  ".gitlab-ci.yml",
  ".gitmodules",
  ".google_authenticator",
  ".hgignore",
  ".htaccess",
  ".htpasswd",
  ".htdigest",
  ".ksh_history",
  ".lesshst",
  ".lhistory",
  ".lighttpdpassword",
  ".lldb-history",
  ".lynx_cookies",
  ".my.cnf",
  ".mysql_history",
  ".nano_history",
  ".netrc",
  ".node_repl_history",
  ".npmrc",
  ".nsconfig",
  ".nsr",
  ".password-store",
  ".pearrc",
  ".pgpass",
  ".php_history",
  ".pinerc",
  ".proclog",
  ".procmailrc",
  ".profile",
  ".psql_history",
  ".python_history",
  ".rediscli_history",
  ".rhosts",
  ".selected_editor",
  ".sh_history",
  ".sqlite_history",
  ".svnignore",
  ".tcshrc",
  ".tmux.conf",
  ".travis.yaml",
  ".travis.yml",
  ".viminfo",
  ".vimrc",
  ".www_acl",
  ".wwwacl",
  ".xauthority",
  ".yarnrc",
  ".zhistory",
  ".zsh_history",
  ".zshenv",
  ".zshrc",
  "Dockerfile",
  "aws-key.yaml",
  "aws-key.yml",
  "aws.yaml",
  "aws.yml",
  "docker-compose.yaml",
  "docker-compose.yml",
  "npm-shrinkwrap.json",
  "package-lock.json",
  "package.json",
  "phpinfo.php",
  "wp-config.php",
  "wp-config.php3",
  "wp-config.php4",
  "wp-config.php5",
  "wp-config.phtml",
  "composer.json",
  "composer.lock",
  "composer.phar",
  "yarn.lock",
  ".env.local",
  ".env.development",
  ".env.test",
  ".env.production",
  ".env.prod",
  ".env.dev",
  ".env.example",
  "php.ini",
  "wp-settings.php",
  "config.asp",
  "config_dev.asp",
  "config-dev.asp",
  "config.dev.asp",
  "config_prod.asp",
  "config-prod.asp",
  "config.prod.asp",
  "config.sample.asp",
  "config-sample.asp",
  "config_sample.asp",
  "config_test.asp",
  "config-test.asp",
  "config.test.asp",
  "config.ini",
  "config_dev.ini",
  "config-dev.ini",
  "config.dev.ini",
  "config_prod.ini",
  "config-prod.ini",
  "config.prod.ini",
  "config.sample.ini",
  "config-sample.ini",
  "config_sample.ini",
  "config_test.ini",
  "config-test.ini",
  "config.test.ini",
  "config.json",
  "config_dev.json",
  "config-dev.json",
  "config.dev.json",
  "config_prod.json",
  "config-prod.json",
  "config.prod.json",
  "config.sample.json",
  "config-sample.json",
  "config_sample.json",
  "config_test.json",
  "config-test.json",
  "config.test.json",
  "config.php",
  "config_dev.php",
  "config-dev.php",
  "config.dev.php",
  "config_prod.php",
  "config-prod.php",
  "config.prod.php",
  "config.sample.php",
  "config-sample.php",
  "config_sample.php",
  "config_test.php",
  "config-test.php",
  "config.test.php",
  "config.pl",
  "config_dev.pl",
  "config-dev.pl",
  "config.dev.pl",
  "config_prod.pl",
  "config-prod.pl",
  "config.prod.pl",
  "config.sample.pl",
  "config-sample.pl",
  "config_sample.pl",
  "config_test.pl",
  "config-test.pl",
  "config.test.pl",
  "config.py",
  "config_dev.py",
  "config-dev.py",
  "config.dev.py",
  "config_prod.py",
  "config-prod.py",
  "config.prod.py",
  "config.sample.py",
  "config-sample.py",
  "config_sample.py",
  "config_test.py",
  "config-test.py",
  "config.test.py",
  "config.rb",
  "config_dev.rb",
  "config-dev.rb",
  "config.dev.rb",
  "config_prod.rb",
  "config-prod.rb",
  "config.prod.rb",
  "config.sample.rb",
  "config-sample.rb",
  "config_sample.rb",
  "config_test.rb",
  "config-test.rb",
  "config.test.rb",
  "config.toml",
  "config_dev.toml",
  "config-dev.toml",
  "config.dev.toml",
  "config_prod.toml",
  "config-prod.toml",
  "config.prod.toml",
  "config.sample.toml",
  "config-sample.toml",
  "config_sample.toml",
  "config_test.toml",
  "config-test.toml",
  "config.test.toml",
  "config.txt",
  "config_dev.txt",
  "config-dev.txt",
  "config.dev.txt",
  "config_prod.txt",
  "config-prod.txt",
  "config.prod.txt",
  "config.sample.txt",
  "config-sample.txt",
  "config_sample.txt",
  "config_test.txt",
  "config-test.txt",
  "config.test.txt",
  "config.xml",
  "config_dev.xml",
  "config-dev.xml",
  "config.dev.xml",
  "config_prod.xml",
  "config-prod.xml",
  "config.prod.xml",
  "config.sample.xml",
  "config-sample.xml",
  "config_sample.xml",
  "config_test.xml",
  "config-test.xml",
  "config.test.xml",
  "config.yaml",
  "config_dev.yaml",
  "config-dev.yaml",
  "config.dev.yaml",
  "config_prod.yaml",
  "config-prod.yaml",
  "config.prod.yaml",
  "config.sample.yaml",
  "config-sample.yaml",
  "config_sample.yaml",
  "config_test.yaml",
  "config-test.yaml",
  "config.test.yaml",
  "config.yml",
  "config_dev.yml",
  "config-dev.yml",
  "config.dev.yml",
  "config_prod.yml",
  "config-prod.yml",
  "config.prod.yml",
  "config.sample.yml",
  "config-sample.yml",
  "config_sample.yml",
  "config_test.yml",
  "config-test.yml",
  "config.test.yml",
  "boot.ini",
  "gruntfile.js",
  "localsettings.php",
  "my.ini",
  "npm-debug.log",
  "parameters.yml",
  "parameters.yaml",
  "services.yml",
  "services.yaml",
  "web.config",
  "webpack.config.js",
  "config.old",
  "config.inc.php",
  "error.log",
  "access.log",
  ".DS_Store",
  "passwd",
  "win.ini",
  "cmd.exe",
  "my.cnf",
  ".bash_history",
  "docker-compose-dev.yml",
  "docker-compose.override.yml",
  "docker-compose.dev.yml",
  "Cargo.lock",
  "secrets.yml",
  "secrets.yaml",
  "docker-compose.staging.yml",
  "docker-compose.production.yml",
  "yaws-key.pem",
  "mysql_config.ini",
  "firewall.log",
  "log4j.properties",
  "serviceAccountCredentials.json",
  "haproxy.cfg",
  "service-account-credentials.json",
  "vpn.log",
  "system.log",
  "webuser-auth.xml",
  "fastcgi.conf",
  "smb.conf",
  "iis.log",
  "pom.xml",
  "openapi.json",
  "vim_settings.xml",
  "winscp.ini",
  "ws_ftp.ini"
].map(&:downcase).freeze
SUSPICIOUS_FILE_EXTENSIONS =
[
  "env",
  "bak",
  "sql",
  "sqlite",
  "sqlite3",
  "db",
  "old",
  "save",
  "orig",
  "sqlitedb",
  "sqlite3db"
].map(&:downcase).freeze
SUSPICIOUS_SQL_KEYWORDS =
[
  "SELECT (CASE WHEN",
  "SELECT COUNT(",
  "SLEEP(",
  "WAITFOR DELAY",
  "SELECT LIKE(CHAR(",
  "INFORMATION_SCHEMA.COLUMNS",
  "INFORMATION_SCHEMA.TABLES",
  "MD5(",
  "DBMS_PIPE.RECEIVE_MESSAGE",
  "SYSIBM.SYSTABLES",
  "RANDOMBLOB(",
  "SELECT * FROM",
  "1'='1",
  "PG_SLEEP(",
  "UNION ALL SELECT",
  "../"
].map(&:downcase).freeze

Class Method Summary collapse

Class Method Details

.include_suspicious_payload?(context) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/aikido/zen/attack_wave/helpers.rb', line 44

def self.include_suspicious_payload?(context)
  context.payloads.each do |payload|
    next unless payload.source == :query

    value = payload.value.downcase

    length = value.length

    next if length < 5 || length > 1_000

    return true if SUSPICIOUS_SQL_KEYWORDS.any? do |keyword|
      value.include?(keyword)
    end
  end

  false
end

.suspicious_method?(method) ⇒ Boolean

Returns:

  • (Boolean)


20
21
22
# File 'lib/aikido/zen/attack_wave/helpers.rb', line 20

def self.suspicious_method?(method)
  SUSPICIOUS_METHODS.include?(method.downcase)
end

.suspicious_path?(path) ⇒ Boolean

Returns:

  • (Boolean)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/aikido/zen/attack_wave/helpers.rb', line 24

def self.suspicious_path?(path)
  path_parts = path.downcase.split("/")

  file_name = path_parts.pop if path_parts.length > 0

  if file_name
    return true if SUSPICIOUS_FILE_NAMES.include?(file_name)

    file_name_parts = file_name.split(".")

    file_extension = file_name_parts.pop if file_name_parts.length > 1

    return true if SUSPICIOUS_FILE_EXTENSIONS.include?(file_extension)
  end

  path_parts.any? do |directory_name|
    SUSPICIOUS_DIRECTORY_NAMES.include?(directory_name)
  end
end

.suspicious_request?(context) ⇒ Boolean

Returns:

  • (Boolean)


14
15
16
17
18
# File 'lib/aikido/zen/attack_wave/helpers.rb', line 14

def self.suspicious_request?(context)
  request = context.request

  suspicious_method?(request.request_method) || suspicious_path?(request.path_info)
end

.web_scanner?(context) ⇒ Boolean

Returns:

  • (Boolean)


6
7
8
9
10
11
12
# File 'lib/aikido/zen/attack_wave/helpers.rb', line 6

def self.web_scanner?(context)
  return true if suspicious_request?(context)

  return true if include_suspicious_payload?(context)

  false
end