Sunday, February 17, 2013

Zeroaccess analysis part I - Network traffic

I have seen quite a lot zeroaccess lately. I got curious and had too look more into what this piece of malware was up to. This first part will cover network traffic stuff mainly. I will post details on other stuff later...

Updated analysis 2013-08-13(even though not much have changed)

So what will happen, on the network, after a typical Zeroaccess infection:

1. During install the bot want to lookup what country it is located in. This is done with geoip lookup @ maxmind. 

So the first thing needed is to lookup Here is the dns q:

And then the geo ip lookup

2. The bot will then continue installing and report back to a C&C server the install status:

This is done over UDP port 53 to, what seem to be a hardcoded addresses: -> amazingly not blacklisted -> -> not blacklisted either ->

This is not DNS traffic as indicated by wireshark but XOR encrypted traffic from the bot on UDP port 53.

The UDP payload:

first packet to
first packet to

This is XORed with the key intial key "LONG" and bitwise ROL for each 4 byte:
decrypted:  a5dfceb7000000004e4f6106c3020000bb94dace

Second packet UDP payload:
encrypted:  e2:91:81:fb:f7:9c:9e:98:53:76:5c:37:f9:70:7a:62:08:cd:33:08
decrypted:  a5dfceb7790000004e4f6106c30200007c29c7cc

Third packet UDP payload:
encrypted:  e2:91:81:fb:0c:9c:9e:98:53:76:5c:37:f9:70:7a:62:58:b8:73:d1
decrypted: a5dfceb7820000004e4f6106c30200002c5c8715

Some parts of the payload seem to be static:
Byte 0-3 : a5:df:ce:b7 - Probably botid
Byte 8-9: 4e:4f - Country Code
Byte 10: 61 - OS version
Byte 11-13: 06:c3:02 -

When the inital install is done:

3. The bot will start to contact supernodes on UDP 16464:

These addresses are hardcoded in the bot at install time.
The payload in the UDP 16464 packets is a requst for updatet P2P ip address lists. See below for further analyzis.

4. The first hit on UDP will kick in TCP and in this case the bot starts talking to: on port 16464 -> blacklisted by spamhaus ->

So what is happening here?

Three TCP sessions are established towards all on destination port 16464.
Seem to be download of plugins/dlls to enhance functionality

src port 49988 - first session:

Only two packets with payload; one request and one response packet:

First data packet over TCP from the bot to payload length 12
Which means:
requsting file 00000001
timestamp: 3a2a5b71
length: 000003a0

