APP安全機(jī)制(一)—— 幾種和安全性有關(guān)的情況

版本記錄

版本號(hào) 時(shí)間
V1.0 2017.08.17

前言

在這個(gè)信息爆炸的年代,特別是一些敏感的行業(yè),比如金融業(yè)和銀行卡相關(guān)等等,這都對(duì)app的安全機(jī)制有更高的需求,很多大公司都有安全 部門,用于檢測自己產(chǎn)品的安全性,但是及時(shí)是這樣,安全問題仍然被不斷曝出,接下來幾篇我們主要說一下app的安全機(jī)制。

APP安全涉及方面

剛接觸app安全大家可能會(huì)有一些疑問,app安全到底涉及到哪些方面,或者說app安全應(yīng)該注意什么?

app安全主要應(yīng)該注意下面幾個(gè)方面:

ipa文件安全

我們?cè)?code>appleStore下載的加殼后的ipa文件,里面會(huì)有很多的資源包,不要在.plist文件、項(xiàng)目中的靜態(tài)文件中存儲(chǔ)關(guān)鍵的信息,如要保存,需要加密處理??梢岳肕AC上的PP軟件助手,將ipa文件拷貝到電腦,直接就能獲取ios的系統(tǒng)目錄。如下圖所示。

ios系統(tǒng)目錄

ipa文件的反編譯工具IDA

前面已經(jīng)說過了,從appleStore下載的都是加殼的ipa文件,想要去殼,可以使用clutchdumpdecrypted、使用gdb調(diào)試 等解密去殼工具,如果手機(jī)是越獄的,則可以從PP助手上下載ipa包,直接就是脫殼后的,還有就是xcode打包的ipa也是沒有殼的。

建立新的項(xiàng)目加幾句代碼:

- (void)viewDidLoad
 {
    [super viewDidLoad];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 70, 200, 100)];

    label.text = @"CeShiLabel007";
    label.backgroundColor = [UIColor redColor];

    [self.view addSubview:label];
}

接著就是將項(xiàng)目打包,獲取的ipa文件解壓后得到.app文件。

下面就下載好IDA,并安裝打開如下所示。

IDA

利用IDA破解ipa文件,可以獲取下面的圖示。

IDA破解ipa文件

由上面可見,字符串完全可以反編譯出來。所以盡量不要在代碼里放一些 關(guān)鍵的數(shù)據(jù),可以通過接口來獲取?;蛘甙褦?shù)據(jù)進(jìn)行加密。

Hopper Disassembler反編譯工具

具體方法還和IDA類似,就是下載軟件和進(jìn)行反編譯,下面引用一個(gè)技術(shù)大牛反編譯微信的圖,如下所示。

微信反編譯

這里可以很清楚的看到QQContactInfoViewController里面的代碼是如何寫的。上面兩種涉及到的都是代碼的反編譯,其實(shí)就是逆向工程


沙盒安全

app的沙盒也是需要注意的地方,里面的文件比如sqlite、plist等等,不要保存敏感和關(guān)鍵信息,如要保存,同樣需要加密。 這里需要注意:

  • .app文件里面存放的使用程序本身的數(shù)據(jù),打包時(shí)候的資源文件都在里面,這個(gè)目錄不會(huì)被iTunes同步;
  • Documents:存儲(chǔ)不可再生的關(guān)鍵性數(shù)據(jù),不會(huì)被iTunes同步;
  • Library:保存配置文件和一些其他文件,NSUserDefault會(huì)存儲(chǔ)到Library下的Preferences中 的 plist文件中,所以不要在NSUserDefault中存一些關(guān)鍵數(shù)據(jù),或者存儲(chǔ)的時(shí)候進(jìn)行AES加密,會(huì)被iTunes同步;
  • temp:臨時(shí)文件,不需要時(shí)候手動(dòng)刪除其內(nèi)的文件,這個(gè)目錄不會(huì)被iTunes同步。
    下面重新回顧一下沙盒的文檔結(jié)構(gòu)。
