陳 曼,談 程,吉慶兵
(中國(guó)電子科技集團(tuán)公司第三十研究所,四川 成都 610041)
Shadowsocks 和ShadowsocksR 常被用于突破防火墻長(zhǎng)城(Great Firewall,GFW),以瀏覽被封鎖、遮蔽或干擾的內(nèi)容[1]。
Shadowsocks(簡(jiǎn)稱(chēng)SS)是一種基于Socks5 代理方式的加密傳輸協(xié)議,也可以指實(shí)現(xiàn)這個(gè)協(xié)議的各種開(kāi)發(fā)包。Shadowsocks 分為服務(wù)器端和客戶(hù)端,使用前需要先將服務(wù)器端程序部署到服務(wù)器上,然后通過(guò)客戶(hù)端連接并創(chuàng)建本地代理。ShadowsocksR(簡(jiǎn)稱(chēng)SSR)在Shadowsocks 的基礎(chǔ)上增加了一些數(shù)據(jù)混淆方式,修復(fù)了部分安全問(wèn)題,并可以提高QoS 優(yōu)先級(jí)。
與TLS 等協(xié)議不同,Shadowsocks 的最初設(shè)計(jì)的目的只是繞過(guò)GFW,而不是提供密碼學(xué)意義的安全,所以Shadowsocks 自行設(shè)計(jì)的加密協(xié)議對(duì)雙方的身份驗(yàn)證僅限于預(yù)共享密鑰,無(wú)完全前向保密,也未曾有安全專(zhuān)家公開(kāi)分析或評(píng)估協(xié)議及其實(shí)現(xiàn)。
本文分析Shadowsocks 和ShadowsocksR 產(chǎn)生的流量的報(bào)文格式和密碼算法,并探討用戶(hù)數(shù)據(jù)在兩種代理軟件保護(hù)下的機(jī)密性問(wèn)題。
Shadowsocks(R)服務(wù)組件包括運(yùn)行在本地電腦上的SS 客戶(hù)端和運(yùn)行在遠(yuǎn)端服務(wù)器上的SS 服務(wù)端。攻擊者能夠獲得的流量通常是從SS 客戶(hù)端發(fā)送至SS 服務(wù)器端的加密流量,而非本地電腦的Socks5 代理發(fā)送至SS 客戶(hù)端的流量。因此,這里分析從SS 客戶(hù)端發(fā)送至SS 服務(wù)器端的加密流量的報(bào)文格式。
圖1 是Shadowsocks 客戶(hù)端配置界面。從該界面可以看出,Shadowsocks 使用時(shí)需要用戶(hù)配置的部分包括服務(wù)器IP、服務(wù)器端口、密碼以及加密等部分。配置完成后,本機(jī)SS 客戶(hù)端與服務(wù)器IP 上的服務(wù)器端口建立連接,傳送通過(guò)密碼和加密處理過(guò)的應(yīng)用數(shù)據(jù)。
圖1 SS 客戶(hù)端配置界面
SS 客戶(hù)端與服務(wù)器端之間傳送TCP 流或UDP報(bào)文。本文重點(diǎn)關(guān)注TCP 流,對(duì)UDP 報(bào)文格式不作介紹。TCP 流的最前面是隨機(jī)數(shù),后續(xù)字節(jié)是密文。隨機(jī)數(shù)的長(zhǎng)度與使用的加密算法有關(guān),用作不同模式下密碼算法的初始向量或其他密碼參數(shù)。密文是用戶(hù)數(shù)據(jù)經(jīng)過(guò)加密得到的。SS 客戶(hù)端轉(zhuǎn)發(fā)用戶(hù)數(shù)據(jù)至SS 服務(wù)器前,會(huì)在用戶(hù)數(shù)據(jù)前加入用戶(hù)訪(fǎng)問(wèn)的地址,地址也是加密傳輸?shù)?。SS 客戶(hù)端發(fā)往服務(wù)器端的TCP 流和反向TCP 流格式分別如圖2 和圖3 所示。
圖2 SS 客戶(hù)端發(fā)往服務(wù)器端的TCP 流
圖3 SS 服務(wù)器端發(fā)往客戶(hù)端的TCP 流
TARGET ADDRESS 表示用戶(hù)要訪(fǎng)問(wèn)的地址,使用Socks5 協(xié)議的地址表示方法,即TARGET ADDRESS 由類(lèi)型、主機(jī)名和端口3 個(gè)字段標(biāo)識(shí)。
Shadowsocks 加密選項(xiàng)的選取不同,用戶(hù)數(shù)據(jù)加密后的格式也不相同。當(dāng)前,Shadowsocks 支持aes-128-ctr、chacha20-ietf 等流密碼算法和aes-192-gcm、chacha20-ietf-poly1305 等AEAD 密碼算法。對(duì)于流密碼算法,加密前后數(shù)據(jù)長(zhǎng)度相同;對(duì)于AEAD 密碼算法,明文會(huì)變成如圖4 所示的密文。
圖4 AEAD 加密算法的密文格式
Shadowsocks 選用的加密算法不同,隨機(jī)數(shù)的長(zhǎng)度也不相同。aes-128-ctr 等ctr 結(jié)尾的流密碼對(duì)應(yīng)的隨機(jī)數(shù)長(zhǎng)度為16 Byte;除bf-cfb 為8 Byte 外,其他cfb 結(jié)尾的流密碼如aes-128-cfb、camellia-256-cfb 等,隨機(jī)數(shù)長(zhǎng)度為16 Byte;chacha20-ietf隨機(jī)數(shù)長(zhǎng)度為16 Byte;AEAD 密碼算法包括chacha 20-ietf-ploy1305、aes-128-gcm、aes-192-gcm 和aes-256-gcm,其隨機(jī)數(shù)長(zhǎng)度與密鑰長(zhǎng)度相等。
圖5 是ShadowsocksR 客戶(hù)端配置界面。相比于Shadowsocks 客戶(hù)端配置界面,這里多出了協(xié)議、協(xié)議參數(shù)、混淆和混淆參數(shù)4 個(gè)配置項(xiàng)。通過(guò)源代碼分析可知,加密、協(xié)議和混淆是3個(gè)相對(duì)獨(dú)立的過(guò)程。首先,ShadowsocksR 先使用協(xié)議和協(xié)議參數(shù)對(duì)用戶(hù)數(shù)據(jù)進(jìn)行封裝(部分協(xié)議會(huì)對(duì)用戶(hù)數(shù)據(jù)進(jìn)行加密),使用戶(hù)數(shù)據(jù)滿(mǎn)足協(xié)議的格式;ShadowsocksR 對(duì)滿(mǎn)足協(xié)議格式的數(shù)據(jù)進(jìn)行加密,加密方式與Shadowsocks的加密方式相同;ShadowsocksR 使用混淆和混淆參數(shù)對(duì)加密后的數(shù)據(jù)進(jìn)行封裝,使加密后的數(shù)據(jù)滿(mǎn)足混淆的格式。
圖5 SSR 客戶(hù)端配置界面
對(duì)Shadowsocks 源碼分析可知,Shadowsocks 中使用的密碼算法包括兩類(lèi),分別是密鑰生成算法和不同加密選項(xiàng)使用的加(解)密算法。
Shadowsocks 配置加密選項(xiàng)時(shí),實(shí)質(zhì)上是同時(shí)選擇了基礎(chǔ)密碼算法和加密模式。加密選項(xiàng)基于TCP 流中的隨機(jī)數(shù)及密鑰生成算法產(chǎn)生的主密鑰來(lái)加密數(shù)據(jù)。不同加密選項(xiàng)使用隨機(jī)數(shù)和主密鑰的方式不同,本文僅以幾個(gè)加密選項(xiàng)為例說(shuō)明。
Shadowsocks 密鑰生成算法基于預(yù)共享密鑰,即Shadowsocks 配置界面的密碼來(lái)生成主密鑰。加密選項(xiàng)確定的情況下,主密鑰的長(zhǎng)度確定。當(dāng)前Shadowsocks 支持的密鑰長(zhǎng)度為16 Byte、24 Byte 和32 Byte。令pwd 表示預(yù)共享密鑰,master key 表示Shadowsocks 加密選項(xiàng)使用的主密鑰,輸入pwd、master key 長(zhǎng)度,通過(guò)最多兩輪MD5 算法得到輸出master key。
CFB 模式的先決要素包括基礎(chǔ)密碼算法、密鑰、所支持的輸入/輸出長(zhǎng)度以及所支持的標(biāo)簽長(zhǎng)度[2];輸入包括IV、明文和偏移參數(shù)s。Shadowsocks 使用aes-192-cfb 加密時(shí),基礎(chǔ)密碼算法使用aes-192;密鑰長(zhǎng)度24 Byte,取值為密鑰生成算法的輸出值master key;IV 長(zhǎng)度為16 Byte,取值為T(mén)CP 流的16 Byte 隨機(jī)數(shù)rand;s 取值為128。
GCM模式的先決要素包括基礎(chǔ)密碼算法、密鑰、所支持的輸入/輸出長(zhǎng)度以及所支持的標(biāo)簽長(zhǎng)度[3];輸入包括IV、明文和附加認(rèn)證數(shù)據(jù)A。Shadowsocks使用aes-256-gcm 加密時(shí),基礎(chǔ)密碼算法使用aes-256;IV 長(zhǎng) 度 為12 Byte,取 值 為0;A 長(zhǎng) 度 為0 Byte;密鑰K 長(zhǎng)度為32 Byte,由密鑰生成算法的輸出值master key 以及TCP 流的32 Byte 隨機(jī)數(shù)rand,通過(guò)3 輪基于SHA-1 哈希函數(shù)的HMAC 算法產(chǎn)生。
Shadowsocks 使用過(guò)時(shí)的哈希函數(shù)生成主密鑰和會(huì)話(huà)密鑰,且主密鑰生成過(guò)程中未加入鹽值。通過(guò)口令猜測(cè)攻擊,攻擊者可以得到用戶(hù)配置,解密后獲取用戶(hù)數(shù)據(jù)。
Shadowsocks 使用過(guò)時(shí)的哈希函數(shù)用于密鑰生成。Shadowsocks 基于MD5 算法生成主密鑰,進(jìn)一步使用MD5 算法、基于SHA-1 的HAMC 算法等從主密鑰導(dǎo)出會(huì)話(huà)密鑰。由于密碼學(xué)界對(duì)MD5 算法和SHA1 算法的一系列破解方法的提出[4-5],應(yīng)用程序和密碼庫(kù)等已逐步取消對(duì)MD5 和SHA-1 算法的支持。中國(guó)和美國(guó)在2012 年分別制定哈希函數(shù)標(biāo)準(zhǔn),稱(chēng)為SM3 和SHA-3。
Shadowsocks 主密鑰生成僅與pwd 和master key長(zhǎng)度有關(guān)。由于沒(méi)有加入鹽值,攻擊者可快速構(gòu)建主密鑰庫(kù),加快攻擊的速度。
密鑰生成算法輸入pwd、master key 長(zhǎng)度得到輸出master key。猜測(cè)master key 和加密選項(xiàng),任意攻擊者解密數(shù)據(jù)流得到用戶(hù)數(shù)據(jù),通過(guò)驗(yàn)證用戶(hù)數(shù)據(jù)是否滿(mǎn)足特定規(guī)則或AEAD 的標(biāo)簽是否正確,攻擊者可以判定猜測(cè)的master key 和加密選項(xiàng)是否正確。獲取正確的master key 和加密選項(xiàng)后,攻擊者可解密用戶(hù)發(fā)送的任意流量,嚴(yán)重威脅用戶(hù)數(shù)據(jù)的機(jī)密性。
猜測(cè)得到正確參數(shù)的困難性即是猜測(cè)得到正確加密選項(xiàng)的困難性和猜測(cè)出用戶(hù)密碼的困難性。Shadowsocks 支持的加密選項(xiàng)個(gè)數(shù)是固定的,其隨機(jī)性較小,猜測(cè)得到正確加密選項(xiàng)的概率較大。而受易用性、可記憶的密碼數(shù)量等限制,用戶(hù)設(shè)置的Shadowsocks 密碼通常是非隨機(jī)的,這就允許通過(guò)口令猜測(cè)的方法驗(yàn)證猜測(cè)正確性。對(duì)批量用戶(hù)進(jìn)行攻擊時(shí),攻擊者通過(guò)構(gòu)建預(yù)共享密鑰庫(kù)的方式增加pwd 命中的概率,縮短算法運(yùn)行時(shí)間。
密鑰生成算法的輸入僅包含pwd 和密鑰長(zhǎng)度。Shadowsocks 支持的密鑰長(zhǎng)度有16 Byte、24 Byte 和32 Byte。不同長(zhǎng)度的密鑰是在上一長(zhǎng)度密鑰上拼接,也就是說(shuō),從32 Byte 密鑰中可以直接讀取出同一pwd 生成的16 Byte 密鑰和24 Byte 密鑰。因此,攻擊者可能將存儲(chǔ)預(yù)共享密鑰庫(kù)轉(zhuǎn)化存儲(chǔ)32 Byte 密鑰庫(kù),通過(guò)時(shí)空折中[6]實(shí)現(xiàn)參數(shù)獲取加速。
此外,對(duì)于流密碼算法,其他參數(shù)相同情況下,cfb 模式和ctr 模式解密得到的第一字節(jié)完全相同。遍歷加密enc 時(shí),可將cfb 和ctr 看作同一種,減小遍歷次數(shù)實(shí)現(xiàn)參數(shù)獲取加速。
通過(guò)3.2 節(jié),攻擊者得到了Shadowsocks 的全部配置信息,即得到四元組(服務(wù)器IP,服務(wù)器端口,密碼,加密)或四元組(服務(wù)器IP,服務(wù)器端口,密鑰,加密)。獲取這些參數(shù)后,可方便地進(jìn)行流量解密。由于流密碼算法和AEAD 密碼算法的報(bào)文格式不同,流量解密流程也不相同。流密碼算法按照?qǐng)D3 的方式從TCP 流中取密文進(jìn)行解密。AEAD 密碼算法按照?qǐng)D4的方式從TCP流中取密文進(jìn)行解密。
ShadowsocksR 的參數(shù)獲取方法與Shadowsocks參數(shù)獲取方法類(lèi)似?;煜突煜齾?shù)不涉及加解密步驟,按照混淆的封裝格式直接解封裝即可剔除其影響。由于協(xié)議和協(xié)議參數(shù)的影響,TCP 流解密后的明文特征被隨機(jī)化,無(wú)法通過(guò)明文特征判定參數(shù)是否正確。然而,由于每種協(xié)議都用了特定的協(xié)議格式,可以通過(guò)驗(yàn)證明文是否滿(mǎn)足協(xié)議格式的方法確定密碼、加密的參數(shù)正確性,同時(shí)確定協(xié)議的參數(shù)正確性。最后,根據(jù)協(xié)議類(lèi)型和通過(guò)密碼、加密解密得到的明文,攻擊者可以進(jìn)一步猜測(cè)并確定協(xié)議參數(shù)。
獲取所有參數(shù)后,通過(guò)讀取混淆和混淆參數(shù)去除混淆封裝、讀取密碼和加密得到明文、讀取協(xié)議和協(xié)議參數(shù)提取明文或進(jìn)一步解密,攻擊者可實(shí)現(xiàn)SSR 流量的解密。
Shadowsocks 和ShadowsocksR 作為國(guó)內(nèi)常用的網(wǎng)絡(luò)代理軟件,生成的流量的機(jī)密性?xún)H依賴(lài)于配置界面的參數(shù)設(shè)置。攻擊者通過(guò)捕獲網(wǎng)絡(luò)流量和遍歷參數(shù)的方法可獲取用戶(hù)參數(shù),一旦獲取用戶(hù)參數(shù),攻擊者就可以監(jiān)聽(tīng)所有用戶(hù)數(shù)據(jù),嚴(yán)重威脅數(shù)據(jù)機(jī)密性。由于攻擊者使用被動(dòng)攻擊方法,用戶(hù)對(duì)于這種攻擊行為完全無(wú)感知。為保障用戶(hù)數(shù)據(jù)機(jī)密性,建議用戶(hù)增加Shadowsocks 和ShasowdocksR 配置參數(shù)的隨機(jī)性。Shadowsocks 和ShasowdocksR 配置中,加密、協(xié)議和混淆的參數(shù)個(gè)數(shù)固定,自由度較低,建議用戶(hù)增加密碼、協(xié)議參數(shù)的隨機(jī)性。此外,建議Shadowsocks 和ShadowsocksR 開(kāi)發(fā)者使用SM3、SHA-3 替代現(xiàn)有的哈希算法,并且在主密鑰生成過(guò)程中加入鹽值。