SkylineLulu


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

Z3求解器在Windows下的安装

发表于 2018-06-24 | 分类于 tool

z3(github链接点这里)是由微软公司开发的一个SMT求解器(定理证明器),能够检查逻辑表达式的可满足性。

环境: Visual Studio 2015 Command Prompt

安装准备:

  1. 配置Visual Studio Command Prompt:在Visual Studio的菜单栏中选择 工具-外部工具-添加
    external
    参数为
    标题:mycmd
    命令:C:\Windows\System32\cmd.exe
    参数:/k “D:\VS2015\Common7\Tools\VsDevCmd.bat”
    初始目录:$(ProjectDir)
    mycmd

  2. 打开Visual Studio Command Prompt:电脑的开始-Visual Studio 2015-目录下有各种环境下的命令窗口,这里选择64位的。
    VS
    安装过程:

  3. 打开github上下载的Z3目录:cd F:\z3-master\z3-master
  4. 若Visual Studio为32-bit builds:
    1
    python scripts/mk_make.py

如果是64-bit build:

1
python scripts/mk_make.py -x

  1. cd build

  2. nmake
    若提示“Z3 was successfully built.”就成功了
    success

5.然后按照提示,新建 PYTHONPATH环境变量,将build/python目录添加到其中;并将build添加到path环境变量中。

DroidPill

发表于 2018-06-14 | 分类于 Paper

《DroidPill: Pwn Your Daily-Use Apps》
来源:AsiaCCS 2017 (CCF C)
关键词:Mobile System Security; Android Malware; App Confusion Attack; App Virtualization
摘要:
本文构建了安卓中的应用层虚拟化沙箱,相当于实现了一个应用层虚拟化框架,并基于该框架实现了一种新的攻击方式:App Confusion Attack。

1.Introduction

Android malware可被分成以下四类:数据窃取、勒索软件、权限提升、远程控制。
除了最后一种是网络攻击外,其他三种都需要利用良性软件及其数据。

2. Virtualization-based Attacks

2.1 App attacks

已有的攻击及其局限性
(1)申请Android上的危险权限。–但是,应用数据不易获得。
(2)利用app本身存在的弱点攻击,如SQL注入。–应用漏洞很少。
(3)利用UI混淆攻击,如钓鱼。–UI混淆攻击行为限制
(4)重打包,并引诱用户安装。–大多数应用来源于正规市场,导致重打包不可行

App Confusion Attack
DroidPill使用的两种攻击向量是:app shortcut manipulation和top activity preemption
目的是:用户不能识别出DroidPill和正常系统的区别

相比于上述四种攻击,此攻击的优势在于
(1)malware可以通过虚拟环境完全掌控guest app的代码和数据
(2)部署于应用层,不需要对kernel层进行修改。因此攻击范围很广
(3)并不需要普通app的数据和代码。相比于重打包,不是灰色的

2.2 App Virtualization

虚拟化方式可分成两类:inclusive和exclusive
inclusive:
将guest app运行在sandbox app的虚拟环境中。可同时运行多个非系统app。模拟核心系统服务,如PackageManager和Activity Manager,从而管理多个guest app(guest app或它们之间的组件之间的IPC通信)。
App Object Transition(AOT)可以用来实现虚拟化。当app安装时,它在manifest文件中注册了一系列的组件,沙箱会创建guest app和已注册组件的map。会破坏UI完整性。
exclusive:
只能加载固定的一组app。不需要虚拟化任何核心系统服务。sandbox app和guest app是同时安装的,尽管它也使用了AOT来部署虚拟化逻辑,但是map是在沙箱app创建时建立的,运行时不会改变。

已有虚拟化方法的比较
Boxify和NJAS:其中sandbox service主要是安装虚拟环境,如hook代码;broker执行虚拟化逻辑和安全策略。
Boxify: inclusive虚拟化,sandbox service和guest app使用isolated process标签,从而限制了权限的使用。sandbox service安装了GOT hook(Shim),重定向Binder IPC和guest app的系统调用到broker。broker主要是监控拦截系统调用。
title
NJAS:exclusive虚拟化。guest app和broker进程有相同的权限。ptrace基于ptrace机制拦截监控guest app。
两个缺点:1)只能运行一个guest app。2)AOT不充足,对组件的代理不够完善。
title

