mirror of
https://github.com/cliffe/SecGen.git
synced 2026-02-23 04:08:02 +00:00
Merge branch 'week_4_merge_branch' of https://github.com/cliffe/SecGen into week_4_merge_branch
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 :backup_server_ip
|
||||
attr_accessor :ids_server_ip
|
||||
attr_accessor :hackerbot_server_ip
|
||||
|
||||
def initialize
|
||||
super
|
||||
self.module_name = 'Hackerbot Config Generator HvHB1'
|
||||
self.title = 'HvHB1'
|
||||
|
||||
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.backup_server_ip = []
|
||||
self.ids_server_ip = []
|
||||
self.hackerbot_server_ip = []
|
||||
end
|
||||
|
||||
def get_options_array
|
||||
super + [['--backup_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 '--backup_server_ip'
|
||||
self.backup_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,50 @@
|
||||
<?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 a test covering the first few hackerbot labs</name>
|
||||
<author>Z. Cliffe Schreuders</author>
|
||||
<module_license>GPLv3</module_license>
|
||||
<description>Generates a config file for a hackerbot for a lab test..</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>backup_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>
|
||||
|
||||
<!--TODO: less flags-->
|
||||
<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"/>
|
||||
<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,23 @@
|
||||
|
||||
<attack>
|
||||
<% $file = SecureRandom.hex(2) %>
|
||||
<!--shell on the backup server-->
|
||||
<get_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@<%= $backup_server_ip %> /bin/bash</get_shell>
|
||||
|
||||
<prompt>Use scp to copy the desktop /bin/ directory to the backup_server: <%= $backup_server_ip %>:/home/<%= $main_user %>/remote-bin-backup-<%= $file %>/, which should then include the backed up bin/ directory.</prompt>
|
||||
|
||||
<post_command>ls /home/<%= $main_user %>/remote-bin-backup-<%= $file %>/bin/ls /home/<%= $main_user %>/remote-bin-backup-<%= $file %>/bin/mkdir > /dev/null; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>No such file or directory</output_matches>
|
||||
<message>:( You didn't copy to the remote /home/<%= $main_user %>/remote-bin-backup-<%= $file %>/bin/... Remember that the trailing / changes whether you are copying directories or their contents...</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
@@ -0,0 +1,115 @@
|
||||
|
||||
<attack>
|
||||
<!--shell on the backup server-->
|
||||
<get_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@<%= $backup_server_ip %> /bin/bash</get_shell>
|
||||
|
||||
<!-- topic: Rsync-->
|
||||
<prompt>It's your job to set up remote backups for <%= $second_user %> (a user on your system). Use rsync to create a full (epoch) remote backup of /home/<%= $second_user %> from your desktop system to the backup_server: <%= $backup_server_ip %>:/home/<%= $main_user %>/remote-rsync-full-backup/<%= $second_user %>.</prompt>
|
||||
|
||||
<post_command>ls /home/<%= $main_user %>/remote-rsync-full-backup/<%= $second_user %>/<%= $files.sample %> > /dev/null; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>No such file or directory</output_matches>
|
||||
<message>:( You didn't copy to remote ssh /home/<%= $main_user %>/remote-rsync-full-backup/<%= $second_user %>/ Remember that the trailing / changes whether you are copying directories or their contents...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Doesn't look like you have backed up all of <%= $second_user %>'s files to /home/<%= $main_user %>/remote-rsync-backup/<%= $second_user %>. Try SSHing to the server and look at what you have backed up there.</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
<attack>
|
||||
<% $first_notes = SecureRandom.hex(2) %>
|
||||
<% $hidden_flag = 'not_a_flag' %>
|
||||
<!--shell on the desktop-->
|
||||
<!-- topic: Rsync-->
|
||||
<prompt>The <%= $second_user %> user is about to create some files...</prompt>
|
||||
|
||||
<post_command>sudo -u <%= $second_user %> bash -c 'echo "Note to self: drink more water <%= $first_notes %>" > /home/<%= $second_user %>/notes; echo "Beep boop beep" > /home/<%= $second_user %>/logs/log2; echo <%= $hidden_flag %> > /home/<%= $second_user %>/personal_secrets/flag; echo $?'</post_command>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( Oh no. Access errors. <%= $second_user %> failed to write the files... The user needs to be able to write to their files!</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>Ok, good... </message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<!--shell on the backup server-->
|
||||
<get_shell>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@<%= $backup_server_ip %> /bin/bash</get_shell>
|
||||
|
||||
<!-- topic: Rsync differential-->
|
||||
<prompt>Create a differential backup of <%= $second_user %>'s desktop files to the backup_server: <%= $backup_server_ip %>:/home/<%= $main_user %>/remote-rsync-differential1/.</prompt>
|
||||
|
||||
<!--grep retval=0 when match is found, 1/2 otherwise-->
|
||||
|
||||
<post_command>grep '<%= $hidden_flag %>' /home/<%= $main_user %>/remote-rsync-differential1/<%= $second_user %>/personal_secrets/flag > /dev/null; status1=$?; ls /home/<%= $main_user %>/remote-rsync-differential1/<%= $second_user %>/<%= $files.sample %> > /dev/null; status2=$?; echo $status1$status2</post_command>
|
||||
<condition>
|
||||
<output_matches>0[1-9]</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %> </message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>[1-9][1-9]</output_matches>
|
||||
<message>:( You didn't backup to the specified remote directory.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>00</output_matches>
|
||||
<message>:( You backed up to the correct location, but it wasn't an incremental backup... You probably need to ssh in and delete that last backup and try again.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
|
||||
<attack>
|
||||
<!--shell on the desktop-->
|
||||
<!-- topic: Rsync-->
|
||||
<prompt>I am going to attack you now!</prompt>
|
||||
|
||||
<post_command>rm -r /home/<%= $second_user %>/*; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( Oh no. Access errors. <%= $second_user %>. You need to let this happen!</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>I just deleted all <%= $second_user %>'s files! They don't call me Hackerbot for nothin'!</message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
|
||||
<attack>
|
||||
<!--shell on the desktop server-->
|
||||
|
||||
<!-- topic: Rsync incremental-->
|
||||
<prompt>Restore <%= $second_user %>'s notes file to it's earliest state</prompt>
|
||||
|
||||
<post_command>grep '<%= $first_notes %>' /home/<%= $second_user %>/notes > /dev/null; status1=$?; echo $status1</post_command>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %> </message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>[0-9]</output_matches>
|
||||
<message>:( That's not the earliest state...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,19 @@
|
||||
<attack>
|
||||
<% $file = SecureRandom.hex(2) %>
|
||||
<prompt>An attempt to write /tmp/<%= $file %> is coming from user <%= $second_user %>. Stop the attack by creating the file without permission for other users to write to the file.</prompt>
|
||||
|
||||
<post_command>sudo -u <%= $second_user %> bash -c 'echo boom > /tmp/<%= $file %>'; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>Permission denied</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_equals>0</output_equals>
|
||||
<message>:( We managed to write to your file! You need to use access controls to protect the file. Create a new file.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
<attack>
|
||||
<% $log_file = $log_files.sample %>
|
||||
<!-- topic: Protecting integrity with file attributes-->
|
||||
<prompt>An attempt to delete /home/<%= $main_user %>/<%= $log_file %> is coming. Stop the attack using file attributes.</prompt>
|
||||
|
||||
<post_command>rm --interactive=never /home/<%= $main_user %>/<%= $log_file %>; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>Operation not permitted</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition> <!-- TODO: chmod to defeat the defense? -->
|
||||
<output_matches>Permission denied</output_matches>
|
||||
<message>:( You did protect the file, but not using file attributes.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_equals>0</output_equals>
|
||||
<message>:( We managed to delete your file! You need to use file attributes to protect the file. Create a new file.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>No such file or directory</output_matches>
|
||||
<message>:( The file should exist!</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
<attack>
|
||||
<% $log_file = $log_files.first %>
|
||||
<!-- topic: Protecting integrity with file attributes-->
|
||||
<prompt>An attempt to overwrite /home/<%= $main_user %>/<%= $log_file %> is coming. Stop the attack by making the file append only.</prompt>
|
||||
|
||||
<post_command>echo 'your logs are gone!' > /home/<%= $main_user %>/<%= $log_file %>; echo 'appended!' >> /home/<%= $main_user %>/<%= $log_file %>; tail -n2 /home/<%= $main_user %>/<%= $log_file %>; echo $?</post_command>
|
||||
<condition>
|
||||
<output_not_matches>appended!</output_not_matches>
|
||||
<message>:( You stopped anything from being appended to the file. What kind of log file do you think this is?</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Operation not permitted</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack>true</trigger_next_attack>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>No such file or directory</output_matches>
|
||||
<message>:( The file should exist!</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
<attack>
|
||||
<!-- topic: Protecting integrity with read-only filesystems-->
|
||||
<prompt>An attempt to edit a file in /etc/ is coming. Stop the attack by bind mounting /etc/ as read-only.</prompt>
|
||||
|
||||
<post_command>echo 'not read only!' > /etc/you_were_hacked; adduser --disabled-password --gecos "" yourehacked</post_command>
|
||||
<condition>
|
||||
<output_matches>Read-only file system</output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %></message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted</output_matches>
|
||||
<message>:( You stopped the attack, but not by using read only bind mounting...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
</attack>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
<attack>
|
||||
<% $random_user = 'user' + SecureRandom.hex(3) %>
|
||||
<!-- topic: Detecting changes to resources using backups-->
|
||||
<prompt>An attempt to add a new user is coming, let it happen. But first create a backup of /etc/passwd to /home/<%= $main_user %>/backups/passwd.</prompt>
|
||||
|
||||
<post_command>rm /etc/.pwd.lock; sudo adduser <%= $random_user %> --gecos '<%= $random_user %>' --disabled-password --quiet; echo $?</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
<condition>
|
||||
<output_matches>returned error code</output_matches>
|
||||
<message>:( Couldn't add a user -- make sure /etc/ is not still read-only mounted!.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>User added</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>already exists</output_matches>
|
||||
<message>:( Remove the user and try again.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>Now after the attack, find the username added by diffing using a backup. What username was created?</question>
|
||||
<answer>^<%= $random_user %>$</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
<attack>
|
||||
<!-- topic: Detecting changes to resources using backups-->
|
||||
<prompt>An attempt to edit a config file is coming, let it happen. But first make sure you have a backup of the /etc/ directory at /home/<%= $main_user %>/backups/etc/.</prompt>
|
||||
<post_command>changedf=`find /etc/ -name '*.sh' | sort -R | head -n 1`; echo '# <%= $flags.pop %>' >> $changedf; echo $changedf</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
<condition>
|
||||
<output_matches>/etc/</output_matches>
|
||||
<message>A flag has been inserted into a random file in /etc/. Find the flag. Get to work!</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes... We are trying to write to /etc/</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right... We are trying to write to /etc/</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
<attack>
|
||||
<!-- topic: Detecting changes to resources using backups-->
|
||||
<prompt>An attempt to edit a config file is coming, let it happen. But first make sure you have a backup of the /etc/ directory at /home/<%= $main_user %>/backups/etc/.</prompt>
|
||||
<post_command>changedf=`find /home/<%= $main_user %>/backups/etc/ -name '*.sh' | sort -R | head -n 1`; echo '# <%= $flags.pop %>' >> $changedf; echo $changedf</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
<condition>
|
||||
<output_matches>/home/<%= $main_user %>/backups/</output_matches>
|
||||
<message>A flag has been inserted into a random file IN YOUR BACKUPS! (Did you really think that was a safe place to store them?) Find the flag. Get to work!</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes... We are trying to write to /home/<%= $main_user %>/backups/etc/</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right... We are trying to write to /home/<%= $main_user %>/backups/etc/</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
<attack>
|
||||
<% $random = SecureRandom.hex %>
|
||||
<!-- topic: File integrity checkers-->
|
||||
<prompt>Creating a new file in /home/<%= $main_user %>/... Let it happen.</prompt>
|
||||
|
||||
<post_command>echo '<%= $random %>' > /home/<%= $main_user %>/something_secret; echo $?</post_command>
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>Created /home/<%= $main_user %>/something_secret</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What is the SHA1 hash of /home/<%= $main_user %>/something_secret?</question>
|
||||
<answer>^<%= Digest::SHA1.hexdigest ("#{$random + "\n"}") %>$</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,26 @@
|
||||
<attack>
|
||||
<!-- topic: File integrity checkers-->
|
||||
<prompt>Going to create a new file in /etc/, use hash comparisons to detect which new file changes.</prompt>
|
||||
<post_command>x=`find /etc/ -type d | sort -R | head -n 1`; mktemp -p $x -t "XXXXXXXX"</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
|
||||
<condition>
|
||||
<output_matches>/etc.*</output_matches>
|
||||
<message>Good. Now answer this...</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes... We need to be able to write to /secrets/something_secret/</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What is the file that was created?</question>
|
||||
<answer>{{post_command_output}}</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,26 @@
|
||||
<attack>
|
||||
<!-- topic: File integrity checkers-->
|
||||
<prompt>Going to copy a new random binary in /bin/|/usr/bin/ use hash comparisons to find the filename of the copied file.</prompt>
|
||||
<post_command>srcf=`find /bin/ /usr/bin/ -executable | sort -R | head -n 1`; srcf="${srcf%\\n}"; dest=$srcf.$RANDOM; cp $srcf $dest; echo $dest</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
|
||||
<condition>
|
||||
<output_matches>/bin/</output_matches>
|
||||
<message>Good. Now answer this...</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes...</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What is the file that was created?</question>
|
||||
<answer>{{post_command_output}}</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,27 @@
|
||||
<!--copied a new random file in /etc/ use hash comparisons to find the filename. -->
|
||||
<attack>
|
||||
<!-- topic: File integrity checkers-->
|
||||
<prompt>Going to copy a new random file in /etc/ use hash comparisons to find the filename.</prompt>
|
||||
<post_command>srcf=`find /etc/ -type f | sort -R | head -n 1`; srcf="${srcf%\\n}"; dest=$srcf.$RANDOM; cp $srcf $dest; echo $dest</post_command>
|
||||
<suppress_command_output_feedback />
|
||||
|
||||
<condition>
|
||||
<output_matches>/etc.*</output_matches>
|
||||
<message>Good. Now answer this...</message>
|
||||
<trigger_quiz />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>Permission denied|Operation not permitted|Read-only</output_matches>
|
||||
<message>:( You stopped the attack, rather than monitor for changes... </message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<quiz>
|
||||
<question>What is the file that was created?</question>
|
||||
<answer>{{post_command_output}}</answer>
|
||||
<correct_answer_response>:) <%= $flags.pop %></correct_answer_response>
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
</attack>
|
||||
@@ -0,0 +1,42 @@
|
||||
# Hacker vs Hackerbot 1
|
||||
|
||||
## 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)
|
||||
- backup_server (IP address: <%= $backup_server_ip %>)
|
||||
- desktop
|
||||
|
||||
All of these VMs need to be running to complete the lab.
|
||||
|
||||
### Your login details for the "desktop" and "backup_server" VMs
|
||||
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.
|
||||
|
||||
## Hackerbot!
|
||||

|
||||
|
||||
This exercise involves interacting with Hackerbot, a chatbot who will task you to complete tasks and will attack your systems. If you satisfy Hackerbot by completing the challenges, she will reveal flags to you.
|
||||
|
||||
---
|
||||
|
||||
Some commands you may find useful include:
|
||||
* `rsync`
|
||||
* `chattr`
|
||||
* `lsattr`
|
||||
* `chmod`
|
||||
* `hashdeep`
|
||||
* `shasum`
|
||||
* `mount`
|
||||
|
||||
Remember you can learn more about the commands by running:
|
||||
```bash
|
||||
man *command*
|
||||
```
|
||||
@@ -0,0 +1,138 @@
|
||||
<%
|
||||
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 $first_account.key?("leaked_filenames") && $first_account['leaked_filenames'].size > 0
|
||||
$files = $first_account['leaked_filenames']
|
||||
$log_files = $first_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
|
||||
$second_user = $second_account['username'].to_s
|
||||
$example_file = "/home/#{$second_user}/#{$files.sample}"
|
||||
$example_dir = "/home/#{$second_user}/personal_secrets/"
|
||||
|
||||
$backup_server_ip = self.backup_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 = 9
|
||||
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>sshpass -p <%= $root_password %> ssh -oStrictHostKeyChecking=no root@{{chat_ip_address}} /bin/bash</get_shell>
|
||||
|
||||
|
||||
<messages>
|
||||
<show_attack_numbers />
|
||||
|
||||
<greeting>You are about to be attacked!</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>HvHB1</title>
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'intro.md.erb').result(self.get_binding) %></tutorial>
|
||||
<footer>
|
||||
<%= 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>
|
||||
|
||||
|
||||
<!-- Two random permission attacks-->
|
||||
<%
|
||||
$permission_attacks = ['file_perms_attack_1.xml.erb', 'file_perms_attack_2.xml.erb', 'file_perms_attack_3.xml.erb', 'file_perms_attack_4.xml.erb'].shuffle
|
||||
%>
|
||||
<%= ERB.new(File.read self.templates_path + $permission_attacks.pop ).result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + $permission_attacks.pop ).result(self.get_binding) %>
|
||||
|
||||
<!-- Four random integrity attacks-->
|
||||
<%
|
||||
$integrity_attacks = ['integrity_attack1.xml.erb', 'integrity_attack2.xml.erb', 'integrity_attack3.xml.erb', 'integrity_attack4.xml.erb', 'integrity_attack5.xml.erb', 'integrity_attack6.xml.erb', 'integrity_attack7.xml.erb'].shuffle
|
||||
%>
|
||||
<%= ERB.new(File.read self.templates_path + $integrity_attacks.pop ).result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + $integrity_attacks.pop ).result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + $integrity_attacks.pop ).result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + $integrity_attacks.pop ).result(self.get_binding) %>
|
||||
|
||||
<!--Three flags from using rsync to backup and recover-->
|
||||
<%= ERB.new(File.read self.templates_path + 'backups_rsync_steps_attacks.xml.erb' ).result(self.get_binding) %>
|
||||
|
||||
|
||||
</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, li code .pln {
|
||||
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.
|
||||
|
||||

|
||||
@@ -3,7 +3,7 @@
|
||||
<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 a backups lab</name>
|
||||
<name>Hackerbot config for a IDS lab</name>
|
||||
<author>Z. Cliffe Schreuders</author>
|
||||
<module_license>GPLv3</module_license>
|
||||
<description>Generates a config file for a hackerbot for a backups lab.
|
||||
@@ -29,6 +29,7 @@
|
||||
</generator>
|
||||
</default_input>
|
||||
|
||||
<!--TODO: less flags-->
|
||||
<default_input into="flags">
|
||||
<generator type="flag_generator"/>
|
||||
<generator type="flag_generator"/>
|
||||
@@ -36,10 +37,6 @@
|
||||
<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">
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
</messages>
|
||||
|
||||
<tutorial_info>
|
||||
<title>Backing Up and Recovering from Disaster: SSH/SCP, Deltas, and Rsync</title>
|
||||
<title>IDS</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' %>
|
||||
@@ -230,7 +230,7 @@ I'm about to attack your system, use Snort to detect the method of attack.
|
||||
|
||||
<attack>
|
||||
<pre_shell>nmap -sX <%= $web_server_ip %> > /dev/null; echo $? </pre_shell>
|
||||
<shell>false</shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>#5 Your webserver is about to be scanned/attacked. Make sure you are using Snort to monitor your network...</prompt>
|
||||
@@ -255,11 +255,10 @@ I'm about to attack your system, use Snort to detect the method of attack.
|
||||
<trigger_next_attack />
|
||||
</quiz>
|
||||
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'snort.md.erb').result(self.get_binding) %></tutorial>
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<shell>msfconsole -x "use exploit/unix/misc/distcc_exec; set RHOST <%= $web_server_ip %>; exploit"</shell>
|
||||
<get_shell>msfconsole -x "use exploit/unix/misc/distcc_exec; set RHOST <%= $web_server_ip %>; exploit"</get_shell>
|
||||
<post_command>whoami > /dev/null; echo "<%= $flags.pop %>" > /dev/null; echo 'Find the flag! (in the network traffic)'</post_command>
|
||||
|
||||
<prompt>#6 Your webserver is about to be scanned/attacked. Use Tcpdump and/or Wireshark to view the behaviour of the attacker. There is a flag to be found over the wire. </prompt>
|
||||
|
||||
@@ -46,7 +46,7 @@ Tcpdump can format the output in various ways, showing various levels of detail.
|
||||
```bash
|
||||
sudo tcpdump -A -i eth1
|
||||
```
|
||||
> This shows the packet **content** without the information about the source and destination.
|
||||
> This shows the packet **content** without the information about the source and destination. Note that this content will contain binary data that can be difficult understand.
|
||||
|
||||
When you ==access a web page in a browser on the desktop VM== (go ahead... ==reload this labsheet== webpage), Tcpdump will display the content, so long as the traffic is not SSL encrypted (for example, so long as the URL doesn't start with http**s**://). Depending on the webserver and browser, the content may be compressed (but not encrypted) to save bandwidth.
|
||||
|
||||
|
||||
@@ -50,12 +50,17 @@ There are lots more options that can make rules more precise and efficient. For
|
||||
|
||||
Lets create a basic rule that detects any web traffic on port 80.
|
||||
|
||||
```bash
|
||||
echo "alert tcp any any -> any 80 (msg: "Web traffic detected - RANDOM"; sid:1000002; rev:1;)" >> /etc/snort/rules/my.rules
|
||||
**On your IDS server:**
|
||||
|
||||
systemctl restart snort
|
||||
```bash
|
||||
echo 'alert tcp any any -> any 80 (msg: "Web traffic detected - ASDFGH"; sid:1000002; rev:1;)' >> /etc/snort/rules/my.rules
|
||||
|
||||
service snort restart
|
||||
```
|
||||
Browse to a website, and confirm the rule worked to generate an alert containing RANDOM.
|
||||
|
||||
==**Don't forget to reload Snort every time you add or modify a rule!**==
|
||||
|
||||
**From your desktop VM**, browse to a website, and confirm the rule worked to generate an alert containing "ASDFGH". Note that Hackerbot will require you to include particular text within the alerts of the rules you write.
|
||||
|
||||
|
||||
# TODO RANDOM
|
||||
@@ -63,21 +68,16 @@ Browse to a website, and confirm the rule worked to generate an alert containing
|
||||
|
||||
Add a rule to detect any attempt to connect to a Telnet server, the output message must include "- RANDOM". Connections to a Telnet server could be a security issue, since logging into a networked computer using Telnet is known to be insecure because traffic is not encrypted. Don't forget to reload Snort!
|
||||
|
||||
|
||||
#TODO SecGen module to install telnetd
|
||||
|
||||
|
||||
|
||||
Once you have saved your rule and reloaded Snort, test this rule by using Telnet. Rather than starting an actual Telnet server (unless you want to do so), you can simulate this by using Netcat to listen on the Telnet port, then connect with Telnet from the desktop VM.
|
||||
|
||||
On a terminal on the Kali Linux VM:
|
||||
|
||||
```bash
|
||||
netcat -l -p 23
|
||||
```
|
||||
|
||||
Leaving that running, and on a terminal on the openSUSE VM:
|
||||
|
||||
|
||||
```bash
|
||||
telnet localhost
|
||||
```
|
||||
|
||||
@@ -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 = 'IDS'
|
||||
|
||||
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,52 @@
|
||||
<?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 a IDS rules lab</name>
|
||||
<author>Z. Cliffe Schreuders</author>
|
||||
<module_license>GPLv3</module_license>
|
||||
<description>Generates a config file for a hackerbot for a IDS lab.
|
||||
Topics covered: Writing Snort rules.</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>
|
||||
|
||||
<!--TODO: less flags-->
|
||||
<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"/>
|
||||
<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,432 @@
|
||||
# Intrusion Detection and Prevention Systems: Configuration and Monitoring using Snort
|
||||
|
||||
## 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)
|
||||
- ids_server (IP address: <%= $ids_server_ip %>)
|
||||
- web_server (IP address: <%= $web_server_ip %>)
|
||||
- desktop
|
||||
|
||||
All of these VMs need to be running to complete the lab.
|
||||
|
||||
**Ensure VMs allow promiscuous mode**
|
||||
If you are completing this lab on Leeds Beckett oVirt infrastructure, this should be sorted. Otherwise, if you have used SecGen to spin up VMs, you need to ensure your VMs have permission to monitor networks by using promiscuous mode.
|
||||
|
||||
### Your login details for the "desktop" and "ids_server" VMs
|
||||
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 the VM needs to be running to complete the lab.
|
||||
|
||||
You don't need to login to the backup_server or web_server, but you will connect to them via SSH and http later in 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 monitor the network and will attack your 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.
|
||||
|
||||
---
|
||||
## Network monitoring basics
|
||||
It is important for an organisation to monitor their network for detecting unwanted behaviour, such as malicious attacks or organisational resources being misused.
|
||||
|
||||
### Tcpdump
|
||||
|
||||
This section gives a quick overview of the basics of network monitoring, using tools such as Tcpdump. Keep in mind that these are important foundations, and we will quickly build on these.
|
||||
|
||||
**From your desktop VM**, ==SSH into the ids_server==. **Leave this console open in a separate tab** (Shift-Ctrl-T):
|
||||
|
||||
```bash
|
||||
ssh <%= $main_user %>@<%= $ids_server_ip %>
|
||||
|
||||
sudo -i
|
||||
```
|
||||
|
||||
**From this ssh session:** To view live network traffic, ==start tcpdump on the ids_server via ssh:==
|
||||
|
||||
```bash
|
||||
tcpdump
|
||||
```
|
||||
> Tip: If running tcpdump generates the error "packet printing is not supported for link type USB\_Linux: use -w", then append "-i *eth0*" to each tcpdump command. (Where eth0 is the name of the interface as reported by ifconfig).
|
||||
|
||||
With tcpdump still running via ssh, **from the desktop VM** ==perform a ping to the ids_server VM.==
|
||||
|
||||
```bash
|
||||
ping <%= $ids_server_ip %>
|
||||
```
|
||||
> Run the above from the desktop VM (not from the tab SSHed to the ids_server).
|
||||
|
||||
> Note that tcpdump displays the network activity taking place, including the pings, and various TCP connections and ARP requests. Depending on your environment you might be seeing the traffic between various VMs.
|
||||
|
||||
The IDS server has a network card interface that can enter promiscuous mode, meaning that it can view traffic destined to other systems on the network. (Not just the traffic destined for the ids_server, as would normally be the case.)
|
||||
|
||||
Test this, **from the desktop** ==ping the web_server==:
|
||||
|
||||
```bash
|
||||
ping <%= $web_server_ip %>
|
||||
```
|
||||
> If your network is configured correctly, from the Tcpdump running on the ids_server you should see the pings between these separate VMs (the desktop, and the web_server). Take the time to confirm that this is working.
|
||||
|
||||
Once you have seen tcpdump in action displaying these packets ==press Ctrl-C to exit.==
|
||||
|
||||
Tcpdump can format the output in various ways, showing various levels of detail.
|
||||
|
||||
**From the ids_server SSH session** tab, ==run:==
|
||||
|
||||
```bash
|
||||
tcpdump -q
|
||||
```
|
||||
> This shows a less verbose version of the output.
|
||||
|
||||
**From the desktop** ==Ping the web_server VM again and observe the tcpdump output in the ssh session.==
|
||||
|
||||
```bash
|
||||
tcpdump -A
|
||||
```
|
||||
> Shows the packet content without the information about the source and destination.
|
||||
|
||||
When you ==access a web page in a browser on the desktop VM== (go ahead... ==reload this labsheet== webpage), Tcpdump will display the content, so long as the traffic is not SSL encrypted (for example, so long as the URL doesn't start with http**s**://).
|
||||
|
||||
==Ping the web_server again== and observe the output.
|
||||
|
||||
Stop tcpdump (Ctrl-C) on the ids_server VM once you have observed the output.
|
||||
|
||||
==Run the following== command **on the ids_server** SSH session:
|
||||
|
||||
```bash
|
||||
tcpdump -v
|
||||
```
|
||||
> The above is even more verbose, showing lots of detail about the network traffic.
|
||||
|
||||
Now try the ==port scan again==. Note the very detailed output.
|
||||
|
||||
It is possible to write tcpdump network traffic to storage, so that it can be analysed later:
|
||||
```bash
|
||||
tcpdump -w /tmp/tcpdump-output
|
||||
```
|
||||
|
||||
While that is running, ==access a web page from Firefox on the desktop VM== browse to:
|
||||
> ==<%= $web_server_ip %>==
|
||||
|
||||
Then ==close tcpdump== (Ctrl-C).
|
||||
|
||||
To view the file containing the tcpdump output on the Kali VM type:
|
||||
|
||||
```bash
|
||||
less /tmp/tcpdump-output
|
||||
```
|
||||
> (Press "y" to see the output if you are warned that it may be a binary file)
|
||||
|
||||
> You should be able to PageUp and PageDown through the file.
|
||||
|
||||
> Press "Q" to quit when ready
|
||||
|
||||
Run `man tcpdump` and read about the many options for output and filtering.
|
||||
|
||||
### Tcpdump filtering
|
||||
|
||||
We can also use tcpdump to do some simple monitoring of the network traffic to detect certain key words.
|
||||
|
||||
**On the ids_server** ssh session, ==run:==
|
||||
|
||||
```bash
|
||||
tcpdump -A | grep "GET"
|
||||
```
|
||||
> Tip: if you are using a UK keyboard and the VM configured for US, the "|" symbol is located where "\~" is.
|
||||
|
||||
Open a web browser **on the desktop VM**, and visit [*http://<%= $web_server_ip %>*](http://<%= $web_server_ip %>), note that tcpdump captures *most* network content, and grep can be used to filter it down to lines that are interesting to us.
|
||||
|
||||
Note that making sense of this information using tcpdump and/or Wireshark is possible (and is a common sys-admin task), but the output is too noisy to be constantly and effectively monitored by a human to detect security incidents. Therefore we can use an IDS such as Snort to monitor and analyse the network traffic to detect activity that it is configured to alert.
|
||||
|
||||
Make sure tcpdump is stopped (Ctrl-C).
|
||||
|
||||
## IDS monitoring basics
|
||||
|
||||
Continuing **on the ids_server VM** ssh session:
|
||||
|
||||
==Make a backup== of the snort’s configuration file in case anything goes wrong:
|
||||
|
||||
```bash
|
||||
cp /etc/snort/snort.conf /etc/snort/snort.conf.bak
|
||||
```
|
||||
|
||||
==Change Snort’s output== to something more readable:
|
||||
|
||||
```bash
|
||||
vi /etc/snort/snort.conf
|
||||
```
|
||||
> (Remember: editing using vi involves pressing "i" to insert/edit text, then *Esc*,
|
||||
|
||||
> ":wq" to write changes and quit)
|
||||
|
||||
==Comment out== the line starting with "`output` …"
|
||||
> (Put a \# in front of it)
|
||||
|
||||
==Add the following line:==
|
||||
`output alert_fast`
|
||||
> **Help with find in vi:** the find command in vi is the / character (forward slash) . When **NOT in insert mode** (pressing Esc will get you out of insert mode if you need to), to find "output" you could enter / output \[+ PRESS ENTER\] Then press the n character to find the next output and the next and the next and the next etc.
|
||||
>
|
||||
> If there is still no alert file in /var/log/snort/, you may need to edit /etc/snort/snort.debian.conf, to use the correct interface (for example, eth1 if the output of "ifconfig" does not contain "eth0").
|
||||
|
||||
==Start Snort:==
|
||||
|
||||
```bash
|
||||
systemctl start snort
|
||||
```
|
||||
|
||||
Snort should now be running, monitoring network traffic for activity.
|
||||
|
||||
==Do an nmap port scan of the ids_server== VM (from the desktop VM):
|
||||
|
||||
```bash
|
||||
nmap <%= $ids_server_ip %>
|
||||
```
|
||||
|
||||
This should trigger an alert from Snort, which is stored in an alerts log file.
|
||||
|
||||
"Follow" the Snort alert log file by running:
|
||||
|
||||
```bash
|
||||
tail -f /var/log/snort/alert
|
||||
```
|
||||
>The tail program will wait for new alerts to be written to the file, and will display them as they are logged.
|
||||
|
||||
==LogBook question: Does the log match what happened? Are there any false positives (alerts that describe things that did not actually happen)?==
|
||||
|
||||
==Do an nmap port scan of the web_server== VM (from the desktop VM):
|
||||
|
||||
```bash
|
||||
nmap <%= $web_server_ip %>
|
||||
```
|
||||
|
||||
This should trigger another alert.
|
||||
|
||||
Press Ctrl-C to ==stop the alert tail process==, if it did not do so automatically.
|
||||
|
||||
The Snort configuration file can be configured to output, a "tcpdump" formatted network capture.
|
||||
|
||||
Open the snort.conf file in vi:
|
||||
|
||||
```bash
|
||||
vi /etc/snort/snort.conf
|
||||
```
|
||||
> (Remember: editing using vi involves pressing "i" to insert/edit text, then *Esc*, ":wq" to write changes and quit)
|
||||
|
||||
Add the following line and then save the changes (or uncomment by removing the \#):
|
||||
|
||||
`output log_tcpdump: tcpdump.log`
|
||||
|
||||
Restart Snort:
|
||||
|
||||
```bash
|
||||
systemctl restart snort
|
||||
```
|
||||
|
||||
Try another type of port scan, such as an ==Xmas Tree scan from the desktop== VM (Hint: `man nmap`).
|
||||
|
||||
Then run the following command to ==view the contents of the log:==
|
||||
|
||||
```bash
|
||||
tcpdump -r /var/log/snort/tcpdump.log.*
|
||||
```
|
||||
|
||||
You can use tcpdump’s various flags to change the way it is displayed, or you could even open the logged network activity in Wireshark.
|
||||
|
||||
##Configuring Snort
|
||||
|
||||
**On the ids_server** ssh session, ==edit /etc/snort/snort.conf==; for example:
|
||||
|
||||
```bash
|
||||
vi /etc/snort/snort.conf
|
||||
```
|
||||
> (Remember: editing using vi involves pressing "i" to insert/edit text, then *Esc*, ":wq" to write changes and quit)
|
||||
|
||||
Scroll through the config file and, take notice of these details:
|
||||
|
||||
- In a production environment you would configure Snort to to correctly identify which traffic is considered LAN traffic, and which IP addresses are known to run various servers (this is also configured in snort.debian.conf). In this case, we will leave these settings as is.
|
||||
|
||||
- Note the line "`var RULE_PATH /etc/snort/rules`": this is where the IDS signatures are stored.
|
||||
|
||||
- Note the presence of a Back Orifice detector preprocessor "bo". Back Orifice was a Windows Trojan horse that was popular in the 90s.
|
||||
|
||||
- We have already seen the "sfportscan" preprocessor in practice, detecting various kinds of port scans.
|
||||
|
||||
- The "arpspoof" preprocessor is described as experimental, and is not enabled by default.
|
||||
|
||||
- Towards the end of the config file are "include" lines, which specify which of the rule files in RULE\_PATH are in effect. As is common, lines beginning with "\#" are ignored, which is used to list disabled rule files. There are rule files for detecting known exploits, attacks against services such as DNS and FTP, denial of service (DoS) attacks, and so on.
|
||||
|
||||
Add the following line below the other include rules (at the end of the file):
|
||||
|
||||
`include $RULE_PATH/my.rules`
|
||||
|
||||
Save your changes to snort.conf
|
||||
> (For example, in vi, press Esc, then type ":wq").
|
||||
|
||||
> Hint: you may find it easier to use Esc, then type ":w" to write your changes to disk and then type ":q" to exit (or "x" shorthand for "wq").
|
||||
|
||||
Run this command, to ==create your new rule file:==
|
||||
|
||||
```bash
|
||||
touch /etc/snort/rules/my.rules
|
||||
```
|
||||
|
||||
==Edit the file.== For example:
|
||||
|
||||
```bash
|
||||
vi /etc/snort/rules/my.rules
|
||||
```
|
||||
|
||||
==Add this line (*with your own name*), and save your changes:==
|
||||
|
||||
`alert icmp any any ->any any (msg: "*Your-name*: ICMP Packet found"; sid:1000000; rev:1;)`
|
||||
|
||||
> For example, `alert icmp any any -> any any (msg: "**Cliffe**: ICMP Packet found"; sid:1000000; rev:1;)`
|
||||
|
||||
Now that you have new rules, tell Snort to ==reload its configuration:==
|
||||
|
||||
```bash
|
||||
systemctl restart snort
|
||||
```
|
||||
> If after attempting a reload, Snort fails to start, then you have probably made a configuration mistake, so check the log for details by running: `tail /var/log/syslog`
|
||||
|
||||
Due to the new rule you have just applied, sending a simple ICMP Ping (typically used to troubleshoot connectivity) will trigger a Snort alert.
|
||||
|
||||
Try it, **from the desktop** VM, ==ping the web_server:==
|
||||
|
||||
```bash
|
||||
ping <%= $web_server_ip %>
|
||||
```
|
||||
|
||||
Check for the Snort alert. You should see that the ping was detected, and our new message was added to the alerts log file.
|
||||
|
||||
## Writing your own Snort rules
|
||||
|
||||
Snort is predominantly designed as a signature-based IDS. Snort monitors the network for matches to rules that indicate activity that should trigger an alert. You have now seen Snort detect a few types of activity, and have added a rule to detect ICMP packets. Next you will apply more complicated rules, and create your own.
|
||||
|
||||
In addition to the lecture slides, you may find this resource helpful to complete these tasks:
|
||||
|
||||
> Martin Roesch (n.d.) **Chapter 2:** Writing Snort Rules - How to Write Snort Rules and Keep Your Sanity. In: *Snort Users Manual*. Available from: <[*http://www.snort.org.br/documentacao/SnortUsersManual.pdf*](http://www.snort.org.br/documentacao/SnortUsersManual.pdf)>
|
||||
|
||||
In general, rules are defined on one line (although, they can break over lines by using `\`), and take the form of:
|
||||
|
||||
**header (body)**
|
||||
|
||||
where header = "**action** (log,alert) **protocol** (ip,tcp,udp,icmp,any) **source_IP** **source_port** **direction** (->,<>) **destination_IP** **destination_port**"
|
||||
|
||||
> for example: `alert tcp any any -> any any` to make an alert for all TCP traffic, or `alert tcp any any -> 192.168.0.1 23` to make an alert for connections to telnet on the given IP address
|
||||
|
||||
and body = "**option; option: "parameter"; ...**"
|
||||
|
||||
The most common options are:
|
||||
|
||||
> `msg: "message to display"`
|
||||
|
||||
and, to search the packet’s content:
|
||||
|
||||
> `content: "some text to search for"`
|
||||
|
||||
To set the type of alert:
|
||||
|
||||
> `classtype:misc-attack`
|
||||
>
|
||||
> (where *misc-attack* is defined in `/etc/snort/classification.conf`)
|
||||
|
||||
To give a unique identifier and revision version number:
|
||||
|
||||
> `sid:1000001; rev:1`
|
||||
|
||||
So for example the body could be:
|
||||
|
||||
> `msg: "user login attempt"; content: "user"; classtype:attempted-user; sid:1000001; rev:1;`
|
||||
|
||||
And bringing all this together a Snort rule could read:
|
||||
|
||||
> `alert tcp any any -> 192.168.0.1 110 (msg: "Email login attempt"; content: "user"; classtype:attempted-user; sid:1000001; rev:1;)`
|
||||
|
||||
This rule looks at packets destined for 192.168.0.1 on the pop3 Email port (110), and sends an alert if the content contains the "user" command (which is used to log on to check email). Note that this rule is imperfect as it is, since it is case sensitive.
|
||||
|
||||
There are lots more options that can make rules more precise and efficient. For example, making them case insensitive, or starting to search content after an offset. Feel free to do some reading, to help you to create better IDS rules.
|
||||
|
||||
==Figure out how the rule could be improved to be case insensitive.==
|
||||
|
||||
==Browse the existing rules in `/etc/snort/rules` and figure out how at least two of them work.==
|
||||
|
||||
Lets create a basic rule that detects any web traffic on port 80.
|
||||
|
||||
```bash
|
||||
echo "alert tcp any any -> any 80 (msg: "Web traffic detected - RANDOM"; sid:1000002; rev:1;)" >> /etc/snort/rules/my.rules
|
||||
|
||||
systemctl restart snort
|
||||
```
|
||||
Browse to a website, and confirm the rule worked to generate an alert containing RANDOM.
|
||||
|
||||
# TODO RANDOM
|
||||
# HACKERBOT ATTACKS
|
||||
(Move up above)
|
||||
I'm about to attack your system, use Snort to detect the method of attack.
|
||||
??? quiz???
|
||||
Random IP address? LPORT?
|
||||
|
||||
---
|
||||
Add a rule to detect any attempt to connect to a Telnet server, the output message must include "- RANDOM". Connections to a Telnet server could be a security issue, since logging into a networked computer using Telnet is known to be insecure because traffic is not encrypted. Don't forget to reload Snort!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Once you have saved your rule and reloaded Snort, test this rule by using Telnet. Rather than starting an actual Telnet server (unless you want to do so), you can simulate this by using Netcat to listen on the Telnet port, then connect with Telnet from the desktop VM.
|
||||
|
||||
On a terminal on the Kali Linux VM:
|
||||
|
||||
```bash
|
||||
netcat -l -p 23
|
||||
```
|
||||
|
||||
Leaving that running, and on a terminal on the openSUSE VM:
|
||||
|
||||
|
||||
```bash
|
||||
telnet localhost
|
||||
```
|
||||
Type "hello"
|
||||
|
||||
|
||||
|
||||
##TODO
|
||||
Create a rule that only triggers on loading the Webserver's homepage (http://<%= $web_server_ip %>). Don't forget to reload Snort.
|
||||
|
||||
---
|
||||
|
||||
Create a rule that triggers on the
|
||||
|
||||
##TODO
|
||||
Create a Snort rule that detects visits to the Leeds Beckett website from the Kali VM, but does not get triggered by general web browsing.
|
||||
|
||||
Hints:
|
||||
> Look at some of the existing Snort rules for detecting Web sites, such as those in /etc/snort/rules/community-inappropriate.rules
|
||||
|
||||
> In the IMS labs or when using oVirt, you are likely using the proxy to access the web, so you will need to approach your rules a little differently, you may find you need to change the port you are listening to. Look at the output of tcpdump -A when you access a web page, what does the traffic contain that may point to what is being accessed? Have a look through the output of tcpdump for the text "Host".
|
||||
|
||||
As before, include your name in the alert message.
|
||||
|
||||
##TODO
|
||||
|
||||
Setup Snort as an intrusion *prevention* system (IPS): on the Kali VM so that it can actually deny traffic, and demonstrate with a rule. You may wish to extend the Leeds Beckett website rule, so that all attempts to access the website are denied by Snort.
|
||||
|
||||
|
||||
# write a rule that detects
|
||||
"Top secret"
|
||||
Randomly specified content
|
||||
Randomly generated content (requires network monitoring)
|
||||
attacks
|
||||
random port number (by service name?)
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# Intrusion Detection and Prevention Systems: Configuration and Monitoring using Snort
|
||||
|
||||
## 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)
|
||||
- ids_server (IP address: <%= $ids_server_ip %>)
|
||||
- web_server (IP address: <%= $web_server_ip %>)
|
||||
- desktop
|
||||
|
||||
All of these VMs need to be running to complete the lab.
|
||||
|
||||
**Ensure the ids_server VM is allowed promiscuous mode.** If you are completing this lab on Leeds Beckett oVirt infrastructure, this should be sorted. Otherwise, if you have used SecGen to spin up VMs, you need to ensure your VMs have permission to monitor networks using promiscuous mode. On the Leeds Beckett oVirt infrastructure we have snoop networks, which mirror all the traffic between systems. On Virtualbox, you would need to go to Advanced network settings for the host-only network on the ids_server and enable promiscious mode.
|
||||
|
||||
### Your login details for the "desktop" and "ids_server" VMs
|
||||
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 or web_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 monitor the network and will attack your systems. 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.
|
||||
|
||||
---
|
||||
## Getting Snort up and running
|
||||
|
||||
==Change Snort's output== to something more readable:
|
||||
|
||||
```bash
|
||||
sudo vi /etc/snort/snort.conf
|
||||
```
|
||||
> (Remember: editing using vi involves pressing "i" to insert/edit text, then *Esc*,
|
||||
|
||||
> ":wq" to write changes and quit)
|
||||
|
||||
==Add the following line:==
|
||||
`output alert_fast`
|
||||
|
||||
==Change Snort's interface== to eth1 (or as you identified earlier), and set the local network to your IP address range (or "any"):
|
||||
|
||||
```bash
|
||||
sudo vi /etc/snort/snort.debian.conf
|
||||
```
|
||||
> Set the interface and HOME network range, and exit vi (Esc, ":wq").
|
||||
|
||||
==Restart Snort:==
|
||||
|
||||
```bash
|
||||
sudo service snort stop
|
||||
sudo service snort start
|
||||
```
|
||||
> Using "reload" or "restart" may not update the interface.
|
||||
|
||||
Snort should now be running, monitoring network traffic for activity.
|
||||
|
||||
It can be helpful to monitor network traffic while writing IDS rules. Start Wireshark:
|
||||
|
||||
```bash
|
||||
kdesudo wireshark &
|
||||
```
|
||||
> For this exercise you can ignore the warnings about running Wireshark as root, or read online to learn to use setcap to grant Wireshark more specific privileges.
|
||||
@@ -0,0 +1,140 @@
|
||||
<%
|
||||
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
|
||||
$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 = 10
|
||||
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>Your web server is going to be attacked. I have inside information that will help you to monitor your network for the attacks. If you work with me I'll provide you with 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>IDS: Writing rules</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>
|
||||
<get_shell>msfconsole -x "use exploit/unix/misc/distcc_exec; set RHOST <%= $web_server_ip %>; exploit"</get_shell>
|
||||
<post_command>whoami > /dev/null; echo "<%= $flags.pop %>" > /dev/null; echo 'Find the flag! (in the network traffic)'</post_command>
|
||||
|
||||
<prompt>#6 Your webserver is about to be scanned/attacked. Use Tcpdump and/or Wireshark to view the behaviour of the attacker. There is a flag to be found over the wire. </prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>0</output_matches>
|
||||
<message>Hope you caught that.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>1</output_matches>
|
||||
<message>:( Failed to contact the web server (<%= $web_server_ip %>)</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something was not right...</message>
|
||||
</else_condition>
|
||||
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'write_snort_rules.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.
|
||||
|
||||

|
||||
@@ -0,0 +1,3 @@
|
||||
## Resources
|
||||
|
||||
Martin Roesch (n.d.) **Chapter 2:** Writing Snort Rules - How to Write Snort Rules and Keep Your Sanity. In: *Snort Users Manual*. Available from: <[*http://www.snort.org.br/documentacao/SnortUsersManual.pdf*](http://www.snort.org.br/documentacao/SnortUsersManual.pdf)>
|
||||
@@ -0,0 +1,144 @@
|
||||
## Intrusion detection system (IDS) monitoring basics
|
||||
|
||||
Continuing **on the ids_server VM:**
|
||||
|
||||
==Make a backup== of the snort's configuration file in case anything goes wrong:
|
||||
|
||||
```bash
|
||||
sudo cp /etc/snort/snort.conf /etc/snort/snort.conf.bak
|
||||
```
|
||||
|
||||
==Change Snort's output== to something more readable:
|
||||
|
||||
```bash
|
||||
sudo vi /etc/snort/snort.conf
|
||||
```
|
||||
> (Remember: editing using vi involves pressing "i" to insert/edit text, then *Esc*,
|
||||
|
||||
> ":wq" to write changes and quit)
|
||||
|
||||
==Add the following line:==
|
||||
`output alert_fast`
|
||||
|
||||
==Change Snort's interface== to eth1 (or as you identified earlier), and set the local network to your IP address range (or "any"):
|
||||
|
||||
```bash
|
||||
sudo vi /etc/snort/snort.debian.conf
|
||||
```
|
||||
> Set the interface and HOME network range, and exit vi (Esc, ":wq").
|
||||
|
||||
==Start Snort:==
|
||||
|
||||
```bash
|
||||
sudo service snort stop
|
||||
sudo service snort start
|
||||
```
|
||||
> Using "reload" or "restart" may not update the interface.
|
||||
|
||||
Snort should now be running, monitoring network traffic for activity.
|
||||
|
||||
==Have a chat with Hackerbot== (**from the desktop VM**).
|
||||
|
||||
This should trigger an alert from Snort, which is stored in an alerts log file.
|
||||
|
||||
**From the ids_server**, ==follow the Snort alert log== file by running (you may like to do this from a new tab):
|
||||
|
||||
```bash
|
||||
sudo tail -f /var/log/snort/alert
|
||||
```
|
||||
>The tail program will wait for new alerts to be written to the file, and will display them as they are logged.
|
||||
|
||||
==Do an nmap port scan of the web_server== VM (from the desktop VM):
|
||||
|
||||
```bash
|
||||
nmap <%= $web_server_ip %>
|
||||
```
|
||||
|
||||
This should trigger another alert.
|
||||
|
||||
==LogBook question: Does the log match what happened? Are there any false positives (alerts that describe things that did not actually happen)?==
|
||||
|
||||
Try another type of port scan, such as an ==Xmas Tree scan from the desktop== VM (Hint: `man nmap`).
|
||||
|
||||
Press Ctrl-C to ==stop the alert tail process==, if it did not do so automatically.
|
||||
|
||||
The Snort configuration file is also configured to output a "tcpdump" formatted network capture. (`output log_tcpdump: tcpdump.log`)
|
||||
|
||||
Then run the following command to ==view the contents of the log:==
|
||||
|
||||
```bash
|
||||
sudo ls /var/log/snort/
|
||||
sudo tcpdump -r /var/log/snort/tcpdump.log.XXXXX
|
||||
```
|
||||
> Where XXXXX is one of the logs shown from the first command.
|
||||
|
||||
You can use tcpdump's various flags to change the way it is displayed, or you could even open the logged network activity in Wireshark.
|
||||
|
||||
##Configuring Snort
|
||||
|
||||
**On the ids_server**, ==edit /etc/snort/snort.conf==; for example:
|
||||
|
||||
```bash
|
||||
vi /etc/snort/snort.conf
|
||||
```
|
||||
> (Remember: editing using vi involves pressing "i" to insert/edit text, then *Esc*, ":wq" to write changes and quit)
|
||||
|
||||
Scroll through the config file and, take notice of these details:
|
||||
|
||||
- In a production environment you would configure Snort to to correctly identify which traffic is considered LAN traffic, and which IP addresses are known to run various servers (this is also configured in snort.debian.conf). In this case, we will leave these settings as is.
|
||||
|
||||
- Note the line "`var RULE_PATH /etc/snort/rules`": this is where the IDS signatures are stored.
|
||||
|
||||
- Note the presence of a Back Orifice detector preprocessor "bo". Back Orifice was a Windows Trojan horse that was popular in the 90s.
|
||||
|
||||
- Note the "sfportscan" preprocessor (is it enabled?), which can detect various kinds of port scans.
|
||||
|
||||
- The "arpspoof" preprocessor is described as experimental, and is not enabled by default.
|
||||
|
||||
- Towards the end of the config file are "include" lines, which specify which of the rule files in RULE\_PATH are in effect. As is common, lines beginning with "\#" are ignored, which is used to list disabled rule files. There are rule files for detecting known exploits, attacks against services such as DNS and FTP, denial of service (DoS) attacks, and so on.
|
||||
|
||||
Add the following line below the other include rules (at the end of the file):
|
||||
|
||||
`include $RULE_PATH/my.rules`
|
||||
|
||||
Save your changes to snort.conf
|
||||
> (For example, in vi, press Esc, then type ":wq").
|
||||
|
||||
> Hint: you may find it easier to use Esc, then type ":w" to write your changes to disk and then type ":q" to exit (or "x" shorthand for "wq").
|
||||
|
||||
Run this command, to ==create your new rule file:==
|
||||
|
||||
```bash
|
||||
sudo touch /etc/snort/rules/my.rules
|
||||
```
|
||||
|
||||
==Edit the file.== For example:
|
||||
|
||||
```bash
|
||||
sudo vi /etc/snort/rules/my.rules
|
||||
```
|
||||
|
||||
==Add this line (*with your own name*), and save your changes:==
|
||||
|
||||
`alert icmp any any ->any any (msg: "*Your-name*: ICMP Packet found"; sid:1000000; rev:1;)`
|
||||
|
||||
> For example, `alert icmp any any -> any any (msg: "**Cliffe**: ICMP Packet found"; sid:1000000; rev:1;)`
|
||||
|
||||
Now that you have new rules, tell Snort to ==reload its configuration:==
|
||||
|
||||
```bash
|
||||
sudo service snort stop
|
||||
sudo service snort start
|
||||
```
|
||||
> If after attempting a reload, Snort fails to start, then you have probably made a configuration mistake, so check the log for details by running: `tail /var/log/syslog`
|
||||
|
||||
Due to the new rule you have just applied, sending a simple ICMP Ping (typically used to troubleshoot connectivity) will trigger a Snort alert.
|
||||
|
||||
Try it, **from the desktop** VM, ==ping the web_server:==
|
||||
|
||||
```bash
|
||||
ping <%= $web_server_ip %>
|
||||
```
|
||||
|
||||
Check for the Snort alert. You should see that the ping was detected, and our new message was added to the alerts log file.
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
### Tcpdump
|
||||
|
||||
This section gives a quick overview of the basics of network monitoring, using tools such as Tcpdump and Wireshark. Keep in mind that these are important foundations, and we will quickly build on these.
|
||||
|
||||
**From your ids_server VM.** (==Login to the ids_server VM==)
|
||||
|
||||
To view live network traffic, ==start tcpdump on the ids_server:==
|
||||
|
||||
First, identify the network interface card (nic) to use:
|
||||
```bash
|
||||
ip -4 -o a s | grep <%= $ids_server_ip %>
|
||||
```
|
||||
> The "ip a s" command lists all local IP addresses, and -4 filters to only show IPv4, while -o sets one-line output mode
|
||||
|
||||
```bash
|
||||
sudo tcpdump -i eth1
|
||||
```
|
||||
> Where **eth1**, is the name of the interface given in response to the above command.
|
||||
|
||||
With tcpdump still running, **from the desktop VM** ==perform a ping to the ids_server VM.==
|
||||
|
||||
```bash
|
||||
ping <%= $ids_server_ip %>
|
||||
```
|
||||
> Run the above from the desktop VM.
|
||||
|
||||
> Note that Tcpdump displays the network activity taking place, including the pings, and various TCP connections and ARP requests. Depending on your environment you might also be seeing the traffic between various other VMs.
|
||||
|
||||
==Stop the ping== with Ctrl-C.
|
||||
|
||||
The IDS server has a network card interface that can enter promiscuous mode, meaning that it can view traffic destined to other systems on the network. (Without entering promiscuous mode a computer would only view the traffic destined for itself.)
|
||||
|
||||
Test this, **from the desktop** ==ping the web_server==:
|
||||
|
||||
```bash
|
||||
ping <%= $web_server_ip %>
|
||||
```
|
||||
> If your network is configured correctly, from the Tcpdump running on the ids_server you should see the pings between these separate VMs (the desktop, and the web_server). Take the time to confirm that this is working. If it is not showing this traffic, but did show the last output, you need to configure the ids_server to be able to view the network traffic.
|
||||
|
||||
Once you have seen tcpdump in action displaying these packets ==press Ctrl-C to exit.==
|
||||
|
||||
Tcpdump can format the output in various ways, showing various levels of detail.
|
||||
|
||||
**From the ids_server**, ==run:==
|
||||
|
||||
```bash
|
||||
sudo tcpdump -A -i eth1
|
||||
```
|
||||
> This shows the packet **content** without the information about the source and destination.
|
||||
|
||||
When you ==access a web page in a browser on the desktop VM== (go ahead... ==reload this labsheet== webpage), Tcpdump will display the content, so long as the traffic is not SSL encrypted (for example, so long as the URL doesn't start with http**s**://). Depending on the webserver and browser, the content may be compressed (but not encrypted) to save bandwidth.
|
||||
|
||||
**From the desktop VM**, use command line tools to ==view the labsheet and webserver pages:==
|
||||
|
||||
```bash
|
||||
curl <%= $web_server_ip %>
|
||||
curl <%= $hackerbot_server_ip %>
|
||||
```
|
||||
|
||||
==Ping the web_server again== and observe the output.
|
||||
|
||||
Stop tcpdump (Ctrl-C) on the ids_server VM once you have observed the output.
|
||||
|
||||
==Run the following== command **on the ids_server:**
|
||||
|
||||
```bash
|
||||
sudo tcpdump -v -i eth1
|
||||
```
|
||||
> The above is even more verbose, showing lots of detail about the network traffic.
|
||||
|
||||
Now try the ==above again==. Note the very detailed output.
|
||||
|
||||
It is possible to write tcpdump network traffic to storage, so that it can be analysed later:
|
||||
```bash
|
||||
sudo tcpdump -w /tmp/tcpdump-output -i eth1
|
||||
```
|
||||
|
||||
While that is running, ==access a web page from Firefox on the desktop VM== browse to ==[*http://<%= $web_server_ip %>*](http://<%= $web_server_ip %>)== (In a new tab.)
|
||||
|
||||
Then ==close tcpdump== (Ctrl-C).
|
||||
|
||||
To view the file containing the tcpdump output on the ids_server VM type:
|
||||
|
||||
```bash
|
||||
less /tmp/tcpdump-output
|
||||
```
|
||||
> (Press "y" to see the output if you are warned that it may be a binary file)
|
||||
|
||||
> You should be able to PageUp and PageDown through the file.
|
||||
|
||||
> Press "Q" to quit when ready
|
||||
|
||||
Run `man tcpdump` and read about the many options for output and filtering.
|
||||
|
||||
### Tcpdump filtering and Wireshark
|
||||
|
||||
We can also use tcpdump to do some simple monitoring of the network traffic to detect certain key words.
|
||||
|
||||
**On the ids_server**, ==run:==
|
||||
|
||||
```bash
|
||||
kdesudo wireshark &
|
||||
|
||||
sudo tcpdump -A -i eth1 | grep "GET"
|
||||
```
|
||||
> For this exercise you can ignore the warning about running Wireshark as root, or read online to learn to use setcap to grant Wireshark more specific privileges.
|
||||
|
||||
In Wireshark, choose the network interface card (such as eth1) then click the green start icon, to ==start monitoring traffic==. Generate some traffic and explore how to ==view it using Wireshark==.
|
||||
|
||||
You can also open the captured network traffic in Wireshark.
|
||||
|
||||
Open a web browser **on the desktop VM**, and visit [*http://<%= $web_server_ip %>*](http://<%= $web_server_ip %>), note that tcpdump captures *most* network content, and grep can be used to filter it down to lines that are interesting to us.
|
||||
|
||||
Note that making sense of this information using tcpdump and/or Wireshark is possible (and is a common sys-admin task), but the output is too noisy to be constantly and effectively monitored by a human to detect security incidents. Therefore we can use an IDS such as Snort to monitor and analyse the network traffic to detect activity that it is configured to alert.
|
||||
|
||||
Make sure tcpdump is stopped (Ctrl-C).
|
||||
@@ -0,0 +1,116 @@
|
||||
## Writing your own Snort rules
|
||||
|
||||
Snort is predominantly designed as a signature-based IDS. Snort monitors the network for matches to rules that indicate activity that should trigger an alert. You have now seen Snort detect a few types of activity, and have added a rule to detect ICMP packets. Next you will apply more complicated rules, and create your own.
|
||||
|
||||
You may find external reference guides to writing Snort rules helpful. See the resources section below, and Google may come in handy.
|
||||
|
||||
In general, rules are defined on one line (although, they can break over lines by using `\`), and take the form of:
|
||||
|
||||
**header (body)**
|
||||
|
||||
where header = "**action** (log,alert) **protocol** (ip,tcp,udp,icmp,any) **source_IP** **source_port** **direction** (->,<>) **destination_IP** **destination_port**"
|
||||
|
||||
> for example: `alert tcp any any -> any any` to make an alert for all TCP traffic, or `alert tcp any any -> 192.168.0.1 23` to make an alert for connections to telnet on the given IP address
|
||||
|
||||
and body = "**option; option: "parameter"; ...**"
|
||||
|
||||
The most common options are:
|
||||
|
||||
> `msg: "message to display"`
|
||||
|
||||
and, to search the packet's content:
|
||||
|
||||
> `content: "some text to search for"`
|
||||
|
||||
To set the type of alert:
|
||||
|
||||
> `classtype:misc-attack`
|
||||
>
|
||||
> (where *misc-attack* is defined in `/etc/snort/classification.conf`)
|
||||
|
||||
To give a unique identifier and revision version number:
|
||||
|
||||
> `sid:1000001; rev:1`
|
||||
|
||||
So for example the body could be:
|
||||
|
||||
> `msg: "user login attempt"; content: "user"; classtype:attempted-user; sid:1000001; rev:1;`
|
||||
|
||||
And bringing all this together a Snort rule could read:
|
||||
|
||||
> `alert tcp any any -> 192.168.0.1 110 (msg: "Email login attempt"; content: "user"; classtype:attempted-user; sid:1000001; rev:1;)`
|
||||
|
||||
This rule looks at packets destined for 192.168.0.1 on the pop3 Email port (110), and sends an alert if the content contains the "user" command (which is used to log on to check email). Note that this rule is imperfect as it is, since it is case sensitive.
|
||||
|
||||
There are lots more options that can make rules more precise and efficient. For example, making them case insensitive, or starting to search content after an offset. Feel free to do some reading, to help you to create better IDS rules.
|
||||
|
||||
==Figure out how the rule could be improved to be case insensitive.==
|
||||
|
||||
==Browse the existing rules in `/etc/snort/rules` and figure out how at least two of them work.==
|
||||
|
||||
Lets create a basic rule that detects any web traffic on port 80.
|
||||
|
||||
```bash
|
||||
echo "alert tcp any any -> any 80 (msg: "Web traffic detected - RANDOM"; sid:1000002; rev:1;)" >> /etc/snort/rules/my.rules
|
||||
|
||||
sudo service snort restart
|
||||
```
|
||||
Browse to a website, and confirm the rule worked to generate an alert containing the text 'RANDOM'.
|
||||
|
||||
|
||||
# TODO RANDOM
|
||||
# HACKERBOT ATTACKS
|
||||
|
||||
Add a rule to detect any attempt to connect to a Telnet server, the output message must include "- RANDOM". Connections to a Telnet server could be a security issue, since logging into a networked computer using Telnet is known to be insecure because traffic is not encrypted. Don't forget to reload Snort!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Once you have saved your rule and reloaded Snort, test this rule by using Telnet. Rather than starting an actual Telnet server (unless you want to do so), you can simulate this by using Netcat to listen on the Telnet port, then connect with Telnet from the desktop VM.
|
||||
|
||||
On a terminal on the Kali Linux VM:
|
||||
|
||||
```bash
|
||||
netcat -l -p 23
|
||||
```
|
||||
|
||||
Leaving that running, and on a terminal on the openSUSE VM:
|
||||
|
||||
|
||||
```bash
|
||||
telnet localhost
|
||||
```
|
||||
Type "hello"
|
||||
|
||||
|
||||
|
||||
##TODO
|
||||
Create a rule that only triggers on loading the Webserver's homepage (http://<%= $web_server_ip %>). Don't forget to reload Snort.
|
||||
|
||||
---
|
||||
|
||||
Create a rule that triggers on the
|
||||
|
||||
##TODO
|
||||
Create a Snort rule that detects visits to the Leeds Beckett website from the Kali VM, but does not get triggered by general web browsing.
|
||||
|
||||
Hints:
|
||||
> Look at some of the existing Snort rules for detecting Web sites, such as those in /etc/snort/rules/community-inappropriate.rules
|
||||
|
||||
> In the IMS labs or when using oVirt, you are likely using the proxy to access the web, so you will need to approach your rules a little differently, you may find you need to change the port you are listening to. Look at the output of tcpdump -A when you access a web page, what does the traffic contain that may point to what is being accessed? Have a look through the output of tcpdump for the text "Host".
|
||||
|
||||
As before, include your name in the alert message.
|
||||
|
||||
##TODO
|
||||
|
||||
Setup Snort as an intrusion *prevention* system (IPS): on the Kali VM so that it can actually deny traffic, and demonstrate with a rule. You may wish to extend the Leeds Beckett website rule, so that all attempts to access the website are denied by Snort.
|
||||
|
||||
|
||||
# write a rule that detects
|
||||
"Top secret"
|
||||
Randomly specified content
|
||||
Randomly generated content (requires network monitoring)
|
||||
attacks
|
||||
random port number (by service name?)
|
||||
|
||||
@@ -28,8 +28,10 @@ To make things even more interesting, ==edit the /etc/passwd file== and move the
|
||||
```bash
|
||||
sudo vi /etc/passwd
|
||||
```
|
||||
> **Be careful, making the wrong changes to this file will stop your system from working!**
|
||||
|
||||
> Move the cursor onto the line representing your new account (probably at the bottom).
|
||||
>
|
||||
|
||||
> In vi type:
|
||||
> :m *-==number==*
|
||||
>
|
||||
|
||||
@@ -53,7 +53,7 @@ Clearly, **the list of hashes is much smaller**.
|
||||
Create a new file somewhere in /etc/, containing your name. Name the file whatever you like (for example /etc/test).
|
||||
> Hint: 'sudo vi /etc/test', 'i' to enter insert mode, and after typing your name, 'Esc', ':wq'.
|
||||
|
||||
Also, change an existing file in /etc/, but do be careful to only make a minor change that will **not cause damage to your system**. For example, you could use vi to edit /etc/hostname ('sudo vi /etc/hostname'), and add a comment to the file such as '#find this comment!'
|
||||
Also, change an existing file in /etc/, but do be careful to only make a minor change that will **not cause damage to your system**. For example, you could use vi to edit /etc/wgetrc ('sudo vi /etc/wgetrc'), and add a comment to the file such as '#find this comment!'
|
||||
|
||||
Lets try to identify what has changed on our system...
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@ def check_output_conditions(bot_name, bots, current, lines, m)
|
||||
|
||||
sleep(1)
|
||||
# prompt for current hack
|
||||
if bots[bot_name]['messages'].key?('show_attack_numbers')
|
||||
m.reply "** ##{current + 1} **"
|
||||
end
|
||||
m.reply bots[bot_name]['attacks'][current]['prompt']
|
||||
else
|
||||
m.reply bots[bot_name]['messages']['last_attack'].sample
|
||||
@@ -130,6 +133,9 @@ def read_bots (irc_server_ip_address)
|
||||
current = bots[bot_name]['current_attack']
|
||||
|
||||
# prompt for the first attack
|
||||
if bots[bot_name]['messages'].key?('show_attack_numbers')
|
||||
m.reply "** ##{current + 1} **"
|
||||
end
|
||||
m.reply bots[bot_name]['attacks'][current]['prompt']
|
||||
m.reply bots[bot_name]['messages']['say_ready'].sample
|
||||
end
|
||||
@@ -148,6 +154,9 @@ def read_bots (irc_server_ip_address)
|
||||
current = bots[bot_name]['current_attack']
|
||||
|
||||
# prompt for current hack
|
||||
if bots[bot_name]['messages'].key?('show_attack_numbers')
|
||||
m.reply "** ##{current + 1} **"
|
||||
end
|
||||
m.reply bots[bot_name]['attacks'][current]['prompt']
|
||||
m.reply bots[bot_name]['messages']['say_ready'].sample
|
||||
else
|
||||
@@ -169,6 +178,9 @@ def read_bots (irc_server_ip_address)
|
||||
current = bots[bot_name]['current_attack']
|
||||
|
||||
# prompt for current hack
|
||||
if bots[bot_name]['messages'].key?('show_attack_numbers')
|
||||
m.reply "** ##{current + 1} **"
|
||||
end
|
||||
m.reply bots[bot_name]['attacks'][current]['prompt']
|
||||
m.reply bots[bot_name]['messages']['say_ready'].sample
|
||||
else
|
||||
@@ -204,6 +216,7 @@ def read_bots (irc_server_ip_address)
|
||||
if bots[bot_name]['attacks'][current].key?('get_shell_command_output')
|
||||
correct_answer.gsub!(/{{pre_shell_command_output_first_line}}/, (bots[bot_name]['attacks'][current]['get_shell_command_output']||'').split("\n").first)
|
||||
end
|
||||
correct_answer.chomp!
|
||||
|
||||
if answer.match(correct_answer)
|
||||
m.reply bots[bot_name]['messages']['correct_answer']
|
||||
@@ -218,6 +231,9 @@ def read_bots (irc_server_ip_address)
|
||||
|
||||
sleep(1)
|
||||
# prompt for current hack
|
||||
if bots[bot_name]['messages'].key?('show_attack_numbers')
|
||||
m.reply "** ##{current + 1} **"
|
||||
end
|
||||
m.reply bots[bot_name]['attacks'][current]['prompt']
|
||||
m.reply bots[bot_name]['messages']['say_ready'].sample
|
||||
else
|
||||
@@ -369,9 +385,9 @@ def read_bots (irc_server_ip_address)
|
||||
rescue # continue consuming until input blocks
|
||||
end
|
||||
begin
|
||||
Timeout.timeout(5) do # timeout 10 sec
|
||||
Timeout.timeout(15) do # timeout 10 sec
|
||||
stdin.close # no more input, end the program
|
||||
post_lines = stdout_err.read.chomp()
|
||||
post_lines << stdout_err.read.chomp()
|
||||
end
|
||||
rescue Timeout::Error
|
||||
Process.kill("KILL", wait_thr.pid)
|
||||
|
||||
247
scenarios/labs/5_ids_rules.xml
Normal file
247
scenarios/labs/5_ids_rules.xml
Normal file
@@ -0,0 +1,247 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<scenario xmlns="http://www.github/cliffe/SecGen/scenario"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/scenario">
|
||||
|
||||
<system>
|
||||
<system_name>desktop</system_name>
|
||||
<base distro="Debian 7.8" type="desktop" name="KDE"/>
|
||||
|
||||
<input into_datastore="organisation">
|
||||
<generator type="organisation"/>
|
||||
</input>
|
||||
|
||||
<!--generate two accounts, YOU and someone else-->
|
||||
<input into_datastore="accounts">
|
||||
<generator type="account">
|
||||
<input into="username">
|
||||
<generator type="random_word_generator">
|
||||
<input into="wordlist">
|
||||
<value>mythical_creatures</value>
|
||||
</input>
|
||||
</generator>
|
||||
</input>
|
||||
<input into="password">
|
||||
<value>tiaspbiqe2r</value>
|
||||
</input>
|
||||
<input into="super_user">
|
||||
<value>true</value>
|
||||
</input>
|
||||
<input into="leaked_filenames">
|
||||
<value></value>
|
||||
</input>
|
||||
<input into="strings_to_leak">
|
||||
<value></value>
|
||||
</input>
|
||||
</generator>
|
||||
<generator type="account">
|
||||
<input into="username">
|
||||
<generator type="random_word_generator">
|
||||
<input into="wordlist">
|
||||
<value>mythical_creatures</value>
|
||||
</input>
|
||||
</generator>
|
||||
</input>
|
||||
<input into="password">
|
||||
<value>test</value>
|
||||
</input>
|
||||
<input into="super_user">
|
||||
<value>false</value>
|
||||
</input>
|
||||
<input into="leaked_filenames">
|
||||
<value></value>
|
||||
</input>
|
||||
<input into="strings_to_leak">
|
||||
<value></value>
|
||||
</input>
|
||||
</generator>
|
||||
<generator type="account">
|
||||
<input into="username">
|
||||
<generator type="random_word_generator">
|
||||
<input into="wordlist">
|
||||
<value>mythical_creatures</value>
|
||||
</input>
|
||||
</generator>
|
||||
</input>
|
||||
<input into="password">
|
||||
<value>test</value>
|
||||
</input>
|
||||
<input into="super_user">
|
||||
<value>false</value>
|
||||
</input>
|
||||
<input into="leaked_filenames">
|
||||
<value></value>
|
||||
</input>
|
||||
<input into="strings_to_leak">
|
||||
<value></value>
|
||||
</input>
|
||||
</generator>
|
||||
</input>
|
||||
|
||||
<input into_datastore="hackerbot_access_root_password">
|
||||
<generator type="strong_password_generator"/>
|
||||
</input>
|
||||
|
||||
<!--Create the users-->
|
||||
<utility module_path=".*parameterised_accounts">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<utility module_path=".*kde_minimal">
|
||||
<input into="autologin_user">
|
||||
<datastore access="0" access_json="['username']">accounts</datastore>
|
||||
</input>
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
<input into="autostart_konsole">
|
||||
<value>true</value>
|
||||
</input>
|
||||
</utility>
|
||||
<utility module_path=".*handy_cli_tools"/>
|
||||
<utility module_path=".*nmap"/>
|
||||
|
||||
<utility module_path=".*iceweasel">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
<input into="autostart">
|
||||
<value>true</value>
|
||||
</input>
|
||||
<input into="start_page">
|
||||
<value>http://172.16.0.5</value>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<utility module_path=".*pidgin">
|
||||
<input into="server_ip">
|
||||
<value>172.16.0.5</value>
|
||||
</input>
|
||||
<input into="accounts">
|
||||
<datastore access="0">accounts</datastore>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<vulnerability module_path=".*ssh_root_login">
|
||||
<input into="root_password">
|
||||
<datastore>hackerbot_access_root_password</datastore>
|
||||
</input>
|
||||
</vulnerability>
|
||||
|
||||
<network type="private_network" range="172.16.0.0"/>
|
||||
</system>
|
||||
|
||||
<system>
|
||||
<system_name>ids_server</system_name>
|
||||
<base distro="Debian 7.8" type="desktop" name="KDE"/>
|
||||
|
||||
<utility module_path=".*parameterised_accounts">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<utility module_path=".*kde_minimal">
|
||||
<input into="autologin_user">
|
||||
<datastore access="0" access_json="['username']">accounts</datastore>
|
||||
</input>
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
<input into="autostart_konsole">
|
||||
<value>true</value>
|
||||
</input>
|
||||
</utility>
|
||||
<utility module_path=".*handy_cli_tools"/>
|
||||
<utility module_path=".*snort"/>
|
||||
<utility module_path=".*wireshark"/>
|
||||
<utility module_path=".*nmap"/>
|
||||
|
||||
<vulnerability module_path=".*ssh_root_login">
|
||||
<input into="root_password">
|
||||
<datastore>hackerbot_access_root_password</datastore>
|
||||
</input>
|
||||
</vulnerability>
|
||||
|
||||
<network type="private_network" range="172.16.0.0"/>
|
||||
</system>
|
||||
|
||||
<system>
|
||||
<system_name>web_server</system_name>
|
||||
<base platform="linux" distro="Debian 7.8"/>
|
||||
|
||||
<utility module_path=".*parameterised_accounts">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<vulnerability module_path=".*distcc_exec"/>
|
||||
|
||||
<!--TODO: FIXME ftp modules are currently broken-->
|
||||
<!--<service module_path=".*vsftpd"/>-->
|
||||
|
||||
<service type="httpd"/>
|
||||
|
||||
<!--<service module_path="services/unix/http/parameterised_website">
|
||||
<input into="organisation">
|
||||
<datastore>organisation</datastore>
|
||||
</input>
|
||||
</service>-->
|
||||
|
||||
<vulnerability module_path=".*ssh_root_login">
|
||||
<input into="root_password">
|
||||
<datastore>hackerbot_access_root_password</datastore>
|
||||
</input>
|
||||
</vulnerability>
|
||||
|
||||
<network type="private_network" range="172.16.0.0"/>
|
||||
</system>
|
||||
|
||||
<system>
|
||||
<system_name>hackerbot_server</system_name>
|
||||
<base distro="Kali" name="MSF"/>
|
||||
|
||||
<service type="ircd"/>
|
||||
|
||||
<utility module_path=".*metasploit_framework"/>
|
||||
<utility module_path=".*handy_cli_tools"/>
|
||||
<utility module_path=".*nmap"/>
|
||||
|
||||
<service type="httpd"/>
|
||||
|
||||
<utility module_path=".*hackerbot">
|
||||
<input into="hackerbot_configs">
|
||||
<generator module_path=".*ids_rules">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
<input into="root_password">
|
||||
<datastore>hackerbot_access_root_password</datastore>
|
||||
</input>
|
||||
<input into="ids_server_ip">
|
||||
<value>172.16.0.3</value>
|
||||
</input>
|
||||
<input into="web_server_ip">
|
||||
<value>172.16.0.4</value>
|
||||
</input>
|
||||
<input into="hackerbot_server_ip">
|
||||
<value>172.16.0.5</value>
|
||||
</input>
|
||||
</generator>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<network type="private_network" range="172.16.0.0"/>
|
||||
|
||||
<build type="cleanup">
|
||||
<input into="root_password">
|
||||
<generator type="strong_password_generator"/>
|
||||
</input>
|
||||
</build>
|
||||
</system>
|
||||
|
||||
</scenario>
|
||||
234
scenarios/labs/hacker_vs_hackerbot_1.xml
Normal file
234
scenarios/labs/hacker_vs_hackerbot_1.xml
Normal file
@@ -0,0 +1,234 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<scenario xmlns="http://www.github/cliffe/SecGen/scenario"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/scenario">
|
||||
|
||||
<system>
|
||||
<system_name>desktop</system_name>
|
||||
<base distro="Debian 7.8" type="desktop" name="KDE"/>
|
||||
|
||||
<input into_datastore="IP_addresses">
|
||||
<value>172.16.0.2</value>
|
||||
<value>172.16.0.3</value>
|
||||
<value>172.16.0.4</value>
|
||||
</input>
|
||||
|
||||
<input into_datastore="organisation">
|
||||
<generator type="organisation"/>
|
||||
</input>
|
||||
|
||||
<!--generate two accounts, YOU and someone else-->
|
||||
<input into_datastore="accounts">
|
||||
<generator type="account">
|
||||
<input into="username">
|
||||
<generator type="random_word_generator">
|
||||
<input into="wordlist">
|
||||
<value>mythical_creatures</value>
|
||||
</input>
|
||||
</generator>
|
||||
</input>
|
||||
<input into="password" into_datastore="desktop_login_password">
|
||||
<generator type="strong_password_generator"/>
|
||||
</input>
|
||||
<input into="super_user">
|
||||
<value>true</value>
|
||||
</input>
|
||||
<input into="leaked_filenames">
|
||||
<value>trade_secrets/code.pl</value>
|
||||
<value>trade_secrets/credit_card</value>
|
||||
<value>personal_secrets/credit_card</value>
|
||||
<value>logs/log1</value>
|
||||
<value>personal_secrets/address_book</value>
|
||||
</input>
|
||||
<input into="strings_to_leak">
|
||||
<value>no warnings; `$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=(
|
||||
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
|
||||
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
|
||||
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`</value>
|
||||
<value>Visa 4111 1111 1111 1111
|
||||
American Express 3400 0000 0000 009
|
||||
Diner's Club 3000 0000 0000 04</value>
|
||||
<value>MasterCard 5500 0000 0000 0004</value>
|
||||
<value>[80380.876359] usb 3-1: USB disconnect, device number 3
|
||||
[80382.626853] usb 3-1: new full-speed USB device number 4 using xhci_hcd
|
||||
[80382.755813] usb 3-1: New USB device found, idVendor=096e, idProduct=0858
|
||||
[80382.755819] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
|
||||
[80382.755822] usb 3-1: Product: U2F CCID KBOARD
|
||||
[80382.755825] usb 3-1: Manufacturer: FT
|
||||
[80382.757386] hid-generic 0003:096E:0858.0004: hiddev0,hidraw0: USB HID v1.00 Device [FT U2F CCID KBOARD] on usb-0000:00:14.0-1/input0
|
||||
[80383.925811] usb 3-1: USB disconnect, device number 4
|
||||
</value>
|
||||
<generator type="person" />
|
||||
</input>
|
||||
</generator>
|
||||
<generator type="account">
|
||||
<input into="username">
|
||||
<generator type="random_word_generator">
|
||||
<input into="wordlist">
|
||||
<value>mythical_creatures</value>
|
||||
</input>
|
||||
</generator>
|
||||
</input>
|
||||
<input into="password">
|
||||
<generator type="strong_password_generator"/>
|
||||
</input>
|
||||
<input into="super_user">
|
||||
<value>false</value>
|
||||
</input>
|
||||
<input into="leaked_filenames">
|
||||
<value>trade_secrets/code.pl</value>
|
||||
<value>trade_secrets/credit_card</value>
|
||||
<value>personal_secrets/credit_card</value>
|
||||
<value>logs/log1</value>
|
||||
<value>personal_secrets/address_book</value>
|
||||
</input>
|
||||
<input into="strings_to_leak">
|
||||
<value>no warnings; `$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=(
|
||||
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
|
||||
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
|
||||
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`</value>
|
||||
<value>Visa 4111 1111 1111 1111
|
||||
American Express 3400 0000 0000 009
|
||||
Diner's Club 3000 0000 0000 04</value>
|
||||
<value>MasterCard 5500 0000 0000 0004</value>
|
||||
<value>[80380.876359] usb 3-1: USB disconnect, device number 3
|
||||
[80382.626853] usb 3-1: new full-speed USB device number 4 using xhci_hcd
|
||||
[80382.755813] usb 3-1: New USB device found, idVendor=096e, idProduct=0858
|
||||
[80382.755819] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
|
||||
[80382.755822] usb 3-1: Product: U2F CCID KBOARD
|
||||
[80382.755825] usb 3-1: Manufacturer: FT
|
||||
[80382.757386] hid-generic 0003:096E:0858.0004: hiddev0,hidraw0: USB HID v1.00 Device [FT U2F CCID KBOARD] on usb-0000:00:14.0-1/input0
|
||||
[80383.925811] usb 3-1: USB disconnect, device number 4
|
||||
</value>
|
||||
<generator type="person" />
|
||||
</input>
|
||||
</generator>
|
||||
</input>
|
||||
|
||||
<input into_datastore="hackerbot_access_root_password">
|
||||
<generator type="strong_password_generator"/>
|
||||
</input>
|
||||
|
||||
<!--Create the users-->
|
||||
<utility module_path=".*parameterised_accounts">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<utility module_path=".*kde_minimal">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
<input into="autostart_konsole">
|
||||
<value>true</value>
|
||||
</input>
|
||||
</utility>
|
||||
<utility module_path=".*handy_cli_tools"/>
|
||||
<utility module_path=".*nmap"/>
|
||||
<utility module_path=".*wireshark"/>
|
||||
|
||||
<utility module_path=".*iceweasel">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
<input into="autostart">
|
||||
<value>true</value>
|
||||
</input>
|
||||
<input into="start_page">
|
||||
<datastore access="2">IP_addresses</datastore>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<utility module_path=".*pidgin">
|
||||
<input into="server_ip">
|
||||
<datastore access="2">IP_addresses</datastore>
|
||||
</input>
|
||||
<input into="accounts">
|
||||
<datastore access="0">accounts</datastore>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<vulnerability module_path=".*ssh_root_login">
|
||||
<input into="root_password">
|
||||
<datastore>hackerbot_access_root_password</datastore>
|
||||
</input>
|
||||
</vulnerability>
|
||||
|
||||
<network type="private_network" >
|
||||
<input into="IP_address">
|
||||
<datastore access="0">IP_addresses</datastore>
|
||||
</input>
|
||||
</network>
|
||||
</system>
|
||||
|
||||
|
||||
<system>
|
||||
<system_name>backup_server</system_name>
|
||||
<base platform="linux" distro="Debian 7.8"/>
|
||||
|
||||
<utility module_path=".*parameterised_accounts">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<vulnerability module_path=".*ssh_root_login">
|
||||
<input into="root_password">
|
||||
<datastore>hackerbot_access_root_password</datastore>
|
||||
</input>
|
||||
</vulnerability>
|
||||
|
||||
<network type="private_network" >
|
||||
<input into="IP_address">
|
||||
<datastore access="1">IP_addresses</datastore>
|
||||
</input>
|
||||
</network>
|
||||
</system>
|
||||
|
||||
<system>
|
||||
<system_name>hackerbot_server</system_name>
|
||||
<base distro="Kali" name="MSF"/>
|
||||
|
||||
<service type="ircd"/>
|
||||
|
||||
<utility module_path=".*metasploit_framework"/>
|
||||
<utility module_path=".*handy_cli_tools"/>
|
||||
<utility module_path=".*nmap"/>
|
||||
|
||||
<service type="httpd"/>
|
||||
|
||||
<utility module_path=".*hackerbot">
|
||||
<input into="hackerbot_configs">
|
||||
<generator module_path=".*hacker_vs_hackerbot_1">
|
||||
<input into="accounts">
|
||||
<datastore>accounts</datastore>
|
||||
</input>
|
||||
<input into="root_password">
|
||||
<datastore>hackerbot_access_root_password</datastore>
|
||||
</input>
|
||||
<input into="backup_server_ip">
|
||||
<datastore access="1">IP_addresses</datastore>
|
||||
</input>
|
||||
<input into="hackerbot_server_ip">
|
||||
<datastore access="2">IP_addresses</datastore>
|
||||
</input>
|
||||
</generator>
|
||||
</input>
|
||||
</utility>
|
||||
|
||||
<network type="private_network" >
|
||||
<input into="IP_address">
|
||||
<datastore access="2">IP_addresses</datastore>
|
||||
</input>
|
||||
</network>
|
||||
|
||||
<build type="cleanup">
|
||||
<input into="root_password">
|
||||
<generator type="strong_password_generator"/>
|
||||
</input>
|
||||
</build>
|
||||
</system>
|
||||
|
||||
</scenario>
|
||||
@@ -172,7 +172,7 @@ def build_vms(project_dir, options)
|
||||
end
|
||||
sleep(10)
|
||||
end
|
||||
else
|
||||
else # TODO: elsif vagrant_output[:exception].type == ProcessHelper::TimeoutError >destroy individually broken vms as above?
|
||||
Print.err 'Vagrant up timeout, destroying VMs and retrying...'
|
||||
GemExec.exe('vagrant', project_dir, 'destroy -f')
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user