ZeroAccess has always distributed its malicious payloads to infected computers using a peer-to-peer protocol. The use of a peer-to-peer protocol removes the need to maintain centralized command-and-control (C&C) servers to distribute malicious payloads. In 2011, ZeroAccess’ peer-to-peer protocol communicated over TCP, but in the second quarter of 2012 the protocol was modified to use UDP. This was the last significant update to the ZeroAccess peer-to-peer protocol until June 29, 2013.
Symantec has been closely monitoring the ZeroAccess peer-to-peer networks since its discovery. On June 29, 2013, we noticed a new module being distributed amongst ZeroAccess peers communicating on the UDP-based peer-to-peer network that operates on ports 16464 and 16465. ZeroAccess maintains a second UDP-based network that operates on ports 16470 and 16471. ZeroAccess peers communicate to other peers connected to the same network; peers do not communicate across networks.
The module discovered on June 29 modifies the peer-to-peer functionality of ZeroAccess to make its peer-to-peer network more robust and resilient against outside manipulation. The following is a summary of the key code changes made on June 29, 2013, affecting ZeroAccess peer-to-peer functionality:
- The number of supported peer-to-peer protocol messages has been decreased from three to two.
- A secondary internal peer list is now used that can hold over 16 million peer IP addresses, up from 256 IP addresses.
- The secondary internal peer list is stored as a Windows NTFS alternate data stream.
- The logic of how a ZeroAccess peer will contact other peers has been modified.
- Error checks and timeouts have been added to the malicious file download TCP connections.
In addition to the code update being available on the UDP 16464/16465 peer network for existing peers, after June 29, 2013, we have observed new ZeroAccess installers for the UDP 16464/16465 network which infect computers with ZeroAccess also contain the new peer-to-peer protocol and code changes.
Interestingly, the ZeroAccess UDP 16470/16471 network has not yet received the code update. The new ZeroAccess installer samples for the UDP 16470/16471 network also do not contain the new code. In the past, both the UDP 16464/16465 and UDP 16470/16471 networks generally received new features and code modifications at approximately the same time.
Most of the code changes made by the ZeroAccess authors in this update seem to be in response to published research on ZeroAccess or other perceived weaknesses the authors found in the code. These changes are also further evidence that ZeroAccess continues to be actively developed and remains a threat. Symantec expects development of ZeroAccess to continue and will actively monitor the threat for those changes.
The following sections provide further technical details on the peer-to-peer protocol and related code changes made to ZeroAccess.
Modified peer-to-peer protocol
When discovered in 2012, ZeroAccess’ UDP-based peer-to-peer protocol supported three message types: getL, retL, and newL. A number of security researchers have described the messages and pointed out flaws in the protocol, especially regarding the newL message type. The newL message type is used by ZeroAccess to share directly routable IP addresses (often called super nodes or super peers) amongst its peers. When a peer receives a newL message it adds the included IP address within the newL message type into its internal peer list. The peer also forwards the newL message to other peers it knows about, magnifying the message’s effect. Prior to June 29, by crafting a newL message and sending it to a ZeroAccess peer it was possible to introduce a rogue IP address into an infected ZeroAccess peer’s internal peer list and have that rogue newL message distributed to other ZeroAccess peers.
The new peer-to-peer protocol removes the newL message type, allowing the botnet to filter out rogue peer IPs.
Expanded internal peer-list
Another flaw previously identified regarding ZeroAccess’ peer-to-peer protocol is the fixed internal peer list size. Prior to the June 29 update, a ZeroAccess’ internal peer list was capped at 256 peers. After June 29, a secondary peer list was added and memory reserved to hold up to 16 million peer IP addresses. The list of 256 peers continues to be the “working set” of peers that are periodically contacted. The secondary peer list is used for redundancy purposes.
When the peer list was only 256 peers in length it was feasible that a significant ZeroAccess clean-up action could cut off ZeroAccess peers from the peer-to-peer network because none of their 256 known peers were online. It also became theoretically feasible to replace a ZeroAccess peer’s 256 internal peer list with rogue IP addresses. The secondary peer list makes both of these actions more difficult.
The secondary peer list is written to disk, along with the 256 peer working set. Previous to June 29, the 256 peers from the internal peer list were stored in a file named "@". After June 29, the @ file still exists and continues to contain 256 peer IP addresses from the working set of peers. The secondary peer list, containing up to 16 million IP address, is stored as an NTFS alternate data stream of the @ file. The NTFS alternate data stream also uses the @ filename.
Altered run-time peer contact behavior
Prior to June 29, one of the peers from the 256 peers in ZeroAccess’ internal peer list would be contacted using a getL each second to ask for any data on new malicious modules and new ZeroAccess peer IP addresses. This behavior continues after June 29. However, for any remote peer that responds to a message, that responding peer’s IP address and response time-stamp will be added to the secondary peer list.
The IP’s in the secondary contact list are also contacted when ZeroAccess first starts up. At startup, as many as 16 IPs from the secondary peer list will be contacted each second. This secondary peer list communication will continue until at least 16 remote peers have responded to the infected host. Once an infected peer has been contacted by 16 remote peers, peers from the secondary list will not be contacted until the infected computer is restarted. The secondary peer list will continue to be added to and updated as remote peers respond as part of the normal periodic contact with the 256 peers from the working set. This behavior allows a ZeroAccess client to keep a large list of previously contacted peers for redundancy and still operate with a small working set of 256 peers in order for malicious payloads to be quickly distributed throughout the ZeroAccess network.
Another runtime peer-contact behavior change is the keeping of a contacted-peer state table. ZeroAccess peers continue to send unsolicited getL messages to remote peers and expect to receive retL messages in response. The retlL responses contain malicious payload metadata as well as new peer IP addresses. Prior to June 29, an infected peer would accept any UDP message from any IP address, regardless of whether the infected host had contacted that remote IP address before or not. After June 29, a ZeroAccess peer will continue to accept getL messages from any remote IP, but will only accept a retL message from an IP address that the receiving peer had previously sent a getL message to. Basically, when a ZeroAccess peer sends a getL message to a remote IP address it will add that remote IP address to a table in memory. When a ZeroAccess peer receives a retL message, it will scan its table of IP addresses that it previously sent a getL message to, if the peer’s IP address that sent the retL message does not appear in the table the ZeroAccess peer that received the retL message will disregard it. This change ensures that unsolicited retL messages are ignored and makes using retL messages as a means of introducing rogue IP addresses (like newL messages could be used in the previous protocol) more difficult.
Improved payload file transfer resiliency
A ZeroAccess peer already contains checks to ensure it does not download a rogue payload file from a remote host. A payload file’s metadata in retL messages is digitally signed and cannot be easily forged. In addition, the malicious payload files themselves are digitally signed, the signature is checked after the file is downloaded. The digital signatures prevent a rogue peer from introducing an arbitrary executable module into the peer-to-peer network. The June 29 code change adds checks to ensure that TCP file transfers are not taking too long to complete. These changes seem to be designed to protect against a kind of denial-of-service attack where a rogue peer attempts to trick a ZeroAccess peer into downloading a large number of files from a rogue peer that would deliver the file data too slowly. Using this attack it would be possible to occupy all TCP ports on an infected computer, not allowing it to download the intended malicious payloads.