[REVS] Backdoor Spotcom Analysis
From: SecuriTeam (support_at_securiteam.com)
Date: 11/27/03
- Previous message: SecuriTeam: "[EXPL] EPIC4 CTCP Nicknames Buffer Overflow"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
To: list@securiteam.com Date: 27 Nov 2003 12:09:10 +0200
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
Backdoor Spotcom Analysis
------------------------------------------------------------------------
SUMMARY
Spotcom is a backdoor client application that allows a hacker to control
infected machine from the internet. It uses a fake DNS server for
communication. The server IP address (218.242.252.211) is hard-coded in
the program body. This particular piece of software was installed on
machine via a bug in IE. Although it is not limited in this form of
distribution, it still needs one as it includes no spreading mechanism in
itself. Spotcom installs itself as a Windows NT service by replacing
itself with a valid Microsoft service QOS RSVP. Service installation
requires system level privileges. If the system is configured properly,
this program is not a threat. The program also uses some other NT-specific
win32 API calls, which makes it only available on NT/W2K/XP (and maybe
later).
DETAILS
The program is distributed in two files:
%sysdir%\msrsvp.exe
%sysdir%\olegui.dll
It may also create one or more files of the following name:
%sysdir%\wins\logX.txt
Where X presents a physical drive letter (C, D, and so on).
Uninstallation:
Replace the path %sysdir%\msrsvp.exe with %sysdir%\rsvp.exe in QOS RSVP
service and delete files %sysdir%\msrsvp.exe and %sysdir%\olegui.dll. Note
that the installation allows taking over any service, not only RSVP.
msrsvp.exe is also capable of creating a service of its own, named as "IIS
publishing service" (more on this in chapter 3.).
Defense:
Close direct outbound access from clients (DNS, HTTP, FTP..).
System installation:
The two executable files are packed as one executable using a custom
binder application. The binder was named as "web2.exe", it was packed
using the UPX executable packer and its size is 36864 bytes. The binder
extracts the files msrsvp.exe and olegui.dll and executes msrsvp.exe with
argument "replace rsvp", which replaces the executable path in Microsoft
QOS RSVP service (for more information of msrsvp.exe arguments, see
chapter "msrsvp.exe arguments"). After that, it starts the service
(chapter "Running").
msrsvp.exe arguments:
msrsvp.exe accepts a couple of command line arguments. When executed
without argument, it attempts to run as a NT service.
install This makes a new service in the system, named as "IIS
publishing service"
replace <service> Replace service executable path with msrsvp.exe
remove Remove "IIS publishing service"
listen <port> Listen on TCP port and spawn a cmd.exe
connect <host> <port> Connect cmd.exe to host and TCP port
Communication protocol:
The communication protocol is a binary protocol that uses UDP port 53.
Although it runs over a standard DNS port, the protocol has little to do
with the DNS protocol (the Internet Domain Name System). Basically, the
protocol is a simple request-response type protocol. The client sends
requests and timeouts if the server does not answer. When timeout occurs,
the client sends another query. When the server has command in its queue
for the client, it sends a single packet that includes the command
transaction id and all the necessary arguments in predefined locations in
the packet payload. The client executes the command, replies with small
reply packet and sends query again. Before the query phase (Phase 2) can
happen, the server database has to be synchronized (Phase 1).
The following are example packets of each protocol transaction in tcpdump
format:
Phase 1 - synchronization (transaction id 0x46)
After startup, the client sends periodically a synchronization packet to
server. Packet's payload is of size 84 bytes and it consists of mostly
random bytes. This is because of un-initialized stack variables in the
client code. The packet should include the client's IP address (bolded at
offset 0x65) but instead of it, there's a pointer to the IP address. This
makes no sense, probably it's a bug.
19:13:30.664571 IP 192.168.1.20.1231 > 218.242.252.211.53: 522 [70a] [0q]
[2n][6144au] (84)
0x0000 4500 0070 0bd6 0000 8011 9524 c0a8 0114 E..p.......$....
0x0010 daf2 fcd3 04cf 0035 005c 7be8 020a 0000 .......5.\{.....
0x0020 0000 0046 0002 1800 ffff ffff c0f9 d000 ...F............
0x0030 5cc3 fc77 c80b 1800 d800 0000 0906 0200 \..w............
0x0040 0000 0000 0000 0175 9af8 d000 7801 1800 .......u....x...
0x0050 0500 0000 4000 0000 e802 1800 e802 1800 ....@...........
0x0060 d12c f977 78f4 981a 0002 0000 0000 0000 .,.wx...........
Phase 1 - server reply (transaction id 0x15)
The server replies to synchronization request with the following message
19:13:30.666950 IP 218.242.252.211.53 > 192.168.1.20.1231: 21 [0q] (12)
(DF)
0x0000 4500 0028 0000 4000 3f11 a242 daf2 fcd3 E..(..@.?..B....
0x0010 c0a8 0114 0035 04cf 0014 612a 0015 0000 .....5....a*....
0x0020 0000 0000 0000 0000 0000 0000 0000 ..............
Phase 2 - query (transaction id 0x24)
After the synchronization, client starts sending periodically query
packets. The query packet's payload includes a client name (offset 0x28)
as returned by GetComputerName win32 API call.
19:14:20.692468 IP 192.168.1.20.1231 > 218.242.252.211.53: 532 [36a] [2q]
[2au][|domain]
0x0000 4500 004e 0bd8 0000 8011 9544 c0a8 0114 E..N.......D....
0x0010 daf2 fcd3 04cf 0035 003a 6f1d 0214 0000 .......5.:o.....
0x0020 0002 0024 0000 0002 4a54 5245 5300 0000 ...$....JTRES...
0x0030 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0040 0000 0000 0000 0000 0000 0000 0000 ..............
Phase 2 - server command (various transaction ids)
Normally, server doesn't respond to query packets. When it responds, it
encapsulates a command to client in packet payload. Following packet is an
example of command timeout 16 seconds (id 0x0b):
19:14:20.694464 IP 218.242.252.211.53 > 192.168.1.20.1231: 11 [0q] [16au]
(12)(DF)
0x0000 4500 0028 0000 4000 3f11 a242 daf2 fcd3 E..(..@.?..B....
0x0010 c0a8 0114 0035 04cf 0014 6124 000b 0000 .....5....a$....
0x0020 0000 0000 0000 0010 0000 0000 0000 ..............
See the chapter "Commands" for complete list of commands.
Phase 2 - client reply (transaction id 0x04)
Client always replies to command packets with the following packet:
19:14:20.695026 IP 192.168.1.20.1231 > 218.242.252.211.53: 533 [4a] [3q]
Type0(Class 0)? .[|domain]
0x0000 4500 002e 0bd9 0000 8011 9563 c0a8 0114 E..........c....
0x0010 daf2 fcd3 04cf 0035 001a 5f17 0215 0000 .......5.._.....
0x0020 0003 0004 0000 0000 0000 0000 0000 ..............
Commands:
The following table lists all the commands that are implemented in the
client code.
Command (transaction id) Description
synchronize (0x15) Synchronize client for communication
timeout (0x0b) Set timeout for queries. Default is 50 seconds.
Basically, this adjusts timeout parameters in select() winsock API call.
listen (0x0c0b) Listen on TCP port and spawn a cmd.exe (simple telnet
server)
connect (0x0c0c) Connect cmd.exe to remote host using defined TCP port
(reverse telnet)
monitor (0x0c0d) Start filesystem monitoring. For more information, see
chapter "File system monitoring"
getfile (0x0c0e) Connect to remote server using a custom TCP protocol
and request a file. Returned file is written over an existing local
filesystem file (see chapter "getfile").
Most of the above commands need no further explanation. We'll take a
closer look in file system monitoring and getfile function in the
following chapters.
File system monitoring:
Transaction with id 0x0c0d starts a special function that Jarkko calls a
file system monitor. It starts by determining all mounted disks with
GetLogicalDrives() win32 API call. Then it starts a new thread for every
drive it founds and begins to monitor the drive filesystem activity with
ReadDirectoryChangesW() API call. When something happens in filesystem, it
writes the action in log file %sysdir%\wins\logX.txt where X is the drive
letter (C, D, ..). Example log file logC.txt:
Directory/File added - C:\New Text Document.txt
Directory/File removed - C:\New Text Document.txt
Directory/File added -
C:\RECYCLER\S-1-5-21-789336058-838170752-725345543-500\Dc339.txt
The function reads three parameters in command packet payload: server
name/address, username and password. These parameters are used later for
transferring log files to remote server using the FTP protocol. The
transfer takes place two times in a day, about 04 and 12 (the exact time
depends on when the client has started execution). The client first
changes its directory as "use". Then it makes two directories, first one
named as its IP address and the second one presenting a current date
inside the first directory. Then it uploads all the log files in that
directory. Example log:
Sun Nov 23 12:07:41 2003 CWD use
Sun Nov 23 12:07:41 2003 MKD 192.168.1.20
Sun Nov 23 12:07:42 2003 CWD 192.168.1.20
Sun Nov 23 12:07:42 2003 MKD 2003-11-23-12-7
Sun Nov 23 12:07:42 2003 CWD 2003-11-23-12-7
Sun Nov 23 12:07:42 2003 TYPE I
Sun Nov 23 12:07:42 2003 PORT 192,168,1,20,5,47
Sun Nov 23 12:07:42 2003 STOR logC.txt
getfile:
This function reads four parameters in command packet payload: server IP
address, TCP port, authentication string and a local filename. It makes a
TCP connection to server and sends the authentication string to server.
The server then responds something (no matter what) and waits for next
packet from client. After that, the server throws some data in the TCP
connection and the clients writes that data in place of the local file
determined as an argument.
OK.. What's this? Jarkko guesses it is some sort of remote file fetching
implementation. It may even be a buggy http client implementation (server
may request a normal "GET /file.exe HTTP/1.0" stuff in authentication
string). But what's strange, the client throws the authentication string
with two NULL-bytes in front (\0\0string). My apache server was very upset
about that. Jarkko was able to fetch files with custom server
implementation using netcat. But that sounds very strange, why in earth
the author has chosen this instead of normal HTTP? This function may be
worth of further examination.
Conclusion:
Jarkko was really impressed about couple of things in this backdoor. First
thing was the file system monitoring feature described in chapter "File
system monitoring". Using this simple technique, it is possible to spy on
every single filesystem operation in system. In effect, this gives the
hacker quite good overview what's interesting in this particular system.
Another thing that caught my attention was a fair amount of work that the
program does for keeping it stealthy - DLL injection and using DNS port
for reverse communication channel. The DLL injection is becoming de-facto
in Trojan industry and they are now really looking for alternative
communication channels instead of normal "direct" connection to client or
using reverse channel via HTTP. This is getting scary. What about this
type of program that uses real DNS protocol for communication? Registering
an anonymous subdomain with full NS records is not a big deal.. Do you
allow recursive DNS queries from workstations? Is your network safe? Well,
Jarkko hopes that we will never see this kind of super Trojan.
This implementation also suffers from a couple of flaws. First off, it
does not implement any kind of code-obscuring techniques. It is all right
there, ready to disassemble and read. Or maybe it does, Jarkko is just
missing it for that reason. Second thing, there is at least one entry
level programming error in the code (IP address handling of
gethostbyname(), see chapter "Communication protocol"). This is very
strange, because the IP address is determined successfully with the very
same routines elsewhere in the code (see chapter "File system monitoring"
for example). This makes me wonder, is this some development version
released in hurry or impatient cut-and-paste? Anyway, the idea and design
is still very good.
ADDITIONAL INFORMATION
The original document is available at:
<http://www.klake.org/~jt/malware/spotcom/>
http://www.klake.org/~jt/malware/spotcom/.
The information has been provided by <mailto:jt@klake.org> Jarkko
Turkulainen.
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Previous message: SecuriTeam: "[EXPL] EPIC4 CTCP Nicknames Buffer Overflow"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|