沙盒文檔

源代碼安全

通過fileclass-dump、theos、otool等工具,黑客可以分析編譯之后的二進(jìn)制程序文件,不過相對(duì)于這些工具來說,IDA的威脅最大。IDA是一個(gè)收費(fèi)的反匯編工具,對(duì)于Objective-C代碼,它常常可以反匯編到可以方便閱讀的程度,這對(duì)于程序的安全性,也是一個(gè)很大的危害。因?yàn)橥ㄟ^閱讀源碼,黑客可以更加方便地分析出應(yīng)用的通信協(xié)議和數(shù)據(jù)加密方式。
同樣不要在代碼中存儲(chǔ)關(guān)鍵信息,比如通信接口的AES加密的密鑰,這是因?yàn)橛妹摎すぞ呖梢詫?duì)加殼的ipa文件進(jìn)行處理,越獄手機(jī)就是這么越獄的,在利用IDAHopper進(jìn)行反編譯和分析,就可以得到很容易理解的偽代碼。

  • 關(guān)鍵數(shù)據(jù)不要保存在本地,盡量通過接口進(jìn)行獲取。
  • 如果非要保存關(guān)鍵數(shù)據(jù),那么一定要加密后保存,運(yùn)行時(shí)候解密獲取數(shù)據(jù)。
  • 密鑰要定期更換,如果密鑰是才能夠服務(wù)端獲取,那么服務(wù)端進(jìn)行更新處理等。
  • 密鑰如果寫在代碼里,app升級(jí)版本的時(shí)候,新版本app對(duì)應(yīng)接口版本修改為新的秘鑰,舊的接口版本和APP版本還有以前舊的秘鑰。

對(duì)于IDA這類工具,我們的應(yīng)對(duì)措施就比較少了。除了可以用一些宏來簡單混淆類名外,也可以將關(guān)鍵的邏輯用純C語言來實(shí)現(xiàn)。例如微信的iOS端的通信底層,就是用C語言實(shí)現(xiàn)的。這樣的方式除了能保證通信協(xié)議的安全外,也可以在iOS和Android等多個(gè)平臺(tái)使用同一套底層通信代碼,達(dá)到復(fù)用的目的。


網(wǎng)絡(luò)安全

網(wǎng)絡(luò)安全很大一部分就是網(wǎng)絡(luò)通信安全,在網(wǎng)絡(luò)傳輸?shù)倪^程中存在不安全的結(jié)點(diǎn),所以我們應(yīng)該對(duì)敏感數(shù)據(jù)進(jìn)行加密,同于保證用戶的信息安全,黑客可以設(shè)置網(wǎng)絡(luò)代理服務(wù)器,截獲所有的網(wǎng)絡(luò)請(qǐng)求,即使是https加密通信,黑客仍然可以使用中間人攻擊Man-In-The-Middle Attack,指的是攻擊者與通信的兩端分別創(chuàng)建獨(dú)立的聯(lián)系,并交換其所收到的數(shù)據(jù),使通信的兩端認(rèn)為他們正在通過一個(gè)私密的連接與對(duì)方直接對(duì)話,但事實(shí)上,整個(gè)會(huì)話都被攻擊者完全控制)來截取通信內(nèi)容。

1. 通信協(xié)議安全相關(guān)

在成功破解了通信協(xié)議后,黑客可以模擬客戶端登錄,進(jìn)而偽造一些用戶行為,可能對(duì)用戶數(shù)據(jù)造成危害。

下面我們就先了解下關(guān)于https方面的內(nèi)容。

