我的编程空间,编程开发者的网络收藏夹
学习永远不晚

浅谈IOS如何对app进行安全加固

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

浅谈IOS如何对app进行安全加固

防止 tweak 依附

通常来说,我们要分析一个 app,最开始一般是砸壳,

$ DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /path/to/XXX.app/XXX

然后将解密之后的二进制文件扔给类似 hopper 这样的反编译器处理。直接将没有砸壳的二进制文件扔个 hopper 反编译出来的内容是无法阅读的(被苹果加密了)。所以说砸壳是破解分析 app 的第一步。对于这一步的防范,有两种方式。

1.限制二进制文件头内的段

通过在 Xcode 里面工程配置 build setting 选项中将

-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null

添加到 "Other Linker Flags"(注意这里我在项目中碰到了一个 问题,在 iPod touch iOS 9.3 的设备上,使用了 swift 的项目会导致莫名奇妙的 swift 标准库无法找到,而在 iOS 10 的设备上没有这个问题。之前并没有以为是因为添加了这个的原因,直到网上搜了所有解决方案,比如这个 SO Post 都没有效果的时候,我才发现是这个设置的原因)

2.setuid 和 setgid

Apple 不接受调用这两个函数的 app,因为它可以通过查看符号表来判断您的二进制运行文件是否包含这两个函数

检测越狱设备上是否有针对性 tweak

一般来说在越狱手机上,我们会使用 TheOS 创建 tweak 类型的工程。然后针对我们要分析的类,使用提供的 logify.pl 命令生成的 mk 文件来打印该类所有方法的入参和出参。这对分析 app 的运行方式有很大的帮助。当然,我们也可以自己创建某个类的 mk,来 hook 某个函数,让它以我们想要的方式运行,比如说对于一些做了证书绑定的 app,如果它用的框架是 AFNetWorking 的话,那么我们可以创建一个 mk 文件,hook AFSecurityPolicy 类的下列方法:


- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain

让这个方法永远返回 YES,那么大多数的应用所做的证书绑定也就失效了。用过 TheOS 的 tweak 模版的话,你会发现这种方式相当简单快速。

对于这一步的防范,可以在工程的 main 函数里面加入一层判断,首先读取 /Library/MobileSubstrate/DynamicLibraries 下所有的 plist 文件的内容,查看是否某个 plist 含有你的 app 的 bundle id,是的话,可以判定有人想利用 tweak 攻击你的 app,这时候你可以采取比如说将 app 给 crash 掉,或者限制某些功能等方式来应对。

具体原理可以查看参考资料4,简单来说,就是 MobileSubstrate 在 app 加载到内存的时候会先去检查 /Library/MobileSubstrate/DynamicLibraries 下面是否有需要加载的 tweak,有的话就加载,怎么判断有没有?就是根据 plist 里面的 bundle ID 判断的。

代码参考如下


static __inline__ __attribute__((always_inline)) int anti_tweak()
{
    uint8_t lmb[] = {'S', 'u', 'b', 's', 't', 'r', 'a', 't', 'e', '/', 'D', 'y', 'n', 'a', 'm', 'i', 'c', 0, };
    NSString *dir = [NSString stringWithFormat:@"/%@/%@%s%@", @"Library", @"Mobile", lmb, @"Libraries"];
    NSArray *dirFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dir error:nil];
    NSArray *plistFiles = [dirFiles filteredArrayUsingPredicate:
                           [NSPredicate predicateWithFormat:
                            [NSString stringWithFormat:@"%@ %@%@ '.%@%@'",@"self", @"EN", @"DSWITH", @"pli", @"st"]]];
    int cnt = 0;
    for (NSString *file in plistFiles) {
        NSString *filePath = [dir stringByAppendingPathComponent:file];
        NSString *fileContent = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
        if (fileContent && [fileContent rangeOfString:[[NSBundle mainBundle] bundleIdentifier]].location != NSNotFound) {
            cnt ++;
        }
    }
    // 返回有针对本 app 的 tweak 数量,为 0 说明没有
    return cnt;
}

