通用方法-什么是固件库函数-小白渗透自学路线

通用方法-什么是固件库函数-小白渗透自学路线

背景介绍

固件系统中的二进制文件依赖于特定的系统环境执行,针对固件的研究在没有足够的资金的支持下需要通过固件的模拟来执行二进制文件程序。依赖于特定硬件环境的固件无法完整模拟,需要hook掉其中依赖于硬件的函数。

的锁定

对于特定函数的锁定技术分为动态注入锁定和静态注入锁定两种。静态注入指的是通过修改静态二进制文件中的内容来实现对特定函数的注入。动态注入则指的是在运行的过程中对特定的函数进行锁定,动态注入锁定一方面可以通过锁定PLT表或者GOT表来实现,另一方面可以通过环境变量来实现。

在《揭秘家用路由器挖掘》中作者针对D-link DIR-605L()路由器中的Web应用程序boa,通过hook技术锁定 ()和()函数修复boa对硬件的依赖,使得qemu--mips可以模拟执行,在文中作者通过环境变量实现对函数的锁定。网上针对的锁定也有大量的描述。但是仍旧不是普适的。

存在的问题

环境变量的开关在编译生成ulibc的时候指定,当关闭该选项的时候,无法使用来预加载指定的动态链接库文件。

固件的二进制文件中会将二进制文件中的信息去除掉,只保留下的信息,使得无法通过来增加动态链接库实现锁定。 支持对二进制文件的patch修改,或者添加执行过程中的链接lib。

本文方案思路

在ELF文件中,存在 ,ld.so通过该段内容来加载程序运行过程中需要的lib文件,图1为在IDA中反编译后查看的段的内容。

二进制固件函数劫持术-DYNAMIC932.png

图1 结构体数组

段介绍

段开头包含了由N个组成的结构体,该结构体的D_tag代表了结构体的类型。d_un为通过union 联合的指针d_ptr或者对应的结构体的值d_val。

typedef struct {    Elf32_Sword d_tag;    union {        Elf32_Word d_val;        Elf32_Addr d_ptr;    } d_un;}Elf32_Dyn;

d_tag字段保存了类型的定义参数,详见ELF(5)手册。下面列出了动态链接器常用的比较重要的类型值

1- 该类型的数据结构保存了程序所需要的共享库的名字相对字符串表的偏移量

2- 动态符号表的地址,对应的节名为.

3- 符号散列表的名称,对应的节名为.hash又称为.gnu.hash

4- 符号字符串表的地址,对应的节名为 .

5- 全局偏移表的地址

如上各个字段对应到IDA 中显示如下,d_tag字段代表了动态段的类型,当该值为1的时候。表示程序依赖的共享库的名字,其对应的d_val表示了是要加载的lib的名称在 table中的偏移。

共享库文件名对应的结构体的类型值为0x01,如图2所示,-保存有5个二进制文件所依赖的共享库名字,其D_VAL的值是指向 table的偏移量。

二进制固件函数劫持术-DYNAMIC1754.png

图2 共享库依赖图

段的定位

从二进制文件头起始定位段的流程如下:

-> ->

中保存有 的偏移

二进制固件函数劫持术-DYNAMIC2033.png

图3 ELF

中保存有 的相关结构体信息

二进制固件函数劫持术-DYNAMIC2233.png

图4

展开该结构体,可以找到段在文件中的偏移量

二进制固件函数劫持术-DYNAMIC2429.png

结构体

伪造

动态段由的结构体数组组成,的结构体定义如下:

在和之间仍存在一段空余空余可填充空间。本文利用该段空间填充,实现特定lib的加载。

【----帮助网安学习,所有资料加:,备注“掘金”获取!】

① 网安学习成长路径思维导图

② 60+网安经典常用工具包

③ 100+SRC分析报告

④ 150+网安攻防实战技术电子书

⑤ 最权威CISSP 认证考试指南+题库

⑥ 超1800页CTF实战技巧手册

⑦ 最新网安大厂面试题合集(含答案)

⑧ APP客户端安全检测指南(安卓+IOS)

本文方案实验与测试

利用和之间的空余区域,在该区域伪造出新的的一个数组。如下图,不修改二进制文件大小,伪造增添.so,使得二进制文件加载 .so。在.so中编写对应的锁定函数。

思路:将原有的数组元素依次后移,并在该数组的首部添加伪造的.so,该lib的命名可以选用 table中的任一字符串即可。

二进制固件函数劫持术-DYNAMIC3341.png

核心移动代码,将中的元素依次后移一个,段 [0]元素作为要伪造填充的数据,在本文的实验中,将[0]中的value值加1。由于在MIPS下存在大小端两种架构,在小端机器上的代码解决大端架构的填充伪造时要注意大小端的转换问题。

