碳基体

奋斗在产品安全第一线的安全妹子

iOS设备安装Metasploit Framework的方法

原文:Mobile Pwning:Using Metasploit on iOS

Metasploit是我最喜欢的安全工具,没有之一,现在介绍如何在iOS设备上安装它。


一、安装准备条件

1. 越狱设备

2. SSH

SSH服务端:iOS设备上安装openssh (Cydia中搜索),开启SSH服务

SSH客户端:PC上安装SSH客户端软件(SecureCRT比较好),远程连接iOS设备。

由于我的PC机与iOS设备处于隔离网段,因此我采用的USB连接方式(itunnel mux+ SecureCRT)

 itunnel_mux.exe --lport 1234

 ssh -p 1234 root@127.0.0.1

3.APT(cydia中搜索)


二、正式安装

第一步:更新系统与安装wget与subversion

 apt-get update && apt-get dist-upgrade

 apt-get install wget subversion

第二步:安装ruby与Metasploit Frame依赖包

 wget https://ininjas.com/repo/debs/ruby_1.9.2-p180-1-1_iphoneos-arm.deb

 wget https://ininjas.com/repo/debs/iconv_1.14-1_iphoneos-arm.deb

 wget https://ininjas.com/repo/debs/zlib_1.2.3-1_iphoneos-arm.deb

 dpkg -i iconv_1.14-1_iphoneos-arm.deb

 dpkg -i zlib_1.2.3-1_iphoneos-arm.deb

 dpkg -i ruby_1.9.2-p180-1-1_iphoneos-arm.deb

安装结束后,为了节省空间,你可以删除这些安装包,注意:*表示上面的安装包,记得不要把有用的deb都删除掉了

 rm -rf *.deb 

检测ruby是否安装成功,查看ruby版本信息

 ruby -v

第三步:安装metasploit framework

 cd /private/var

 svn co https://www.metasploit.com/svn/framework3/trunk/  msf3

运行msf

 cd mfs3/

 ruby msfconsole


三、后记

最好在ipad和iPhone上安装,itouch就算了,系统空间小,会无法运行msf。其实,在iOS设备上安装MSF的方法早在去年网上就有攻略了,那个时候是MSF4.3版本,安装依赖包还是采用的apt.saurik.com/cydia/debs源。



参考资料:

Mobile Pwning:Using Metasploit on iOS

来源:碳基体

objective-c runtime安全措施之二:反注入

O'Reilly.Hacking.and.Securing.iOS.Applications>>读书笔记

反注入:在类函数被调用前做完整性检测(预防应用自定义函数或apple标准库函数被修改或替换)

  

原理:调用dladdr()函数检查类方法的基本信息是否合法

  

例子1:检查Foundation框架类中NSMutableURLRequest基类(用于改变URL请求)的setHTTPBody方法的基本信息

  

#include <dlfcn.h>

#include <objc/objc.h>

#include <objc/runtime.h>

#include <stdio.h>

#include <string.h>

int main() {

Dl_info info;

  

IMP imp = class_getMethodImplementation(

objc_getClass("NSMutableURLRequest"),

sel_registerName("setHTTPBody:"));

printf("pointer %p\n", imp);

if (dladdr(imp, &info)) {

printf("dli_fname: %s\n", info.dli_fname);

printf("dli_sname: %s\n", info.dli_sname);

printf("dli_fbase: %p\n", info.dli_fbase);

printf("dli_saddr: %p\n", info.dli_saddr);

} else {

printf("error: can't find that symbol.\n");

}

}

在Mac OS上使用gcc编译

$ gcc -o main main.m -lobjc -framework Foundation

然后运行该程序和观察输出,这些信息(地址空间、文件名、符号名)可以确认该函数来源、是否合法

$ ./main

  

pointer 0x7fff8e7aba62

  

dli_fname: /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation

  

dli_sname: -[NSMutableURLRequest(NSMutableHTTPURLRequest) setHTTPBody:]

  

