iOS加固

1. 需求背景

App越獄機(jī)存在反編譯的情景。存在刷金幣色迂,等類似外掛的行為瘟忱。App加固奥额。使越獄者不能hookApp的方法。

2. 舊方案問題

玩吧App越獄可逆向访诱。

3. iOS上線版本

v10.5

4. 影響范圍/ 風(fēng)險(xiǎn)預(yù)警

需要測試詳細(xì)測試垫挨。改動(dòng)全局。 需要越獄測試機(jī)触菜,我這邊做加固完模擬攻防九榔。

開發(fā)周期 3-5天,測試周期:3-5天涡相。

5. 測試注意點(diǎn)

測開需要也做下模擬逆向攻防哲泊。并且做全局測試回歸。

建議逐步改進(jìn)漾峡。

6.技術(shù)方案

6.1.使用NSFileManager判斷設(shè)備是否安裝了如下越獄常用工具:

eg:

/Applications/Cydia.app
/Library/MobileSubstrate/MobileSubstrate.dylib
/bin/bash
/usr/sbin/sshd
/etc/apt

if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app"]){

return YES;

}

6.1.1 嘗試打開cydia應(yīng)用注冊(cè)的URL scheme:

if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]){
NSLog(@"Device is jailbroken");
}

6.1.2 嘗試讀取下應(yīng)用列表攻旦,看看有無權(quán)限獲取:
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/User/Applications/"]){
NSLog(@"Device is jailbroken");
NSArray *applist = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/User/Applications/"
error:nil];
NSLog(@"applist = %@",applist);
}

攻擊者可能會(huì)hook NSFileManager 的方法生逸,讓你的想法不能如愿牢屋。可以回避 NSFileManager槽袄,

6.1.3 嘗試打開cydia應(yīng)用注冊(cè)的URL scheme:使用stat系列函數(shù)檢測Cydia等工具:

import <sys/stat.h>

void checkCydia(void)
{
struct stat stat_info;
if (0 == stat("/Applications/Cydia.app", &stat_info)) {
NSLog(@"Device is jailbroken");
}
}

6.1.4 如果攻擊者可能會(huì)利用 Fishhook原理 hook了stat烙无。

import <dlfcn.h>

void checkInject(void)
{
int ret ;
Dl_info dylib_info;
int (*func_stat)(const char *, struct stat *) = stat;
if ((ret = dladdr(func_stat, &dylib_info))) {
NSLog(@"lib :%s", dylib_info.dli_fname);
}
}

如果結(jié)果不是 /usr/lib/system/libsystem_kernel.dylib 的話,那就100%被攻擊了遍尺。

6.1.5 還可以檢索一下自己的應(yīng)用程序是否被鏈接了異常動(dòng)態(tài)庫截酷。

列出所有已鏈接的動(dòng)態(tài)庫:

import <mach-o/dyld.h>

void checkDylibs(void)
{
uint32_t count = _dyld_image_count();
for (uint32_t i = 0 ; i < count; ++i) {
NSString *name = [[NSString alloc]initWithUTF8String:_dyld_get_image_name(i)];
NSLog(@"--%@", name);
}
}

通常情況下,會(huì)包含越獄機(jī)的輸出結(jié)果會(huì)包含字符串: Library/MobileSubstrate/MobileSubstrate.dylib 乾戏。

攻擊者可能會(huì)給MobileSubstrate改名迂苛,但是原理都是通過DYLD_INSERT_LIBRARIES注入動(dòng)態(tài)庫三热。

通過檢測當(dāng)前程序運(yùn)行的環(huán)境變量:
void printEnv(void)

{

char *env = getenv("DYLD_INSERT_LIBRARIES");

NSLog(@"%s", env);

}

未越獄設(shè)備返回結(jié)果是null,越獄設(shè)備就各有各的精彩了三幻,尤其是老一點(diǎn)的iOS版本越獄環(huán)境就漾。

6.2 為了不讓攻擊者理清自己程序的敏感業(yè)務(wù)邏輯,于是我們想方設(shè)法提高逆向門檻念搬。利用static關(guān)鍵字裁掉函數(shù)符號(hào)抑堡。

