Neeris worm: looking for "case zero"
Par Sylvain SARMEJEANNE, jeudi 3 septembre 2009 à 14:38 :: General :: #332 :: rss
The first half of 2009 has seen the following main virus threats: Conficker, Virut and Neeris. The latter is a worm which spreads like Conficker by exploiting the
MS08-067 vulnerability. It was far from receiving the same media attention as Conficker but did succeed in infecting many companies. Different ways of spotting the first infected machine on a network, namely the infection source, are described in this post.
It is assumed that all machines are synchronized with a time server; comparing time between machines then makes sense and our problem boils down to determining the infection date of each machine. This can be determined from the modifications the worm made on the system, mainly on the filesystem, events and registry (NB: a filter like "Category is Write" in Process Monitor is a good starting point).
Filesystem
The worm begins by copying itself in C:\WINDOWS\system under a randomly chosen name, netmon.exe in this case. NTFS attributes give the file creation date and time, that is to say an infection date (NB: first, fls is used to get the index of the file in the MFT, then istat is used to retrieve the information):
$ fdisk -ul neeris_disque.raw neeris_disque.raw1 * 63 8369864 4184901 7 HPFS/NTFS
$ fls -o 63 -r neeris_disque.raw | grep netmon ++ r/r 9433-128-3: netmon.exe
$ istat -o 63 neeris_disque.raw 9433 $STANDARD_INFORMATION Attribute Values: Created: Mon Aug 31 18:02:33 2009 File Modified: Mon Aug 31 18:02:32 2009 MFT Modified: Tue Sep 1 06:36:38 2009 Accessed: Mon Aug 31 18:02:33 2009
Similarly, the worm drops a rootkit in C:\WINDOWS\system32\drivers\sysdrv32.sys. The properties of this file also give us an infection date:
$ fls -o 63 -r neeris_disque.raw | grep sysdrv32.sys +++ r/r 9437-128-3: sysdrv32.sys $ istat -o 63 neeris_disque.raw 9437 $STANDARD_INFORMATION Attribute Values: Created: Mon Aug 31 18:02:36 2009 File Modified: Mon Aug 31 18:02:36 2009 MFT Modified: Mon Aug 31 18:02:36 2009 Accessed: Mon Aug 31 18:02:36 2009
This gives us another time, showing us that this action occurred a few seconds after the other one.
We have another option: prefetch files. Prefetch is a functionality of the Windows Memory Manager which aims at speeding up the boot and application load process, enabled by default and configurable via the HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters registry key (refer to chapter 7 of the Windows Internals book for more details). Like every application, the worm is also impacted by this mechanism and Windows will create the appropriate files in C:\WINDOWS\Prefetch:
$ fls -o 63 -r neeris_disque.raw | grep NETMON ++ r/r 9436-128-4: NETMON.EXE-0D87B210.pf
$ istat -o 63 neeris_disque.raw 9436 $STANDARD_INFORMATION Attribute Values: Created: Mon Aug 31 18:02:34 2009 File Modified: Mon Aug 31 18:02:44 2009 MFT Modified: Mon Aug 31 18:02:44 2009 Accessed: Mon Aug 31 18:02:34 2009
The filesystem timeline (the capture below was taken with PTK) shows that at the time determined above, temporary Internet files have been written under the NetworkService account. This is a sign of a successful exploitation of a vulnerability in a Windows network service:

All directories and files in the capture above, if their names are not system dependent, can be used to determine the infection date.
Events
The rootkit is loaded via the Windows Service Control Manager and this will generate a 7035 event in the System event log, providing us with an infection date:

Searching for this event is trivial as the rootkit always installed itself as Play Port I/O Driver. The only issue we may face would be the overwrite of these events. However, the time given by this method is relatively late (10s after the main executable was dropped).
Registry
Several modifications are made in the registry:
- new value in the HKLM\SOFTWARE\CurrentVersion\Run key under a randomly chosen name (netmon here), pointing to a copy of the worm in C:\WINDOWS\system
- new firewall exception (new value in the HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\AuthorizedApplications\List key)
- kernel rootkit (new HKLM\SYSTEM\CurrentControlSet\Services\sysdrv32 key)
- the worm runs even in safe mode with or without network support (new HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\{Minimal,Network}\netmon keys)
In the registry, dates and times are stored, but they correspond to keys and not values. Indeed, the LastWriteTime is stored in a _CM_KEY_CONTROL_BLOCK structure:
lkd> dt nt!_CM_KEY_CONTROL_BLOCK +0x038 KcbLastWriteTime : _LARGE_INTEGER
We are looking for a registry key specifically created by the worm which we will be able to extract the LastWriteTime (last modification time) from, and not a new value in an existing key. The second and third points above meet this requirement. The date and time can be extracted manually with regedit by exporting the key in text format:

The procedure can be automatized via the RegQueryInfoKey function which returns the information in its lpftLastWriteTime field.
Another method would be to analyze the RAM. The task has recently become easy thanks to the possibility of using RegRipper plugins against memory dumps via Volatility. First, let's list the hives available in our RAM dump via the hivelist plugin:
$ ./volatility hivelist -f neeris_ram.raw Address Name 0xe17ff008 \Documents and Settings\<user>\Local Settings\Application Data\Microsoft\Windows\UsrClass.dat 0xe17f7b60 \Documents and Settings\<user>\NTUSER.DAT 0xe13112b0 \WINDOWS\system32\config\software 0xe1311b60 \WINDOWS\system32\config\default 0xe1309008 \WINDOWS\system32\config\SECURITY 0xe1309758 \WINDOWS\system32\config\SAM 0xe101b008 \WINDOWS\system32\config\system
Now, our plugin can be executed against these hives and will return the information, for example from the SYSTEM hive:
$ perl rip.pl -p neeris_lexsi -r neeris_ram.raw@0xe101b008 ControlSet001\Services\sysdrv32 [Mon Aug 31 16:02:41 2009] ControlSet001\Control\Safeboot\Minimal\netmon [Mon Aug 31 16:02:33 2009] ControlSet001\Control\Safeboot\Network\netmon [Mon Aug 31 16:02:33 2009] ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\AuthorizedApplications\List [Tue Sep 1 04:36:38 2009]
In these examples, the given time doesn't take into account the time zone (this is a memory dump from a French system at UTC+2). The time of the sysdrv32 key matches the one extracted from the event log. However, the AuthorizedApplications\List key has been modified afterwards and doesn't give a correct time.
This RegRipper plugin is available for download (please note that the plugin is not exhaustive and is only a proof of concept).
If these keys were removed by the antivirus, it is still possible to apply the LastWriteTime method on a key where the worm only added a value, such as HKLM\SOFTWARE\CurrentVersion\Run or HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\AuthorizedApplications\List, rather than on a key it created. This will surely returns a result, but it may not be correct due to legitimate modifications of these keys by other programs, which also affect the date and time (see the example above about the RAM dump). Anyway, if these dates match, chances are that this is the right infection date.
Processes
By analyzing the RAM, it is also possible to determine the time when the netmon.exe process was launched via the psscan2 Volatility plugin (NB: pslist will not work here due to the rootkit which hides this process):
$ ./volatility psscan2 -f neeris_ram.raw
PID PPID Time created Time exited Offset PDB Remarks
1352 556 Mon Aug 31 11:07:23 2009 0x00f79228 0x00f66000 spoolsv.exe
916 556 Mon Aug 31 11:06:55 2009 0x0102f6b0 0x06a00000 svchost.exe
852 556 Mon Aug 31 11:06:53 2009 0x0103b020 0x0643a000 svchost.exe
772 556 Mon Aug 31 11:06:48 2009 0x0104da90 0x05c50000 svchost.exe
568 484 Mon Aug 31 11:06:41 2009 0x0106b938 0x057d7000 lsass.exe
556 484 Mon Aug 31 11:06:41 2009 0x0106d090 0x057cb000 services.exe
1664 1608 Mon Aug 31 16:02:34 2009 0x0107d670 0x06f26000 netmon.exe
356 4 Mon Aug 31 11:06:34 2009 0x0108c4d0 0x047dc000 smss.exe
460 356 Mon Aug 31 11:06:37 2009 0x010b5488 0x052ae000 csrss.exe
484 356 Mon Aug 31 11:06:38 2009 0x011b7020 0x05473000 winlogon.exe
4 0 0x011f29c8 0x00039000 System
1964 556 Mon Aug 31 11:08:13 2009 0x0604cb00 0x001c4000 alg.exe
1924 556 Mon Aug 31 11:08:09 2009 0x060c8020 0x024a0000 svchost.exe
1036 556 Mon Aug 31 11:07:06 2009 0x078e9508 0x0791e000 svchost.exe
1208 1140 Mon Aug 31 11:07:16 2009 0x07d29020 0x07de8000 explorer.exe
1204 1208 Mon Aug 31 11:19:46 2009 0x07d92820 0x0554a000 cmd.exe
Modulo the 2-hour time difference, this gives us the same date and time as determined above.
Network connections
Finally, sockets also have a creation date. By listing the sockets associated with our process (PID 1664), we are given the connections corresponding to the exploitation of the MS08-067 vulnerability on remote hosts; the first of these dates is the first exploitation attempt, and the date matches (modulo 2 hours again):
$ ./volatility sockets -f neeris_ram.raw | grep 1664 Pid Port Proto Create Time 1664 4637 6 Tue Sep 01 04:39:01 2009 1664 4641 6 Tue Sep 01 04:39:02 2009 1664 4645 6 Tue Sep 01 04:39:02 2009 1664 1664 6 Tue Sep 01 01:10:06 2009 1664 2866 6 Mon Aug 31 22:01:10 2009 1664 4634 6 Tue Sep 01 04:39:00 2009 1664 4638 6 Tue Sep 01 04:39:02 2009 1664 3502 6 Tue Sep 01 01:52:38 2009 1664 4642 6 Tue Sep 01 04:39:02 2009 1664 4646 6 Tue Sep 01 04:39:02 2009 1664 3762 6 Tue Sep 01 01:53:03 2009 1664 14575 6 Mon Aug 31 16:02:36 2009 1664 3495 6 Tue Sep 01 01:52:37 2009 1664 1669 6 Tue Sep 01 01:10:07 2009 1664 4635 6 Tue Sep 01 04:39:00 2009 1664 4639 6 Tue Sep 01 04:39:02 2009
Conclusion
Different ways of determining the date when a system has been infected by Neeris have been described, through disk and RAM analysis. These methods have their own advantages and drawbacks, but their efficiency can be decreased by the actions performed by the antivirus which may remove pieces of evidence when removing the worm. Analyzing the RAM can be useful, provided the first responder doesn't arrive too late...