zl程序教程

您现在的位置是:首页 >  APP

当前栏目

iOS小技能:敏感逻辑的保护方案

2023-02-18 16:34:23 时间

前言

把函数名隐藏在结构体里,以函数指针成员的形式存储 (案例:js从OC本地方法获取设备及签名信息)

  1. 原理:为了提高代码的安全性,可以采用把把函数名隐藏在结构体里,以函数指针成员的形式存储。编译后,只留了下地址,去掉了名字和参数表,提高了逆向成本和攻击门槛 。
  2. 应用场景:签名函数
  3. 下载Demo:https://download.csdn.net/download/u011018979/16751837

I 把函数名隐藏在结构体里,以函数指针成员的形式存储

核心代码,比如签名算法,可采用C语言实现,并把函数名隐藏在结构体里,以函数指针成员的形式存储,这样编译后,只留了下地址,去掉了名字和参数表,提高了逆向成本和攻击门槛.

1.1 >* KNUtil.h

@interface KNUtil : NSObject
/**
 把函数名隐藏在结构体里,以函数指针成员的形式存储。
 编译后,只留了下地址,去掉了名字和参数表,提高了逆向成本和攻击门槛.
 */
typedef struct _util {
    void (*cign)(char *kns[],unsigned int kncount, const char *knkey, unsigned char *knput);
}CNtKNil_t ;
#define SharedUtilStruct ([KNUtil sharedUtil])//提供给外围的接口
+ (CNtKNil_t *)sharedUtil;

1.2 >* KNUtil.m

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//留给读者自己实践

1.3 >* 外围调用

SharedUtilStruct->cign(key ,count,knkey, knput);

1.4 案例:js根据key从本地方法获取设备及签名信息 (完整demo)

在OC本地方法封装签名方法,签名方法采用C语言实现,并把函数名隐藏在结构体里,以函数指针成员的形式存储,这样编译后,只留了下地址,去掉了名字和参数表,提高了逆向成本和攻击门槛.

2021-04-14 17:28:28.762113+0800 SignWithjsKey[23919:2084235] getGyqAppParams: {"api_version":"v1.1.4","appid":"3","time":"1618392508","operator":"中国电信","user_id":"https:\/\/kunnan.blog.csdn.net\/","vn":"1.0","device_id":"b2d4b9fba63ba7b47dbf27","channel":"default","device_name":"iPhone8,1","os":"iOS","sign":"b2ad581d2e30730f3aed506fc7593957","openudid":"0dce01d7424ac89e920e847e96","token":"#公号:iOS逆向","root":"1","idfv":"-D089-4021-82A9-65D8C711","height":"1334","width":"750","xyz":"0.00697,0.007675,-1.009369","os_version":"14.0","network":"no_network","vc":"1","idfa":"-3693-4940-3C59E53FA55"}

从CSDN下载Demo:https://download.csdn.net/download/u011018979/16751837

1、应用场景:签名函数 2、原理:为了提高代码的安全性,可以采用把把函数名隐藏在结构体里,以函数指针成员的形式存储。编译后,只留了下地址,去掉了名字和参数表,提高了逆向成本和攻击门槛. 3、文章:https://kunnan.blog.csdn.net/article/details/115857706

II 扩展属性

Extended File Attributes(EAs)在 OS X Tiger 中被引入,存储在 HFS+ 文件系统的 B*-Tree 中, 128KB 的容量。

把那些少量的,应用程序特定的数据,比如作者,文件历史记录,窗口或光标位置,或者网络的元数据关联到文件,存储在EAs中。

在终端使用ls 命令的 @ 参数进行查看EAs:ls -lrt@a

-@ Display extended attribute keys and sizes in long (-l) output.

-rw-r--r--@  1 mac  staff   1167  7 29  2021 .gitignore
 com.apple.TextEncoding    15 
 com.apple.lastuseddate#PS    16 
 com.apple.quarantine    21 
 
-rw-r--r--@  1 mac  staff  10244  3 31 18:24 .DS_Store
 com.apple.FinderInfo    32 
 com.apple.quarantine    21 

Finder 存储了 32 个字节的信息在 .DS_Store Xcode 中需要 15 个字节为一个特定的文件表示 TextEncoding 。

2.1 不应该被用于关键数据

在 UNIX 文件系统中文件的关键属性信息:路径、权限和时间戳。在 OS X 和 iOS,额外的元数据可以存储在扩展文件属性EAs中,但是扩展属性不应该被用于关键数据,并非所有卷格式支持扩展属性,也就是说,HFS+ 和 FAT32 之间的复制可能导致信息丢失。

2.2 扩展属性 API

#include <sys/xattr.h>

int setxattr(const char *path, const char *name, const void *value, size_t size, u_int32_t position, int options);

int removexattr(const char *path, const char *name, int options);