3.Design

3.1 Design rationale

与上述两个沙箱的区别:1)他俩都需要监控。2)DroidPill要符合UI完整性要求,从而防止用户看出来真实环境与沙箱环境的区别。
broker和guest app是同一个进程。hook DVM和native层的GOT hook,同时可获得JAVA API的调用。
如果选用inclusive方法,1是会暴露自己的icon,2是要申请所有权限。
因此采用exclusive方法,基于特定的apk文件。相比NJAS,DroidPill可以在良性app中安装恶意代码。

3.2 System overview

title
bait用于引诱用户安装恶意软件,包含了攻击向量。
constructor用于安装broker和加载guest app
broker负责虚拟化,调节OS和guest app之间的通信。hook DVM和native层

隔离进程。为每个组件定制进程名(Manifest)。
相比NJAS,DroidPill的两个特性:1是进程隔离,2是选择性加载app。

3.3 Constructor

(1)Guest app loading
一般是通过createPackageContext加载的其他app的代码,使用了CONTEXT INCLUDE CODE和CONTEXT IGNORE SECURITY标签。

(2)Virtual execution context
在android中,android.app.LoadedApk用于在apk文件加载到内存中时存储apk的元数据,包括包名、代码加载器(ClassLoader)、资源(android.content.res.Resources和android.content.res.AssetManager)、数据文件路径等。
android.app.ContextImpl提供了与其他APP或者系统交互的接口,如连接到Android系统服务,启动activity和service,访问包数据等。

每个组件都有自己的ContextImpl对象,但一个APP只有一个LoadedApk对象。

DroidPill包括两层:native层和virtualization层
title
native layer——ContextImpl和LoadedApk(createPackageContext时调用)
virtualization layer——(加载broker的native库到内存时调用)

3.4 Broker

Public app objects
每个package都有一个独特的UID。在manifest中定义,要去PM或其他系统服务注册来获取运行时操作。
(1)Component
(2)Authority
(3)Account Type,在线账户服务,与服务器进行账户认证
(4)Custom Permission,自定义权限
(5)Intent Action,隐式intent,DroidPill中的guest app和sandbox app时一样的,因此破坏了UI完整性。

Virtualization logic
(1)为每个app创建进程名,同时在安装时向PM进行注册,创建object map
(2)broker使用map在运行时执行AOT。

拦截Binder IPC。对比NJAS,NJAS只能拦截一中object,DroidPill拦截了所有五个object。
因此,NJAS不能实现隐式的intent action。
guest app和sandbox app有不同的UID,但是文件重定向guest app是sandbox app的子目录。

4.Attack vectors

两种技术:
1.app shortcut manipulation
替换原app为新的shortcut,但是从通知栏启动的依然是原app。
2.top activity preemption
替换目标activity
三种得知ontop activity的方法:1)阅读系统日志;2)运行android.app.ActivityManager.getRunningTasks;3)通过获取proc文件进行侧信道攻击。
前两种方法不能在android 4.1和5.0上用。

5.Evaluation

Case study
1.浏览器chrome。获取所有的浏览记录和用户输入
2.云存储勒索软件dropbox。本地缓存文件的打开和写入。
3.应用市场客户端Xiaomi Market欺骗。替换从市场上下载的良性app为恶意app。hook startActivity拦截市场app向installer发送的Intent。修改URI。
4.VPN流量嗅探Betternet。结合tapjacking attack拦截VPN流量。
5.获取广告利益。

6.Discussion

6.1 Limitations

(1)android版本仅限于4.4之前。
(2)不能加载付费软件
(3)申请很多权限
(4)不能拦截在native层与系统服务交互的软件
(5)点击系统通知,进去的依然是原始app
(6)进去是初始状态,且不能更新

6.2 Countermeasures

(1)系统层面
获取包名、公司名、安全映像
(2)应用市场层面
开发者可将app分成两部分:boot loader app(安装在设备上)和library(主要功能,上传到Google license server)。但不能保证除Google Play外的应用市场

本文的优势在于提出了一种新的应用层虚拟化技术,且攻击场景和案例多样化。并且提出了DroidPill相对于Boxify和NJAS的缺陷与优势。

64位Windows中IAT表的获取

发表于 2018-06-09 | 分类于 Windows

这个之后详细再写出来

