免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234
最近访问板块 发新帖
楼主: W.Z.T

突破linux内核模块验证 [复制链接]

论坛徽章:
0
发表于 2019-12-20 16:05 |显示全部楼层
本帖最后由 custjcy 于 2019-12-21 13:56 编辑

楼主后面发的工具代码,只是把struct_module改名的。如果需要修改某个symbol的crc值,可以参考下面的代码(把楼主的工具修改了一下)。直接存成文件比如module_fucker.c,然后gcc -o module_fucker.bin module_fucker.c 生成可执行文件,然后执行命令修改,例如: ./module_fucker.bin -s -c sample.ko struct_module 0x76656456

如果要修改的地方比较多,可以参考 https://blog.csdn.net/mr_pang_1991/article/details/50014211 帖子生成Module.symvers文件后编译驱动

  1. /*
  2. * Linux kernel module fucker
  3. *
  4. * by wzt       <[email]wzt.wzt@gmail.com[/email]>
  5. *
  6. */

  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <unistd.h>
  11. #include <fcntl.h>
  12. #include <elf.h>
  13. #include <sys/stat.h>
  14. #include <sys/mman.h>

  15. #define MODULE_NAME_LEN         (64 - sizeof(unsigned long))

  16. struct modversion_info
  17. {
  18.         unsigned long crc;
  19.         char name[MODULE_NAME_LEN];
  20. };

  21. Elf32_Ehdr *ehdr = NULL;
  22. Elf32_Phdr *phdr = NULL;
  23. Elf32_Shdr *shdr = NULL;
  24. Elf32_Shdr *shstrtab = NULL;
  25. Elf32_Sym *dynsym_ptr = NULL;
  26. Elf32_Sym *symtab_ptr = NULL;
  27. Elf32_Sym *dynstr_ptr = NULL;

  28. char *Real_strtab = NULL;
  29. char *dynstr = NULL;
  30. char *strtab_ptr = NULL;
  31. char dynstr_buffer[2048];   
  32. char strtab_buffer[4096];
  33. char *real_strtab = NULL;

  34. unsigned int shstrtab_off, shstrtab_len, shstrtab_num;
  35. unsigned int strtab_off, strtab_size;

  36. int elf_fd;
  37. struct stat f_stat;
  38.    
  39. void usage(char *pro)
  40. {
  41.         fprintf(stderr, "usage: %s <options> <module>\n\n", pro);
  42.         fprintf(stderr, "-w -v\tCheck vermgaic in module.\n");
  43.         fprintf(stderr, "-w -c\tCheck crc value in module.\n");
  44.         fprintf(stderr, "-s -v <new_vermagic>\tSet vermagic in module.\n");
  45.         fprintf(stderr, "-s -c\tSet crc value in module. please append two more arguments after <module>: <symbol> <crc>. i.e. %s -s -c sample.ko module_layout 0xa925871a\n", pro);

  46.         exit(0);
  47. }

  48. int init_load_elf(char *elf_file)
  49. {
  50.         char buff[1024];

  51.         elf_fd = open(elf_file, O_RDWR);
  52.         if (elf_fd == -1) {
  53.                 perror("open");
  54.                 return 0;
  55.         }
  56.         fprintf(stderr, "[+] Open %s ok.\n", elf_file);

  57.         if (fstat(elf_fd, &f_stat) == -1) {
  58.                 perror("fstat");
  59.                 return 0;
  60.         }

  61.         ehdr = (Elf32_Ehdr *)mmap(NULL, f_stat.st_size, PROT_WRITE|PROT_READ, MAP_SHARED, elf_fd, 0);
  62.         if(ehdr == MAP_FAILED) {
  63.                 perror("mmap");
  64.                 return 0;
  65.         }

  66.         phdr = (Elf32_Phdr *)((unsigned long)ehdr + ehdr->e_phoff);
  67.         shdr = (Elf32_Shdr *)((unsigned long)ehdr + ehdr->e_shoff);

  68.         shstrtab = &shdr[ehdr->e_shstrndx];
  69.         shstrtab_off = (unsigned int)shstrtab->sh_offset;
  70.         shstrtab_len = shstrtab->sh_size;

  71.         real_strtab = (char *)( (unsigned long)ehdr + shstrtab_off );

  72.         printf("[+] .Shstrtab Size :0x%x,%d\n", shstrtab->sh_size, shstrtab->sh_name);
  73.         printf("[+] .Shstrtab Off: 0x%x\n", shstrtab_off);

  74.         return 1;
  75. }

  76. int display_module_crc_info(void)
  77. {
  78.         struct modversion_info *versions;
  79.         char *buff = NULL;
  80.         unsigned int version_off, version_size, num_versions;
  81.         int i, j;

  82.         buff = (char *)malloc(shstrtab_len + 2);
  83.         if (!buff) {
  84.                 fprintf(stderr, "[-] Malloc failed.\n");
  85.                 return 0;
  86.         }

  87.         memcpy(buff, real_strtab, shstrtab_len + 1);
  88.         for (i = 0 ; i < (int)ehdr->e_shnum ; i++){
  89.                 if (!strcmp(buff + shdr[i].sh_name,"__versions")){
  90.                         printf("[+] found section %s.\n", buff + shdr[i].sh_name);
  91.                         version_off = (unsigned int)shdr[i].sh_offset;
  92.                         version_size = (unsigned int)shdr[i].sh_size;
  93.                         printf("[+] version off: 0x%x\n", version_off);
  94.                         printf("[+] version size: 0x%x\n", version_size);
  95.                         break;
  96.                 }
  97.         }

  98.         printf("[+] %x,%x\n", (unsigned long)ehdr + version_off, shdr[i].sh_addr);
  99.         versions = (void *)((unsigned long)ehdr + version_off);
  100.         num_versions = version_size / sizeof(struct modversion_info);
  101.         printf("[+] num_versions: %d\n", num_versions);

  102.         for (j = 0; j < num_versions; j++) {
  103.                 printf("[+] %s:0x%08x.\n", versions[j].name, versions[j].crc);
  104.         }

  105.         free(buff);
  106.         return 1;
  107. }

  108. int set_module_crc_info(char* moduleName, char* moduleCrc)
  109. {
  110.         struct modversion_info *versions;
  111.         char *buff = NULL;
  112.         unsigned int version_off, version_size, num_versions;
  113.         int i, j;

  114.         buff = (char *)malloc(shstrtab_len + 2);
  115.         if (!buff) {
  116.                 fprintf(stderr, "[-] Malloc failed.\n");
  117.                 return 0;
  118.         }

  119.         memcpy(buff, real_strtab, shstrtab_len + 1);
  120.         for (i = 0 ; i < (int)ehdr->e_shnum ; i++){
  121.                 if (!strcmp(buff + shdr[i].sh_name,"__versions")){
  122.                         printf("[+] found section %s.\n", buff + shdr[i].sh_name);
  123.                         version_off = (unsigned int)shdr[i].sh_offset;
  124.                         version_size = (unsigned int)shdr[i].sh_size;
  125.                         printf("[+] version off: 0x%x\n", version_off);
  126.                         printf("[+] version size: 0x%x\n", version_size);
  127.                         break;
  128.                 }
  129.         }

  130.         printf("[+] %x,%x\n", (unsigned long)ehdr + version_off, shdr[i].sh_addr);
  131.         versions = (void *)((unsigned long)ehdr + version_off);
  132.         num_versions = version_size / sizeof(struct modversion_info);
  133.         printf("[+] num_versions: %d\n", num_versions);

  134.         for (j = 0; j < num_versions; j++) {
  135.                 printf("[+] %s:0x%08x.\n", versions[j].name, versions[j].crc);
  136.                 if (moduleName != NULL && !strcmp(versions[j].name, moduleName)) {
  137.                         if (moduleCrc != NULL) {
  138.                                 fprintf(stderr, "[+] Found symbol %s, and will set crc code to %s\n", moduleName, moduleCrc);
  139.                                 sscanf(moduleCrc, "0x%08x", &versions[j].crc);
  140.                                 
  141.                         } else {
  142.                                 fprintf(stderr, "[+] Found symbol %s, please input the crc code (like format: 0xa925871a):\n", moduleName);
  143.                                 scanf("0x%08x", &versions[j].crc);
  144.                         }
  145.                         break;
  146.                 }
  147.         }

  148.         printf("[+] after set moduel crc:\n");
  149.         for (j = 0; j < num_versions; j++) {
  150.                 printf("[+] %s:0x%08x.\n", versions[j].name, versions[j].crc);
  151.         }

  152.         free(buff);
  153.         return 1;
  154. }

  155. static char *next_string(char *string, unsigned long *secsize)
  156. {
  157.         /* Skip non-zero chars */
  158.         while (string[0]) {
  159.                 string++;
  160.                 if ((*secsize)-- <= 1)
  161.                         return NULL;
  162.         }

  163.         /* Skip any zero padding. */
  164.         while (!string[0]) {
  165.                 string++;
  166.                 if ((*secsize)-- <= 1)
  167.                         return NULL;
  168.         }
  169.         return string;
  170. }

  171. static char *get_modinfo(Elf32_Shdr *sechdrs, unsigned int info, const char *tag)
  172. {
  173.         char *p;
  174.         unsigned int taglen = strlen(tag);
  175.         unsigned long size = sechdrs[info].sh_size;

  176.         for (p = (char *)(ehdr +sechdrs[info].sh_offset); p; p = next_string(p, &size)) {
  177.                 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
  178.                         return p + taglen + 1;
  179.         }
  180.         return NULL;
  181. }

  182. int display_module_vermagic_info(void)
  183. {
  184.         char *buff, *p;
  185.         char *ver = "vermagic";
  186.         unsigned int taglen = strlen(ver);
  187.         int size, i;

  188.         buff = (char *)malloc(shstrtab_len + 2);
  189.         if (!buff) {
  190.                 fprintf(stderr, "[-] Malloc failed.\n");
  191.                 return 0;
  192.         }

  193.         memcpy(buff, real_strtab, shstrtab_len + 1);
  194.         for (i = 0 ; i < (int)ehdr->e_shnum ; i++){
  195.                 if (!strcmp(buff + shdr[i].sh_name,".modinfo")){
  196.                         printf("[+] found section %s.\n", buff + shdr[i].sh_name);
  197.                         break;
  198.                 }
  199.         }

  200.         size = shdr[i].sh_size;
  201.         printf("[+] size: 0x%x.\n", size);

  202.         p = (char *)((unsigned long)ehdr + shdr[i].sh_offset);
  203.         printf("[+] 0x%08x\n", p);

  204.         for (; p; p = next_string(p, &size)) {
  205.                 printf("[+] %s\n", p);
  206.                 if (strncmp(p, "vermagic", taglen) == 0 && p[taglen] == '=') {
  207.                         printf("[+] %s\n", p + taglen + 1);
  208.                         //memset(p + taglen + 1, 'A', 30);
  209.                 }
  210.         }

  211.         return 1;
  212. }

  213. int set_module_vermagic_info(char *new_vermagic)
  214. {
  215.         char *buff, *p;
  216.         char *ver = "vermagic";
  217.         unsigned int taglen = strlen(ver);
  218.         int size, i;

  219.         buff = (char *)malloc(shstrtab_len + 2);
  220.         if (!buff) {
  221.                 fprintf(stderr, "[-] Malloc failed.\n");
  222.                 return 0;
  223.         }

  224.         memcpy(buff, real_strtab, shstrtab_len + 1);
  225.         for (i = 0 ; i < (int)ehdr->e_shnum ; i++){
  226.                 if (!strcmp(buff + shdr[i].sh_name,".modinfo")){
  227.                         printf("[+] found section %s.\n", buff + shdr[i].sh_name);
  228.                         break;
  229.                 }
  230.         }

  231.         size = shdr[i].sh_size;
  232.         printf("[+] size: 0x%x.\n", size);

  233.         p = (char *)((unsigned long)ehdr + shdr[i].sh_offset);
  234.         printf("[+] 0x%08x\n", p);

  235.         for (; p; p = next_string(p, &size)) {
  236.                 printf("[+] %s\n", p);
  237.                 if (strncmp(p, "vermagic", taglen) == 0 && p[taglen] == '=') {
  238.                         printf("[+] %s\n", p + taglen + 1);
  239.                         if (strlen(p + taglen + 1) < strlen(new_vermagic)) {
  240.                                 printf("[-] New vermagic len must < current magic len.\n");
  241.                                 return 0;
  242.                         }
  243.                         memset(p + taglen + 1, '\0', strlen(new_vermagic));
  244.                         memcpy(p + taglen + 1, new_vermagic, strlen(new_vermagic));
  245.                 }
  246.         }

  247.         return 1;
  248. }

  249. int exit_elf_load(void)
  250. {
  251.         close(elf_fd);
  252.         if (munmap(ehdr, f_stat.st_size) == -1) {
  253.                 return 0;
  254.         }

  255.         return 1;
  256. }

  257. int main(int argc, char **argv)
  258. {
  259.         if (argc == 1) {
  260.                 usage(argv[0]);
  261.         }

  262.         if (!strcmp(argv[1], "-w") && !strcmp(argv[2], "-c")) {
  263.                 fprintf(stderr, "[+] Display %s module crc value.\n", argv[3]);
  264.                 if (!init_load_elf(argv[3])) {
  265.                         fprintf(stderr, "[-] Init elf load failed.\n");
  266.                         return 0;
  267.                 }
  268.                 display_module_crc_info();
  269.                 exit_elf_load();
  270.         }
  271.         else if (!strcmp(argv[1], "-s") && !strcmp(argv[2], "-c")) {
  272.                 fprintf(stderr, "[+] Set %s module crc value.\n", argv[3]);
  273.                 if (!init_load_elf(argv[3])) {
  274.                         fprintf(stderr, "[-] Init elf load failed.\n");
  275.                         return 0;
  276.                 }
  277.                 set_module_crc_info( argc >= 4 ? argv[4] : NULL, argc >= 5 ? argv[5] : NULL);
  278.                 exit_elf_load();
  279.         }
  280.         if (!strcmp(argv[1], "-w") && !strcmp(argv[2], "-v")) {
  281.                 fprintf(stderr, "[+] Display %s module crc value.\n", argv[3]);
  282.                 if (!init_load_elf(argv[3])) {
  283.                         fprintf(stderr, "[-] Init elf load failed.\n");
  284.                         return 0;
  285.                 }
  286.                 display_module_vermagic_info();
  287.                 exit_elf_load();
  288.         }
  289.         if (!strcmp(argv[1], "-s") && !strcmp(argv[2], "-v")) {
  290.                 fprintf(stderr, "[+] Display %s module crc value.\n", argv[4]);
  291.                 if (!init_load_elf(argv[4])) {
  292.                         fprintf(stderr, "[-] Init elf load failed.\n");
  293.                         return 0;
  294.                 }
  295.                 set_module_vermagic_info(argv[3]);
  296.                 exit_elf_load();
  297.         }
  298.         else {
  299.                 return 0;
  300.         }

  301. }
复制代码

论坛徽章:
0
发表于 2019-12-20 16:08 |显示全部楼层
其它参考帖子:绕过CONFIG_MODVERSIONS
https://blog.csdn.net/mr_pang_1991/article/details/50014211

论坛徽章:
0
发表于 2019-12-20 16:19 |显示全部楼层
如果crc 不一致多的话,可以参考这个帖子 https://blog.csdn.net/mr_pang_1991/article/details/50014211

论坛徽章:
0
发表于 2019-12-20 16:21 |显示全部楼层
如果要修改的地方比较多,可以参考这个帖子:
绕过CONFIG_MODVERSIONS
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会

【架构革新 高效可控】2020年12月21日-23日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP