Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C (http://www.go4expert.com/articles/c-tutorials/)
-   -   Virus Code in Linux - C Code That Changes it's Process Name Run Time (http://www.go4expert.com/articles/virus-code-linux-c-code-changes-process-t27234/)

poornaMoksha 29Nov2011 06:30

Virus Code in Linux - C Code That Changes it's Process Name Run Time
 
The other day I was searching a bit on Linux viruses on Internet. Though there are quite a few now but still cannot be compared with the volumes that we have on windows. Another thing that I found was the permission robustness that Linux file system has as compared to windows OS. So, whiling reading all this, I read one line which meant something like :
The one good thing that Linux virus can do is to have innocent names so that one cannot immediately track the virus by running ps command
Well, this line left an impression in my mind. I started thinking of a process that can change its name at regular intervals so that it becomes a bit difficult to track it. Then quickly I wrote a code that does exactly the above. Here is the code.

The Code of Virus in Linux



Code:

#include<stdio.h>
 #include<stdlib.h>
 #include<string.h>
 #include<unistd.h>
 
 int main(int argc, char* argv[])
 {
    char buff[1024]; // Buffer to read lines
    char new_name[1028]; // Buffer to store new process name
 
    char *ptr = NULL;
    FILE *fp  = NULL;
 
    a: memset(buff,'\0', sizeof(buff)); // Setting the memory with NULLs
    memset(new_name,'\0', sizeof(new_name)); // Setting the memory with NULLs
 
    // Introduce constant 3 bytes '123' in the beginning 
    // of every name that we change our process name to. 
    // So that we can at-least easily track our process name
    // when we check it using ps command. Note that
    // this is only for practice purpose otherwise there
    // is no need for a set of constant bytes like these.
    new_name[0] = '1';
    new_name[1] = '2';
    new_name[2] = '3';
 
    // Run the command 'ps -aef > ps.txt'
    // This command will store the result of 'ps -aef' in a text file 'ps.txt'
    // The files would have entries like :
        // UID        PID  PPID  C STIME TTY          TIME CMD
        // root        1    0  0 20:49 ?        00:00:00 /sbin/init
        // root        2    0  0 20:49 ?        00:00:00 [kthreadd]
        // root        3    2  0 20:49 ?        00:00:00 [migration/0]
        // root        4    2  0 20:49 ?        00:00:00 [ksoftirqd/0]
 
    system("/bin/sh -c 'ps -aef > ps.txt'");
 
 
    // Open the file 'ps.txt'
    fp = fopen("ps.txt", "r");
 
    if(NULL == fp)
    {
        printf("\n File open failed\n");
        return -1;
    }
 
    // Get each line from file until the whole file is read or some error occurs
    while(NULL != fgets(buff, sizeof(buff), fp))
    {
        // Search for the character '[' in the line fetched from file.
        // This is because most of the process names are enclosed in '[' brackets.
        // For example :
        // root        2    0  0 20:49 ?        00:00:00 [kthreadd]
        ptr = strchr(buff, '[');
 
        unsigned int len = strlen(buff);
 
        if(NULL == ptr)
        {
            // Search for the character '/' in the line fetched from file.
            // This is because many of the process names are start with '/'.
            // For example :
            // root        1    0  0 20:49 ?        00:00:00 /sbin/init
            ptr = strchr(buff, '/');
        }
        if(NULL != ptr)
        {
            // If any one of '[' or '/' is found than copy the complete process
            // name in the buffer which already holds 123 as its first three bytes.
            // Make sure that you do not overwrite the first three bytes of the buffer
            // new_name which contains 123 as its first three bytes
            strncat((new_name+3), ptr, ((buff + len-1) - ptr));
        }
        else
        {
            // If the line fetched does not contain either of '[' or '/'
            // Then use a default process name '/bin/bash'
            ptr = "/bin/bash";
            strncpy((new_name+3), ptr, strlen(ptr));
        }
 
        // Since by now we have the new_name buffer filled with
        // new process name so copy this name to arg[0] so as to 
        // change our process name. 
        strncpy(argv[0], new_name, sizeof(new_name));
 
        printf("\n %s \n", new_name);
 
        //A delay of eight seconds so that you can run the command 'ps -aef'
        // and check the new name of our process. :-)
        sleep(8);
         
        //Time to fetch a new line from ps.txt so just reset
        // the buffer new_name with NULL bytes except the first
        // three bytes which are '123'. 
        memset((new_name+3),'\0', sizeof(new_name));
    }
 
    // Seems like either we are done reading all the lines
    // from ps.txt or fgets() encountered some error. In either
    // of the case, just close the file descriptor
    fclose(fp);
 
    // Since we do not want to stop even now, so lets re run the
    // whole cycle again from running the command 'ps -aef > ps.txt'
    // to reading each line using fgets() and changing the our process
    // name accordingly
    goto a;
 
    return 0;
 }

Explanation of Virus in Linux



The code above :
  1. Runs the command 'ps -aef' and stores its output in ps.txt
  2. Reads the text file ps.txt line by line and extracts the process names.
  3. Then that process name is used for our process.
  4. Note that since the above code is used for practice and to build understanding of the concept so it uses a constant string "123" in the beginning of every new process name so that it becomes easy to track(using ps command) that this is our process.
  5. If some how a process name could not be found by the logic, then name '/bin/bash' is used by default .
  6. If all the lines in ps.txt are read then the logic is written in such a way that steps 1 to steps 3 start repeating again.
  7. Hence we see the above code when executed, becomes a process that changes its name after every one second.
  8. Please make sure that in case you want to terminate the process then terminate it using ctrl+c as its an infinite running process.

Note that I have tested the above code on my 64 bit Linux Mint.

Execution



Now, when I executed the above code, here is what I could see.

On the terminal where I executed my code, I could see my code spitting the new process names it created :

Code:

  ~/practice $ ./namepid 
 
  123/bin/bash 
 
  123/sbin/init 
 
  123[kthreadd] 
 
  123[migration/0] 
 
  123[ksoftirqd/0] 
 
  123[watchdog/0] 
 ^C

While simultaneously on the other terminal I executed the command 'ps -aef' again and again and I could see the entries like :

Code:

himanshu  2515  2102  1 06:09 pts/1    00:00:00 123/bin/bash
 himanshu  2515  2102  0 06:09 pts/1    00:00:00 123/sbin/init
 himanshu  2515  2102  0 06:09 pts/1    00:00:00 123[kthreadd]
 himanshu  2515  2102  0 06:09 pts/1    00:00:00 123[migration/0]
 himanshu  2515  2102  0 06:09 pts/1    00:00:00 123[ksoftirqd/0]
 himanshu  2515  2102  0 06:09 pts/1    00:00:00 123[watchdog/0]

So we see that the above code was successfully able to change its name after every 8 seconds.

Conclusion



To Conclude, In this article I shared a code which when executed can change its name after every 8 seconds. This is just a prototype code that I wrote after I got this idea. I'd love to hear some improvements in the code shared here or if somebody can add some more features to it then he/she is also welcome to post his/her code here but the code should be well commented and should be in working condition.

Waiting for your replies and Stay tuned for more!!!


All times are GMT +5.5. The time now is 20:35.