防 http 抓包

通常破解一个 app,我们会抓包。这样的话,我们的 app 所有接口,接口数据都会暴露在逆向人员的眼皮底下。这时候,我们可以限制 http 抓包。方式很简单,就是将 NSURLSessionConfiguration 的 connectionProxyDictionary 设置成空的字典,因为这个属性就是用来控制会话的可用代理的。可用参见官方文档,也就是参考资料5。下面是对于 AFNetWorking 的使用方法:


// 继承 AFHTTPSessionManager,重写下列方法
- (instancetype)initWithServerHost:(PDLServerHost*)serverHost {
#ifdef DEBUG
    // debug 版本的包仍然能够正常抓包
    self = [super initWithBaseURL:serverHost.baseURL];
#else
// 由于使用 ephemeralSessionConfiguration session 发起的请求不带 cookie 和使用缓存等
    NSURLSessionConfiguration *conf = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    conf.connectionProxyDictionary = @{};
    self = [super initWithBaseURL:serverHost.baseURL sessionConfiguration:conf];
#endif
    return self;
}

但是由于 OC 方法很容易被 hook,避免抓包是不可能的,所以,个人认为最好的方式是对请求参数进行加密(最好是非对称加密,比如 RSA)

混淆(或者加密)硬编码的明文字符串

对于被砸壳的二进制文件,逆向分析人员分析代码有一条重要线索,也就是被硬编码的明文字符串。比如说,你的 app 被人抓包了,某些数据请求接口也被人发现了,那么很简单,逆向人员可以直接拷贝特征比较明显的字符串到 hopper 中搜索,通过查看该字符串被引用的地方,可以很快的找到相应的逻辑代码。

对于这一步的防范,需要做的就是对硬编码的明文进行加密或混淆。 有个开源代码可以用,UAObfuscatedString,但是这个开源混淆代码写出来的字符串是相当长的(也就是麻烦),同时不支持加密。最近我写了一个工具,可以在编译期间加密所有代码中的明文字符串,在 app 运行的时候解密字符串。这个工具的特点如下:

简单,开发人员可以硬编码明文字符串,所有的加密会在编译开始时自动处理

可以自定义加密或者混淆方式,(为了不影响 app 运行效率,需要提供一个简单快速的加密或混淆方式)提高解密难度

使用 Swift 开发

Swift 是目前比较新的开发 iOS 语言,由于 Swift 目前还不是很稳定,越狱开源社区对这个的支持也不是很即时,比如说 class-dump 工具目前就不支持含有 Swift 的二进制文件。 TheOS 也是最近才开始支持 Swift,但是还没有加到主分支上(可以参见Features)。所以目前来看,至少 Swift 可能比纯 OC 的工程要安全一点点。当然,等 Swift 日趋稳定,以及越狱开源社区的逐渐支持,这一点优势可能就不明显了。

使用静态内连 C 函数

由于 OC 语言的动态性,导致 OC 的代码是最容易被破解分析的。在安全性上,更推荐使用 C 语言写成的函数。但是 C 语言的函数也是可以被 hook 的,主要有3种方式:

使用 Facebook 开源的fishhook

使用 MobileSubstrate 提供的 hook C 语言函数的方法


void MSHookFunction(void* function, void* replacement, void** p_original);

使用 mach_override,关于mach_override 和 fishhook的区别请看 mach_override 和 fishhook 区别

由于上面这三种方式可以 hook C 函数。要想不被 hook 解决方法是使用静态内联函数,这样的话需要被 hook 的函数没有统一的入口,逆向人员想要破解只能去理解该函数的逻辑。

使用 block

严格来说使用 block 并不能很大程度提高安全性,因为逆向人员只要找到使用该 block 的方法,一般来说在其附近就会有 block 内代码的逻辑。