dli_fbase: 0x7fff8e633000

  

dli_saddr: 0x7fff8e7aba62

  

例子2:使用dladdr函数检查类中的所有方法的通用代码

  

#include <dlfcn.h>

#include <stdio.h>

#include <objc/objc.h>

#include <objc/runtime.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

static inline BOOL validate_methods(const char *, const char *)

__attribute__((always_inline));

BOOL validate_methods(const char *cls, const char *fname) {

Class aClass = objc_getClass(cls);

Method *methods;

unsigned int nMethods;

Dl_info info;

IMP imp;

char buf[128];

Method m;

if (!aClass)

return NO;

methods = class_copyMethodList(aClass, &nMethods);

while(nMethods--) {

m = methods[nMethods];

printf("validating [ %s %s ]\n",

(const char *) class_getName(aClass),

(const char *) method_getName(m));

imp = method_getImplementation(m);

if (!imp) {

printf("error: method_getImplementation(%s) failed\n",

(const char *) method_getName(m));

free(methods);

return NO;

}

if (! dladdr(imp, &info)) {

printf("error: dladdr() failed for %s\n",

(const char *)method_getName(m));

free(methods);

return NO;

}

/* Validate image path */

  

if (strcmp(info.dli_fname, fname))

goto FAIL;

/* Validate class name in symbol */

  

snprintf(buf, sizeof(buf), "[%s ",

(const char *) class_getName(aClass));

if (strncmp(info.dli_sname+1, buf, strlen(buf)))

{

snprintf(buf, sizeof(buf), "[%s(",

(const char *) class_getName(aClass));

if (strncmp(info.dli_sname+1, buf, strlen(buf)))

goto FAIL;

}

/* Validate selector in symbol */

  

snprintf(buf, sizeof(buf), " %s]",

(const char *) method_getName(m));

if (strncmp(info.dli_sname + (strlen(info.dli_sname) - strlen(buf)),

buf, strlen(buf)))

{

goto FAIL;

}

}

return YES;

FAIL:

printf("method %s failed integrity test:\n",

(const char *)method_getName(m));

printf(" dli_fname: %s\n", info.dli_fname);

printf(" dli_sname: %s\n", info.dli_sname);

printf(" dli_fbase: %p\n", info.dli_fbase);

printf(" dli_saddr: %p\n", info.dli_saddr);

free(methods);

return NO;

}

【注意】

  

  1. 重命名检查函数(例如不要用validate_methods这样具有明显意义的名字)

  

  1. 在应用的多处加入检查函数,任何与敏感数据交互的方法在执行前都需要检查

  

  1. 例子中的logging和printf语句只是用来调试,代码正式发布前要移除

  

  1. 验证完整性只是提高了攻击的门槛,不能完全防御黑客,需要综合应用多种技巧,例如思路一中的反调试技巧,及马上要介绍的反汇编技巧。


来源:碳基体

iOS与Android的一些区别

前言

总结了在做iOS与Android安全研究时,需要了解的区别。包括系统架构的区别,安装包的区别,文件系统的区别,二进制文件的区别,安全机制的区别与版权保护的区别



一、系统架构的区别(左边iOS,右边Android)


1.iOS架构

分为4层,分别为

(1)cocoa Touch层:包括Foundation Framework,UIkit Framework,Address Book UI Framework

(2)媒体层:包括图像(Quartz,Core Animation,OpenGL ES),音频(Core Audio,OpenAL)和视频技术

(3)核心服务层:例如CoreFoundation.framework是基于C语言的接口集,提供应用的基本数据管理和服务功能;CFNetwork.framework是一组高性能的C语言接口集,提供网络协议的面向对象的抽象。开发者可以使用CFNetwork框架操作协议栈,并且可以访问底层的结构如BSD sockets等;Security.framework提供管理证书,公钥/私钥对和信任策略等的接口来确保应用数据的安全性

(4)核心OS层: 基于Mac操作系统


2.Android架构

