silvio 病毒填充

silvio病毒填充技术解析

silvio病毒填充技术

silvio

以下参考文章:

相关源码可以从以下两个网站查询(silvio的实际源码作者并没有给出):


silvio病毒填充技术,是在上世纪90年代就已经提出的一种简单的寄生技术,主要就是因为虚拟内存技术中对于虚拟内存分页管理方法的一种利用。在text段和data段之间的内存页中放入寄生虫。

64位

段与节

这里关于段与节的说法我不是很清楚,实际上如果说是在text段和data段的说法的话,那我们通过vmmap可以看到:

image-20231116203806036

三个红色即protect为r-xp的就是代码段,粉色protect为rw-p的为data段,我无法确认其中是否有空闲的memory放置shellcode(即parasite)。

若是为节,我们可以通过readelf -S 查看:

image-20231116204244737

通过计算,我们可以得到.text节:size:0x195,对齐方式为16字节对齐,所以可以得到占
405/4096(页) 405/4096(页) 405/4096(页)

以上错误

即为一页,同样的如果为段的话:size:0x200:
.init+.plt+.plt.sec+.text+.fini=0x1b+0x20+0x10+0x195+0xd=0x1ed≈0x200=1/5k .init + .plt + .plt.sec + .text + .fini = 0x1b + 0x20 + 0x10 + 0x195 + 0xd = 0x1ed ≈0x200 = 1/5k .init+.plt+.plt.sec+.text+.fini=0x1b+0x20+0x10+0x195+0xd=0x1ed0x200=1/5k
因为页对齐机制,所以实际分得1k memory。可以通过上面vmmap看到。所以有约为4/5k大小空闲。

data段也大致相同
.initarray+.finiarray+.dynamic+.got+.got.plt+.data+.bss=0x8+0x8+0x1d0+0x10+0x20+0x10+0x8=0x228≈1/5k .initarray + .finiarray + .dynamic + .got + .got.plt + .data + .bss = 0x8 + 0x8 + 0x1d0 + 0x10 + 0x20 + 0x10 + 0x8 = 0x228 ≈ 1/5k .initarray+.finiarray+.dynamic+.got+.got.plt+.data+.bss=0x8+0x8+0x1d0+0x10+0x20+0x10+0x8=0x2281/5k
依旧为1页。

通过上面我们也可以看到,实际上text段和data段起始位置不太一样:text往往都是从起始地址开始写:

image-20231116211852059

image-20231116212218553

image-20231116212254359

而data段开头:

image-20231116212309004

image-20231116212329465

并不是从页开头写的。

程序无关代码

虽然对于当前绝大多数的程序,因为可重定位代码的高效,安全性,而选择可重定位的方式,但这并不意味着他禁止使用了绝对代码(absoluate code),比如立即数,所以这里我们认为,如果要进行一个寄生虫的注射,必然不能干扰源程序的运行,即这里需要使用程序无关代码(pic)。

例如,我们如果往text段前或者后拓展,极有可能会覆盖数据,导致文件错误,无法执行(即破坏了重定位地址,或者绝对代码),往data段前填充或许是一种办法(因为data段就在stack段下方,空间足够),但是data段的执行权限不好把握,所以这里作者给出了一种实现方法:

在page边界开始填充,通过前面的计算,我们可以看到无论是代码段还是data段,都有大片冗余空间,没有好好利用。


PIC(position-independent-code)称作地址无关代码,出现原因是为了让多个进程能够共用一个动态库,因为不同进程中需要映入的地址是不同的,所以为了让程序在装载过程中都能运行,PIC诞生了。

PIC的做法是让指令部分做到地址无关,所以可以让所有进程共享一份。但是数据部分并不地址无关,而是让所有进程在地址空间中都产生一份副本。

所谓地址无关代码 PIC(Place Independent Code)就是其变量,标号,以及调用函数不使用编译时生成内存地址,因此能够加载入内存中的任何位置执行的代码。例如plt,got,重定位表等等

下面我们着重介绍三个头

ELF header

image-20231116221243729

在/usr/include/elf.h下可以找到:即为上图

struct:

cat elf.h| grep 'e_'
  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
  Elf32_Half    e_type;                 /* Object file type */
  Elf32_Half    e_machine;              /* Architecture */
  Elf32_Word    e_version;              /* Object file version */
  Elf32_Addr    e_entry;                /* Entry point virtual address */
  Elf32_Off     e_phoff;                /* Program header table file offset */
  Elf32_Off     e_shoff;                /* Section header table file offset */
  Elf32_Word    e_flags;                /* Processor-specific flags */
  Elf32_Half    e_ehsize;               /* ELF header size in bytes */
  Elf32_Half    e_phentsize;            /* Program header table entry size */
  Elf32_Half    e_phnum;                /* Program header table entry count */
  Elf32_Half    e_shentsize;            /* Section header table entry size */
  Elf32_Half    e_shnum;                /* Section header table entry count */
  Elf32_Half    e_shstrndx;             /* Section header string table index */
  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
  Elf64_Half    e_type;                 /* Object file type */
  Elf64_Half    e_machine;              /* Architecture */
  Elf64_Word    e_version;              /* Object file version */
  Elf64_Addr    e_entry;                /* Entry point virtual address */
  Elf64_Off     e_phoff;                /* Program header table file offset */
  Elf64_Off     e_shoff;                /* Section header table file offset */
  Elf64_Word    e_flags;                /* Processor-specific flags */
  Elf64_Half    e_ehsize;               /* ELF header size in bytes */
  Elf64_Half    e_phentsize;            /* Program header table entry size */
  Elf64_Half    e_phnum;                /* Program header table entry count */
  Elf64_Half    e_shentsize;            /* Section header table entry size */
  Elf64_Half    e_shnum;                /* Section header table entry count */
  Elf64_Half    e_shstrndx;             /* Section header string table index */

这里主要注意的是ELF header位于文件开头,便于寻找定位,同样的它还标出了program header ,entrypoint以及 section header的address和size

section header
 cat elf.h| grep 'sh_'
  Elf32_Word    sh_name;                /* Section name (string tbl index) */
  Elf32_Word    sh_type;                /* Section type */
  Elf32_Word    sh_flags;               /* Section flags */
  Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
  Elf32_Off     sh_offset;              /* Section file offset */
  Elf32_Word    sh_size;                /* Section size in bytes */
  Elf32_Word    sh_link;                /* Link to another section */
  Elf32_Word    sh_info;                /* Additional section information */
  Elf32_Word    sh_addralign;           /* Section alignment */
  Elf32_Word    sh_entsize;             /* Entry size if section holds table */
--------------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值