挖洞經驗 | 記一次針對Twitter(Periscope)API 的有趣挖洞經歷
![](https://img.796t.com/res/2022/04-29/10/08afaa71e531e12310a7a51619811d92.jpeg)
近期,我在Twitter的Periscope服務中發現了一個漏洞。這是一個CSRF(跨站請求偽造)漏洞,雖然這個漏洞並不算是高危漏洞,但是發現該漏洞的整個過程我認為是非常值得跟大家分享的。
就在幾天之前,我發現Twitter釋出了一個名叫ProducerAPI的介面,該介面目前僅提供給Twitter的合作伙伴使用,Twitter的第三方合作伙伴可以在特定的應用(例如外部相機裝置)中利用該API與Periscope賬號同步流媒體視訊。
![](https://img.796t.com/res/2022/04-29/10/05969151a6dfa88a8be8490c79ee6ce1.jpeg)
注:在此之前,Periscope曾是一家流媒體直播服務運營商。廣大使用者不僅可以通過Periscope與其他人進行視訊直播,而且還可以分享視訊或進行評論。Twitter在2015年3月份以接近億美金的架構收購了Periscope,並將其融入了自己現有的社交平臺服務中。
這樣看來,Twitter應該在這裡需要使用到一些與OAuth相關的東西,而就我過去所積累的經驗來看,OAuth的實現過程中一般都會存在安全問題,因此我決定要深入分析一下這個API介面。
在分析過程中,我遇到的第一個問題就是Twitter似乎並沒有提供Periscope API的開發文件。不過Twitter在一篇官方部落格中列舉出了能夠使用這個API的第三方廠商,所以我感覺可以看看這些廠家是怎樣跟這個API互動的,然後也許還能從中找出一些端倪。但不幸的是,大多數的這些廠商或服務都需要訂閱之後才能使用Periscope的功能,即便是我願意為服務付費也沒用。
不過我後來發現有一個移動端應用程式(Mevo for iOS)也在使用這個API。在這個移動應用中,OAuth請求都是直接從客戶端傳送的,這樣我們就有可能通過攔截並分析網路流量來了解API的呼叫情況了。與OAuth 1.0a不同的是(OAuth 1.0a使用了簽名來隱藏類似consume_secret這樣的重要資訊,並防止流量被攔截),OAuth 2.0會通過HTTPS來發送所有流量。因此,除非應用程式使用了某種安全係數非常高的證書機制(可以使用SSL Kill Switch2來解決),否則這些還是難不倒我們的。
![](https://img.796t.com/res/2022/04-29/10/ffbde1a5cb680a65238c1b2536a0a470.jpeg)
我遇到的第二個問題是,為了使用這個App,我首先得要有一個Mevo攝像頭才行…在亞馬遜上逛了一圈之後,最便宜的Mevo攝像頭要399.99美金,窮哭在廁所的我當然不會為了測試而去買這麼貴的東西了,而且這裡還不一定存在漏洞。
於是乎,我決定通過另一種方法來進行測試,即逆向工程分析。首先,我需要一臺已越獄的iPhone和Clutch來解密IPA檔案,然後用class-dump來生成Objective-C標頭檔案,最後再用Hopper來對程式碼進行反彙編。
一開始我嘗試在標頭檔案中搜索字串“Periscope”,因為那些負責處理Periscope互動邏輯的類很有可能會包含這個字串。
![](https://img.796t.com/res/2022/04-29/10/21f4cd36611fb4ebcdf55b439d4a26a1.jpeg)
搜尋之後,這些類似PeriscopeBroadcastCreateOperation.h或PeriscopeBroadcastPublishAPIOperation.h的檔名吸引了我的注意,因為這些標頭檔案看起來似乎與Periscope API的呼叫有關。通過對這些檔案進行分析之後,我發現它們都繼承了PeriscopeAPIOperation類,所以接下來我就要重點分析這個PeriscopeAPIOperation類了。
PeriscopeAPIOperation類的程式碼如下所示:
//
// Generated by class-dump 3.5 (64 bit).//// class-dump is Copyright (C) 1997-1998,2000-2001, 2004-2013 by Steve Nygard.// #import "GroupOperation.h" @class NSDictionary, NSMutableURLRequest,PeriscopeOAuthOperation,PeriscopeRefreshTokenAPIOperation,URLSessionTaskOperation; @interface PeriscopeAPIOperation :GroupOperation{NSDictionary *_JSON;URLSessionTaskOperation *_taskOperation;PeriscopeRefreshTokenAPIOperation *_refreshTokenOperation;PeriscopeOAuthOperation *_oauthOperation;NSMutableURLRequest *_request;} + (void)removeCookies;+ (void)logout;+ (id)userID;+ (id)refreshToken;+ (id)accessToken;+ (void)updateAccessToken:(id)arg1;+ (void)setAccessToken:(id)arg1refreshToken:(id)arg2 forAccount:(id)arg3;+ (_Bool)isUserAuthorized;+ (id)buildRequestForPath:(id)arg1params:(id)arg2 query:(id)arg3 queryItems:(id)arg4 HTTPMethod:(id)arg5accessToken:(id)arg6; @property(retain, nonatomic)NSMutableURLRequest *request; // @synthesize request=_request;@property(retain, nonatomic)PeriscopeOAuthOperation *oauthOperation; // @synthesizeoauthOperation=_oauthOperation;@property(retain, nonatomic)PeriscopeRefreshTokenAPIOperation *refreshTokenOperation; // @synthesizerefreshTokenOperation=_refreshTokenOperation;@property(retain, nonatomic)URLSessionTaskOperation *taskOperation; // @synthesizetaskOperation=_taskOperation;@property(retain) NSDictionary *JSON; //@synthesize JSON=_JSON; - (void).cxx_destruct;- (void)repeatOperation;- (_Bool)operationHas401Code;- (_Bool)shouldHandle401Code;- (void)operationDidFinish:(id)arg1withErrors:(id)arg2;- (void)finishWithError:(id)arg1;- (id)initWitMethod:(id)arg1params:(id)arg2;- (id)initWitMethod:(id)arg1params:(id)arg2 HTTPMethod:(id)arg3;- (id)initWitMethod:(id)arg1queryItems:(id)arg2;- (id)initWitMethod:(id)arg1params:(id)arg2 HTTPMethod:(id)arg3 queryItems:(id)arg4; @end
大家可以從上面這段程式碼中看到,其中包含了很多很多的屬性和方法。從這些方法名中可以看出,這個類應該就是負責處理Periscope API呼叫的類了。
接下來,我打開了Hopper來驗證我的想法。果然沒錯,這些方法都會呼叫initWitMethod並通過傳遞各種引數來實現API的初始化。
![](https://img.796t.com/res/2022/04-29/10/586f270d2ff64c2449a8b83a41db78c9.jpeg)
這樣一來,我只需要找出其他呼叫了這個方法的地方,我就能夠列出所有的Periscope API呼叫以及相關的引數名。通過對相關類進行深入分析之後,我還可以從靜態字串中提取出Mevo的API root、clinet_id以及client_secret了。
接下來,我們就可以檢查Periscope的OAuth實現中的漏洞了,而Periscope初始的身份認證節點並沒有部署CSRF保護機制。如果一個第三方應用可以請求獲取使用者Periscope賬號資訊的完整許可權,那麼攻擊者就有可能建立一個惡意第三方應用來偽裝成使用者執行惡意操作了。
總結
1.從今以後,我都會時刻關注Twitter的更新情況,並在第一時間對Twitter新上線的功能進行安全測試。 2.將功能開放給特定的第三方(或在公開API之前)不意味著你就不用對該功能的安全性進行測試了,有時我們只需要找到一個訪問API的方法,我們也許就能輕鬆地找出其中存在的安全問題。當然了,如果廠商給特定服務設立了漏洞獎勵計劃的話,你也許就不必繞彎路了。 3.最後一點,當你沒錢的時候,不要立刻放棄,你應該想辦法繞過或避免那些需要你花錢的東西。不過你也可以換個角度考慮,人們一般都不喜歡去投資那些所謂的“不確定性”,這也就意味著如果某個服務需要收費,說明會有一部分人不願意花錢去測試,那你就很有可能從中發現一些別人無法發現的漏洞了。如果這個服務又有漏洞獎勵計劃的話,那你估計就要發財了。
參考資料
關於該漏洞的詳細技術分析以及PoC,請參考釋出在HackerOne上的原始報告。