分为4层,分别为

(1)应用程序:使用java编写

(2)应用程序框架:

  • 活动管理器:用来管理应用程序生命周期并提供常用的导航回退功能

  • 资源管理器:提供非代码资源的访问,如本地字符串、图形和布局文件

  • 内容提供器:用来存放和获取数据并使用这些数据可以被所有应用程序访问

  • XMPP服务器:基于XML的网络实时通讯协议

(3)系统运行库+Android运行时

系统运行库:android包括一些c/c++库,这些库能被android系统中的不同的组件使用,例如libc是一个从BSD继承来的标准c系统函数库;webkit为Web浏览器引擎,支持Android浏览器(苹果Safari的引擎也是webkit)。SQLite为功能强劲的轻量级关系数据库引擎(iOS也是采用的该数据库引擎)。

Android运行时:包括核心库(基本类库,例如data structure,network,file system等),很多实现代码都来自Apache Harmony项目,主要目的时保证虚拟机的类库能够与Java SE类库最大程度的兼容)与Dalvik虚拟机(用于运行dex:dalvik executable格式二进制可执行文件,该虚拟机较之java虚拟机的最大区别是Dalvik基于寄存器)

(4)linux内核:基于linux 2.6内核


总的来说,如果要深层次挖掘Android的漏洞就要明白linux内核安全,如果要挖身深层次挖掘iOS的漏洞就要了解Mac内核安全(BSD内核安全)。

二、安装包的区别(左边iOS,右边Android)

 总的来说,安装包由可执行文件,资源文件,签名文件,配置文件组成。


 三、文件系统的区别(左边iOS,右边Android)

注意: android的sdcard是不受文件访问控制约束的


四、二进制文件的区别

1. iOS二进制文件格式

mach-o , dylib

 

2.Android二进制文件的区别

dex, so(ELF shared object)


五、安全机制的区别

1. iOS安全机制

(1)安全沙箱

进程隔离,每个程序都有自己的虚拟地址空间。应用程序在安装之后,系统就通过计算得到一个标识,然后基于应用程序的根目录和这个标识构件一个指向应用程序目录的路径,其他应用程序都不能进行访问。iOS 的沙箱是基于TrustBSD策略框架的内核扩展模块,针对每个进程都可以制定特殊的沙箱配置文件,沙箱配置文件编译后以2进制的方式保存在KernelCache文件中(iOS下),需反汇编成可读的文本格式来查看内核中的沙盒规则


(2)代码签名

apple需要所有开发人员对自己的iPhone应用程序使用数字签名技术。这个签名用来标识应用程序的开发者以及保证应用程序在签名之后不被更改和损坏。开发者证书由apple提供(这是与android最大的区别,android是自签名),有以下两类证书:

Developer Certificate:用于本机测试

Distribution Certificate:Ad-hoc用于100台设备以内的测试和共享;app store用于发布应用程序

所有的可执行文件、库文件都需要Apple签名后才可以运行在iOS中,内核会在调用execve之前检测Mach-o文件中的LC_CODE_SIGNATURE段是否有效和可信任的,iOS启动的时候同样也会检测KernelCache的签名是否有效

代码签名的破坏可见《iOS平台游戏安全之IPA破解原理及防御

(3)ASLR(address space layout randomisation)/DEP


PIE: position independent executable


iOS 4.3后开始支持该功能,iOS上的预装应用都开启了该功能

 

ASLR的其他信息可见《ASLR


 

DEP(Data execution Prevention),内核不允许将页面保护标志设置为RWS,并在ARMv6引入XN(execute never)标志位,从而在硬件上支持执行保护。


(4)文件系统加密

 

Data protection APIs

NSFileProtectionNone

NSFileProtectionComplete

NSFileProtectionCompleteUnlessOpen

NSFileProtectionCompleteUntilUserAuthentication

KSecAttrAccessibleAlways

KSecAttrAccessibleWhenUnlocked

KSecAttrAccessibleAfterFirstUnlock