ADBI框架在Android6.0平台上的使用

发表于 2018-06-03 | 分类于 Android

环境:
Android 6.0

问题:
ADBI框架在Android5上可以稳定运行,但是在Android6.0中并不能得到函数在GOT表中保存的真正地址。Inline hook方式也会出现此问题,导致hook失败。

原因:
经过对hook框架的研读,参考了网上对Android5-6的变化,我发现Android6.0里面的GOT HOOK框架有改变,Android6的动态库加载的基地址不再固定,即和/proc/id/maps里的地址不一致了。因此之前通过/proc/id/maps拿到的基地址不正确。

解决思路:
通过soinfo结构拿到load_bias来作为基地址去算got函数地址的偏移。就是将module_base改成load_bias。

具体代码:
分成两部分:一个是GOT hook,一个是inline hook.

1.GOT hook(hook.c)

在Android5.0中,get_module_base的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
* lookup the start address of a specific module
* return 0 if FAILED
*/

//函数功能:在指定pid的内存文件中查找包含module_path字符串的so,并返回其在内存中的起始地址
//成功返回so起始地址,失败返回0
uint32_t get_module_base(pid_t pid, const char *module_path)
{
FILE *fp = NULL;
char *pch = NULL;
char filename[32];
char line[512];
uint32_t addr = 0;

//若pid为负值,proc/self/maps是查找本进程的内存映射信息
//snprintf()对filename字串赋值
if ( pid < 0 )
snprintf(filename, sizeof(filename), "/proc/self/maps");
//若pid为非负值,proc/pid/maps查找指定pid进程的内存映射信息
else
snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);

//处理打开内存文件失败
if ( (fp = fopen(filename, "r")) == NULL )
{
LOGE("open %s failed!", filename);
return 0;
}

//逐行读取内存文件maps
while ( fgets(line, sizeof(line), fp) )
{
//如果在maps文件中搜索在module_path字符串(模块名称?)
if ( strstr(line, module_path) )
{
LOGE("[+]:2");
//strtok()把字串line按"-"分割,返回被分割出字符串的指针
pch = strtok(line, "-");
//strtoul()把字串pch转换成16进制
//此处addr为模块所处内存空间的起始地址(XXX-YYY中的XXX)
addr = strtoul(pch, NULL, 16);
break;
}
}

fclose(fp);

return addr;
}

在Android6.0中,在hook.c文件中添加soinfo的结构体定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 typedef struct link_map_t {
uintptr_t l_addr;
char* l_name;
uintptr_t l_ld;
struct link_map_t* l_next;
struct link_map_t* l_prev;
} link_map_t;

typedef void (*linker_function_t)();

#define SOINFO_NAME_LEN 128
typedef struct soinfo {
char name[SOINFO_NAME_LEN];
const Elf32_Phdr* phdr;
size_t phnum;
Elf32_Addr entry;
Elf32_Addr base;
unsigned size;

uint32_t unused1; // DO NOT USE, maintained for compatibility.

Elf32_Dyn* dynamic;

uint32_t unused2; // DO NOT USE, maintained for compatibility
uint32_t unused3; // DO NOT USE, maintained for compatibility

struct soinfo* next;

unsigned flags;

const char* strtab;
Elf32_Sym* symtab;
size_t nbucket;
size_t nchain;
unsigned* bucket;
unsigned* chain;

//------------------

// This is only used by 32-bit MIPS, but needs to be here for
// all 32-bit architectures to preserve binary compatibility.
unsigned* plt_got;

Elf32_Rel* plt_rel;
size_t plt_rel_count;

Elf32_Rel* rel;
size_t rel_count;

linker_function_t* preinit_array;
size_t preinit_array_count;

linker_function_t* init_array;
size_t init_array_count;
linker_function_t* fini_array;
size_t fini_array_count;

linker_function_t init_func;
linker_function_t fini_func;

// ARM EABI section used for stack unwinding.
unsigned* ARM_exidx;
size_t ARM_exidx_count;

size_t ref_count;
link_map_t link_map;

int constructors_called;

// When you read a virtual address from the ELF file, add this
// value to get the corresponding address in the process' address space.
Elf32_Addr load_bias;

} soinfo;

uint32_t load_bias_addr;

