Skip to content
Snippets Groups Projects
Commit 4766f945 authored by Jörg Sachse's avatar Jörg Sachse
Browse files

initial commit (confidential information removed)

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 1089 additions and 0 deletions
# CRLF vs. LF:
* text=auto
# make 'git diff' use ansible-vault for vault files, so you can see decrypted
# content if you have the password
*.vault diff=ansible-vault merge=binary
#!/bin/bash
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=$(git hash-object -t tree /dev/null)
fi
# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)
# Redirect output to stderr.
exec 1>&2
# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
# Note that the use of brackets around a tr range is ok here, (it's
# even required, for portability to Solaris 10's /usr/bin/tr), since
# the square bracket bytes happen to fall in the designated range.
test $(git diff --cached --name-only --diff-filter=A -z $against |
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
cat <<\EOF
Error: Attempt to add a non-ASCII file name.
This can cause problems if you want to work with people on other platforms.
To be portable it is advisable to rename the file.
If you know what you are doing you can disable this check using:
git config hooks.allownonascii true
EOF
exit 1
fi
# If there are whitespace errors, print the offending file names and fail.
# exec git diff-index --check --cached $against --
################################################################################
## Everything below this is customized, everything above is from the example. ##
################################################################################
### PREPARE
# Expand aliases and make alias command work in the bash script.
shopt -s expand_aliases
REPOPATH="$(git rev-parse --show-toplevel)"
GREP_CMD='grep -Rn --color'
GREP_EXCLUDES="--exclude-dir=\.git --exclude-dir=\.githooks --exclude=*\.example"
### YAMLLINT stage
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
YAML_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".yml$")
if [[ ${YAML_FILES} != "" ]]; then
for file in ${YAML_FILES}; do
yamllint "${file}"
if [[ ${?} -ne 0 ]]; then
exit 1
fi
done
fi && echo "SUCCESS: Yamllint stage."
### VAULT detection stage
VAULT_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".vault$")
if [[ ${VAULT_FILES} != "" ]]; then
echo "ERROR: Vaultfiles found:"
for file in ${VAULT_FILES}; do
echo "- ${file}"
done
exit 1
fi
# https://docs.ansible.com/ansible/latest/user_guide/vault.html#vault-format
if [[ ${STAGED_FILES} != "" ]]; then
for file in ${STAGED_FILES}; do
grep -e "\$ANSIBLE_VAULT;[[:digit:]]\.[[:digit:]];AES256" "${file}"
[[ ${?} -eq 0 ]] && echo "ERROR: Ansible-Vault in String found in file '${file}'." && exit 1
done
fi
echo "SUCCESS: Vault detection stage."
### URL detection stage
${GREP_CMD} ${GREP_EXCLUDES} -e "http[s]*.*git.*SLUB" -e "http[s]*.*git.*slub" -e "git@" "${REPOPATH}"
if [[ ${?} -eq 0 ]]; then
echo "ERROR: found internal URLs."
exit 1;
fi
echo "SUCCESS: URL detection stage."
### IP address detection stage
# This is pretty basic regex matching, but it's a start.
IP_REGEX='[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
${GREP_CMD} ${GREP_EXCLUDES} -e "${IP_REGEX}" "${REPOPATH}" | grep -v "127.0.0"
if [[ ${?} -eq 0 ]]; then
echo "ERROR: found IP address."
exit 1;
fi
echo "SUCCESS: IP address detection stage."
### SSH-Key detection stage
${GREP_CMD} ${GREP_EXCLUDES} -e "ssh-[dr]sa " "${REPOPATH}"
if [[ ${?} -eq 0 ]]; then
echo "ERROR: found SSH key."
exit 1;
fi
echo "SUCCESS: SSH Key detection stage."
### DONE
# Return explicit 0.
exit 0;
# Compiled source #
###################
*.bin
*.com
*.class
*.dll
*.exe
*.o
*.so
*.pyc
__pycache__
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
*.tar.gz
*.tgz
# Logs and databases #
######################
*.log
*.sql
*.sqlite
# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Linux packages #
##################
*.deb
*.rpm
# Ansible specific files #
##########################
*.retry
*.vault
# Vim #
#######
# swap
[._]*.s[a-v][a-z]
[._]*.sw[a-p]
[._]s[a-v][a-z]
[._]sw[a-p]
# session
Session.vim
# temporary
.netrwhist
# auto-generated tag files
tags
# Vagrant #
###########
.vagrant/
*.box
---
extends: default
rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
line-length: disable
truthy: disable
# Ansible-Role "ansible_lza_server_hardening"
## Description
This role provides all necessary tasks to harden servers agains external and internal attacks.
## Prerequisites
To use this role, the following software must be installed on your workstation:
* ansible
To deploy this role to a managed host, the following software must be installed on the target:
* Python3
* SSHd
It is recommended to use Debian VMs as deployed by SLUB's UDA tool with this role.
## Quick Start
```
ansible-playbook site.yml [-i <INVENTORY_FILE>] [--limit <HOSTNAME>] [-u <USERNAME>] [-b]
```
## General Ansible usage
Most options already have sensible defaults in `ansible.cfg`. However, you can override these defaults using CLI options/flags if you want to.
To simply run the playbook, just call the `site.yml` playbook like this:
```
ansible-playbook site.yml -u <username>
```
If you want to limit the execution to a subset of all hosts that are listed in the inventory, use the `-l` or `--limit` option like this:
```
ansible-playbook site.yml -l <hostna*>
ansible-playbook site.yml -l <hostname>
ansible-playbook site.yml -l <hostname1>:<hostname2>:...
ansible-playbook site.yml -l <inventory_group>
ansible-playbook site.yml --limit=<hostna*>
```
If you do not have Vault password files in the directory above the role direcory, you have to give the Vault password before execution:
```
ansible-playbook site.yml --ask-vault-pass
```
You can use your own inventory file by adding the `-i` or `--inventory=INVENTORY` option:
```
ansible-playbook site.yml -i inventory.yml
ansible-playbook site.yml --inventory=inventory.yml
```
Tasks in this role have been tagged to enable users to only run subsets of tasks. This can be leveraged to decrease run times or run only certain tasks after small changes.
To list all available tags, use:
```
ansible-playbook site.yml --list-tags
```
You can then run only certain tagged tasks by using the `--tags` option:
```
ansible-playbook site.yml -t tag1,tag2,...,tagN
ansible-playbook site.yml --tags=tag1,tag2,...,tagN
```
For more help with ansible-playbook, use the `--help` flag.
## Testing the role
Tests have been implemented using the Molecule framework. The details on using the test suite are described below `molecule/`.
## Variables
Many variables have been "hidden" in encrypted Ansible Vaults. For security reasons, these Vaults are maintained in a separate private internal repository of SLUB's Git. However, in order to better understand the data within the vaults, you can find `\*.vault.example` files below the `vars/` directory.
If you work outside of SLUBArchive and have no access to the vault repository, make sure to put the necessary vaults in the expected paths at `../ansible_vaults/<ROLENAME>/`.
## git configuration
Just run the `setup_gitconfig.sh` script that comes with the repo to correctly setup all necessary local Git configurations.
## Author Information
If you have any comments or find bugs, please contact langzeitarchiv@slub-dresden.de or issue a pull request.
[defaults]
# If set, configures the path to the Vault password file as an alternative to
# specifying --vault-password-file on the command line.
vault_identity_list = ../lza_install_common.pass, ../lza_server_hardening.pass, ../slub_osquery.pass
# Path to default inventory file
# Administrators can override this by using the "-i <inventoryfile>" CLI
# argument.
inventory = ../ansible_vaults/inventory.yml
# Remote user name
# We DELIBERATELY set this to an non-existent non-root username to make sure
# the role can only be run if an Administrator knows the correct remote_user
# name and passes it as a CLI argument.
remote_user = non-root-user
# By default, ansible will use the 'linear' strategy but you may want to try
# another one
strategy = free
# Don't like cows? that's unfortunate.
# Set to 1 if you don't want cowsay support or export ANSIBLE_NOCOWS=1
nocows = 1
# Custom role path that guarantees roles are always found, no matter where a
# user checks them out.
roles_path = ../:~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
[inventory]
# Ignore these extensions when parsing a directory as inventory source.
ignore_extensions = .pyc, .pyo, .swp, .bak, ~, .rpm, .md, .txt, ~, .orig, .ini, .cfg, .retry
[ssh_connection]
# Enabling pipelining reduces the number of SSH operations required to
# execute a module on the remote server. This can result in a significant
# performance improvement when enabled, however when using "sudo:" you must
# first disable 'requiretty' in /etc/sudoers
# By default, this option is disabled to preserve compatibility with
# sudoers configurations that have requiretty (the default on many distros).
pipelining = True
This directory contains files, script files and directories for use with the copy/script resource.
\ No newline at end of file
###################
# Debian defaults #
###################
### CONTROL RULES
# First rule - delete all.
-D
# Increase the buffers to survive stress events. Make this bigger for busy
# systems.
-b8192
# This determines how long to wait in burst of events.
--backlog_wait_time 0
# Set failure mode to syslog.
-f1
##################
# SLUB specifics #
##################
# based on:
# - https://github.com/bfuzzy/auditd-attack.git
# - https://github.com/chef-cookbooks/auditd.git
# format Filesystem rules ("watches"):
# -w <path-to-file> -p <permissions> -k <keyname>
# Watches can also be created using the syscall format, which allows for
# greater flexibility and options. However, it is very important to only
# use syscall rules when you have to since these affect performance!!!
# watch write access & attribute changes for /etc/passwd and shadow
-w /etc/passwd -p wa -k password
-w /etc/shadow -p wa -k password
# watch write access & attribute changes for apt repositories
-w /etc/apt -p wa -k repos
### Self Auditing --------------------------------------------------------
## Audit the audit logs
# (un-)successful attempts to read information from
# the audit records
-w /var/log/audit -p rwxa -k auditlog
## Auditd configuration
# Modifications to audit configuration that occur while the audit
# collection functions are operating
-w /etc/audit -p wa -k auditconfig
-w /etc/libaudit.conf -p wa -k auditconfig
-w /etc/audisp -p wa -k audispconfig
# Monitor for use of audit management tools
-w /sbin/auditctl -p x -k audittools
-w /sbin/auditd -p x -k audittools
### Filters --------------------------------------------------------------
## We put these early because audit is a first match wins system.
# Ignore current working directory records
-a always,exclude -F msgtype=CWD
# Ignore EOE records (End Of Event, not needed)
-a always,exclude -F msgtype=EOE
# This is not very interesting and wastes a lot of space if the server is
# public facing
-a always,exclude -F msgtype=CRYPTO_KEY_USER
# Cron jobs fill the logs with stuff we normally don't want (works with
# SELinux)
-a never,user -F subj_type=crond_t
-a exit,never -F subj_type=crond_t
-a never,exit -F path=/usr/sbin/cron -F success=0
# filter
# 4294967295 is just (unsigned long) -1. -1 means that loginuid was not set. This is normal behavior for processes that were not spawned by any login process (e.g. for daemons). loginuid is -1 by default; pam_loginuid module changes it to your user id whenever you login (in a tty/in DM/via ssh), and this value is preserved by child processes.
# https://stackoverflow.com/questions/22914627/some-uids-in-proc-pid-loginuid-are-strange
-a always,exclude -F msgtype=USER_AUTH -F auid=4294967295 -F uid=processing
-a always,exclude -F msgtype=USER_ACCT -F auid=4294967295 -F uid=processing
-a always,exclude -F msgtype=CRED_ACQ -F auid=4294967295 -F uid=processing
-a always,exclude -F msgtype=CRED_DISP -F auid=4294967295 -F uid=processing
-a always,exclude -F msgtype=USER_END
-a always,exclude -F msgtype=SERVICE_STOP
# VMWare tools
-a exit,never -F arch=b64 -S fork -F success=0 -F path=/usr/lib/vmware-tools -F subj_type=initrc_t -F exit=-2
# Check_MK/xinetd
-a never,exit -F arch=b64 -F msgtype=SYSCALL -S setuid -S setgid -S openat -S execve -F success=0 -F path=/usr/sbin/xinetd
-a never,exit -F msgtype=EXECVE -F a1=/usr/bin/check_mk_agent
-a never,exit -F msgtype=PATH -F name=/usr/bin/check_mk_agent
-a never,exit -F msgtype=PROCTITLE
## High Volume Event Filter (especially on Linux Workstations)
-a exit,never -F arch=b64 -F dir=/dev/shm -k sharedmemaccess
# -a exit,never -F arch=b64 -F dir=/var/lock/lvm -k locklvm
### Rules ----------------------------------------------------------------
## Kernel Related Events
-w /etc/sysctl.conf -p wa -k sysctl
-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/insmod -k T1215_Kernel_Modules_and_Extensions
-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/modprobe -k T1215_Kernel_Modules_and_Extensions
-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/rmmod -k T1215_Kernel_Modules_and_Extensions
-a always,exit -F arch=b64 -S finit_module -S init_module -S delete_module -F auid!=-1 -k T1215_Kernel_Modules_and_Extensions
-w /etc/modprobe.conf -p wa -k T1215_Kernel_Modules_and_Extensions
# Time Related Events
-a exit,always -F arch=b64 -S adjtimex -S settimeofday -S clock_settime -k T1099_Timestomp
-a always,exit -F arch=b64 -S clock_settime -k T1099_Timestomp
-w /etc/localtime -p wa -k T1099_Timestomp
# Cron configuration & scheduled jobs related events
-w /etc/cron.allow -p wa -k T1168_Local_Job_Scheduling
-w /etc/cron.deny -p wa -k T1168_Local_Job_Scheduling
-w /etc/cron.d -p wa -k T1168_Local_Job_Scheduling
-w /etc/cron.daily -p wa -k T1168_Local_Job_Scheduling
-w /etc/cron.hourly -p wa -k T1168_Local_Job_Scheduling
-w /etc/cron.monthly -p wa -k T1168_Local_Job_Scheduling
-w /etc/cron.weekly -p wa -k T1168_Local_Job_Scheduling
-w /etc/crontab -p wa -k T1168_Local_Job_Scheduling
-w /var/spool/cron/crontabs/ -k T1168_Local_Job_Scheduling
-w /etc/inittab -p wa -k T1168_Local_Job_Scheduling
-w /etc/init.d -p wa -k T1168_Local_Job_Scheduling
-w /etc/init -p wa -k T1168_Local_Job_Scheduling
-w /etc/at.allow -p wa -k T1168_Local_Job_Scheduling
-w /etc/at.deny -p wa -k T1168_Local_Job_Scheduling
-w /var/spool/at -p wa -k T1168_Local_Job_Scheduling
-w /etc/anacrontab -p wa -k T1168_Local_Job_Scheduling
# Account Related Events
-w /etc/sudoers -p wa -k T1078_Valid_Accounts
-w /usr/bin/passwd -p x -k T1078_Valid_Accounts
-w /usr/sbin/groupadd -p x -k T1078_Valid_Accounts
-w /usr/sbin/groupmod -p x -k T1078_Valid_Accounts
-w /usr/sbin/addgroup -p x -k T1078_Valid_Accounts
-w /usr/sbin/useradd -p x -k T1078_Valid_Accounts
-w /usr/sbin/usermod -p x -k T1078_Valid_Accounts
-w /usr/sbin/adduser -p x -k T1078_Valid_Accounts
# Privleged Command Execution Related Events
-a exit,always -F arch=b64 -F euid=0 -S execve -k T1078_Valid_Accounts
-a always,exit -F path=/usr/sbin/userdel -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/bin/ping -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/bin/umount -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/bin/mount -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/bin/su -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/bin/chgrp -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/bin/ping6 -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/sbin/pam_timestamp_check -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/sbin/unix_chkpwd -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/sbin/usermod -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/sbin/newusers -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/sbin/groupdel -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/sbin/semanage -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/sbin/userhelper -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/rlogin -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/sudoedit -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/at -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/gpasswd -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/crontab -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/rcp -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/passwd -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/chsh -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/chfn -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/chage -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/setfacl -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/chacl -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/chcon -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/newgrp -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-a always,exit -F path=/usr/bin/newrole -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
# Media Export Related Events
-a always,exit -F arch=b64 -S mount -F auid>=500 -F auid!=4294967295 -k T1052_Exfiltration_Over_Physical_Medium
# Session Related Events
-w /var/run/utmp -p wa -k T1108_Redundant_Access
-w /var/log/wtmp -p wa -k T1108_Redundant_Access
-w /var/log/btmp -p wa -k T1108_Redundant_Access
# Login Related Events
-w /var/log/faillog -p wa -k T1021_Remote_Services
-w /var/log/lastlog -p wa -k T1021_Remote_Services
-w /var/log/tallylog -p wa -k T1021_Remote_Services
# Pam Related Events
-w /etc/pam.d/ -p wa -k T1071_Standard_Application_Layer_Protocol
-w /etc/security/limits.conf -p wa -k T1071_Standard_Application_Layer_Protocol
-w /etc/security/pam_env.conf -p wa -k T1071_Standard_Application_Layer_Protocol
-w /etc/security/namespace.conf -p wa -k T1071_Standard_Application_Layer_Protocol
-w /etc/security/namespace.init -p wa -k T1071_Standard_Application_Layer_Protocol
-w /etc/pam.d/common-password -p wa -k T1201_Password_Policy_Discovery
# SSH Related Events
-w /etc/ssh/sshd_config -p rwxa -k T1021_Remote_Services
# C2 Releated Events - Log 64 bit processes (a2!=6e filters local unix socket calls)
#-a exit,always -F arch=b64 -S connect -F a2!=110 -k T1043_Commonly_Used_Port
# C2 Releated Events - Log 32 bit processes (a0=3 means only outbound sys_connect calls)
#-a exit,always -F arch=b32 -S socketcall -F a0=3 -k T1043_Commonly_Used_Port
# Priv Escalation Related Events
-w /bin/su -p x -k T1169_Sudo
-w /usr/bin/sudo -p x -k T1169_Sudo
-w /etc/sudoers -p rw -k T1169_Sudo
-a always,exit -F arch=b64 -S chmod -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S chown -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S fchmod -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S fchmodat -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S fchown -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S fchownat -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S fremovexattr -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S fsetxattr -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S lchown -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S lremovexattr -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S lsetxattr -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S removexattr -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S setxattr -F auid>=500 -F auid!=4294967295 -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S execve -C auid!=uid -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -k T1166_Seuid_and_Setgid
-a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -F exit=EPERM -k T1166_Seuid_and_Setgid
-w /usr/bin -p wa -k T1068_Exploitation_for_Privilege_Escalation
# Recon Related Events
-w /etc/group -p wa -k T1087_Account_Discovery
-w /etc/passwd -p wa -k TT1087_Account_Discovery
-w /etc/gshadow -p rwxa -k T1087_Account_Discovery
-w /etc/shadow -p rwxa -k T1087_Account_Discovery
-w /etc/security/opasswd -p rwxa -k T1087_Account_Discovery
-w /usr/sbin/nologin -p rwxa -k T1087_Account_Discovery
-w /sbin/nologin -p rwxa -k T1087_Account_Discovery
-w /usr/bin/whoami -p x -k T1033_System_Owner_User_Discovery
-w /etc/hostname -p r -k T1082_System_Information_Discovery
-w /sbin/iptables -p x -k T1082_System_Information_Discovery
-w /sbin/ifconfig -p x -k T1082_System_Information_Discovery
-w /etc/login.defs -p wa -k T1082_System_Information_Discovery
-w /etc/resolv.conf -p rwxa -k T1016_System_Network_Configuration_Discovery
-w /etc/hosts.allow -p rwxa -k T1016_System_Network_Configuration_Discovery
-w /etc/hosts.deny -p rwxa -k T1016_System_Network_Configuration_Discovery
-w /etc/securetty -p wa -k T1082_System_Information_Discovery
-w /var/log/faillog -p wa -k T1082_System_Information_Discovery
-w /var/log/lastlog -p wa -k T1082_System_Information_Discovery
-w /var/log/tallylog -p wa -k T1082_System_Information_Discovery
-w /usr/sbin/tcpdump -p x -k T1049_System_Network_Connections_discovery
-w /usr/sbin/traceroute -p x -k T1049_System_Network_Connections_discovery
-w /usr/bin/wireshark -p x -k T1049_System_Network_Connections_discovery
-w /usr/bin/rawshark -p x -k T1049_System_Network_Connections_discovery
#-w /usr/bin/grep -p x -k T1081_Credentials_In_Files
#-w /usr/bin/egrep -p x -k T1081_Credentials_In_Files
#-w /usr/bin/ps -p x -k T1057_Process_Discovery
# Remote Access Related Events
-w /usr/bin/base64 -p x -k T1219_Remote_Access_Tools
-w /bin/nc -p x -k T1219_Remote_Access_Tools
-w /bin/netcat -p x -k T1219_Remote_Access_Tools
-w /usr/bin/ncat -p x -k T1219_Remote_Access_Tools
# Third Party Software - RPM (Redhat/CentOS)
-w /usr/bin/rpm -p x -k T1072_third_party_software
-w /usr/bin/yum -p x -k T1072_third_party_software
# Third Party Software - DPKG / APT-GET (Debian/Ubuntu)
-w /usr/bin/dpkg -p x -k T1072_third_party_software
-w /usr/bin/apt-add-repository -p x -k T1072_third_party_software
-w /usr/bin/apt-get -p x -k T1072_third_party_software
-w /usr/bin/aptitude -p x -k T1072_third_party_software
# Code injection Related Events
# Not specifically required by the STIG; but common sense items
# Optional - could indicate someone trying to do something bad or
# just debugging
-a always,exit -F arch=b64 -S ptrace -k T1055_Process_Injection
# Code injection
-a always,exit -F arch=b64 -S ptrace -F a0=0x4 -k T1055_Process_Injection
# Data injection
-a always,exit -F arch=b64 -S ptrace -F a0=0x5 -k T1055_Process_Injection
# Register injection
-a always,exit -F arch=b64 -S ptrace -F a0=0x6 -k T1055_Process_Injection
# Shell configuration Persistence Related Events
-w /etc/profile.d -p rwxa -k T1156_bash_profile_and_bashrc
-w /etc/profile -p rwxa -k T1156_bash_profile_and_bashrc
-w /etc/shells -p rwxa -k T1156_bash_profile_and_bashrc
-w /etc/bashrc -p rwxa -k T1156_bash_profile_and_bashrc
-w /etc/csh.cshrc -p rwxa -k T1156_bash_profile_and_bashrc
-w /etc/csh.login -p rwxa -k T1156_bash_profile_and_bashrc
# Things that could affect system locale
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale
-w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale
#-w /etc/sysconfig/network -p wa -k system-locale
# System startup and shutdown
-a always,exit -F arch=b64 -S execve -F path=/sbin/reboot -k reboot
-a always,exit -F arch=b64 -S execve -F path=/sbin/init -k reboot
-a always,exit -F arch=b64 -S execve -F path=/sbin/poweroff -k reboot
-a always,exit -F arch=b64 -S execve -F path=/sbin/shutdown -k reboot
# Changes to hostname
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k network_modifications
# Changes to other files
-w /etc/hosts -p wa -k network_modifications
-w /etc/network -p wa -k network
-a always,exit -F dir=/etc/NetworkManager/ -F perm=wa -k network_modifications
# Changes to issue
-w /etc/issue -p wa -k etcissue
-w /etc/issue.net -p wa -k etcissue
# Library search paths
-w /etc/ld.so.conf -p wa -k libpath
# Systemd
-w /bin/systemctl -p x -k systemd
-w /etc/systemd -p wa -k systemd
# 32bit API Exploitation
# If you are on a 64 bit platform, everything _should_ be running in 64
# bit mode. This rule will detect any use of the 32 bit syscalls because
# this might be a sign of someone exploiting a hole in the 32 bit API.
-a always,exit -F arch=b32 -S all -k 32bit_api
# reload rules from disk to overwrite temporary rules in memory
-R /etc/audit/audit.rules
# show active rules: sudo auditctl -l
# find related event for passwd file: ausearch -f /etc/passwd
#!/usr/bin/env bash
# checks the status of the sshd fail2ban jail
# copy plugin to the "/usr/lib/check_mk_agent/plugin" directory
# test it via: check_mk_agent | grep -v grep | grep -A 3 "<<<local>>>"
# REQUIREMENTS:
# - Bash 4 or higher
# - fail2ban
scriptname=$( basename "${0}" ".sh" )
LOCKFILE="/var/lock/${scriptname}.lock"
status=3
itemname='fail2ban_status'
perf_values="-"
# check if fail2ban is installed
BINARY=$( command -v fail2ban-client )
[[ ${BINARY} ]] || exit 1
# check if fail2ban is actually running, otherwise we will get an error:
# "Failed to access socket path: /var/run/fail2ban/fail2ban.sock. Is fail2ban
# running?"
[[ $( pgrep -la fail2ban ) ]] || exit 1
# IMPORTANT: Set lock using "flock", NOT "touch"!!! It's atomic and doesn't have to be cleared after the script ran.
(
flock -n 9 || exit 1
CURR_BANNED=$( ${BINARY} status sshd | grep "Currently banned" | cut -d ":" -f2 | tr -d '[:space:]' )
if [[ ( ${CURR_BANNED} -eq 0 ) ]]; then
# Nobody is currently banned, all OK
status=0
statustext="Fail2Ban currently bans 0 hosts, everything's OK."
elif [[ ( ${CURR_BANNED} -ge 1 ) && ( ${CURR_BANNED} -le 9 ) ]]; then
status=1
statustext="Fail2Ban currently bans ${CURR_BANNED} hosts, something's fishy."
elif [[ ( ${CURR_BANNED} -ge 10 ) ]]; then
status=2
statustext="Fail2Ban currently bans ${CURR_BANNED} hosts, that's REALLY not good."
else
status=3
statustext="Couldn' get Fail2Ban status."
fi
echo "${status} ${itemname} ${perf_values} ${statustext}"
) 9>"${LOCKFILE}"
# Code checked by shellcheck (https://github.com/koalaman/shellcheck) on 2020-12-02
---
- name: save iptables rules (Debian)
block:
- name: Ordner für iptables-Config erstellen
file:
path: "/etc/iptables"
state: directory
owner: "root"
group: "root"
mode: 0755
listen: "save iptables rules"
- name: install netfilter-persistent to be able to save iptables rules
apt:
name: netfilter-persistent
state: present
listen: "save iptables rules"
- name: save iptables rules
command: 'netfilter-persistent save'
listen: "save iptables rules"
when: ansible_os_family == "Debian"
- name: save iptables rules (RedHat)
block:
- name: make sure iptables config file exists
file:
path: "/etc/sysconfig/iptables"
state: touch
owner: "root"
group: "root"
mode: 0600
listen: "save iptables rules"
- name: save rules
command: /usr/sbin/iptables-save # noqa 303
listen: "save iptables rules"
when: ansible_os_family == "RedHat"
- name: activate kernel parameter changes
command: sysctl -p
ignore_errors: true
- name: restart fail2ban.service
service:
name: "fail2ban"
state: restarted
- name: restart sshd
service:
name: "sshd"
state: restarted
- name: restart auditd.service
service:
name: "auditd"
state: restarted
when: ansible_os_family == "Debian"
listen: restart auditd.service
- name: restart auditd.service
service:
name: "auditd"
state: restarted
use: "service"
when: ansible_os_family == "RedHat"
listen: restart auditd.service
- name: restart clamav-daemon service
service:
name: "clamav-daemon"
state: restarted
when: ansible_os_family == "Debian"
- name: restart clamd service
service:
# name: "clamd"
name: "clamonacc"
state: restarted
when: ansible_os_family == "RedHat"
---
galaxy_info:
author: Jörg Sachse
description: role to deploy a hardened install of Debian for use in the SLUBarchiv digital preservation repository
company: SLUB Dresden
# If the issue tracker for your role is not on github, uncomment the next line and provide a value issue_tracker_url: http://example.com/issue/tracker Some suggested licenses: - BSD
# (default) - MIT - GPLv2 - GPLv3 - Apache - CC-BY
license: public domain
min_ansible_version: 2.4
# If this a Container Enabled role, provide the minimum Ansible Container version. min_ansible_container_version: Optionally specify the branch Galaxy will use when accessing the GitHub repo
# for this role. During role install, if no tags are available, Galaxy will use this branch. During import Galaxy will access files on this branch. If Travis integration is configured, only
# notifications for this branch will be accepted. Otherwise, in all cases, the repo's default branch (usually master) will be used. github_branch:
#
# Provide a list of supported platforms, and for each platform a list of versions. If you don't wish to enumerate all versions for a particular platform, use 'all'. To view available
# platforms and versions (or releases), visit: https://galaxy.ansible.com/api/v1/platforms/
#
# platforms: - name: Fedora
# versions: - all - 25 - name: SomePlatform versions: - all - 1.0 - 7 - 99.99
platforms:
- name: Debian
versions:
- 9
- 10
- name: RedHat
versions:
- 6
- 7
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes and categorizes the role. Users find roles by searching for tags. Be sure to remove the '[]' above, if you
# add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
# dependencies: []
# Testing with Molecule
## Prerequisites
In order to be able to use the tests, you need to have some software packages installed. You may need sudo privileges for some of these operations.
### install VirtualBox
# do NOT use distribution packages
# process documented at https://www.virtualbox.org/wiki/Linux_Downloads
#
# add repository URL
sudo echo "deb [arch=amd64] https://download.virtualbox.org/virtualbox/debian stretch contrib" > /etc/apt/sources.d/virtualbox.list
# add GPG key
wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -
# update sources
sudo apt update
# install VirtualBox
sudo apt-get install virtualbox-6.1
### install Vagrant
# do NOT use distribution packages
#
# download Debian package from Hashicorp
wget https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.deb
# install package
sudo dpkg -i vagrant_2.2.9_x86_64.deb
### install Molecule et. al.
# prepare directories
mkdir ~/python-envs/ && cd ~/python-env/
# create Python Virtual Environment with Python3 interpreter (Python2 is deprecated!)
virtualenv -p python3 molecule-env
# enter the Virtual Environment in your current shell (other shells will be unaffected)
source molecule-env/bin/activate
# install packages
pip3 install molecule ansible testinfra ansible-lint molecule-vagrant molecule-docker
# leave the Virtual Environment only when you're done
deactivate
You can find suitable documentation at the respective vendors' websites.
* [Vagrant Installation Guide](https://www.vagrantup.com/docs/installation/)
* [VirtualBox Installation Guide](https://www.virtualbox.org/wiki/Downloads)
* [Molecule Installation Guide](https://molecule.readthedocs.io/en/stable/installation.html)
## Initialising a new Molecule scenario
If you have already created a role without the Molecule test framework or you want to add test scenarios, you can use:
molecule init scenario --scenario-name <my_scenario> --driver [azure|delegated|docker|ec2|gce|linode|lxc|lxd|openstack|vagrant] --verifier-name [ansible|testinfra]
If you need any help with the options, please use:
molecule init role --help
## Running Tests
Molecule helps with creating a test infrastructure, running tests against it and removing the test infrastructure afterwards.
Various test environments are separated into so-called "scenarios" that can be based on different OSses, drivers, verifiers or might just differ in a minor detail.
In the simplest configuration, the `molecule/` directory only contains one `default/` directory that contains the default scenario. This scenario is run if no other scenario is chosen using the `-s` CLI option.
This is the basic usage of Molecule:
# create test infrastructure
cd <role_directory>
molecule create
# run playbooks against test infrastructure
molecule converge
# run Testinfra tests
molecule verify
# remove test infrastructure
molecule destroy
# run all steps at once:
molecule test
It has proven helpful to use Vagrant to create a snapshot of the VM after the creation phase has completed.
# First, get UUID of the VM
vagrant global-status
# Then, create the snapshot
vagrant snapshot save <uuid> <snapshot_name>
# To restore the snapshot, use
vagrant snapshot restore <uuid> <snapshot_name>
# And to remove the snapshot, use
vagrant snapshot delete <uuid> <snapshot_name>
*******
Vagrant driver installation guide
*******
Requirements
============
* Vagrant
* Virtualbox, Parallels, VMware Fusion, VMware Workstation or VMware Desktop
Install
=======
Please refer to the `Virtual environment`_ documentation for installation best
practices. If not using a virtual environment, please consider passing the
widely recommended `'--user' flag`_ when invoking ``pip``.
.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
.. code-block:: bash
$ pip install 'molecule[vagrant]'
---
- name: Converge
hosts: all
roles:
- {role: "ansible_lza_server_hardening", become: true}
---
dependency:
name: galaxy
driver:
name: vagrant
provider:
name: virtualbox
lint: |
set -e
yamllint .
ansible-lint -x formatting
flake8 --ignore=E501
platforms:
- name: molecule-server-hardening-debian
box: debian/buster64
memory: 512
cpus: 1
provisioner:
name: ansible
log: true
config_options:
defaults:
vault_identity_list: "@$HOME/.ansible/roles/molecule_prepare.pass, @$HOME/.ansible/roles/lza_install_common.pass, @$HOME/.ansible/roles/lza_server_hardening.pass"
lint: |
set -e
ansible-lint
vvv: false
verifier:
name: testinfra
env:
PYTHONWARNINGS: "ignore:.*U.*mode is deprecated:DeprecationWarning"
lint: |
set -e
flake8
options:
v: 1
---
- name: Prepare
hosts: all
gather_facts: true
pre_tasks:
- name: include vars
include_vars: "../../../ansible_vaults/molecule_prepare/{{ item }}"
loop:
- "prepare.vault"
- name: Install python for Ansible
raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
become: true
changed_when: false
- name: create users (as deployed in production)
user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
create_home: "yes"
shell: "/bin/bash"
loop: "{{ vault_molecule_users | flatten(levels=1) }}"
become: true
- name: add nonfree repos
apt_repository:
repo: "deb http://ftp2.de.debian.org/debian/ buster main non-free contrib"
state: present
update-cache: "yes"
become: true
- name: Install required packages
apt:
name: [
'aptitude',
'gpg',
'less',
'libuser'
]
state: present
become: true
roles:
- {role: ansible_lza_install_common, become: true}
"""PyTest Fixtures."""
from __future__ import absolute_import
import os
import pytest
def pytest_runtest_setup(item):
"""Run tests only when under molecule with testinfra installed."""
try:
import testinfra
except ImportError:
pytest.skip("Test requires testinfra", allow_module_level=True)
if "MOLECULE_INVENTORY_FILE" in os.environ:
pytest.testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ["MOLECULE_INVENTORY_FILE"]
).get_hosts("all")
else:
pytest.skip(
"Test should run only from inside molecule.", allow_module_level=True
)
def test_hosts_file(host):
f = host.file('/etc/hosts')
assert f.exists
assert f.user == 'root'
assert f.group == 'root'
#!/usr/bin/env bash
set -ex
# Change the path that Git expects the hooks to be in, so we can track the hooks
# within the repository (as the default `.git/` directory is not tracked).
git config --local core.hooksPath .githooks/
# To be able to run `git diff` on Ansible Vault files, please set you local
# `git/config` files as described in (https://stackoverflow.com/a/52863794) for
# the `~/.gitconfig` file or just blindly follow the instructions there to set
# it for you Git installation as a whole.
git config --local core.attributesfile "../.gitattributes"
git config --local diff.ansible-vault.textconv "ansible-vault view"
site.yml 0 → 100644
---
- hosts: "*"
pre_tasks:
- name: Verify that the installed version of Ansible meets this playbook's version requirements.
assert:
that: "ansible_version.full is version_compare('2.2', '>=')"
msg: >
"You must update Ansible to at least 2.2 to use this playbook."
# Collect facts from remote system? Possible values: true, false
gather_facts: true
# Gather only certain subsects of facts. Ansible supports network, hardware, virtual, facter, ohai as subset.
gather_subset:
- network
- virtual
- hardware
# any_error_fatal will mark all the hosts as failed if fails and immediately abort the playbook execution. Possible values: true, false
any_errors_fatal: false
# max_fail_percentage allows you to abort the play if certain threshold of failures have been reached.
max_fail_percentage: 30
serial: 30
# hide sensitive information in verbose/debugging output from others. Possible values: true, false
no_log: false
# execution strategy, possible values: debug, linear, serial, free (https://docs.ansible.com/ansible/latest/user_guide/playbooks_strategies.html)
strategy: linear
roles:
- { role: ansible_lza_install_common, become: true }
- { role: ansible_lza_server_hardening, become: true }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment