0×00
指紋考勤機被越來越多的使用在企業中, 實現了人、地、時三者合一,為企業職員的出勤考察提供了極大的方便。在考勤機驗證指紋成功的一瞬間,會向服務器發送一條職員打卡請求,然后服務器將打卡信息存入數據庫,這時人們通過瀏覽器就能瀏覽到你的考勤信息。那么,如果我們能把考勤機發送的這條“打卡請求”通過抓包的方式捕獲,然后在“適宜”的時間發送出去,是不是就可以實現打卡了。本文根據這個思路,進行了一系列實驗。
0×01
我們的最終目的就是獲取考勤機發送的數據包。為此我們進行了如下實驗。
首先考勤機沒有設置代理的功能,如果想捕獲考勤機發出的請求,首先想到的是ARP欺騙,但是既然我們能直接接觸到考勤機,所以這里直接采取一個暴力的方法:先保證電腦和考勤機在同一個網段,使用USB網卡和一根網線將電腦和考勤機連接,為了保證考勤機能正常聯網,還需要將USB網卡和能上網的網卡進行橋接,此時考勤機可以正常聯網並且所有流量都會經過電腦端。最后,電腦端開啟wireshark,選中USB網卡開始抓包,這樣考勤機發送的數據就會一目了然。現在的網絡拓撲如下:
0×02
捕獲到的網絡流量如下,沒錯,使用了TLS(傳輸層安全協議),加密了所有的數據。目前大多數證書都使用1024位或2048位密鑰。2048位密鑰非常可靠,要想通過暴力的方式破解,這幾乎是不可能的。
通過查閱資料,找到兩種突破SSL的工具:SSLStrip和SSLSplit。SSLStrip很強大,它的核心原理是將HTTPS強制降級為HTTP。SSLSplit的原理是以中間人的身份將偽造的證書插入到服務器和客戶端中間,從而截斷客戶端和服務器之間的流量。這里我們使用SSLStrip。(希望考勤機沒有校驗證書的真偽)==
同時我們注意到考勤機的IP位於4網段,網關為192.168.4.1。
0×03
接下來我們需要搭建一個虛假的網關,來截斷考勤機發出的所有流量。
將之前的USB網卡(eth2)接入Kali系統,Kali使用NAT方式進行聯網,IP:192.168.127.134,子網掩碼:255.255.255.0
命令如下:
//配置USB網卡的IP為192.168.4.1,子網掩碼255.255.255.0root@bogon:~# ifconfig eth2 192.168.4.1 netmask 255.255.255.0//使能USB網卡root@bogon:~# ifconfig eth2 up//開啟IP轉發root@bogon:~# echo 1 > /proc/sys/net/ipv4/ip_forward//為了保證這個虛假網關能聯網,將eth2和eth0進行關聯root@bogon:~# iptables -A FORWARD -i eth2 -o eth0 -j ACCEPT//開啟地址偽裝root@bogon:~# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
同時我們還要搭建一個DHCP服務為考勤機分配IP,這里使用dnsmasq,配置如下,並啟動服務。
root@bogon:~# service dnsmasq start
此時一個4網段的網關已經設置好,USB網卡模擬網關並分配IP地址。這時將考勤機連接應該可以正常聯網。
網絡拓撲如下:
0×04
下面請SSLSplit登場。
先生成一個key文件:
openssl genrsa -out ca.key 2048
然后自簽名用生成的key生成公鑰證書:
openssl req -new -x509 -days 1096 -key ca.key -out ca.crt
這樣我們就把根證書建好了。
接着是用iptables進行流量轉發,把我們需要的端口進行轉發:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8443
接着啟動SSLSplit
sslsplit -D -l connect.log -j /root -S logdir/ -k ca.key -c ca.crt ssl 0.0.0.0 8443 tcp 0.0.0.0 8080
連接考勤機並進行打卡,會發現生產日志文件,里面應該就是我們想要的明文數據包。
0×05
打開一看,部分亂碼。好吧,這又是什么加密?不慌,我們距離成功僅差一步。
仔細觀察,我們可以得到服務器的IP,並且知道考勤機使用了websocket。簡單來說websocket是一種網絡協議,實現了全雙工,客戶端和服務器可以相互主動發送信息給對方。數據傳輸使用的是一系列數據幀,出於安全考慮,客戶端發送的數據幀必須進行掩碼處理后才能發送到服務器,不論是否是在TLS安全協議上都要進行掩碼處理。WebSocket協議已經設計了心跳,這個功能可以到達檢測鏈接是否可用。一個數據幀的結構如下:
廢話不多說,既然數據幀進行了掩碼處理,我們怎么解密呢,網上解密代碼很多,我寫了一個Java版的,部分代碼如下:
0×06
運行程序,終於終於看到了明文===
第一部分代表考勤機發出的登陸請求,包含考勤機的一些信息:設備ID,token
第二部分為websocket的心跳包。
第三部分,在校驗指紋時捕獲到的,所以應該就是我們想要的打卡請求。包含userCode(工號),checkTime(打卡時間)
目前為止,我們已經可以成功解析這個亂碼的文件:
0×07
開始擼代碼。現在已經知道了考勤機與服務器之間的通信內容,現在需要寫一個支持SSL的websocket客戶端將打卡信息發送給服務器。代碼參考這位大神寫的:
https://github.com/palmerc/SecureWebSockets
稍加修改,一個具有打卡功能的安卓客戶端誕生。
下面是打卡后服務器返回的數據,type=”result”時表示成功。通過查閱考勤記錄,確實成功打卡。
修改了一哈界面,是不是很帥呢===
自從有了它,媽媽再也不用擔心我上班遲到了===
0×08
總的來說:
1、實現遠程打卡的思路可以簡單概括為四個字:抓包重放。原理雖然簡單,但是我們在抓包的過程中遇到了很多困難。
2、考勤機的核心問題在於,沒有檢測SSL證書的真偽,導致我們可以偽造證書,獲取考勤機與服務器通信的明文數據包,最終我們寫了一個APP來發送打卡信息,實現了遠程打卡。