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.txtwhere 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 to take over any service, not only RSVP. msrsvp.exe is also capable of creating a service of it's own, named as "IIS publishing service" (more on this in chapter 3.).
Defense: close direct outbound access from clients (DNS, HTTP, FTP..)
install | This makes a new service in the system, named as "IIS publishing service" |
replace |
Replace service service executable path with msrsvp.exe |
remove | Remove "IIS publishing service" |
listen |
Listen on TCP port port and spawn a cmd.exe |
connect |
Connect cmd.exe to host and TCP port port |
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 uninitialized 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 syncronization 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 6. 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 ..............
Command (transaction id) | Description |
synchronize (0x15) | Synchronize client for communication |
timeout (0x0b) | Set timeout for queries. Default is 50 seconds. Basically, this adjusts timout parameters in select() winsock API call. |
listen (0x0c0b) | Listen on TCP port 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 7. |
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 8). |
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.
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 it's directory as "use". Then it makes two directories, first one named as it's 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
OK.. What's this? I guess 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. I 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.
This implementation also suffers from a couple of flaws. First off, it does not implement any kind of code-obscuring techinques. It is all right there, ready to disassemble and read. Or maybe it does, I'm 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 5). This is very strange, because the IP address is determined successfully with the very same routines elsewhere in the code (see chapter 7. for example). This makes me wonder, is this some development version relesed in hurry or impatient cut-and-paste? Anyway, the idea and design is still very good.
Another thing that complicates the testing is the server. I don't like the idea of testing directly with the real thing (218.242.252.211). What if the server is alive? So, the options are pure static analysis of disassembly or some sort of emulation. That is what I did.
The test environment includes one Windows 2000 pro in VMWare virtual machine (client), a Linux/alpha server and OpenBSD firewall that does a NAT for server IP address (218.242.252.211). During live testing, some custom tools had to be developed:
Sun Nov 23 08:18:35 2003: received packet from 192.168.1.20:1316 Sequence: 0x0002 Transaction id: 0x24 (query) Client: JTRES 00 0x02 0x14 0x00 0x00 0x00 0x02 0x00 0x24 08 0x00 0x00 0x00 0x02 0x4a 0x54 0x52 0x45 10 0x53 0x00 0x00 0x00 0x00 0x00 0x00 0x00 18 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 20 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 28 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 30 0x00 0x00 Sun Nov 23 08:18:35 2003: sending packet to 192.168.1.20:1316 Transaction id: 0x0c Sun Nov 23 08:18:35 2003: received packet from 192.168.1.20:1316 Sequence: 0x0003 Transaction id: 0x04 (reply) 00 0x02 0x15 0x00 0x00 0x00 0x03 0x00 0x04 08 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 10 0x00 0x00 0x00 0x00 0x00 0x00Much cleaner look than tcpdump! Using server.c in company with OllyDbg helped greatly in understanding some parts of code.