如果函數(shù)屬性為 static ,那么編譯時(shí)該函數(shù)符號(hào)就會(huì)被解析為local符號(hào)朗徊。
在發(fā)布release程序時(shí)(用Xcode打包編譯二進(jìn)制)默認(rèn)會(huì)strip裁掉這些函數(shù)符號(hào)首妖,無疑給逆向者加大了工作難度。

eg:

static id static_createBtn()
{
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectZero];
[btn setFrame:CGRectMake(50, 100, 100, 100)];
[btn setBackgroundColor:[UIColor blueColor]];
btn.layer.cornerRadius = 7.0f;
btn.layer.masksToBounds = YES;
return btn;

}

怎么讓別的文件也能調(diào)到本文件的static方法呢爷恳?
在本文件建造一個(gè)結(jié)構(gòu)體有缆,結(jié)構(gòu)體里包含函數(shù)指針。把static函數(shù)的函數(shù)指針都賦在這個(gè)結(jié)構(gòu)體里舌仍,再把這個(gè)結(jié)構(gòu)體拋出去妒貌。
這樣做的好處是通危,既隱藏了函數(shù)代碼也豐富了調(diào)用方式铸豁。

6.2.1 為了不讓攻擊者理清自己程序的敏感業(yè)務(wù)邏輯,于是我們想方設(shè)法提高逆向門檻菊碟。利用static關(guān)鍵字裁掉函數(shù)符號(hào)节芥。為了安全,將敏感的方法改寫為C函數(shù)逆害。

改寫方法如下:

@interface XXUtil : NSObject
    • (BOOL)isVerified;
    • (BOOL)isNeedSomething;
    • (void)resetPassword:(NSString *)password;
  1. @end

    改寫為:

    //XXUtil.h

    import <Foundation/Foundation.h>

    typedef struct _util {
    BOOL (isVerified)(void);
    BOOL (
    isNeedSomething)(void);
    void (*resetPassword)(NSString *password);
    }XXUtil_t ;

    define XXUtil ([_XXUtil sharedUtil])

    @interface _XXUtil : NSObject

    • (XXUtil_t *)sharedUtil;
      @end

    import "XXUtil.h"

    static BOOL _isVerified(void)
    {
    //bala bala ...
    return YES;
    }

    static BOOL _isNeedSomething(void)
    {
    //bala bala ...
    return YES;
    }

    static void _resetPassword(NSString *password)
    {
    //bala bala ...
    }

    static XXUtil_t * util = NULL;
    @implementation _XXUtil

    +(XXUtil_t *)sharedUtil
    {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    util = malloc(sizeof(XXUtil_t));
    util->isVerified = _isVerified;
    util->isNeedSomething = _isNeedSomething;
    util->resetPassword = _resetPassword;
    });
    return util;
    }

    • (void)destroy
      {
      util ? free(util): 0;
      util = NULL;
      }
      @end

    調(diào)用 XXUtil->isVerified();

6.3 Objective-C代碼混淆,阻止 class-dump出可讀的信息有效方法是易讀字符替換头镊。

利用#define的方法有一個(gè)好處,就是可以把混淆結(jié)果合并在一個(gè).h中魄幕,在工程Prefix.pch的最前面#import這個(gè).h相艇。不導(dǎo)入也可以編譯、導(dǎo)入則實(shí)現(xiàn)混淆纯陨。

以下腳本坛芽。放進(jìn)Xcode 的Build Phrase 中設(shè)定在編譯之前進(jìn)行方法名的字符串替換。 結(jié)合外部plist要替換的方法使用翼抠。

!/usr/bin/env bash

TABLENAME=symbols
SYMBOL_DB_FILE="symbols"
STRING_SYMBOL_FILE="func.list"
HEAD_FILE="PROJECT_DIR/PROJECT_NAME/codeObfuscation.h"
export LC_CTYPE=C

維護(hù)數(shù)據(jù)庫方便日后作排重

