mirror of
https://github.com/cliffe/SecGen.git
synced 2026-02-21 11:18:06 +00:00
Merge remote-tracking branch 'upstream/ids_rules_lab' into week_6_merge_branch
This commit is contained in:
@@ -95,7 +95,7 @@ class HackerbotConfigGenerator < StringGenerator
|
||||
|
||||
lab_sheet_markdown = generate_lab_sheet(xml_config)
|
||||
|
||||
redcarpet = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(prettify:true, hard_wrap: true, with_toc_data: true), footnotes: true, fenced_code_blocks: true, no_intra_emphasis: true, autolink: true, highlight: true, lax_spacing: true)
|
||||
redcarpet = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(prettify:true, hard_wrap: true, with_toc_data: true), footnotes: true, fenced_code_blocks: true, no_intra_emphasis: true, autolink: true, highlight: true, lax_spacing: true, tables: true)
|
||||
self.html_rendered = redcarpet.render(lab_sheet_markdown).force_encoding('UTF-8')
|
||||
redcarpet_toc = Redcarpet::Markdown.new(Redcarpet::Render::HTML_TOC.new())
|
||||
self.html_TOC_rendered = redcarpet_toc.render(lab_sheet_markdown).force_encoding('UTF-8')
|
||||
|
||||
@@ -203,7 +203,7 @@ Randomised instance generated by [SecGen](http://github.com/cliffe/SecGen) (<%=
|
||||
</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>
|
||||
<message>:( You backed up to the correct location, but it wasn't an differential backup... You probably need to ssh in and delete that last backup and try again.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</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>
|
||||
<message>:( You backed up to the correct location, but it wasn't an differential backup... You probably need to ssh in and delete that last backup and try again.</message>
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Something went wrong...</message>
|
||||
|
||||
@@ -46,7 +46,7 @@ This should trigger an alert from Snort, which is stored in an alerts log file.
|
||||
```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.
|
||||
>The tail program will wait for new alerts to be written to the file, and will display them as they are logged. (Ctrl-C to exit)
|
||||
|
||||
==Do an nmap port scan of the web_server== VM (from the desktop VM):
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
- 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 %>)
|
||||
- web_server (IP address: <%= $web_server_ip %>, leave it running, you don't log into this)
|
||||
- desktop
|
||||
|
||||
All of these VMs need to be running to complete the lab.
|
||||
@@ -34,6 +34,8 @@ Work through the below exercises, completing the Hackerbot challenges as noted.
|
||||
---
|
||||
## Getting Snort up and running
|
||||
|
||||
**On the ids_server VM:**
|
||||
|
||||
==Change Snort's output== to something more readable:
|
||||
|
||||
```bash
|
||||
@@ -43,14 +45,29 @@ sudo vi /etc/snort/snort.conf
|
||||
|
||||
> ":wq" to write changes and quit)
|
||||
|
||||
==Add the following line:==
|
||||
==Add the following lines:==
|
||||
`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"):
|
||||
`include $RULE_PATH/my.rules`
|
||||
|
||||
==Create a new rules file:==
|
||||
|
||||
```bash
|
||||
sudo touch /etc/snort/rules/my.rules
|
||||
```
|
||||
|
||||
Let us edit the rules file without sudo:
|
||||
|
||||
```bash
|
||||
sudo chown <%= $main_user %> /etc/snort/rules/my.rules
|
||||
```
|
||||
|
||||
==Change Snort's interface== to the interface with IP address <%= $ids_server_ip %> (likely eth1), and set the local network to your IP address range (or "any"):
|
||||
|
||||
```bash
|
||||
sudo vi /etc/snort/snort.debian.conf
|
||||
```
|
||||
> If you are not sure which interface to use, list the interfaces with `ifconfig` or `ip a s`
|
||||
> Set the interface and HOME network range, and exit vi (Esc, ":wq").
|
||||
|
||||
==Restart Snort:==
|
||||
@@ -63,9 +80,4 @@ sudo service snort start
|
||||
|
||||
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.
|
||||
It can be helpful to monitor network traffic while writing IDS rules. You can start Wireshark with `kdesudo wireshark &`
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
end
|
||||
|
||||
$main_user = $first_account['username'].to_s
|
||||
$main_user_pass = $first_account['password'].to_s
|
||||
$second_user = $second_account['username'].to_s
|
||||
$example_file = "/home/#{$second_user}/#{$files.sample}"
|
||||
$example_dir = "/home/#{$second_user}/personal_secrets/"
|
||||
@@ -114,14 +115,15 @@ Randomised instance generated by [SecGen](http://github.com/cliffe/SecGen) (<%=
|
||||
<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>
|
||||
<prompt>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>
|
||||
<output_matches>Find the flag</output_matches>
|
||||
<message>Hope you caught that.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
@@ -136,5 +138,150 @@ Randomised instance generated by [SecGen](http://github.com/cliffe/SecGen) (<%=
|
||||
<tutorial><%= ERB.new(File.read self.templates_path + 'write_snort_rules.md.erb').result(self.get_binding) %></tutorial>
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<% $rand_port = rand(65535)
|
||||
$rand_alert1 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; nmap -sT -p <%= $rand_port - 1 %>-<%= $rand_port + 1 %> <%= $web_server_ip %> > /dev/null; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects any TCP connection attempt to TCP port <%= $rand_port %> to <%= $web_server_ip %>. The alert must include the message "<%= $rand_alert1 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--01</output_matches>
|
||||
<message>:( Failed to scan your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--[01][01]1</output_matches>
|
||||
<message>:( Failed to scp to your system (the second time).</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--00.*<%= $rand_alert1 %>.*<%= $rand_alert1 %></output_matches>
|
||||
<message>:( Almost. The alert did fire, but it fired more than once!</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches><%= $rand_alert1 %></output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
|
||||
<attack>
|
||||
<% $rand_content1 = SecureRandom.hex(3)
|
||||
$rand_alert2 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; (sleep 1; echo "USER <%= $rand_content1 %>"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110 > /dev/null; (sleep 1; echo "user test"; echo "pass test"; echo "stat"; echo "quit"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110 > /dev/null; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects any packet with the contents "<%= $rand_content1 %>" to <%= $web_server_ip %>. The alert must include the message "<%= $rand_alert2 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert2 %>.*<%= $rand_alert2 %></output_matches>
|
||||
<message>:( Almost, but your rule triggered too many times. Are you inspecting the content of the connection?</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert2 %></output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
<!-- 3 random services -->
|
||||
<%= ERB.new(File.read self.templates_path + 'random_service_ids_rule.xml.erb').result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + 'random_service_ids_rule.xml.erb').result(self.get_binding) %>
|
||||
<%= ERB.new(File.read self.templates_path + 'random_service_ids_rule.xml.erb').result(self.get_binding) %>
|
||||
|
||||
<!--Email login attempt
|
||||
Tries a port scan, then connects twice once with caps, then lower, first with actual user, then incorrect creds, last 2 should trigger the rule
|
||||
-->
|
||||
<attack>
|
||||
<% $rand_alert4 = SecureRandom.hex(3)
|
||||
$flag1 = $flags.pop
|
||||
$flag2 = $flags.pop
|
||||
$flag3 = $flags.pop
|
||||
%>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; nmap -sT -p 110 <%= $web_server_ip %> > /dev/null; (sleep 1; echo "USER <%= $main_user %>"; echo "PASS <%= $main_user_pass %>"; echo "STAT"; echo "QUIT"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110; (sleep 1; echo "user test"; echo "pass test"; echo "stat"; echo "quit"; sleep 2; killall -9 nc ) | nc <%= $web_server_ip %> 110; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects any unencrypted POP3 email *user authentication attempt* (someone trying to log in), to a mail server on <%= $web_server_ip %>. The alert must include the message "<%= $rand_alert4 %>". Up to three flags will be awarded, based on the quality of the rule.</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %>.*<%= $rand_alert4 %>.*<%= $rand_alert4 %></output_matches>
|
||||
<message>:( Almost, but your rule triggered too many times. Are you inspecting the content of the connection?</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %>.*Classification.*User.*<%= $rand_alert4 %></output_matches>
|
||||
<message>:-D Well done! ALL THREE FLAGS!: <%= $flag1 %>, <%= $flag2 %>, <%= $flag3 %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %>.*<%= $rand_alert4 %></output_matches>
|
||||
<message>8-) Well done! Two flags: <%= $flag1 %>, <%= $flag2 %>. Could be further improved with a classification.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--0.*<%= $rand_alert4 %></output_matches>
|
||||
<message>:) Well done! <%= $flag1 %>. The alert did get triggered, but it fired only under some conditions. Is your rule caps sensitive? More flags are to be had from a better rule ;-)</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
<attack>
|
||||
<% $rand_alert5 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; curl <%= $web_server_ip %> >/dev/null; curl <%= $web_server_ip %>/contact.html >/dev/null; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -n /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects access to http://<%= $web_server_ip %> but NOT http://<%= $web_server_ip %>/contact.html. The alert must include the message "<%= $rand_alert5 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--01</output_matches>
|
||||
<message>:( Failed to test your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--[01][01]1</output_matches>
|
||||
<message>:( Failed to scp to your system (the second time).</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--00.*<%= $rand_alert5 %>.*<%= $rand_alert5 %></output_matches>
|
||||
<message>:( Almost, but your rule triggered too many times. Are you inspecting the content of the connection?</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--00.*<%= $rand_alert5 %></output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
|
||||
</hackerbot>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<attack>
|
||||
<% $services = {'FTP'=>'20','Telnet'=>'23','SMTP'=>'25','HTTP'=>'80','POP3'=>'110','IMAP'=>'143','SNMP'=>'161','LDAP'=>'389','HTTPS'=>'443','LDAPS'=>'636'}
|
||||
$rand_service1 = $services.keys.sample
|
||||
$rand_alert3 = SecureRandom.hex(3) %>
|
||||
<pre_shell>sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_before; stat1=$?; nmap -sT -p 1000,<%= $services[$rand_service1] %> <%= $web_server_ip %> > /dev/null; stat2=$?; sshpass -p <%= $root_password %> scp -prv -oStrictHostKeyChecking=no root@<%= $ids_server_ip %>:/var/log/snort/alert /tmp/snort_alert_after; stat3=$?; echo --$stat1$stat2$stat3; diff -u /tmp/snort_alert_before /tmp/snort_alert_after | tail -n 5</pre_shell>
|
||||
<get_shell>false</get_shell>
|
||||
<post_command></post_command>
|
||||
|
||||
<prompt>Create a Snort rule that detects any TCP connection attempt to <%= $rand_service1 %> (just the connection attempt, does not require content inspection) on <%= $web_server_ip %>. The alert must include the message "<%= $rand_alert3 %>".</prompt>
|
||||
|
||||
<condition>
|
||||
<output_matches>^--1</output_matches>
|
||||
<message>:( Failed to scp to your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--01</output_matches>
|
||||
<message>:( Failed to scan your system.</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches>^--[01][01]1</output_matches>
|
||||
<message>:( Failed to scp to your system (the second time).</message>
|
||||
</condition>
|
||||
<condition>
|
||||
<output_matches><%= $rand_alert3 %></output_matches>
|
||||
<message>:) Well done! <%= $flags.pop %>.</message>
|
||||
<trigger_next_attack />
|
||||
</condition>
|
||||
<else_condition>
|
||||
<message>:( Your rule didn't get triggered (or didn't include the right message).</message>
|
||||
</else_condition>
|
||||
</attack>
|
||||
@@ -1,16 +1,91 @@
|
||||
## Networking concepts (potentially revision)
|
||||
### The Internet protocol suite
|
||||
Modern network traffic (such as the Internet) typically uses the Internet protocol suite set of communications protocols.
|
||||
|
||||
The Internet protocol suite has four abstraction layers:
|
||||
|
||||
> * "**The application layer** is the scope within which applications create user data and communicate this data to other applications on another or the same host. The applications, or processes, make use of the services provided by the underlying, lower layers, especially the Transport Layer which provides reliable or unreliable pipes to other processes. The communications partners are characterized by the application architecture, such as the client-server model and peer-to-peer networking. This is the layer in which all higher level protocols, such as SMTP, FTP, SSH, HTTP, operate. Processes are addressed via ports which essentially represent services.
|
||||
> * **The transport layer** performs host-to-host communications on either the same or different hosts and on either the local network or remote networks separated by routers. It provides a channel for the communication needs of applications. UDP is the basic transport layer protocol, providing an unreliable datagram service. The Transmission Control Protocol provides flow-control, connection establishment, and reliable transmission of data.
|
||||
> * **The internet layer** has the task of exchanging datagrams across network boundaries. It provides a uniform networking interface that hides the actual topology (layout) of the underlying network connections. It is therefore also referred to as the layer that establishes internetworking, indeed, it defines and establishes the Internet. This layer defines the addressing and routing structures used for the TCP/IP protocol suite. The primary protocol in this scope is the Internet Protocol, which defines IP addresses. Its function in routing is to transport datagrams to the next IP router that has the connectivity to a network closer to the final data destination.
|
||||
> * **The link layer** defines the networking methods within the scope of the local network link on which hosts communicate without intervening routers. This layer includes the protocols used to describe the local network topology and the interfaces needed to effect transmission of Internet layer datagrams to next-neighbor hosts."
|
||||
(https://en.wikipedia.org/wiki/Internet_protocol_suite#Abstraction_layers)
|
||||
|
||||
### Common services and (application layer) protocols
|
||||
In order to make sense of network traffic, it is important to be aware of common protocols and port numbers.
|
||||
|
||||
| TCP/UDP | Port(s) | Service |
|
||||
|---------|---------|---------|
|
||||
| tcp | 20/21 | File Transfer Protocol (FTP) (RFC 959) |
|
||||
| tcp | 22 | Secure Shell (SSH) (RFC 4250-4256) |
|
||||
| tcp | 23 | Telnet (RFC 854) |
|
||||
| tcp | 25 | Simple Mail Transfer Protocol (SMTP) (RFC 5321) |
|
||||
| tcp/udp | 53 | Domain Name System (DNS) (RFC 1034-1035) |
|
||||
| udp | 69 | Trivial File Transfer Protocol (TFTP) (RFC 1350) |
|
||||
| tcp | 80 | Hypertext Transfer Protocol (HTTP) (RFC 2616) |
|
||||
| tcp | 110 | Post Office Protocol (POP) version 3 (RFC 1939) |
|
||||
| tcp/udp | 137/138/139 | NetBIOS (RFC 1001-1002) |
|
||||
| tcp | 143 | Internet Message Access Protocol (IMAP) (RFC 3501) |
|
||||
| tcp/udp | 161/162 | Simple Network Management Protocol (SNMP) (RFC 1901-1908, 3411-3418) |
|
||||
| tcp/udp | 389 | Lightweight Directory Access Protocol (LDAP) (RFC 4510) |
|
||||
| tcp | 443 | Hypertext Transfer Protocol over SSL/TLS (HTTPS) (RFC 2818) |
|
||||
| tcp/udp | 636 | Lightweight Directory Access Protocol over TLS/SSL (LDAPS) (RFC 4513) |
|
||||
| tcp | 989/990 | FTP over TLS/SSL (RFC 4217) |
|
||||
| tcp | 6660-6669 | Internet Relay Chat (IRC) |
|
||||
|
||||
Please ensure you understand what each of these ports are used for. If you are not aware of what these protocols are, do some online reading.
|
||||
> This may be a useful resource: http://www.pearsonitcertification.com/articles/article.aspx?p=1868080
|
||||
|
||||
Keep in mind that in recent years more and more network based functionality is moving to be hosted via Web protocols (HTTP and HTTPS).
|
||||
|
||||
### Using Wireshark
|
||||
|
||||
Note that in Wireshark you can view individual packets, including IP and TCP headers. Wireshark also has support for viewing TCP streams, so that you can view the traffic at the application layer as it is sent between the two computers (such as, client and server). (Simply right-click on a TCP entry and select *Follow > TCP Stream*.)
|
||||
|
||||
**On the ids_server VM:**
|
||||
|
||||
==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.
|
||||
|
||||
Start capturing, listening to the interface with IP address <%= $ids_server_ip %>.
|
||||
> If you are not sure, list the interfaces with `ifconfig` or `ip a s`
|
||||
|
||||
**On the desktop VM:**
|
||||
|
||||
While Wireshark is listening, ==access a web page from Firefox, browse to [*http://<%= $web_server_ip %>*](http://<%= $web_server_ip %>)== (In a new tab.)
|
||||
|
||||
**On the ids_server VM:**
|
||||
|
||||
Note that Wireshark uses colouring to make it easier to view traffic at a glance. ==View the colouring rules== via *View > Coloring Rules*.
|
||||
|
||||
In Wireshark ==use display filters== to narrow down the packets displayed. At the top of the Wireshark window, enter `tcp.port == 80`, and press Enter.
|
||||
|
||||
Right click the Web traffic, and select *Follow TCP Stream*.
|
||||
|
||||
> Note that the website request starts with the client sending "GET /"...
|
||||
|
||||
Note that you can also view the unzipped version of the content in Wireshark. In the view below the list of packets, ==expand the "Line-based text data: text/html" heading==
|
||||
|
||||
==LogBook Question: What is the difference between these views?==
|
||||
|
||||
Also experiment with using Wireshark display filters of `http` and `irc`.
|
||||
|
||||
## 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.
|
||||
Snort is primarily 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. 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.
|
||||
You may find external reference guides to writing Snort rules helpful. See the resources section below, and Google may come in handy (from outside the VMs).
|
||||
|
||||
In general, rules are defined on one line (although, they can break over lines by using `\`), and take the form of:
|
||||
|
||||
**header (body)**
|
||||
**header** (**body**)
|
||||
|
||||
where header = "**action** (log,alert) **protocol** (ip,tcp,udp,icmp,any) **source_IP** **source_port** **direction** (->,<>) **destination_IP** **destination_port**"
|
||||
where header = "**action** (such as *log* or *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
|
||||
> for example: `alert tcp any any -> any any` to make an alert for *any* TCP traffic, or `alert tcp any any -> <%= $web_server_ip %> 80` to make an alert for connections to unencrypted Web on the web_server VM's IP address
|
||||
|
||||
and body = "**option; option: "parameter"; ...**"
|
||||
|
||||
@@ -34,96 +109,39 @@ To give a unique identifier and revision version number:
|
||||
|
||||
So for example the body could be:
|
||||
|
||||
> `msg: "user login attempt"; content: "user"; classtype:attempted-user; sid:1000001; rev:1;`
|
||||
> `msg: "Website access"; content: "GET"; sid:1000001; rev:1;`
|
||||
|
||||
<% $random_string = SecureRandom.hex(3) %>
|
||||
|
||||
And bringing all this together a Snort rule could read:
|
||||
> `alert tcp any any -> <%= $web_server_ip %> 80 (msg: "Website access <%= $random_string %>"; content: "GET /"; sid:1000001; rev:1;)`
|
||||
|
||||
> `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.
|
||||
**On the ids_server VM:**
|
||||
|
||||
Add the rule, and reload Snort:
|
||||
|
||||
```bash
|
||||
echo "alert tcp any any -> 192.168.0.1 110 (msg: "Email login attempt"; content: "user"; classtype:attempted-user; sid:1000001; rev:1;)" >> /etc/snort/rules/my.rules
|
||||
echo 'alert tcp any any -> <%= $web_server_ip %> 80 (msg: "Website access <%= $random_string %>"; content: "GET /"; sid:1000001; rev:1;)' >> /etc/snort/rules/my.rules
|
||||
|
||||
sudo service snort restart
|
||||
```
|
||||
|
||||
# TODO add instructions to test this email rule
|
||||
==Test the new rule...==
|
||||
|
||||
There are many 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.
|
||||
**On the desktop VM:**
|
||||
|
||||
==Figure out how the rule could be improved to be case insensitive.==
|
||||
While Wireshark is listening, ==access a web page from Firefox == browse to ==[*http://<%= $web_server_ip %>*](http://<%= $web_server_ip %>)== (In a new tab.)
|
||||
|
||||
Lets create a basic rule that detects any traffic on port 80 (web). ==Load this rule into Snort:==
|
||||
**On the ids_server VM:**
|
||||
==View the Snort alert file, to confirm your new rule generated an alert==
|
||||
|
||||
```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
|
||||
sudo tail /var/log/snort/alert
|
||||
```
|
||||
Browse to a website, and confirm the rule worked to generate an alert containing the text 'RANDOM'.
|
||||
> Hackerbot will require you to include specific messages in your rules.
|
||||
|
||||
> The output should include the alert, with <%= $random_string %>. Note that Hackerbot will instruct you to include random strings such as this, in the alerts.
|
||||
> In this case, the website may have resulted in a few HTTP connections, therefore triggering the rule a few times.
|
||||
|
||||
==LabBook Question: Browse the existing rules in `/etc/snort/rules` and describe how one of the existing rules works.==
|
||||
|
||||
|
||||
# TODO list common protocols and the ports they use
|
||||
|
||||
|
||||
# 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?)
|
||||
|
||||
Tip: **Don't forget to reload Snort each time you change your rules.**
|
||||
6
modules/services/unix/email/popa3d/manifests/config.pp
Normal file
6
modules/services/unix/email/popa3d/manifests/config.pp
Normal file
@@ -0,0 +1,6 @@
|
||||
class popa3d::config{
|
||||
service { 'popa3d':
|
||||
enable => true,
|
||||
ensure => 'running',
|
||||
}
|
||||
}
|
||||
5
modules/services/unix/email/popa3d/manifests/install.pp
Normal file
5
modules/services/unix/email/popa3d/manifests/install.pp
Normal file
@@ -0,0 +1,5 @@
|
||||
class popa3d::install{
|
||||
package { ['popa3d']:
|
||||
ensure => 'installed',
|
||||
}
|
||||
}
|
||||
2
modules/services/unix/email/popa3d/popa3d.pp
Normal file
2
modules/services/unix/email/popa3d/popa3d.pp
Normal file
@@ -0,0 +1,2 @@
|
||||
include popa3d::install
|
||||
include popa3d::config
|
||||
21
modules/services/unix/email/popa3d/secgen_metadata.xml
Normal file
21
modules/services/unix/email/popa3d/secgen_metadata.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<service xmlns="http://www.github/cliffe/SecGen/service"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.github/cliffe/SecGen/service">
|
||||
<name>POP3 Server popa3d</name>
|
||||
<author>Z. Cliffe Schreuders</author>
|
||||
<module_license>MIT</module_license>
|
||||
<description>popa3d is a tiny POP3 daemon designed with security as the primary goal. Accepts logins from existing users on the system.
|
||||
</description>
|
||||
|
||||
<type>pop3</type>
|
||||
<platform>linux</platform>
|
||||
|
||||
<!--optional details-->
|
||||
<software_name>popa3d</software_name>
|
||||
|
||||
<requires>
|
||||
<type>update</type>
|
||||
</requires>
|
||||
</service>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user