我們先了解下https ,HTTPS從最終的數(shù)據(jù)解析的角度,與HTTP沒有任何的區(qū)別,HTTPS就是將HTTP協(xié)議數(shù)據(jù)包放到SSL/TSL層加密后,在TCP/IP層組成IP數(shù)據(jù)報(bào)去傳輸,以此保證傳輸數(shù)據(jù)的安全;而對(duì)于接收端,在SSL/TSL將接收的數(shù)據(jù)包解密之后,將數(shù)據(jù)傳給HTTP協(xié)議層,就是普通的HTTP數(shù)據(jù)。HTTP和SSL/TSL都處于OSI模型的應(yīng)用層。從HTTP切換到HTTPS是一個(gè)非常簡單的過程。

它雖然號(hào)稱是安全的,但是也是可以抓包和解析的,所以網(wǎng)絡(luò)通信一定要有自己的加密方式,接口返回的數(shù)據(jù)最好也加密。

下面我們就看一下charles抓包。

http抓包

http抓包我們需要按照下面步驟配置charles。

  • 打開Charles程序。
  • 查看Mac電腦的IP地址,如192.168.1.7。
  • 打開iOS設(shè)置,進(jìn)入當(dāng)前wifi連接,設(shè)置HTTP代理Group,將服務(wù)器填為上一步中獲得的IP,即192.168.1.7,端口填8888
  • iOS設(shè)備打開你要抓包的app進(jìn)行網(wǎng)絡(luò)操作。
  • Charles彈出確認(rèn)框,點(diǎn)擊Allow按鈕即可。

https老版本抓包

  • 下載Charles證書,解壓后導(dǎo)入到iOS設(shè)備中(將crt文件作為郵件附件發(fā)給自己,再在iOS設(shè)備中點(diǎn)擊附件即可安裝;也可上傳至dropbox之類的網(wǎng)盤,通過safari下載安裝)。
  • 在Charles的工具欄上點(diǎn)擊設(shè)置按鈕,選擇Proxy Settings,切換到SSL選項(xiàng)卡,選中Enable SSL Proxying
  • 這一步跟Fiddler不同,F(xiàn)iddler安裝證書后就可以抓HTTPS網(wǎng)址的包了,Charles 還 需要在上一步的SSL選項(xiàng)卡的Locations表單填寫要抓包的域名和端口,點(diǎn)擊Add按鈕,在彈出的表單中Host填寫域名,比如填 api.instagram.com,Port443。

https新版本抓包

Charles新版本的 Proxy Settings 選項(xiàng)里是沒有 SSL選項(xiàng)卡的。在左側(cè)的域名上點(diǎn)右鍵Enable SSL Proxying,就可以用了。

https相關(guān)代碼書寫

app中一般用的就是AFNetworking這個(gè)框架,常見的問題包括:

  • 信任任何證書

AFNetworking中定義allowInvalidCertificates = true,就是表示忽略所有的證書。

AFHTTPRequestOperationManager* manager = [AFHTTPRequestOperationManager manager];
manager.securityPolicy.allowInvalidCertificates = YES;

這種情況的危險(xiǎn)就是可以用charles破解https加密的數(shù)據(jù),在一般測試環(huán)境不用CA發(fā)布的證書,而是自簽名證書,訪問的也不是域名,而是IP??梢允褂?code>#ifdef DEBUG來進(jìn)行設(shè)置。

#ifdef DEBUG

manager.securityPolicy.allowInvalidCertificates = YES;
manager.securityPolicy.validatesDomainName = NO;

#endif
  • 信任證書管理機(jī)構(gòu)(CA)頒發(fā)的證書

黑客可以買到這個(gè)證書,AFNetworking2.5.2以及之前的版本都有漏洞,在不安全網(wǎng)路中黑客就可以使用CA證書對(duì)該app的https加密數(shù)據(jù)進(jìn)行監(jiān)聽和篡改。

  • 信任合法證書,采取服務(wù)器和客戶端雙向認(rèn)證

雖然安全性提高了不少不過還是可以破解的,可以看這篇文章Bypassing OpenSSL Certificate Pinning in iOS Apps

