Welcome to HBH! If you had an account on hellboundhacker.org you will need to reset your password using the Lost Password system before you will be able to login.

system() or execv()? c++ remote shell construction


ghost's Avatar
0 0

hi all,

This is my first post. I'm writing a server in c++ that will allow remote terminal commands to be executed on the hosting machine similar to a SSH service. currently I'm trying to send the commands by using the system() function. However the system () function returns an int. So by sending the ouput of system() across the wire it will not return the data im looking for. is my only other option execv()?

or would it be easier to just try to emulate a shell on the serving machine. This is a little out of my scope seeing as how im not THAT advanced in the c++ language. I have read several exploits written in c++ that utilize this method. Not to sure what direction to go here.

#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <dirent.h>


#define PORT 6666
#define MAXBUFF 1024



using namespace std;


int main()
{

	int sock1,portno;
	char buffer[MAXBUFF];
	struct sockaddr_in serv;
	string str;

	portno= htons(PORT);


sock1= socket(AF_INET, SOCK_STREAM, 0);

	if(sock1 < 0)
	{
		cout<<"error opening socket\n";
	}


memset(&serv,'\0', sizeof(serv));
	serv.sin_family= AF_INET;
	serv.sin_port = portno;
	serv.sin_addr.s_addr= INADDR_ANY;


if (bind(sock1, (struct sockaddr*)&serv, sizeof(serv)) <0)
	{
		cout<<"error on bind\n";
	}


listen(sock1,5);

while(1)
	{

int newsock;
struct sockaddr_in client;
		int len;
len = sizeof(struct sockaddr_in);


		newsock = accept(sock1, (struct sockaddr*)&client, (socklen_t*)&len);
		
		cout<<"new connection from "<<inet_ntoa(client.sin_addr)<<":"<<ntohs(client.sin_port)<<"\n";

		write(newsock, "welcome\r\n",9);
		write(newsock, "please select an option below.\r\n",32);
		//these are the options //

int i,n;


		
i= recv(newsock, buffer, MAXBUFF-1,0);
buffer[i]='\0';

n = atoi(buffer);


		
					if ( n == 1)

		{
			write(newsock, "you have pressed 1 \r\n",21);
			write(newsock, "please enter a unix command to execute.\r\n",41);
            memset(buffer,'\0', sizeof(buffer));
			i= recv(newsock, buffer, MAXBUFF-1,0);
buffer[i]='\0';

	
			
					if (buffer[0] == 'l' && buffer[1] == 's')
			{
				write(newsock,"you have chosen list directory\r\n",34);
				system("ls");
		
				
			
				
			}

			

			
		}		
	close(newsock);
	}

	close(sock1);
return 0;
	
}

that system () call will display the "ls" terminal command like its supposed to on the serving machine. like i stated before sending it through the socket will result in an int. Thanks for the help in advance. Any suggestions would be great.


ghost's Avatar
0 0

Scrap the integer 'i', and use read() as opposed to recv().


ghost's Avatar
0 0

As far as i know all read () does over recv() is add an extra argument for flags right? at the moment i don't have a need for the flags. unless your saying use read() to read in the buffer as a null terminated string. Which is what the int i; is performing by tacking on the '\0' char to the end of the character array.

still havent gotten any responds to the main question though. " best way to display terminal output from the remote machine." so with that….BUMP


ghost's Avatar
0 0

… use popen instead and select/poll the client & process FDs to send/recv from either.


ynori7's Avatar
Future Emperor of Earth
0 0

nebularvisions4 wrote: However the system () function returns an int. So by sending the ouput of system() across the wire it will not return the data im looking for. is my only other option execv()? What data are you expecting to be returned? I'm pretty sure the execv function only returns if there's an error (and the return value will be -1), otherwise the program ends.

If you want to execute system commands, use execvp (that one doesn't require you to specify the path to the command). System() doesn't work on unix machines I believe. If you want your program to continue running after executing the command, you'll have to fork the process and have the child do the execution.

By the way, your tabbing sucks.

EDIT: This is coming from my knowledge of C. I can't say with certainty that it applies exactly to C++.