但是个人认为使用 block 的安全性是比直接使用 oc 方法是要高的。在我的逆向分析 app 的经验中,对于使用了 block 的方法,目前我还不知道到怎么 hook (有知道的话,可以在 blog 上提个 issue 告诉我,先谢过)同时对于含有嵌套的 block 或者是作为参数传递的 block,处理起来就更加复杂了。所以,如果能将内敛 C 函数,嵌套 block , block 类型参数组合起来的话,安全性应该是会有一定提升。

代码混淆

代码混淆的方式有几种:

添加无用又不影响逻辑的代码片段,迷糊逆向人员

对关键的类、方法,命名成与真实意图无关的名称

个人认为最好的一个加密混淆工具是ios-class-guard,不过目前这个项目已经停止维护了。但是这种方式的混淆我觉得才是最终极的方案。

其他方法

比如 ptrace 反调试等(不过据说已经可以很容易被绕过)


// see http://iphonedevwiki.net/index.php/Crack_prevention for detail
static force_inline void disable_gdb() {
#ifndef DEBUG
    typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
#ifndef PT_DENY_ATTACH
#define PT_DENY_ATTACH 31
#endif
    // this trick can be worked around,
    // see http://stackoverflow.com/questions/7034321/implementing-the-pt-deny-attach-anti-piracy-code
    void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
    ptrace_ptr_t ptrace_ptr = dlsym(handle, [@"".p.t.r.a.c.e UTF8String]);
    ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
    dlclose(handle);
#endif
}

注意事项

通过了解 OC 的运行时特性和 mach-o 二进制文件的结构,借助现有的工具,你会发现 hook 方法 是很简单就能完成的。虽然上面我提到了一些提高安全性的几个方案,但是,所有这些方式只是增加了逆向人员的逆向难度,并不能让 app 变的坚不可摧。不过采取一定的措施肯定比什么措施都不采取来的安全。

以上就是浅谈IOS如何对app进行安全加固的详细内容,更多关于IOS如何对app进行安全加固的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

浅谈IOS如何对app进行安全加固

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

浅谈IOS如何对app进行安全加固

目录防止 tweak 依附1.限制二进制文件头内的段2.setuid 和 setgid检测越狱设备上是否有针对性 tweak防 http 抓包混淆(或者加密)硬编码的明文字符串使用 Swift 开发使用静态内连 C 函数使用 block代码
2022-05-28

如何进行Linux 的安全合规性检查和加固

今天给大家介绍一下如何进行Linux 的安全合规性检查和加固。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。1. 账号和口令1.1 禁用或删除无用账号减少系统无
2023-06-28

如何进行Linux的安全合规性检查和加固

如何进行Linux的安全合规性检查和加固,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。指导系统管理人员或安全检查人员进行Linux操作系统的安全合规性检查和加固
2023-06-15

如何对Java项目进行安全处理