所以,不要完全信任HTTPS的安全性,任何的協(xié)議、代碼都是會(huì)有漏洞的,關(guān)鍵的數(shù)據(jù)一定要自己進(jìn)行加密。

有關(guān)證書的配置在AFNetworking上的代碼如下所示:

NSURL * url = [NSURL URLWithString:@"https://www.google.com"];
AFHTTPRequestOperationManager * requestOperationManager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
dispatch_queue_t requestQueue = dispatch_create_serial_queue_for_name("kRequestCompletionQueue");
requestOperationManager.completionQueue = requestQueue;
AFSecurityPolicy * securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

//allowInvalidCertificates 是否允許無效證書(也就是自建的證書),默認(rèn)為NO
//如果是需要驗(yàn)證自建證書,需要設(shè)置為YES
securityPolicy.allowInvalidCertificates = YES;

//validatesDomainName 是否需要驗(yàn)證域名,默認(rèn)為YES;
//假如證書的域名與你請(qǐng)求的域名不一致,需把該項(xiàng)設(shè)置為NO
//主要用于這種情況:客戶端請(qǐng)求的是子域名,而證書上的是另外一個(gè)域名。因?yàn)镾SL證書上的域名是獨(dú)立的,假如證書上注冊(cè)的域名是www.google.com,那么mail.google.com是無法驗(yàn)證通過的;當(dāng)然,有錢可以注冊(cè)通配符的域名*.google.com,但這個(gè)還是比較貴的。
securityPolicy.validatesDomainName = NO;

//validatesCertificateChain 是否驗(yàn)證整個(gè)證書鏈,默認(rèn)為YES
//設(shè)置為YES,會(huì)將服務(wù)器返回的Trust Object上的證書鏈與本地導(dǎo)入的證書進(jìn)行對(duì)比,這就意味著,假如你的證書鏈?zhǔn)沁@樣的:
//GeoTrust Global CA 
//    Google Internet Authority G2
//        *.google.com
//那么,除了導(dǎo)入*.google.com之外,還需要導(dǎo)入證書鏈上所有的CA證書(GeoTrust Global CA, Google Internet Authority G2);
//如是自建證書的時(shí)候,可以設(shè)置為YES,增強(qiáng)安全性;假如是信任的CA所簽發(fā)的證書,則建議關(guān)閉該驗(yàn)證;
securityPolicy.validatesCertificateChain = NO;
requestOperationManager.securityPolicy = securityPolicy;

2. 登錄安全相關(guān)

很多app都是明碼傳遞賬號(hào)和密碼的,那么黑客只要截獲網(wǎng)絡(luò)請(qǐng)求,就可以獲得該app的賬號(hào)和密碼,由于現(xiàn)代人的習(xí)慣,很多的賬號(hào)和密碼都是一個(gè),那么后果是不可以想象的。

關(guān)于登錄的加密其實(shí)有很多方法,這里介紹一種:先生成一對(duì)加密的公私鑰,客戶端登錄的時(shí)候,使用公鑰將用戶的密碼加密并傳輸?shù)椒?wù)器,服務(wù)器用私鑰進(jìn)行解密,然后加鹽處理,再多次進(jìn)行MD5處理,在和數(shù)據(jù)庫里面存儲(chǔ)的同樣方法處理過的密碼匹配,如果一致,匹配成功,則表示可以登錄。

3. IAP安全相關(guān)

iOS應(yīng)用內(nèi)支付(IAP)是眾多應(yīng)用贏利的方式,通過先讓用戶免費(fèi)試用或試玩,然后提供應(yīng)用內(nèi)支付來為愿意付費(fèi)的用戶提供更強(qiáng)大的功能,這種模式特別適合不習(xí)慣一開始就掏錢的中國用戶。但由于國內(nèi)越獄用戶的比例比較大,所以我們也需要注意應(yīng)用內(nèi)支付環(huán)節(jié)中的安全問題。簡單來說,越獄后的手機(jī)由于沒有沙盒作為保護(hù),黑客可以對(duì)系統(tǒng)進(jìn)行任意地修改,所以在支付過程中,蘋果返回的已付款成功的憑證可能是偽造的。客戶端拿到付款憑證之后,還需要將憑證上傳到自己的服務(wù)器上,進(jìn)行二次驗(yàn)證,以保證憑證的真實(shí)性。

