苹果手机未受信任的企业级开发者ios设备管理信任不见了UnsplashiOS的系统安全性高于Android系统,主要有几个原因。首先是应用程序安装来源的限制。 iOS 设备必须从App Store 下载应用程序或使用企业证书进行分发。
来自Unsplash
iOS的系统安全性高于Android系统,主要有几个原因。
首先是应用程序安装来源的限制。 iOS设备必须从App Store下载应用程序或使用企业证书进行分发,而Android系统设备可以安装任何安装包(Android Package、APK)。这会导致恶意应用程序很容易被安装到手机上。
其次,iOS上的应用程序有严格的“沙箱”机制。每个应用程序只能访问自己的沙箱目录中的数据,没有公共的读写区域。然而Android系统有公共读写区域,很容易造成信息泄露。
第三,iOS应用程序仅限于在前台运行。只要点击Home按钮,应用程序的所有线程都会被挂起。只能执行一些必须在后台运行的服务(如实时定位、播放音乐等),而Android应用程序则可以创建后台服务。即使应用程序切换到后台,代码仍然可以执行,用户很难注意到。
让我们仔细看看iOS的安全机制。
应用程序安装源
App Store是苹果公司的应用程序市场。苹果手机上使用的QQ、支付宝等应用程序都是从App Store下载的。同样,如果你想开发一款应用程序并将其放在App Store上,你必须将其提交给Apple进行审核。审核通过后,即可在App Store搜索并下载该应用。除了从App Store下载应用程序外,还有其他方式安装应用程序。一种方法是使用企业证书进行分发,每年费用为299 美元。该方法不限制安装设备数量,但安装完成后想要打开该软件时,会出现“不受信任的企业开发者”提示,如图1-1所示。
图1-1 不受信任的企业开发者
这时,我们需要点击“设置”“常规”“设备管理”来信任已安装的应用程序。另一种选择是使用个人/公司证书进行开发和测试,价格为每年99 美元。此方法首先需要将设备的UDID(唯一设备标识符,在第8.1 节中有更详细的描述)添加到开发者帐户。最多可以添加100个设备,然后下载配置文件并在Xcode上运行添加配置文件并编译相应的程序,最后安装在这台设备上。 Xcode 9具有自动注册设备的功能。当我们使用Xcode进行真机调试并连接新设备时,会自动注册,如图1-2所示。
图1-2 使用Xcode 9注册设备
正是App Store严格的审核和应用程序安装源限制,更有效地控制了恶意程序的传播。
沙盒
沙箱是iOS的一种防御机制,每个应用程序都有自己的沙箱。应用程序只能在自己的沙箱目录中读写数据。应用程序A无法访问应用程序B的沙箱,彼此隔离。正因为如此,攻击者上传恶意程序后,即使通过了App Store审核,安装到用户手机上后也无法获取其他应用程序的数据。获取沙箱目录的方法如下:
-(void)getPath{//获取沙箱根目录路径NSString*homeDir=NSHomeDirectory();NSLog(@'homedir%@',homeDir);//获取Documents目录路径NSString*docDir=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory) , NSUserDomainMask,YES)firstObject];NSLog(@'docDir%@',docDir);//获取Library目录路径NSString*libDir=[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask,YES)lastObject];NSLog(@'libDir%@ ',libDir);//获取缓存目录路径NSString*cachesDir=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)firstObject];NSLog(@'cachesDir%@',cachesDir);//获取tmp目录路径NSString*tmpDir=NSTemporaryDirectory();NSLog(@'tmpDir%@',tmpDir);//获取应用程序自己的xx.app目录NSBundle *bundle=[NSBundle mainBundle];NSString *strAppPath=[bundle bundlePath];NSLog (@'appDir%@',strAppPath);}
输出结果如下:
主目录:/var/mobile/Containers/Data/Application/E24754D2-22F8-4E8E-8A6C-2B18561DB5ADdocDir:/var/mobile/Containers/Data/Application/E24754D2-22F8-4E8E-8A6C-2B18561DB5AD/DocumentslibDir:/var/mobile /容器/数据/应用程序/E24754D2-22F8-4E8E-8A6C-2B18561DB5AD/LibraryCachesdir:/VAR/移动/数据/应用程序/E24754D2-22F8-4-4-4-4 E8E-8A6C-2B18561DB5AD/Library/cacheStmpdir:/私有/VAR/移动/容器/数据/应用程序/E24754D2-22F8-4E8E-8A6C-2B18561DB5AD/tmp/appDir:/私有/var/mobile/Containers/Bundle/Application/A5E6DC61-7AAA-467F-BC63-5BEDB8DDB113/testSandbox 。应用程序
沙箱机制限制应用程序只能读写沙箱内的文件,而在某些情况下我们需要访问一些存在于沙箱之外的公共资源(如通讯录、短信、照片、位置等)。苹果提供了公共API来访问公共资源,但会弹出权限申请提示框,用户必须允许才可以操作成功。例如,访问照片需要用户授权,如图1-3所示。
代码签名
代码签名是iOS 的重要安全机制。所有二进制文件都必须经过签名才能执行。在内存中,只有自身签名的页面才会被执行,因此应用程序无法自我升级或动态更改行为。我们可以使用codesign命令来验证应用程序的签名信息是否被泄露。输入以下命令后,如果没有输出信息,则说明签名信息没有被破坏:
协同设计--验证testSandbox.app/
另外,还可以使用以下命令查看签名相关信息:
$ codesign -vv -d testSandbox.app/Executable=/Users/exchen/Library/Developer/Xcode/DerivedData/testSandbox-fzalslvcpprgiodycqxzblqeztql/Build/Products/Debug-iphoneos/testSandbox.app/testSandboxIdentifier=net.exchen.testSandboxFormat=app与Mach-O Thin (arm64)CodeDirectory 捆绑在一起v=20200 size=694 flags=0x0(none) hashes=14+5 location=embeddedSignature size=4701Authority=iPhone 开发者:exchen99@qq.com (248BRN4CNL)Authority=Apple Worldwide Developer关系Certification AuthorityAuthority=Apple Root CASigned 时间=2018年4月8日01:27:40Info.plist条目=26TeamIdentifier=QQ4RE63T4USealed Resources版本=2规则=13个文件=7内部需求计数=1大小=188用户权限隔离
iOS 使用用户权限进行隔离。系统中的浏览器、通话、短信以及从App Store下载的应用程序都以移动用户权限运行,只有重要的系统进程以root用户权限运行。这样,即使恶意软件安装成功,也会因为权限限制而降低被攻击的可能性。我们打开“电话”应用程序(MobilePhone),通过ps命令查看相关进程信息。我们可以看到它正在以移动方式运行:
iPhone:~ root# ps aux | grep 手机移动23754 0.0 0.9 661736 9152 ? Ss 1:00AM 0:01.31 /Applications/MobilePhone.app/MobilePhoneroot 23774 0.0 0.1 537356 572 s001 S+ 1:00AM 000.01 grep 手机
然后打开“短信”应用程序(MobileSMS),通过ps命令查看相关进程信息。你会发现它也是以移动用户身份运行的:
iPhone:~ root# ps aux | grep MobileSMSmobile 23764 0.1 1.2 659024 12384 ? Rs 1:00AM 0:01.82 /Applications/MobileSMS.app/MobileSMSroot 23776 0.0 0.1 537356 572 s001 S+ 1:01AM 000.01 grep MobileSMS 数据执行预防
iOS中有一个数据执行保护(DEP)机制,可以区分可执行代码和内存中的数据。这种机制不允许执行数据,只允许执行代码。默认情况下,数据段的属性为可读、可写、不可执行。如果我们通过vm_protect函数将数据段的属性改为可读、可写、可执行,就会打印错误信息。代码如下所示:
无符号整型数据=0x12345678;struct mach_header* image_addr=_dyld_get_image_header(0); //获取镜像地址vm_address_t offset=image_addr + (int)0x8000; //数据段的偏移kern_return_t err;mach_port_t port=mach_task_self();err=vm_protect(port, (vm_address_t) offset, sizeof(data), NO,VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);if (err !=KERN_SUCCESS) {NSLog(@'prot 错误: %s \n', mach_error_string(err));返回;}vm_write(端口, (vm_address_t) 偏移量, (vm_address_t) 数据, sizeof(data));
运行后打印的错误信息为:
2018-04-08 23:59:01.680009 vm_write[6222:265002] prot 错误:(os/kern)保护失败地址随机化
地址空间布局随机化(ASLR)可以使二进制文件、动态库文件、代码段、数据段每次加载时的内存地址都是随机的。使用_dyld_get_image_vmaddr_slide函数获取模块的ASLR偏移地址,使用_dyld_get_image_header函数获取模块的基地址。我们编写以下代码:
//获取第一个模块的基地址intptr_t slip_addr=_dyld_get_image_vmaddr_slide(0);struct mach_header *mh_addr=_dyld_get_image_header(0);printf('slide_addr:0x%x\n', slip_addr);printf('mh_addr:0x% x\n',mh_addr);
可以发现,第一次运行时,ASLR偏移地址为0x94000,基地址为0x100094000。也可以通过LLDB(低级调试器,详细信息请参见第2.5 节)查看:
mh_addr:0x100094000(lldb) 镜像列表-o -f[ 0]0x0000000000094000 /var/containers/Bundle/Application/9B2F1512-812E-4C3A-BBA7-A15DB63FFB1F/getBaseAddress.app/getBaseAddress(0x00000 0010 0094000)
当我们退出程序并再次运行时,ASLR偏移地址为0xe8000,基地址为0x1000e8000。可以看到,程序每次运行时,偏移地址和基地址都是随机的,一般不会和上次一样:
Slide_addr:0xe8000mh_addr:0x1000e8000(lldb) 图像列表-o -f[ 0]0x00000000000e8000 /var/containers/Bundle/Application/9B2F1512-812E-4C3A-BBA7-A15DB63FFB1F/getBaseAddress.app/getBaseAddress (0x00000001000e8000)
每次手机重启后,内核中模块的基地址也是随机的。
后台程序
Android 应用程序可以创建在后台执行代码的服务。这些服务可能会秘密下载文件并消耗数据,从而导致账单扣除。 iOS 应用程序无法在后台执行代码。只要用户点击Home按钮,前台应用程序的所有线程都会被挂起。只能执行必须在后台执行的操作,例如播放音乐、获取实时位置等。然而,在iOS中,还有后台程序,称为守护进程。例如,当你打开Safari(浏览器)上网时,突然有电话打进来,前台就会显示接听电话的界面。如果没有后台程序,来电如何处理?只是苹果并没有向开发者开放后台程序。越狱后才能编写后台程序。
iOS系统进程launchd在系统启动后会检测/System/Library/LaunchDaemons和/Library/LaunchDaemons这两个目录下的.plist文件,plist文件描述了daemon程序的路径。
接下来我们编写一个守护程序来进行测试。该程序的名称是daemonTest。它的功能是每5秒输出一条消息。具体代码如下:
#include stdio.h#include UIKit/UIKit.hint main(){int i=0;while(1){NSLog(@'Daemon test %d', i);i++;sleep(5);}return 0; }
编译:
clang -arch armv7 -isysroot $(xcrun --sdk iphoneos -show-sdk-path) -framework Foundation -o daemonTest main.m
符号:
codesign -s - --entitlements ~/ent.plist -f daemonTest
签名所需的ent.plist文件内容请参见2.5.1节。然后我们编写一个描述daemonTest 的.plist 文件。文件名为net.exchen.daemonTest.plist。具体内容如下:
?xml version='1.0'encoding='UTF-8'?DOCTYPE plist PUBLIC '-//Apple//DTD PLIST 1.0//EN''http://www.apple.com/DTDs/PropertyList-1.0.dtd'plist 版本='1.0'dictkeyKeepAlive/keytrue/keyLabel/keystringnet.exchen.daemonTest/stringkeyProgramArguments/keyarraystring/usr/bin/daemonTest/string/arraykeyRunAtLoad/keytrue/keySessionCreate/keytrue/keyStandardErrorPath/keystring/dev/null/stringkeyinetdCompatibility/keydictkeyWait/keyfalse//字典/字典/plist
将daemonTest上传到/usr/bin目录下,然后将net.exchen.daemonTest.plist文件上传到/Library/LaunchDaemons/目录下,然后设置相应的权限。命令如下:
chown root:wheel /usr/bin/daemonTestchmod 755 /usr/bin/daemonTestchown root:wheel /Library/LaunchDaemons/net.exchen.daemonTest.plist
使用launchctl load命令启动守护进程:
launchctl 加载/Library/LaunchDaemons/net.exchen.daemonTest.plist
当我们打开控制台查看日志时,可以看到每隔5秒输出一条消息,锁屏状态下也可以执行代码。它是一个真正的后台程序,如图1-4所示。
图1-4 每5秒输出一次信息
使用launchctl unload 命令停止守护进程:
launchctl 卸载/Library/LaunchDaemons/net.exchen.daemonTest.plist
——
如果你也对iOS安全感兴趣,下面的“秘籍”一定会对你有所帮助。 《黑客防御》技术月刊原主编孙斌评价这是一本“一拿到就可以开始谋生”的iOS安全技术书。
这本书主要讲什么?
本书是一套完整的iOS安全知识体系。跟随本书一步一步、系统地学习iOS安全技术。
作者以系统为基础,重点关注安全。涉及的内容不仅包括iOS系统安全机制分析、越狱及后期开发、代码注入与关键点拦截、获取隐私信息的类别和方法、应用破解与防护,还包括秘密泄露。讲解了一些刷单、刷量的技巧,还包括一些基础知识的简明教程。
——
小编试水了,整理了整本书。主要逻辑清晰,语言简单。我觉得如果你有一些相关的开发经验,你可以立即成为一名iOS安全工程师。
摘自拉勾网
我可以读这本书吗?
本书整体深度和广度都比较适中,可以帮助对iOS系统安全感兴趣的研究人员从入门到高级。
潜移默化地阅读,可以让读者对业界一些常见的安全相关技术手段有一个清晰直观的认识。明白后,他们会暗道:“原来如此!”
试读:刷量与作弊
封面新闻报道:【全国超900万人从事流量刷单行业】近日,专家指出,我国各类刷单平台超过1000家,刷单行业总人数已达超过900万。从某地下刷平台的订单信息来看,整个行业中,被刷最多的数据是:文章阅读量、电商评价等。刷单需求者地域特征比较明显,主要分布在互联网经济发达的沿海地区。其中,广东、北京、山东的诈骗人数遥遥领先。
那么App市场如何提高销量和作弊呢?点击阅读原文可跳转图灵社区阅读。