并修改get_module_base的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
uint32_t get_module_base(pid_t pid, const char *module_path)
{
FILE *fp = NULL;
char *pch = NULL;
char filename[32];
char line[512];
uint32_t addr = 0;

void *handle = dlopen( LIBSF_PATH, RTLD_GLOBAL);
soinfo *si = (soinfo*)handle;
addr = si->base;
load_bias_addr = si->load_bias;

//若pid为负值,proc/self/maps是查找本进程的内存映射信息
//snprintf()对filename字串赋值
if ( pid < 0 )
snprintf(filename, sizeof(filename), "/proc/self/maps");
//若pid为非负值,proc/pid/maps查找指定pid进程的内存映射信息
else
snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);

//处理打开内存文件失败
if ( (fp = fopen(filename, "r")) == NULL )
{
LOGE("open %s failed!", filename);
return 0;
}

//逐行读取内存文件maps
while ( fgets(line, sizeof(line), fp) )
{
//如果在maps文件中搜索在module_path字符串(模块名称?)
if ( strstr(line, module_path) )
{
LOGE("[+]:2");
//strtok()把字串line按"-"分割,返回被分割出字符串的指针
pch = strtok(line, "-");
//strtoul()把字串pch转换成16进制
//此处addr为模块所处内存空间的起始地址(XXX-YYY中的XXX)
addr = strtoul(pch, NULL, 16);
break;
}
}

fclose(fp);

return addr;
}

2.Inline hook(inlineHook.c)

在Android5.0中,其中find_name(参考文章点这里)的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int find_name(pid_t pid, char *name, char *libn, unsigned long *addr)

{
struct mm mm[1000];
unsigned long libcaddr;
int nmm;
char libc[1024];
symtab_t s;

if (0 > load_memmap(pid, mm, &nmm)) {
log("[-] cannot read memory map\n")
return -1;
} else
log("[+] success load memory map")

if (0 > find_libname(libn, libc, sizeof(libc), &libcaddr, mm, nmm)) {
log("[-] cannot find lib: %s\n", libn)
return -1;
} else
log("[+] success find lib name: 0x%X", libcaddr)

log("[+] lib: >%s<\n", libc)
s = load_symtab(libc);
if (!s) {
log("[-] cannot read symbol table\n")
return -1;
}else log("[+] success read symbol table")

if (0 > lookup_func_sym(s, name, addr)) {
log("[-] cannot find function: %s\n", name)
return -1;
}else log("[+] success find function: %s: addr - 0x%X, *addr - 0x%X", name, addr, *addr)

*addr += libcaddr;

return 0;
}

在Android6.0中,在inlineHook.c文件中同样添加上述soinfo的结构体定义,并修改find_name函数为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
int find_name(pid_t pid, char *name, char *libn, unsigned long *addr, int syslib)
{
struct mm mm[1000];
unsigned long libcaddr;
int nmm;
char libc[1024];
symtab_t s;

if (0 > load_memmap(pid, mm, &nmm)) {
log("[-] cannot read memory map\n")
return -1;
} else
log("[+] success load memory map")

if (0 > find_libname(libn, libc, sizeof(libc), &libcaddr, mm, nmm)) {
log("[-] cannot find lib: %s\n", libn)
return -1;
} else
log("[+] success find lib name: 0x%X", libcaddr)

log("[+] lib: >%s<\n", libc)
s = load_symtab(libc);
if (!s) {
log("[-] cannot read symbol table\n")
return -1;
}else log("[+] success read symbol table")

if (0 > lookup_func_sym(s, name, addr)) {
log("[-] cannot find function: %s\n", name)
return -1;
}else log("[+] success find function: %s: addr - 0x%X, *addr - 0x%X", name, addr, *addr)

log("[+] libcaddr is 0x%X\n", libcaddr)

void *handle = dlopen( LIBSF_PATH, RTLD_GLOBAL);
soinfo *si = (soinfo*)handle;
load_bias_addr = si->load_bias;
log("[+] load_bias_addr is 0x%X\n", load_bias_addr)

if(syslib == 0){
*addr += libcaddr;
}else if(syslib == 1){
*addr += load_bias_addr;
}else{
log("[-] parameter syslib is wrong !\n")
}

return 0;
}

源码之后整理一下会放出来,有什么问题可以直接来问我~

xposed中函数参数byte[]类型数据读取