另外,我們發(fā)現(xiàn)越獄用戶的手機(jī)上,很可能被黑客用中間人攻擊技術(shù)來劫持支付憑證。這對(duì)于黑客有什么好處呢?因?yàn)樘O果為了保護(hù)用戶的隱私,支付憑證中并不包含任何用戶的賬號(hào)信息,所以我們的應(yīng)用和服務(wù)器無法知道這個(gè)憑證是誰買的,而只能知道這個(gè)憑證是真的還是假的。所以在驗(yàn)證憑證時(shí),哪個(gè)賬號(hào)發(fā)起了驗(yàn)證請(qǐng)求,我們就默認(rèn)這個(gè)憑證是該賬號(hào)擁有的。如果黑客將憑證截獲,就可以偽裝成真實(shí)用戶來驗(yàn)證憑證或者轉(zhuǎn)手出售獲利。打個(gè)比方,這就類似于很多商場的購物卡一樣,由于是不記名的,黑客如果將你買的購物卡偷竊然后去刷卡購物,商場是無法簡單地區(qū)分出來的。因此,對(duì)于應(yīng)用內(nèi)支付,開發(fā)者除了需要仔細(xì)地驗(yàn)證購買憑證外,也需要告知用戶在越獄手機(jī)上進(jìn)行支付的風(fēng)險(xiǎn)。


Reveal UI布局安全

Reveal是一個(gè)很好的UI查看軟件,大家調(diào)試的時(shí)候很多時(shí)候都使用過,但是這里我們知道如果手機(jī)不越獄,只能查看自己調(diào)試的APP,但是如果是越獄的手機(jī),那么還可以查看別的app,如淘寶、去哪兒網(wǎng)等等。


代碼調(diào)試安全

release環(huán)境下NSLog不要打印日志 否則iOS系統(tǒng)日志里都可以查看到,在.pch文件中加下面的幾行代碼就可以解決。

1 #ifdef DEBUG
2 #define NSLog(...) NSLog(__VA_ARGS__)
3 #define debugMethod() NSLog(@"%s", __func__)
4 #else
5 #define NSLog(...)
6 #define debugMethod()
7 #endif

現(xiàn)在很多app是用Swift寫的,在Swift 文件中是允許用 NSLog 的語法來打印,但是 不要這么做,因?yàn)檫@樣就會(huì)導(dǎo)致這段代碼在 release環(huán)境 中也可以正常輸出。通過PP助手、iTools,可以直接 查看 iOS的系統(tǒng)日志。也可以直接通過Xcode-Window-Devices - 點(diǎn)最下面的向上的小箭頭,來看日志。所以Swift中打印還是用print吧。

參考文章

1. 如何確保APP的安全性
2. [iOS]APP安全方面做的幾個(gè)點(diǎn)總結(jié)
3. iOS應(yīng)用安全開發(fā),你不知道的那些事
4. iOS APP 如何做才安全
5. iOS APP安全雜談之三
6. Jonathan Zdziarski《Hacking and Securing ios Application》 沙梓社,吳航《ios應(yīng)用逆向工程》

后記

其實(shí)總的來說app安全,主要可以歸納為網(wǎng)絡(luò)安全、本地文件和數(shù)據(jù)安全源代碼安全三個(gè)大的方面,每個(gè)方面都有很多措施可以保證安全性,也要注意細(xì)節(jié),接下來會(huì)和大家細(xì)說這幾個(gè)方面。未完,待續(xù)~~~

美麗
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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