本篇文章为大家展示了如何对Java项目进行安全处理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、URL中参数显示问题,解决方案:1、普通Get请求修改为Post请求2、参数加密(js加密,Jav
2023-05-31

如何在麒麟操作系统上进行系统的安全加固和防护

在麒麟操作系统上进行系统的安全加固和防护可以通过以下几个步骤实施:1. 及时更新系统:定期检查并应用操作系统的更新补丁,以修复已知的漏洞和安全问题。2. 安装有效的防病毒软件:选择一款可靠的防病毒软件,并及时更新病毒库文件,以保护系统免受恶
2023-10-12

如何通过Python对MySQL数据库进行安全性审计?(Python环境下如何对MySQL数据库进行安全审查?)

通过Python对MySQL数据库进行安全性审计,可提高数据安全性和遵守法规要求。该过程涉及以下步骤:建立连接、获取数据库信息、检查用户权限、分析查询日志、检查配置、使用第三方工具和编写自定义脚本。定期进行审计有助于识别漏洞,实施缓解措施,并保护敏感数据。
如何通过Python对MySQL数据库进行安全性审计?(Python环境下如何对MySQL数据库进行安全审查?)
2024-04-02

MariaDB中如何进行数据加密和安全保护

MariaDB通过列级加密、行级加密和TLS协议实现数据加密,保障数据机密性。通过访问控制、审计日志、防火墙和入侵检测系统,提供安全保护,防止未经授权访问和恶意攻击。最佳实践如强密码、启用SSL/TLS、定期更新和备份,进一步提升数据安全。
MariaDB中如何进行数据加密和安全保护
2024-04-09

MariaDB中如何进行数据加密和安全保护

在MariaDB中,可以通过以下几种方式来进行数据加密和安全保护:使用SSL/TLS协议:通过配置MariaDB服务器和客户端之间的SSL/TLS连接,可以实现数据传输的加密保护,防止数据在传输过程中被窃取或篡改。加密存储引擎:MariaD
MariaDB中如何进行数据加密和安全保护
2024-04-09

如何在PostgreSQL中进行数据加密和安全设置

在PostgreSQL中进行数据加密和安全设置可以通过以下几种方式来实现:使用SSL/TLS协议:通过配置数据库服务器和客户端之间的SSL/TLS连接,可以确保数据在传输过程中是加密的,从而防止数据被窃取或篡改。使用加密函数:Postgre
如何在PostgreSQL中进行数据加密和安全设置
2024-04-09

如何在PostgreSQL中进行数据加密和安全设置

PostgreSQL数据加密和安全设置本文介绍PostgreSQL的安全功能,包括加密、访问控制、审计和用户身份验证。加密方法包括PBE、对称加密和非对称加密。访问控制通过角色和权限管理,允许您控制对数据的访问。审计允许跟踪数据库活动以检测异常行为。用户身份验证方法包括密码、令牌和LDAP。通过遵循最佳实践(如定期更新、使用强密码、启用审计和备份数据),您可以增强PostgreSQL数据库的安全性。
如何在PostgreSQL中进行数据加密和安全设置
2024-04-09

如何在Fedora系统上进行数据加密和安全存储

在Fedora系统上保障数据安全至关重要。本指南提供了多种方法来加密和安全存储数据,包括使用OpenSSL加密文件和文件夹、使用LUKS加密磁盘分区以及创建EncFS容器。遵循这些技术和最佳实践,如使用强密码、定期备份数据和保持系统更新,以保护敏感信息免遭未经授权的访问和泄露。
如何在Fedora系统上进行数据加密和安全存储
2024-04-08

Elasticsearch分布式搜索中的安全与加密通信(如何保障Elasticsearch分布式搜索的安全并进行加密通信?)

本文介绍了保障Elasticsearch分布式搜索系统安全的最佳实践和加密通信方法。通过实施认证、授权、网络安全、数据加密、审计和备份,可以有效防范数据泄露和未经授权访问。加密通信采用TLS/SSL、IPSecVPN和SSH隧道等方法,确保数据在传输过程中得到保护。具体的实施步骤包含身份验证、防火墙配置、数据分片加密、日志记录、备份和TLS/SSL部署等。通过这些措施,Elasticsearch分布式搜索系统的安全性得到显著增强,降低了数据泄露和未经授权访问的风险。
Elasticsearch分布式搜索中的安全与加密通信(如何保障Elasticsearch分布式搜索的安全并进行加密通信?)
2024-04-02

如何使用Python实现对ElasticSearch的安全认证和权限管理?(在Python中,怎样进行ElasticSearch的安全认证和权限设置?)

在Python中实现Elasticsearch安全认证和权限管理涉及以下步骤:创建用户,设置密码和角色。创建角色,指定索引权限。将角色与用户关联。启用安全。启用TLS以加密通信。使用用户名和密码进行身份验证。检查用户权限。最佳实践包括使用强密码、定期轮换密码、创建多个角色和限制特权访问。遵循这些步骤可确保Elasticsearch集群免受未经授权的访问和安全威胁。
如何使用Python实现对ElasticSearch的安全认证和权限管理?(在Python中,怎样进行ElasticSearch的安全认证和权限设置?)
2024-04-02

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录