ssize_t listxattr(const char *path, char *namebuff, size_t size, int options);

ssize_t getxattr(const char *path, const char *name, void *value, size_t size, u_int32_t position, int options);

2.3 案例:不被 iCloud 同步的文件数据

相关API

- (BOOL)setResourceValues:(NSDictionary<NSURLResourceKey, id> *)keyedValues error:(NSError **)error API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

FOUNDATION_EXPORT NSURLResourceKey const NSURLIsExcludedFromBackupKey        API_AVAILABLE(macos(10.8), ios(5.1), watchos(2.0), tvos(9.0)); // true if resource should be excluded from backups, false otherwise (Read-write, value type boolean NSNumber). This property is only useful for excluding cache and other application support files which are not needed in a backup. Some operations commonly made to user documents will cause this property to be reset to false and so this property should not be used on user documents.

设置 com.apple.metadata:com_apple_backup_excludeItem 的 EA

#include <sys/xattr.h>

if (!&NSURLIsExcludedFromBackupKey) {
    // iOS <= 5.0.1
    const char *filePath = [[URL path] fileSystemRepresentation];
    const char *name = "com.apple.MobileBackup";
    u_int8_t value = 1;
    int result = setxattr(filePath, name, &value, sizeof(value), 0, 0);
} else {
    // iOS >= 5.1,
    NSError *error = nil;
    [URL setResourceValue:@YES
                   forKey:NSURLIsExcludedFromBackupKey
                    error:&error];
}

III 敏感信息的安全设计

3.1 敏感信息的安全设计Checklist

  • 临时产生的敏感数据(写入内存或文件),应具有及时清除和释放机制
  • 不要在 HTTP GET 请求参数中包含敏感信息,如用户名、密码、卡号、ID等
  • 禁止表单中的自动填充功能,因为表单中可能包含敏感信息,包括身份验证信息
  • 不要在客户端上以明文形式保存密码或其他敏感信息
  • 为所有敏感信息采用SSL加密传输
  • 禁止将敏感信息(包含加密秘钥等)硬编码在程序中
  • 不要在日志中保存敏感信息,包含但不限于系统详细信息、会话标识符、密码等
  • 禁止在异常中泄露应用服务器的指纹信息,如版本,路径,组件版本等
  • 禁止将源码或sql上传到开源平台或社区,如github、CSDN
  • 请求中含有敏感参数(如订单号、ID等),应进行混淆方式处理,防止产生参数遍历获取信息风险

iOS敏感逻辑的保护方案:【把函数名隐藏在结构体里,以函数指针成员的形式存储】

  • 敏感信息需要展示在web页面上时,应在后台进行敏感字段脱敏处理

身份证、银行卡号 姓名 预留手机号

  • 请求返回数据不应包含请求之外的业务数据,特别是敏感信息数据

3.2 签名key 的存储

  • 使用十六进制宏进行分段存储key比较安全
//https://kunnan.blog.csdn.net
//HexStrToString https://tool.lu/hexstr/
#define KNfir @"68747470733a2f2f"
#define KNfir1 @"6b756e6e616e2e626c6f672e6373646e"
#define KNfir2 @"2e6e6574"
#define key4pay [NSString stringWithFormat:@"%@%@%@",KNfir,KNfir1,KNfir2]
#define key4paystr [GeneralUtil convertHexStrToString:key4Unionpay]

+(NSString *)translate:(NSString *)content{
    return  [GeneralUtil convertHexStrToString:content];
}



  • 16进制转字符串
//

#import "GeneralUtil.h"

@implementation GeneralUtil


+ (BOOL)isBlankString:(NSString *)string {
    if (string == nil || string == NULL) {
        return YES;
    }
    if ([string isKindOfClass:[NSNull class]]) {
        return YES;
    }
    if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0) {
        return YES;
    }
    return NO;
}




+ (NSString *)convertHexStrToString:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }
    
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([str length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr] ;
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    NSString *string = [[NSString alloc]initWithData:hexData encoding:NSUTF8StringEncoding];
    return string;
    
    
}


@end

3.3 使用宏进行替换字符串,来保护关键类名、方法名

  • 根据前缀搜索出需要混淆的类名、方法名, 生成对应的宏文件
#define run OmWJoTZfCqoPshvr
#define iosre egnjoOFDrFiQVRgr

这样使用hopper等反汇编工具无法根据string搜索到关键字符

IV see also

  • static、extern 存储类的应用(创建共享实例、申明公共方法、全局字符串常量)

https://blog.csdn.net/z929118967/article/details/74295191

  • iOS安全之敏感逻辑的保护方案:【把函数名隐藏在结构体里,以函数指针成员的形式存储】(敏感信息的安全设计)

https://kunnan.blog.csdn.net/article/details/83746545