发表于 2018-06-03 | 分类于 Android

之前hook native函数是使用ADBI框架的,但是其平台有限,Android5效果稳定,Android6成功率不高,到Android7就无法使用了。
由于xposed(已支持Android8)也可以Hook native函数,可获取native函数的参数数据,因此想将hook的函数从ADBI框架移植到xposed模块中。但是遇到了一个问题:之前使用ADBI框架获取byte[]类型的参数数据是正常的,但是在xposed中只能获取到地址,一直提示参数为object类型。那么如何在xposed中获得真实数据呢?解决方案参考如下。

如下为ADBI框架中重写的函数,获取byte类型参数a的数据,并写入/sdcard/data.txt中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void new_hookData(JNIEnv* env, jobject thiz, jbyte *a) {

jbyte *arrayBody = (*env)->GetByteArrayElements(env,a,NULL);
jsize len = (*env)->GetArrayLength(env,a);
byte *dDate = (byte *)arrayBody;
int fd = open("/sdcard/data.txt", O_APPEND|O_RDWR|O_CREAT,S_IRWXU);

if(fd < 0)
{
LOGI("[+] open failed");
LOGW("[+] error (errno=%d)", errno);
}
else
{
LOGI("[+] success open");
}

int write_len = write(fd, dDate, len);

(*env)->ReleaseByteArrayElements(env,a,arrayBody,NULL);
close(fd);

old_hookData(env, thiz, a);
}

如下是xposed中的hook代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
findAndHookMethod("className",lp.classLoader,"methodName",byte[].class, new hookData());

class hookData extends XC_MethodHook{
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

byte[] buf = (byte[])param.args[0];
FileHelper filehelper = new FileHelper();
try {
//将byte数组写入文件
createFile("/sdcard/data.txt", buf);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

//将byte数组写入文件
public void createFile(String path, byte[] content) throws IOException {
FileOutputStream fos = new FileOutputStream(path);
fos.write(content);
fos.close();
}
}

over!

Android Permission Unleashed

发表于 2018-05-31 | 分类于 Paper

《Android permissions unleashed》
来源:CSF 2015
关键词:定理证明器,Android权限模型,策略
摘要:
本文利用定力证明器为Android权限建模,将组件的权限定制成策略集合,提出了两个概念:一个是组件栈(Component stack),由frame组成,而frame F = { C, P, Φ },其中, C为component,P为权限集,Φ为策略集。第二个是系统配置,由组件栈组成,Σ = [S1; S2; . . .];针对frame,stack和configuration制了相应的策略范围direct,local和global;将example中的权限与上述结合,构建了权限、组件和策略的逻辑表达。

三星s7 edge(G9350)刷机经验

发表于 2018-05-12 | 分类于 Android

设备:Sumsung S7 Edge
刷入系统: Android 7
刷机方式:线刷
需要安装包: 链接:https://pan.baidu.com/s/1N8U0KFikiGz_QFnfC9EUQg 密码:vuy0

步骤:
1.刷系统。电脑端打开odin刷机软件。手机关机情况下,同时按住“音量键下”+“HOME键”+“开机键”进入开机模式,按照提示按下音量上键。按照顺序刷入五件套,即S7android7.0文件夹中的文件。
具体教程
2.解锁。进入系统,运行“三星解锁.apk”,进行解锁。
3.ROOT(参考:7.0ROOT步骤.txt)。再次关机,同时按住“音量键下”+“HOME键”+“开机键”进入开机模式,打开odin,AP刷入recovery,即G9350_7.0_QC1_twrp_kernel_su2.79.tar文件。在odin的options中去掉Auto Reboot的对勾。start。手机进入twrp模式,清除,格式化data分区,输入yes,重启手机。
备注:查看设置-关于手机-软件信息-版本号,我的手机的版本号后三位为QC1,因此采用该recovery文件。

开机,adb shell, su,就可以看到设备已经ROOT,data也解密了。

Hello World

发表于 2018-05-12

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

12

SkylineLulu

在头顶上,有几千亿的光年。

18 日志
4 分类
18 标签
GitHub E-Mail
友情链接
  • Skylinelulu Github
© 2019 SkylineLulu
由 Hexo 强力驱动
本站访客数:
|
主题 — NexT.Gemini v5.1.4