createTable()
{
echo "create table TABLENAME(src text, des text);" | sqlite3SYMBOL_DB_FILE
}

insertValue()
{
echo "insert into TABLENAME values('1' ,'2');" | sqlite3SYMBOL_DB_FILE
}

query()
{
echo "select * from TABLENAME where src='1';" | sqlite3 $SYMBOL_DB_FILE
}

ramdomString()
{
openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16
}

rm -f SYMBOL_DB_FILE rm -fHEAD_FILE
createTable

touch $HEAD_FILE
echo '#ifndef Demo_codeObfuscation_h

define Demo_codeObfuscation_h' >> $HEAD_FILE

echo "http://confuse string at date" >> HEAD_FILE cat "STRING_SYMBOL_FILE" | while read -ra line; do
if [[ ! -z "line" ]]; then ramdom=`ramdomString` echoline ramdom insertValueline ramdom echo "#defineline ramdom" >>HEAD_FILE
fi
done
echo "#endif" >> $HEAD_FILE

使用:

  1. //添加混淆作用的頭文件(這個(gè)文件名是腳本confuse.sh中定義的)

  2. import "codeObfuscation.h"

效果:

[圖片上傳失敗...(image-7b2a62-1591782762772)]

網(wǎng)上也有一些工具咙轩。混淆方法比較多阴颖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末活喊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子量愧,更是在濱河造成了極大的恐慌钾菊,老刑警劉巖帅矗,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異煞烫,居然都是意外死亡损晤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門红竭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尤勋,“玉大人,你說我怎么就攤上這事茵宪∽畋” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵稀火,是天一觀的道長暖哨。 經(jīng)常有香客問我,道長凰狞,這世上最難降的妖魔是什么篇裁? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮赡若,結(jié)果婚禮上达布,老公的妹妹穿的比我還像新娘。我一直安慰自己逾冬,他們只是感情好黍聂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著身腻,像睡著了一般产还。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嘀趟,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天脐区,我揣著相機(jī)與錄音,去河邊找鬼她按。 笑死牛隅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的尤溜。 我是一名探鬼主播倔叼,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼宫莱!你這毒婦竟也來了丈攒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎巡验,沒想到半個(gè)月后际插,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡显设,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年框弛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捕捂。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瑟枫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出指攒,到底是詐尸還是另有隱情慷妙,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布允悦,位于F島的核電站膝擂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏隙弛。R本人自食惡果不足惜架馋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望全闷。 院中可真熱鬧叉寂,春花似錦、人聲如沸室埋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姚淆。三九已至,卻和暖如春屡律,著一層夾襖步出監(jiān)牢的瞬間腌逢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國打工超埋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搏讶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓霍殴,卻偏偏與公主長得像媒惕,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子来庭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • iOS的越獄檢測和反越獄檢測原理剖析 為什么要檢測越獄妒蔚?因?yàn)樵姜z后會(huì)大幅降低安全性。對(duì)于一些金融類的APP或者游戲...
    蘿卜_7fad閱讀 14,408評(píng)論 3 19
  • http://blog.csdn.net/sakulafly/article/details/21159257 判...
    wzf_taker閱讀 2,200評(píng)論 0 1
  • 一個(gè)博主分享的防護(hù)思路,常用方法,給大家分享一下( 原文請(qǐng)github 直接搜索ZXHookDetection )...
    海利昂閱讀 686評(píng)論 0 0
  • 總體內(nèi)容1、逆向課程簡介2肴盏、學(xué)習(xí)逆向的條件3科盛、iOS越獄(iOS Jailbreak)的優(yōu)點(diǎn)和缺點(diǎn)4、完美越獄和非...
    IIronMan閱讀 1,955評(píng)論 0 8
  • 在應(yīng)用開發(fā)過程中菜皂,我們希望知道設(shè)備是否越獄贞绵,正以什么權(quán)限運(yùn)行程序,好對(duì)應(yīng)采取一些防御和安全提示措施恍飘。 那么榨崩,到底應(yīng)...
    無灃閱讀 1,249評(píng)論 0 3