亞馬遜AWS IoT使用MQTTS(在TLS上的MQTT)來提供物聯網設備與雲平台直接的通信功能。出於安全考慮,建議給每個設備配備了證書來認證,同時,設備也要安裝亞馬遜的根證書;這樣,在使用8883端口建立TLS連接時,客戶端SDK既對AWS進行驗證,同時AWS IoT也對設備的證書進行驗證。由此,便對中間人攻擊帶來了較高的要求,下面記錄一下這幾天的爬坑經理。
0.方案
整體方案類似於這個:https://wiki.dequis.org/notes/facebook/
用Host-Only模式的virtual box虛擬機當受害者,用iptables使其可以上網,並在虛擬網卡vboxnet0上搭建mitmproxy來嗅探。
VBox虛擬機(安裝SDK) ====> VBoxnet0網絡接口(搭建mitmproxy)======>eth0(公網訪問AWS)
用到的工具:
Kali Linux
Virtual Box
mitmproxy
wireshark
dnsmasq
iptables
openssl
1.注冊AWS IoT
注冊AWS比較麻煩,還需要可支付美元的信用卡,不過因為擔心被扣費刷爆,我隨便baidu了一個填上。但是,由於扣費1USD不成功,導致下一步驗證碼總是過不去,所以填真實的信用卡比較靠譜。(奇怪的是,我靜置1天后莫名其妙通過了;期間AWS發郵件說因為虛假信息要封號,我靠三寸不爛之舌通過了驗證。)之后就是根據AWS的說明下載並試用SDK,特別值得一提的是,他提供了一個向導,直接注冊設備生成證書和對應平台SDK,非常方便,我選用了生成的Linux Python SDK來實驗。
2. Kali下安裝virtual box
請參考網上其他教程。特別說明,一定要apt-get update ,apt-get upgrade ,apt-get dist-upgrade 升級到最新,並且reboot,到最新的內核版本安裝,否則各種Linux headers和內核版本對應不上產生的問題。
3. virtual box采用host-only模式
https://www.virtualbox.org/manual/ch06.html#network_hostonly
使用host-only聯網可參考:https://unix.stackexchange.com/questions/383791/virtualbox-host-only-with-internet
注意,virtual box修改網絡模式的時候要關掉虛擬機!(在windows上用慣了VMare注意一下)
開始打算直接使用NAT,然后在host主機上(宿主機)搭建中間人代理mitmproxy,然而不知為何一直抓不到包,並且不像VMare可以看到虛擬網絡接口,故使用host-only配合iptables
4.設置iptables使用mitmproxy中間人代理
https://media.readthedocs.org/pdf/mitmproxy/latest/mitmproxy.pdf
iptables教程:http://www.cnblogs.com/haven/archive/2012/09/27/2705859.html
(常用-t指定表,-S顯示設置的規則,-F對該表的規則進行刪除)
開啟ipv4轉發 sysctl -w net.ipv4.ip_forward=1
我設置的規則:(eth0外網連接,vboxnet0是host上的虛擬接口)
首先兩個網絡接口可以互相轉發
iptables -A FORWARD -i eth0 -o vboxnet0 -j ACCEPT
iptables -A FORWARD -i vboxnet0 -o eth0 -j ACCEPT
設置中間人代理以及NAT:
iptables -t nat -A PREROUTING -i vboxnet0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -A PREROUTING -i vboxnet0 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8080
iptables -t nat -A PREROUTING -i vboxnet0 -p tcp -m tcp --dport 8883 -j REDIRECT --to-ports 8080 //8883端口是mqtts
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE //在eth0設置nat改變原地址
最后,記得將虛擬機的默認路由修改為主機上的虛擬網卡vboxnet0的地址192.168.56.1,這樣iptables的-i vboxnet0才會起作用。DNS可以設置為8.8.8.8。
注意,這里將mitmproxy搭建在vboxnet0,開始我選擇搭建在eth0,但是不知為何一直抓不到包。
5. 設置SSL證書
http://docs.mitmproxy.org/en/stable/certinstall.html#the-mitmproxy-certificate-authority
首先讓客戶端SDK信任mitmproxy的證書,但是,AWS提供的證書和mitmproxy提供的證書在格式上不同,不能僅僅替換證書文件,還需要轉換,在執行腳本時-r參數替換為mitmproxy的證書文件。
openssl x509 -in mitmproxy-ca-cert.pem -inform PEM -out foo.crt //更改證書格式
python aws-iot-device-sdk-python/samples/basicPubSub/basicPubSub.py -e axxxxxx9x.iot.us-east-2.amazonaws.com -r foo.crt -c 0000.cert.pem -k 0000.private.key
客戶端設備的證書也要經過轉換才能提供給mitmproxy,不然服務器會斷開連接。
格式轉換參考:https://stackoverflow.com/questions/28712088/unable-to-load-certificate-6300error0906d06cpem-routinespem-read-biono-star
使用客戶端證書:http://docs.mitmproxy.org/en/stable/certinstall.html#using-a-client-side-certificate (文檔有個坑,這里其實不能單純指定文件夾,最好指定證書文件,官網文檔沒及時更新)
填坑:https://github.com/mitmproxy/mitmproxy/pull/494/commits/ff6bfba4a6a1c440018c4873d9edeb64da0f8e7f (這里說明了客戶端證書怎么用,若指定文件夾要求文件名和訪問域名一致)
openssl rsa -in 0000.private.key -out unprotected.0000.private.key
cat unprotected.0000.private.key 0000.cert.pem > mitm_0000.cert.pem
特別注意,這里不明原因客戶端SDK和mitmproxy都會檢測到域名不匹配(安全問題?),需要特別處理。SDK我選擇注釋掉了出錯的那一行/usr/local/lib/python2.7/dist-packages/AWSIoTPythonSDK/core/protocol/paho/client.py的800行左右的self._tls_match_hostname();mitmproxy使用--insecure參數,屆時會顯示警告,但是不會斷開連接。
192.168.56.2:52369: Certificate Verification Error for 52.15.111.27:8883: hostname 'no-hostname' doesn't match either of u'*.iot.us-east-2.amazonaws.com', u'iot.us-east-2.amazonaws.com'
192.168.56.2:52369: Ignoring server verification error, continuing with connection。
6.wireshark解密ssl
http://docs.mitmproxy.org/en/stable/dev/sslkeylogfile.html
設置環境變量讓mitmproxy記錄下ssl的密鑰:
export SSLKEYLOGFILE=~/IoT/keylog (會影響瀏覽器 ,最好選用下面這個環境變量)
export MITMPROXY_SSLKEYLOGFILE=~/IoT/keylog
7.最后
1)運行代理:
mitmdump -T --insecure --client-certs ~/IoT/connect_device_package/mitm_0000.cert.pem --host --raw-tcp -w 11111
-v可以顯示詳細信息。
一定要設置--raw-tcp,否則代理會因為mqtt不是標准的http協議而出錯。(重要補充:最好是設置成-tcp,因為-raw-tcp會讓mitmdump自動推斷協議。奇怪的是,抓取rachio這個app的http2協議時,要設置--raw-tcp才不會導致app崩潰。到時候大家多試一試吧)
2)打開wireshark並設置過濾條件為ssl && tcp.port==8883
3)運行sdk腳本:
python aws-iot-device-sdk-python/samples/basicPubSub/basicPubSub.py -e axxxxxx9x.iot.us-east-2.amazonaws.com -r foo.crt -c 0000.cert.pem -k 0000.private.key
4)將密鑰導入wireshark即可解密出mqtts消息:
編輯——首選想——protocals——ssl—— (Pre)-Master-Secret log filename
,選擇記錄下的密鑰。
By Ascii0x03,歡迎轉載,請注明出處,謝謝。
http://www.cnblogs.com/ascii0x03/p/7798072.html
2017-11-07