Writing your first RAT [Remote Administration Tool]

So you want to know how to write your first Remote Administration Tool?

In order to keep our first tool very simple, we're going to create a Remote Shell.
Our Remote Shell should allow us to run commands on the target's computer.
In future tutorials, we'll discuss how to do more, but this should give us a place to start.

The language we'll be using is C#

If you don't have C#, you can get it for free Here

Open Visual Studio and Select New Project
Choose C# Console Application and name it BackdoorServer

 

The key to starting any program is to do some brainstorming and figure
out what our program is going to need to operate, and how.

We want our program to open a port on the target computer and listen.
Then, we want to be able to connect to it and have it execute commands.

We're going to have our program run "cmd.exe" silently, and pipe
input from our socket to the process, then from the process to the socket.

[Client (Us)] -> [Server] -> [CMD.exe Process]
[Client (Us)] <- [Server] <- [CMD.exe Process]

The TcpListener class will allow us to "listen" on a port and accept connections
The Socket class will handle the connections and provide stream access
StreamReader and StreamWriter will be used to send the data

It'd also be nice to require a simple password to get access, it's our shell after all!

Note: For the sake of simplicity our passwords and stream are unencrypted
This is obviously NOT acceptable in a live environment, but we're here to learn :)

Anyway, enough talking, let's take a look at the code!

We need to include Sockets, Threading, .Net, Diagnostics, IO, and of course System

Our thread will be used to read the responses from the shell itself

Here we've setup variables for our Socket, Listener, Port, Password, Server name,
Process, Stream Readers and Writers, and our Thread

We've also set up our default ports and written our default constructor.
Our constructors will allow us to run the backdoor from command line in the future :)

Here we've finalized our constructors and have begun writing the startServer() method

This is the method we will call to begin listening and receiving connections.

Our verbose variable will let us debug our shell if we need to.

listener.AcceptSocket() will open the port we've set and wait for a connection.

At this point, a client has connected, so we open StreamReaders/Writers
so that we can communicate with the client. We don't say anything yet however,
we wait until the client sends something to us, namely a password.

If the first thing they say isn't the password, we disconnect them immediately and
wait for another connection. This ensures that nobody random can connect and
find a message that says "Enter Password:" that would seem a little fishy

If they enter the correct password, we start our shell.

CreateNoWindow and RedirectStandardInput and Output to our server

Then we start a new thread to monitor the replies from our cmd.exe process

[Client] -> [MainProgram] -> [toShell.StandardInput] -> [cmd.exe]
[Client] <- [shellThread] <- [toShell.StandardOutput] <- [cmd.exe]

This ensures a smooth transaction of data.

At the end of our try {} catch {} statements, we run our dropConnection() method
to ensure that our server starts listening again if someone disconnects prematurely

Our getShellInput() method will read each line from our shell as they are sent
and forward them to our client through the outStream.WriteLine() method.

Our getInput() method will conversely take input sent from our client
through the inStream.ReadLine() method and make a call to handleCommand()

The reason to have a handleCommand() method is that it allows us to create
our own commands in the future if we want.

For example, if we want to be able to type shutdown server, we wouldn't
want to send that to cmd.exe because it would have no idea what to do

I wrote a command to catch "exit" so that we drop the connection instead of
just killing the process; otherwise we'd be connected with no shell!

If our handleCommand() method doesn't find a special command
then we just forward what was typed directly to the shell

Here we have our badPass() function which is a shorter version of dropConnection()
The dropConnection() method is what I would call, a little dirty
If any part of this code needs some cleaning, it's calls to this guy.

Basically, it resets all of our variables so that they can be used once again.
Because we've encapsulated so much of our code in try {} catch{} statements,
most of the catch's make calls to this function just so that it doesn't prematurely crash.

If, for example, someone connects, enters, and then just closes their client,
if our program is in the middle of while(tempBuff = inStream.ReadLine())
the stream will be invalidated and it will make a quick call here.

Even though it's a little messy in my opinion, I haven't been able to get it to crash :p

Finally, we make it to our Main function :)

Testing our Backdoor:

We can use telnet to connect to our own computer through loopback on port 1337

Note: If you don't have telnet enabled

If you don't have telnet enabled, you can enable it through Control Panel

Success! ^.^ Bonus: Connect with your phone!

Well we've created our very own Remote Shell!
But you'll notice that we can still see it!!!!
We want it to be hidden, so here's an incredibly simple way to hide it:
Note: Obviously better methods exist, but we're keeping it simple :)

Go to Project -> Backdoor Properties -> Output type: Windows Application

That's it! Hope you learned something!

Download Source Here
Download EXE Here
Download Hidden EXE Here

Note: To connect to the precompiled hidden version, use port 1337 and
password "password." It's named svchost so that it blends in :)