This post explains some measures that you can take to prevent the MySQL cna12.dll attacks from infecting your MySQL server. It follows on from a previous post which explains the attacks. If you find that a cna12.dll file or a piress user account keep reappearing on your MySQL server, then read on.
A good place to start would be to assess whether you actually need MySQL installed on your server and if you don’t, then uninstall it. MySQL may have been pre-installed by a vendor/contractor; may have once been required but is now unused; or it may have been used by other software which has since been removed. If you do need MySQL, then let’s look at some options for securing it.
As discussed in my previous post, What is cna12.dll and the piress user?, there are four conditions that are required for this attack to succeed:
- The MySQL server is accessible from the Internet
- The root user’s password is guessed
- The MySQL Windows account is able to write to the MySQL program folders, namely its plugins and/or bin folder(s)
- The MySQL server is able to access web servers on the Internet
Accessible MySQL server
This is pretty obvious — an attacker can’t attack your system if they can’t get to it. As a good rule of thumb, you should only allow access to systems that actually need it. It is generally considered a bad idea to allow Internet access to your database and other servers which generally only store and process data.
Good design involves placing a user interface system, such as a web site, between the database server (or other back-end system(s)) and the Internet/users. Access to the database server can then be restricted to the web server.
So how can you stop people from accessing your MySQL server? You have a few options (apart from uninstalling MySQL). I would recommend using the ‘defence in depth’ approach and implementing all three:
- Network/ADSL firewall
- Windows Firewall
- Reconfigure MySQL
Network/ADSL firewall
The first line of defence is to prevent network connections to your MySQL server. Configure your firewall to block TCP port 3306. TCP port 3306 is the default MySQL port, but if you have changed this (using the port= option) in your MySQL configuration, then you will obviously need to block the port that you changed it to.
Refer to the documentation for your network equipment if you are unsure how to configure it to block traffic. It is possible that you can’t block traffic with your particular equipment, in which case you can only use one of the other two methods mentioned above.
When blocking MySQL, don’t just block the connections inbound, but, and provided that you don’t need outbound MySQL connections from your MySQL server, also block MySQL connections outbound. This will prevent your MySQL servers from infecting other MySQL servers (at least by connecting to remote MySQL services — some malware has a number of different ways by which it can spread).
In fact, it is a good idea to block all unnecessary inbound and all unnecessary outbound connections to and from all of your hosts, both servers and desktops/laptops.
Windows Firewall
If you have Windows Firewall on your MySQL server, then configure that to block MySQL (TCP port 3306 by default, but if you are using a different port then obviously block the one that you are using). Refer to the Windows help documentation if needed. The same principles apply as for network/ADSL firewalls in that you should block both inbound and outbound MySQL connections, if possible, and generally block all inbound/outbound access that isn’t required.
When configuring Windows Firewall by adding Exceptions, specify the access by using TCP/UDP port numbers and resist the temptation to allow access to individual programs. The reason being you want to allow access based on what your applications should be doing, whereas configuring Windows Firewall to allow access to an application will allow access based on what that application is actually doing.
To illustrate the difference, suppose that cna12.dll implemented a back door, that is an unauthorised and often unauthenticated means of gaining access to your system. Back doors in malicious (and even in some legitimate) applications are common and are often installed, in the case of the malicious applications at least, to allow attackers quick and easy access to your system(s) and often without requiring a username and/or password.
Let’s say that to do this, it starts listening for connections from the Internet, that aren’t normal MySQL connections. If you have configured Windows Firewall to only allow access to your MySQL server using MySQL network connections (TCP port 3306), then attackers can’t connect to the back door to gain access. If, however, you have configured Windows Firewall to allow access to the MySQL program which, thanks to cna12.dll is now listening for back door connections as well as for MySQL connections, then the back door connections will be allowed.
Don’t rely totally on Windows Firewall as I have seen instances where malicious applications have reconfigured the firewall to give themselves access, and if you have a piress account showing up on your server then we can be reasonably sure that there has been some malicious activity. Since each of these attacks downloads a different malicious application though, we can’t be sure what that malicious activity was. Also that piress user has administrator rights and hence could logon remotely and reconfigure your Windows Firewall.
Reconfigure MySQL
It is possible to reconfigure MySQL to only accept connections from the computer that it is running on. To do this, you’ll need to change MySQL’s configuration file, my.ini.
In my installation (v5.5), I found this in the c:\Documents and Settings\All Users\Application Data\MySQL\MySQL Server 5.5\ folder. Note that the Application Data folder is often hidden, in which case you will need to change your Windows Explorer options and enable the Show hidden files and folders option to see it.
If you open my.ini (use Wordpad or Notepad), and scroll down to the [mysqld] section. Somewhere down there, you should see an option specifying how clients can connect to your server. Given that you have found cna12.dll and/or the piress user account, I’d say that there will more than likely be a line that says port=3306.
Make sure that you are looking at the port=3306 line in the [mysqld] section and neither one in the [mysql] section nor one in the [client] section (although the two/three sections will have to match if you want any MySQL clients on your server to connect to MySQL).
Just below the port=3306 line (or anywhere in the [mysqld] section), you can add the following line:
bind-address=127.0.0.1
The bind-address option will cause MySQL to only listen for (IPv4) connections on the loopback interface (127.0.0.1 being the IPv4 address of the loopback interface). The loopback interface is the network interface to enable a host to open network connections to itself without having to find its IP address and use the network interface belonging to the network adapter.
You used to see the 127.0.0.1 IP address given to Internet newbies as *the* site to download porn from (obviously back in the day when most people accessed the Internet from UNIX hosts which would more than likely be running an FTP server)… /me sighs, the Internet isn’t what it used to be…
By only listening on this IP address/interface, MySQL is unable to receive connections from the network. Note that that address is the IPv4 loopback address. Use ::1 for IPv6 loopback connections. If you would like to listen for both IPv4 and IPv6 loopback connections, and you can figure out how to get MySQL to do so, then you’re doing better than I did.
This adds an extra layer of defence as it is harder for malicious applications to change your MySQL configuration (it will involve parsing the configuration file) than it is for them to change the Windows Firewall configuration (registry change).
Another option would be to disable MySQL networking and use a named pipe to connect to the server. However, since named pipes are easily accessible over the network using the CIFS (Common Internet File System) TCP port of 445, and the cna12.dll file created a user with administrator privileges, anyone with knowledge of the piress user’s credentials could potentially connect to that named pipe remotely.
If you find that you need to use a named pipe, and that you can’t talk yourself out of it, then I would seriously consider changing its name from the default value of MySQL. I believe this is done using the socket option in the [mysqld] section of my.ini.
You may need to reconfigure MySQL clients based on any changes you just made. After making the above changes, only clients running on the MySQL server will be able to connect to it. If they are using a TCP connection, then they will now need to connect to 127.0.0.1 (as opposed to the servers Internet/network address) to connect to MySQL. If you changed the name of the named pipe in the [mysqld] section, then you will also need to change it in the [mysql] and/or [client] sections.
Note that MySQL does access control based on the where the client is connecting from, which, when more than one network interface is available to do so, depends on which address you connect to. For instance, if you connect to the MySQL server using your server’s Internet address, then the client connection will come from your server’s Internet address. However, if you use the loopback address, then the client connection will come from the loopback address.
Consequently, if you have used the server’s Internet IP address to specify that clients running on the MySQL server itself can connect to your databases, then you will need to change the access controls to allow clients from 127.0.0.1 (or the IPv6 loopback address of ::1) to access the databases. The documentation for the bind-address MySQL option mutters something about this.
For further information on the options available in the my.ini configuration file, see the MySQL documentation, in particular, the Server Option and Variable Reference.
Writeable program folders
It is generally a bad idea to have application folders, other than data folders which require it, writeable by the application. The reason being if an application gets compromised and controlled by an attacker, there is nothing to stop it from installing malicious applications in to its own folders, nor from infecting its own application files.
This attack is a classic example. The attack installs a malicious MySQL plugin DLL to the MySQL program folders, and then issues a MySQL command to use it.
To protect against this, set Windows NTFS security permissions on the MySQL program folders such that the user under which the MySQL server runs, cannot write/delete/modify files in those folders. The Windows user under which the MySQL server process runs depends on how MySQL was installed, how it is started, and how it is configured.
In order to find the Windows user account that is used to run the MySQL process, start Task Manager (pressing CTRL-SHIFT-Esc should do this). Make sure the Show processes from all users option is ticked, then find the mysqld.exe process. The User Name column will tell you which user account is being used to run the MySQL process. It is a good idea to know this information, as this dictates what privileges the MySQL server process has.
Once you know the Windows user you can start removing that user’s write access to the MySQL program folders. If you make your way over to the c:\Program Files\MySQL\ folder, and open the Properties for the MySQL Server 5.5\ folder (in my case — obviously the name of that folder, and possibly its actual location, will depend on the MySQL version that you installed).
You need to click on the Security tab. Can’t find the Security tab? Not to worry — I’ve already gone through quite the palaver to figure that one out. Go to the Folder Options in Windows Explorer. Click on the View tab. Under Advanced settings there is an option Use simple file sharing (Recommended). Turn it off. Reopen the Properties for the MySQL Server 5.5\ folder. I must admit that I wouldn’t have figured that one out in a pink fit.
Once you have the Security tab open for the MySQL Server 5.5\ folder (or the folder for your version of MySQL), click on the Add… button. Enter the user name of the account under which your MySQL server process is running.
If MySQL is running under the NETWORK SERVICE account, then you will probably find that that account doesn’t have Full Control/Modify/Write permissions to any of the MySQL folders under c:\Program Files\MySQL\. You can check which permissions an account has by clicking on the Advanced button and entering the account user name in to the Effective Permissions tab. If the account doesn’t have write permissions, then you can cancel your way out of the dialogue boxes.
You can remove write privileges from the account running the MySQL server process, back in the Security tab of the Properties page. Click on the Add… button, enter the account user name, and then make sure that only the Read & Execute, List Folder Contents, and Read permissions are ticked.
It would then be prudent to check each folder under the MySQL Server 5.5\ folder to make sure that they are inheriting the permissions from their parent folders and have hence inherited the change that you just made. This can be tedious, but at the very least, check the permissions of the bin\ and lib\plugin\ subfolders. If they didn’t inherit the permissions (that is, the new permissions that you added for the MySQL account user name aren’t showing up) then you will need to add them manually as you did for the MySQL Server 5.5\ folder.
Access to the Internet
It’s too late to protect your own servers by this point, this measure is simply to prevent your infected servers from infecting other servers on the Internet. This is the networking equivalent of someone with the cold/flu virus covering their nose and mouth when they sneeze and/or cough.
It is generally a bad idea to allow servers access to services on the Internet, unless they need it. If you can, proxy necessary services, such as DNS. At the very least, prevent outbound access that mirrors inbound access. For example, your MySQL server requires inbound MySQL access so in this case, block outbound MySQL access. In other words, don’t let a virus/worm infect others using the same method by which it infected you.
Careful now
Standard disclaimer time. While I have attempted to check the technical accuracy of my suggestions, I don’t know much about the circumstances in which your server is being used, and as such the above suggestions may not be suitable for your environment. As with just about any changes in an I.T. environment, you might want to test them in a development/test environment before applying them to any production environments.
With regards to what else may have happened as a result of these attacks, it is hard to say. I’ve noticed that almost every attack of this type downloads different malware. The only way to be completely sure that there is no longer anything malicious lurking on your MySQL server would be to reinstall everything.
Since your MySQL server is obviously on a network, it is possible that any worm/virus/attacker who now has, or had, access to your MySQL server, could have connected to other hosts on your network (depending on your network configuration and layout) and potentially installed malware on them. This is made easier if your Windows hosts can connect to each other and authenticate using Active Directory or using the same account credentials across systems.
Forensically analysing the affected MySQL server may help to determine what else may have taken place, and whether any other systems could have been compromised as a result of the attack and/or subsequent malicious activity. This, however, is a topic which people have written whole books about, so I’m not about to go in to this.