lab updates

This commit is contained in:
Z. Cliffe Schreuders
2019-02-16 15:33:13 +00:00
parent 68428ec828
commit 806d2f3767
4 changed files with 506 additions and 11 deletions

View File

@@ -1,41 +1,190 @@
## Linux Extended ACLs
## Introducing Full Access Control List (ACL) File Permissions
An *access control list (ACL)* is attached to an object (resource) and lists all the subjects (users / active entities) that are allowed access, along with the kind of access that is authorised.
We have explored standard Unix (POSIX) file permissions, which is an abbreviated (simplified) ACL. Modern Linux systems (and some other Unix-based systems) now have more complete (and complicated) **extended** ACL support, enabling .
We have explored standard Unix file permissions, which is an abbreviated (simplified) ACL. With standard Unix file permissions all authorisation is defined in terms of the owning user (u), groups (g), and others (o), and the type of access that can be granted are read (r), write (r), and execute (x) -- along with some special permission flags, SUID, SGID, and stickybit, which change the meaning of these.
Todo: windows includes deny rules
The Unix file permissions (0664) `-rw-rw-r-- 1 user1 group1 5 Feb 5 test` can be thought of as a simplified ACL with:
Set a file ACL on your mysecrets file, using the setfacl command:
Subject | Permission
--- | ---
user1 | read, write
members of group1 | read, write
everyone else | read
While this is an effective way of representing permissions, and is often adequate, using traditional file permissions there is no way of representing more complicated rules, such as also granting specific users access to write the file without making them members of group1.
Modern systems (Windows, Linux, and some other Unix-based systems) now have more complete (and complicated) ACL support, enabling more fine-grained control over authorisation.
A more expressive ACL for a file can represent a state such as:
Subject | Permission
--- | ---
user1 | read, write
user2 | read, write
members of group1 | read, write
members of group2 | read
everyone else | nothing
## Linux Extended ACLs
Linux now has support for full ACLs (known as Linux ACLs or POSIX ACLs). Linux ACLs can include entries for named users and named groups.
ACLs require compatible filesystems so that they can be stored. Linux ACLs are saved as extended attributes (EA), which is used to associate metadata with files.
Linux ACLs that are equivalent with Unix file permissions are known as **minimal ACLs**. Linux ACLs with more than these three entries (owner user, owner group, and others) are known as **extended ACLs**.
Subject type | Text representation
--- | ---
Owner | user::rwx
Named user | user:name:rwx
Owning group | group::rwx
Named group | group:name:rwx
Mask | mask::rwx
Other | other::rwx
The Owner (user::xxx) and Other (other:xxx) permissions are automatically synced to the Unix file permission bits.
==Set a file ACL on your mysecret file==, using the setfacl command:
```bash
setfacl -m u:student:r ~/mysecret
setfacl -m u:user2:r ~/mysecret
```
This grants the "student" user read access to the file.
> The `-m` flag specifies that the ACL is to be modified
> `u:` or `user:` specifies a rule for a named user
> `g:` or `group:` could be used for a named group
> This is followed by the name of the user or group
> Finally read (r), write (w), and/or execute (x) can be specified using letters (rwx) or a number (7, which is the octet representing wrx)
Note that the stat program is not usually ACL aware, so won't report anything out of the usual:
This grants user2 read access to the file (without requiring access granted to any other groups or users).
==Confirm you can access the file from user2:==
```bash
su - user2
cat /home/user1/mysecret
exit
```
Note that the stat program is not usually ACL aware, so won't report anything out of the usual. ==Run:==
```bash
stat ~/mysecret
```
The ls program can be used to detect File ACLs:
The ls program can be used to detect File ACLs. ==Run:==
```bash
ls -la ~/mysecret
```
`-rw-r-----+ 1 cliffe users 22 Feb 28 11:47 mysecrets`
`-rw-r-----+ 1 user1 user1 22 Feb 28 11:47 mysecret`
Note that the output includes a `+`. This indicates an ACL is in place.
Use getfacl to display the permissions:
==Use getfacl to display the permissions:==
```bash
getfacl ~/mysecret
```
## Mask
Extended ACLs contain a mask entry that defines the upper bound (maximum permissions) that can be assigned by the ACL rules that apply to any named users or groups. This mask (mask::xxx) is typically automatically updated to the union (maximum) of all permissions granted, and automatically synced with the value of the group Unix file permission bits.
==Grant full rwx permission to user2:==
```bash
setfacl -m u:user2:rwx ~/mysecret
```
==View the updated permissions visible via `ls`:==
```bash
ls -la ~/mysecret
```
Note that the group file permission has changed (in addition to the `+`, this helps to show the level of permission that can result from the new ACL rule.
Again ==use getfacl to display the ACL rules:==
```bash
getfacl ~/mysecret
```
Note that the mask has changed.
==Change the mask value to "r"==
> Hint: see the table above that describes the text representation.
==Confirm user2 can no longer access the file due to the mask, even though they have rwx permission.==
## Understanding the access check behaviour
The decision making logic has been described as follows:
>If
>>the user ID of the process is the owner, the owner entry determines access
>else if
>>the user ID of the process matches the qualifier in one of the named user entries, this entry determines access
>else if
>>one of the group IDs of the process matches the owning group and the owning group entry contains the requested permissions, this entry determines access
>else if
>>one of the group IDs of the process matches the qualifier of one of the named group entries and this entry contains the requested permissions, this entry determines access
>else if
>>one of the group IDs of the process matches the owning group or any of the named group entries, but neither the owning group entry nor any of the matching named group entries contains the requested permissions, this determines that access is denied
>else
>>the other entry determines access.
>If
>>the matching entry resulting from this selection is the owner or other entry and it contains the requested permissions, access is granted
>else if
>>the matching entry is a named user, owning group, or named group entry and this entry contains the requested permissions and the mask entry also contains the requested permissions (or there is no mask entry), access is granted
>else
>>access is denied.
Quoted from (Grünbacher, 2003) [^1]
## Default ACLs
Directories can have two kinds of ACLs: **access ACLs** (which define the actual rules applied -- this is what we have been using so far), and **default ACLs**.
Default ACLs set the ACL rules that are applied to any new files created in the directory. Directories created inherit the default ACL, as the new access ACL and default ACL.
When a default ACL is specified on the parent directory, `umask` has no effect on the permissions of new files.
==Create a directory to share with user2:==
```bash
mkdir shared
setfacl -m u:user2:rw -d -m u:user2:rw shared
```
==Create a new file in the shared directory.==
==View the ACL created on the new file.==
## Comparison with Windows ACLs
Windows file permissions are similar to Linux ACLs, although they are slightly more complicated.
On Windows permissions are dynamically inherited and checked at access time. Changing permissions on a directory can change the permissions applied to the files within (or even changing the permissions of a directory's parent directory!). Linux ACLs only inherit permissions from default ACLs when they are created, and there is no complicated checking of all the parent directories to calculate access permissions.
Windows has lots more kinds of access that can be assigned (including append and delete permissions, and ACLs can contain rules about inheritance logic, and deny permissions), compared to Linux ACLs that define rules in terms of read, write, and execute (rwx).
Linux ACLs use local UIDs and GIDs to assign identity to all subjects (even when authenticating against remote servers, local UIDs are generated). Windows uses global security identifers (SIDs) that can be local or for domain users (authenticated against a domain controller, the global SID is used on ACLs).
## Hackerbot challenges
## ---------------
Use Linux File ACLs to grant one or more specific users (other class members) read access to your mysecrets file.
Using ACLs, grant any other group (you choose) read-write access to your mygroupshare file.
@@ -44,4 +193,3 @@ Remove the group permission you just added.
> Example: `setfacl -x g:staff file`
TODO: Setting ACL defaults

View File

@@ -17,6 +17,9 @@
$second_user = $second_account['username'].to_s
$second_password = $second_account['password'].to_s
$third_account = JSON.parse(self.accounts[2])
$third_user = $third_account['username'].to_s
$third_password = $third_account['password'].to_s
$server_ip = self.server_ip.first
$root_password = self.root_password

View File

@@ -0,0 +1,5 @@
# Resources
This excellent paper describes Linux ACL in detail:
[^1]: Grünbacher, Andreas. "POSIX Access Control Lists on Linux." *USENIX Annual Technical Conference*, FREENIX Track. 2003.
<https://www.usenix.org/legacy/events/usenix03/tech/freenix03/full_papers/gruenbacher/gruenbacher.pdf>

View File

@@ -0,0 +1,339 @@
<?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">
<name>Access Control Lists lab</name>
<author>Z. Cliffe Schreuders</author>
<description>A Hackerbot lab. Work through the labsheet, then when prompted interact with Hackerbot.</description>
<type>ctf-lab</type>
<type>hackerbot-lab</type>
<type>lab-sheet</type>
<difficulty>intermediate</difficulty>
<system>
<system_name>shared_desktop</system_name>
<base distro="Debian 9" type="desktop" name="KDE"/>
<input into_datastore="IP_addresses">
<!-- 0 desktop -->
<value>172.16.0.2</value>
<!-- 1 server -->
<value>172.16.0.3</value>
<!-- 2 hackerbot_server -->
<value>172.16.0.4</value>
</input>
<!-- generate some usernames to use -->
<input into_datastore="usernames">
<!-- main user -->
<generator type="random_word_generator">
<input into="wordlist">
<value>mythical_creatures</value>
</input>
</generator>
<!-- 4 other users -->
<generator type="random_word_generator">
<input into="wordlist">
<value>mythical_creatures</value>
</input>
</generator>
<generator type="random_word_generator">
<input into="wordlist">
<value>mythical_creatures</value>
</input>
</generator>
<generator type="random_word_generator">
<input into="wordlist">
<value>mythical_creatures</value>
</input>
</generator>
<generator type="random_word_generator">
<input into="wordlist">
<value>mythical_creatures</value>
</input>
</generator>
</input>
<!-- generate some passwords to be cracked -->
<input into_datastore="passwords">
<generator type="medium_password_generator"/>
<generator type="strong_password_generator"/>
<generator type="strong_password_generator"/>
<generator type="strong_password_generator"/>
</input>
<input into_datastore="groups">
<value>staff</value>
<value>team_one</value>
<value>team_two</value>
</input>
<!-- accounts on the desktop, with the main user as a sudoer -->
<input into_datastore="user_accounts_desktop">
<!-- main user, sudoer -->
<generator type="account">
<input into="username">
<datastore access="0">usernames</datastore>
</input>
<input into="password">
<value>tiaspbiqe2r</value>
</input>
<input into="super_user">
<value>true</value>
</input>
</generator>
<!-- other users, with weak passwords, no flags -->
<generator type="account">
<input into="username">
<datastore access="next">usernames</datastore>
</input>
<input into="password">
<datastore access="0">passwords</datastore>
</input>
</generator>
<generator type="account">
<input into="username">
<datastore access="next">usernames</datastore>
</input>
<input into="password">
<datastore access="next">passwords</datastore>
</input>
</generator>
<generator type="account">
<input into="username">
<datastore access="next">usernames</datastore>
</input>
<input into="password">
<datastore access="next">passwords</datastore>
</input>
</generator>
<generator type="account">
<input into="username">
<datastore access="next">usernames</datastore>
</input>
<input into="password">
<datastore access="next">passwords</datastore>
</input>
</generator>
</input>
<input into_datastore="desktop_root_password">
<generator type="strong_password_generator"/>
</input>
<!--Create the groups-->
<utility module_path=".*groups">
<input into="groups">
<datastore>groups</datastore>
</input>
</utility>
<!--Create the users-->
<utility module_path=".*parameterised_accounts">
<input into="accounts">
<datastore>user_accounts_desktop</datastore>
</input>
</utility>
<utility module_path=".*kde_minimal">
<input into="autologin_user">
<datastore access="0">usernames</datastore>
</input>
<input into="accounts">
<datastore>user_accounts_desktop</datastore>
</input>
<input into="autostart_konsole">
<value>true</value>
</input>
</utility>
<utility module_path=".*handy_cli_tools"/>
<utility module_path=".*hash_tools"/>
<utility module_path=".*pam_modules"/>
<utility module_path=".*iceweasel">
<input into="accounts">
<datastore>user_accounts_desktop</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">user_accounts_desktop</datastore>
</input>
</utility>
<vulnerability module_path=".*ssh_root_login">
<input into="root_password">
<datastore>desktop_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>server</system_name>
<base distro="Debian 9" type="server"/>
<!-- user accounts on the server, with matching usernames and passwords, but with flags to find -->
<input into_datastore="user_accounts_server">
<!-- main user, NOT sudoer -->
<generator type="account">
<input into="username">
<datastore access="0">usernames</datastore>
</input>
<input into="password">
<value>tiaspbiqe2r</value>
</input>
<input into="super_user">
<value>false</value>
</input>
<input into="groups">
<value>staff</value>
<value>team_one</value>
</input>
</generator>
<!-- other users, with the SAME passwords -->
<generator type="account">
<input into="username">
<datastore access="next">usernames</datastore>
</input>
<input into="password">
<datastore access="0">passwords</datastore>
</input>
<input into="groups">
<value>staff</value>
<value>team_one</value>
<value>team_two</value>
</input>
</generator>
<generator type="account">
<input into="username">
<datastore access="next">usernames</datastore>
</input>
<input into="password">
<datastore access="next">passwords</datastore>
</input>
<input into="groups">
<value>staff</value>
<value>team_two</value>
</input>
</generator>
<generator type="account">
<input into="username">
<datastore access="next">usernames</datastore>
</input>
<input into="password">
<datastore access="next">passwords</datastore>
</input>
<input into="groups">
<value>staff</value>
</input>
</generator>
<generator type="account">
<input into="username">
<datastore access="next">usernames</datastore>
</input>
<input into="password">
<datastore access="next">passwords</datastore>
</input>
<input into="groups">
<value>staff</value>
</input>
<!-- <input into="leaked_filenames">
<value>flags</value>
</input>
<input into="strings_to_leak">
<generator type="flag_generator" />
<generator type="flag_generator" />
</input> -->
</generator>
</input>
<!--Create the groups-->
<utility module_path=".*groups">
<input into="groups">
<datastore>groups</datastore>
</input>
</utility>
<!--Create the users-->
<utility module_path=".*parameterised_accounts">
<input into="accounts">
<datastore>user_accounts_server</datastore>
</input>
</utility>
<utility module_path=".*handy_cli_tools"/>
<vulnerability module_path=".*ssh_root_login">
<input into="root_password">
<datastore>desktop_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=".*nmap"/>
<utility module_path=".*handy_cli_tools"/>
<service type="httpd"/>
<utility module_path=".*hackerbot">
<input into="hackerbot_configs">
<generator module_path=".*hb_facls">
<input into="accounts">
<datastore>user_accounts_desktop</datastore>
</input>
<input into="root_password">
<datastore>desktop_root_password</datastore>
</input>
<input into="server_ip">
<datastore access="1">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>