void move_dynamic(char* buf){    int x = 0;    Elf32_Dyn* dyn = (Elf32_Dyn *)buf;    while(1){        if(dyn[x].d_tag == 0 && dyn[x].d_un.d_ptr == 0){            break;        }        x++;        if(x>100) {            printf("Error break\n");            break;        }    }    while(x--){        //printf("the index x is %x\n",x);        mem_cpy(&dyn[x],&dyn[x+1],8);    }    dyn[x+1].d_un.d_val = b2l(l2b(dyn[x+1].d_un.d_val) + 1);}

测试环境

中boa程序,锁定函数参考,锁定以及

该固件的ld,关闭了程序选项,未提供/etc/ld.

锁定函数代码,采用了《揭秘家用路由器CVE挖掘》提供的示例代码如下,在原有的基础上,增加来查看显示是否锁定成功。

#include#define MIB_HW_VER 0x250#define MIB_IP_ADDR 170#define MIB_CAPTCHA 0x2C1int apmib_init(void){        printf("helllo");        return 1;}int fork(void){        return 0;}void apmib_get(int code,int *value){        switch(code){                case MIB_HW_VER:                        *value = 1;                        break;                case MIB_IP_ADDR:                        *value = 1;                        break;                case MIB_CAPTCHA:                        *value = 1;                        break;        }        return;}

通过mips-linux-gcc进行编译,这里注意mips-linux-gcc在编译过程中的编译文件的位置要位于参数之后(踩坑了!!!!)

mips-linux-gcc -Wall -fPIC -shared apmib.c -o ibcjson.so

通过如下代码,给原有的boa二进制文件添加一个

#include<stdio.h>#include <stdio.h>#include <stdlib.h>#include "elf.h"#define PATCH "boa_patch"int b2l(int be){return ((be >> 24) &0xff )| ((be >> 8) & 0xFF00)| ((be << 8) & 0xFF0000)| ((be << 24));}char* buf = NULL;int l2b(int le) {return (le & 0xff) << 24| (le & 0xff00) << 8| (le & 0xff0000) >> 8| (le >> 24) & 0xff;}static char *_get_interp(char *buf){int x;// Check for the existence of a dynamic loaderElf_Ehdr *hdr = (Elf_Ehdr *)buf;Elf_Phdr *phdr = (Elf_Phdr * )(buf + l2b(hdr->e_phoff));printf("the phdr address is: 0x%x 0x%x 0x%x 0x%x\n",phdr,l2b(hdr->e_phoff),buf,sizeof(hdr->e_phoff));for(x = 0; x < hdr->e_phnum; x++){if(l2b(phdr[x].p_type) == PT_DYNAMIC){// There is a dynamic loader present, so load itreturn buf + l2b(phdr[x].p_offset);}}return NULL;}int mem_cpy(char* src,char* dst,int len){printf("the src addr is %x , %x\n",src-buf,dst-buf);for(int x=0;x<len;x++){dst[x]=src[x];}return 0;}/*1 2 3 4temp = 2strcpy(1,2)1 2strcpy()*/void move_dynamic(char* buf){int x = 0;Elf32_Dyn* dyn = (Elf32_Dyn *)buf;//Elf32_Dyn tmp_dyn;//mem_cpy()while(1){if(dyn[x].d_tag == 0 && dyn[x].d_un.d_ptr == 0){printf("the x is %d\n",x);break;}x++;if(x>100) {printf("Error break\n");break;}}while(x--){//printf("the index x is %x\n",x);mem_cpy(&dyn[x],&dyn[x+1],8);}dyn[x+1].d_un.d_val = b2l(l2b(dyn[x+1].d_un.d_val) + 1);//FILE* fw = fopen("")}void analyse(char* buf){char* phdr_address = NULL;phdr_address = _get_interp(buf);printf("phdr address: 0x%x\n",phdr_address-buf);move_dynamic(phdr_address);}void save_binary(char* buf,int size){FILE* fw = fopen(PATCH,"wb");fwrite(buf,size,1,fw);fclose(fw);}int main(int argc,char *argv[],char* envp[]){if(argc < 2){printf("not enough argc\n");}FILE* fp = fopen(argv[1],"rb");fseek(fp,0,SEEK_END);int size = ftell(fp);fseek(fp, 0L, SEEK_SET);buf = malloc(size);fread(buf,size,1,fp);analyse(buf);save_binary(buf,size);free(buf);return 0;} 

如下

all: elf.h analyse_ph.c	gcc analyse_ph.c -m32 -g3 -o analyse	./analyse boa_real_n210

针对 的测试截图如下,通过 使得程序加载.so,成功锁定boa,输出

二进制固件函数劫持术-DYNAMIC7544.png

下rand函数锁定测试

rand函数的头文件是.h

编写rand.c

#include#includeint main(){    int a = 0;    a = rand()0;    printf("the a is %d\n",a);    return 0;}//gcc -m32 rand.c -o rand

编写.so

#includeint rand(){    printf("hook !\n");    return 100;}//gcc -fPIC -Wall -shared -m32 rand_hook.c -o rand_hook.so

使用测试,成功实现对该函数的锁定

二进制固件函数劫持术-DYNAMIC8065.png

使用patch,针对段元素添加伪造,测试,依赖的库文件增加ibc.so.6,ibc.so.6需要通过 导入ibc.so.6的文件路径

二进制固件函数劫持术-DYNAMIC8314.png

实现对rand的锁定

二进制固件函数劫持术-DYNAMIC8468.png

总结

本文通过研究二进制文件中的段,通过修改二进制文件增加依赖共享库,可以解决在模拟固件的过程时,固件缺少节信息且固件函数无法通过锁定的问题。该方案仍有不足之处,对于ld加载共享库的依赖顺序、共享库锁定的底层原理尚未深入探究。

参考

《揭秘家用路由器0day挖掘技术》

《二进制分析实战》

更多靶场实验练习、网安学习资料,请点击这里>>

网络安全学习路线图(思维导图)

网络安全学习路线图可以是一个有助于你规划学习进程的工具。你可以在思维导图上列出不同的主题和技能,然后按照逻辑顺序逐步学习和掌握它们。这可以帮助你更清晰地了解自己的学习进展和下一步计划。

1. 网络安全视频资料

2. 网络安全笔记/面试题

3. 网安电子书PDF资料

如果你向网安入门到进阶的全套资料,我都打包整理好了,需要学习的小伙伴可以V我找我拿~

学网络安全/学黑客,零基础资料整理来啦~~~

~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值