First data packet from server( to bot:payload length 928

RC4 encrypted dll.

src port 49989 - second session:

Second data packet source port 49989: payload length 12
encrypted: cb:00:00:80:8f:17:90:3d:00:54:00:00
filename: 800000cb
size: 00005400

Reply data packets from server( to bot: 
Click fraud plugin/dll. RC4 encrypted

src port 49990 - third session:

Third packet:
encrypted: 00:00:00:80:ad:03:be:3d:00:2e:00:00

Get the file : 80000000
filesize: 00002e00

Reply data packets from server( to bot: 
Phone home plugin/dll

5. Next step then is C&C callback to tell the botmasters I'm alive:

UDP 123 traffic towards and
Both packets have the same payload:
encrypted: 47:4e:01:03:8e:9c:ad:f9:de:3b:3d:31:9f:ad:b4:d5:20:ab:e2:be

Which once again is XORED with the key "LONG" and again ROL
decrypted: 00004e4f00003361c3020000a5dfceb7544f167a
decr ascii: ??NO??3aÃ???¥ßηTO?z

Byte 0-1: 0000
Byte 2-3: Country Code
Byte 7: OS version
Byte 12-15: bot ID

6. Now lets keep our P2P address lists up to date:

The "fingerprint" of Zeroaccess. calling supernodes on UDP port 16464 once every second.
The bot here requests updated IP lists from it's peers. XORED 4 Bytes at a time with the iniyial key "ftp2" and then bitwise ROL for each XOR operation.
payload of the request packet:
encrypted: b8:14:35:fe:28:94:8d:ab:c9:c0:d1:99:85:95:6f:3f
Decrypted: 8a6441984c746567000000001614cc0c
decr ascii: ŠdA˜Lteg??????Ì?

Byte 4-7: command -> getL for get updated List

The supenode will then answer(with an XORED payload like the request):

Byte 4-7: Lter -> retL - returning list of peer IP addresses
Byte 16 and onward: IP address of  peer supernode and timestamp since last update. Timestamp is in seconds. Here all are updated within the last second.
defefdfe00000000 ->
cefefdfe00000000 ->
befefdfe00000000 ->
b6fefdfe00000000 ->
b4fefdfe00000000 ->
a6fefdfe00000000 ->
87fefdfe00000000 ->
4deedb5d00000000 ->
44e3e06400000000 ->
74cbd04500000000 ->
61680b8900000000 ->
6d60218e00000000 ->
2509d48e00000000 ->
ca47852a00000000 ->
7068cd9b00000000 ->
d8fc3328000000000 ->

7. With this information we are able to map this botnet issuing commands to the supernodes to give us the IP lists they have :)

Look at my post "Zeroaccess supernodes mapped - part I" for IP's of Supernodes

Check out this post to check a remote host for ZeroAccess infection.

8. There also is a newL command to insert new nodes into the botnet.

Sophos have analyzed this well back in Sept 2012 - Link


  1. Good analysis to you too, can be used for the future reference of ZeroAccess research reference.
    We thank you for your comment on #MalwareMustDie Blog.

    It is good to know that we are not alone on this mission.
    On behalf of our team,


  2. Excellent write up, thanks. The addresses are still active, and still not bloacklisted.

  3. Excellent post, very useful in real world investigation!

  4. Thanks for all feedback!

    Excellent if it helped this way or the other.

  5. Thank you for your insightful write-up!

    Just thought I would add some updated information, we recently saw 2 infections that were very similar to this pattern.

    We saw dest port 53 traffic to (instead of as you saw). I would say block the subnet.

    Then, we saw follow-up UDP traffic to on dest port 16464.

  6. Glad you found it helpful.

    Thanks for the update. I guess that the IP's will change over time. Suprisingly slow though...

    Yes UDP 16464 to fetch P2P lists is a ZA classic.

  7. Hello,

    I am trying to replicate your steps for analysis. i am stuck at the ROL bitwise. I XORed the packet with the key LONG "4c 4f 4e 47" but then the ROL is not giving me the same result as you have here. any tips will be appreciated

  8. Hi,

    Hard to tell from so little info what is the issue. I guess you know the difference between bitwise rotate and bitwise shift.

    As I do not know which packet you are looking into my second guess is that the first XOR failed too and became: aedecfbc (initial port 53 packets)which should decode a5dfceb7. If that is a correct assumption. Just reverse the encrypted string before XOR.

    No luck with that -> ping me on twitter

  9. Thank you for analysis. If we for example take the getL command: "8a6441984c746567000000001614cc0c" then the first four bytes represent the crc32 checksum of the whole packet, as sophos says, whereby the checksum is zero before calculation, so if i calculate "crc32(000000004c746567000000001614cc0c)" i should get "8a644198" as checksum shouldn't i ? Unfortunately i do not, has anyone an idea ?

    1. Hi, thanks!
      Yes that is the idea. Have you converted it to hex??

      hex(binascii.crc32(binascii.a2b_hex("000000004c746567000000001614cc0c")) & 0xffffffff)

    2. Working now ! Great, thank you for this one, but still got one question according the point "First data packet from server( to bot:payload length 928", the RC4 encrypted DLL. I want to decrypt and analyze that exemplary stream you gave. The key is actually the MD5 Hash of the file header information itself, so the request isn't it ? So adapting the endianness i use this key to decrypt the stream. What i am getting is "00000001" which is an dll file. Did you decrypt this, too ? I got an output but neither don't know if it is right decrypted nor how to check if it is the plugin i want, without the need or reverse engineering. Just want to be sure i got the right decrypted file.

    3. Hi,
      I have not gone to the length of decrypting that. Sorry!