KSecAttrAccessibleAlwaysThisdeviceOnly

KSecAttrAccessibleWhenUnlockedThisDeviceOnly

KSecAttrAccessibleAfterFirstUnlockThisDeviceOnly


2.Android安全机制

(1)安全沙箱

每一个Android应用程序(apk文件)会在安装时分配一个独有的linux用户ID(即一个用户id识别一个应用程序),这就为它建立了一个沙箱,使其不能与其他应用程序进行接触。这个用户ID在安装时分配,并在该设备上一直保持同一个数值。所有存储在应用程序中的数据都会赋予该应用程序的用户ID,使其他应用程序无法访问这些数据(如需要访问,见(4)文件访问控制)。


(2)代码签名

采用自签名机制,不需要权威机构签名和审核,完全由用户自行判断是否信任该程序(与iOS区别很大)。签名是为了:

  • 识别代码的作者

  • 检测应用程序是否发生了变化

  • 在应用程序之间建立信任:使用相同数字签名签署的两个应用程序可以相互授予权限来反问基于签名的API,如果他们共享用户ID,那么也可以运行在同一进程中,从而允许访问对方的代码和数据(见(4)文件访问控制)。

代码签名的详细机制可见《Android签名与签名校验


(3)manifest权限管理

Android要求用户在使用API时进行申明,称为permission,对一些敏感API的使用在安装时就可以给用户风险提示,由用户确定是否安装,例如READ_CONTACTS为读取通讯录数据权限。权限在AndroidManifest.xml文件里进行设置,通过<manifest../>元素添加<uses-permission.../>子元素,如下图所示


 

permission分为4个保护等级:normal,dangerous,signature,signatureorsystem。不同的保护级别代表程序要使用此权限时的认证方式。

normal:只要申请就可以使用

dangerous:在安装时需要用户确认才可以使用,最经常使用的权限

signature:告诉android系统这个权限只能授予拥有同样数字签名并且定义了该权限的应用程序

signatureorsystem:需要开发者的应用和系统使用同一个数字证书,即需要系统或者平台签名,真实手机中的系统签名只有厂商知道


应用程序也可以定制权限以保护自己的资源,当前ita应用程序想要访问一个应用程序的受保护资源时,就必须通过它们自己的manifest文件请求适当的权限

 

(4)文件访问控制

因为安全沙箱的存在导致不同应用程序之间的数据(文件)是隔离的。在通过

getSharedPreferences(filename,operatingMode)

openFileOutput(filename,operatingMode)

openOrCreateDatabase(filename,operatingMode, SQLiteDatabase.CursorFactory)

等方法来创建一个新文件时,可以通过指定文件的存储方式operationMode来进行文件的访问控制,android文件存储有以下4种方式:

Context.MODE_PRIVATE:默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容

Context.MODE_APPEND:代表该文件是私有数据,只能被应用本身访问,在该模式下,会检查文件是否存在,存在就往文件追加内容,否则就创建新文件

Context.MODE_WORLD_READABLE:表示当前文件可以被其他应用读取

Context.MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。


除了使用Context.MODE_WORLD_READABLE/Context.MODE_WORLD_WRITEABLE标识位来使两个程序相互访问对方的资源。还可以通过设置AndroidManifest.xml文件的manifest标签中的sharedUserId属性,来使得不同的应用程序共用同一个用户ID,并且这些应用程序还使用同一个签名签署,在满足以上两个条件(共同的sharedUserID,共同的签名)的情况下就可以实现不同应用程序相互资源的访问了,如下图所示


 

(5)ASLR

android 4.1后才开始支持完整版功能


六、版权保护的区别

1. iOS

App store,采用FairPlay DRM保护商店下载应用

2. Android

(1)google play store,采用Android License Verification Library保护商店下载应用

(2)Amazon Appstore DRM

(3)其他


参考:

《移动互联网之智能终端安全揭秘》Android与iOS章

来源:碳基体