首页
社区
课程
招聘
来自高纬的对抗 - 逆向TinyTool自制
发表于: 2017-2-26 16:21 8644

来自高纬的对抗 - 逆向TinyTool自制

2017-2-26 16:21
8644

# 来自高纬的对抗 - 逆向TinyTool自制

Author: ThomasKing

Date: 2017.02.24

Weibo/Twitter: ThomasKing2014

Blog: thomasking2014.com

## 一、序

无论是逆向分析还是漏洞利用,我所理解的攻防博弈无非是二者在既定的某一阶段,以高纬的方式进行对抗,并不断地升级纬度。比如,逆向工程人员一般会选择在Root的环境下对App进行调试分析,其是以root的高权限对抗受沙盒限制的低权限;在arm64位手机上进行root/越狱时,ret2usr利用技术受到PXN机制的约束,厂商从修改硬件特性的高纬度进行对抗,迫使漏洞研究者提高利用技巧。

下文将在Android逆向工程方面,分享鄙人早期从维度攻击的角度所编写的小工具。工具本身可能已经不能适应现在的攻防,“授人以鱼不如授人以渔”,希望能够给各位读者带来一些思路,构建自己的分析利器。

## 二、正

### 0x00 自定义Loader

早期Android平台对SO的保护采用畸形文件格式和内容加密的方式来对抗静态分析。随着IDA以及F5插件地不断完善和增多,IDA已经成为了逆向人员的标配工具。正因如此,IDA成为了畸形文件格式的对抗目标。畸形方式从减少文件格式信息到构造促使IDA加载crash的变化正应证了这一点。对此,鄙人研究通过重建[文件格式信息](http://bbs.pediy.com/thread-192874.htm)的方式来让IDA正常加载。

在完成编写修复重建工具不久之后,鄙人在一次使用IDA的加载bin文件时,猛然意识到畸形文件格式的对抗目标是IDA对ELF文件的加载的默认loader。既然防御的假象和维度仅仅在于默认loader,那么以自定义的loader加载实现高纬攻击,理论是毫无敌手的。

那如何来实现IDA自定义loader呢?

1. 以Segment加载的流程对ELF文件进行解析,获取和重建Section信息(参看上面所说贴子)。

2. 把文件信息在IDA中进行展示,直接调用对应的IDAPython接口

实现加载bin文件的py代码见文末github链接,直接放置于IDA/loaders目录即可。由于早期少有64位的安卓手机,加载脚本仅支持arm 32位格式,有兴趣读者可以改写实现全平台通用。不同ndk版本所编译文件中与动态加载无关的Section不一定存在,注释相应的重建代码即可。

### 0x01 Kernel Helper

以APP分析为例,对于加固过的应用通常会对自身的运行环境进行检测。比如: 检测自身调试状态,监控proc文件等。相信各位读者有各种奇淫技巧来绕过,早期鄙人构建hook环境来绕过。从维度的角度,再来分析这种对抗。对于APP或者bin文件而言,其仅运行于受限的环境中,就算exp提权后也只是权限的提升和对内核有一定的访问控制权。对于Android系统而言,逆向人员不仅能够拿到root最高权限,而且还可以修改系统的所有代码。从攻防双方在运行环境的维度来看,“魔”比”道“高了不只三丈,防御方犹如板上鱼肉。而在代码维度,防御方拥有源代码的控制权,攻防处于完全劣势。随着代码混淆和VMP技术的运用,防御方这块鱼肉越来越不好"啃"。

对于基于linux的安卓系统而言,进程的运行环境和结构是由内核来提供和维护的。从修改内核的维度来对抗,能达到一些不错的效果。下文将详述在内核态dump目标进程内存和系统调用监控。

### 1. 内存DUMP

对内核添加一些自定义功能时,通常可以采用内核驱动来实现。虽然一部分Android手机支持驱动ko文件加载,但内核提供的其他工具则不一定已经编译到内核,在后文中可以看到。nexus系列手机是谷歌官方所支持的,编译刷机都比较方便,推荐使用。

S1. 编译内核

为了让内核支持驱动ko文件的加载,在make memuconfig配置内核选项时,以下勾选:

[*] Enable loadable module support

次级目录所有选项

编译步骤参看谷歌官方提供的内核编译步骤。

S2. 驱动代码

linux系统支持多种驱动设备,这里采用最简单的字符设备来实现。与其他操作系统类似,linux驱动程序也分为入口和出口。在module\_init入口中,对字符设备进行初始化,创建/dev/REHelper字符设备。文末代码采用传统的方式对字符设备进行注册,也可直接使用misc的方式。字符设备的操作方式通过注册file\_operations回调实现,其中ioctl函数比较灵活,满足实现需求。

定义command ID:

#define CMD_BASE 0xC0000000

#define DUMP_MEM (CMD_BASE + 1)

#define SET_PID  (CMD_BASE + 2)

构建dump_request参数:

struct dump_request{

   pid_t pid; //目标进程

   unsigned long addr; //目标进程dump起始地址

   ssize_t count; //dump的字节数

   char __user *buf; //用户空间存储buf

};

在ioctl中实现分支:

    case DUMP_MEM:

        target_task = find_task_by_vpid(request->pid); //对于用户态,进程通过进程的pid来标示自身;在内核空间,通过pid找到对应的进程结构task_struct

        if(!target_task){

            printk(KERN_INFO "find_task_by_vpid(%d) failed\n", request->pid);

            ret = -ESRCH;

            return ret;

        }

        request->count = mem_read(target_task->mm, request->buf, request->count, request->addr); //进程的虚拟地址空间同样由内核进程管理,通过mm_struct结构组织

mem\_read其实是对mem\_rw函数的封装,mem\_rw能够读写目标进程,简略流程:

static ssize_t mem_rw(struct mm_struct *mm, char __user *buf,

           size_t count, unsigned long addr, int write)

{

   ssize_t copied;

   char *page;

...

   page = (char *)__get_free_page(GFP_TEMPORARY); // 获取存储数据的临时页面

...

   while (count > 0) {

       int this_len = min_t(int, count, PAGE_SIZE);

 // 将写入数据从用户空间拷贝到内核空间

       if (write && copy_from_user(page, buf, this_len)) {

           copied = -EFAULT;

           break;

       }

 

// 对目标进程进行读或写操作,具体实现参看内核源码


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 2
支持
分享
最新回复 (14)
雪    币: 29
活跃值: (499)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
2
王总出品,必属精品
2017-2-26 16:31
0
雪    币: 1039
活跃值: (355)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
thx for share.
2017-2-26 16:48
0
雪    币: 756
活跃值: (587)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢分享
2017-2-26 17:38
0
雪    币: 101
活跃值: (88)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
NIUBI
2017-2-26 18:23
0
雪    币: 1380
活跃值: (1626)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
2017-2-26 18:54
0
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
7
文章不错。 论坛刚升级,先把周围基本功能完成,就来支持mkdown
2017-2-26 20:25
0
雪    币: 2307
活跃值: (1013)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
8
谢谢分享
2017-2-27 09:40
0
雪    币: 47
活跃值: (418)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
9
精品文章
2017-2-27 10:13
0
雪    币: 238
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学习了,希望大佬多分享
2017-2-27 22:34
0
雪    币: 0
活跃值: (878)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
编译内核然后内存DUMP拿来脱壳怎么样??
2017-2-28 19:22
0
雪    币: 546
活跃值: (1657)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
12
感谢分析
2017-2-28 20:15
0
雪    币: 546
活跃值: (1657)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
13
kanxue 文章不错。 论坛刚升级,先把周围基本功能完成,就来支持mkdown
论坛看着花俏了许多,还不太适应,建议换个版式或色彩搭配,建议去掉左侧的导航栏,看文章的时候导航栏太碍事。
2017-2-28 20:17
0
雪    币: 41
活跃值: (823)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
来学习学习
2017-11-27 11:10
0
雪    币: 135
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
感谢分析
2017-11-27 17:17
0
游客
登录 | 注册 方可回帖
返回
//