思路分享 | 指纹考勤机实现远程打卡测试
指纹考勤机被越来越多的使用在企业中, 实现了人、地、时三者合一,为企业职员的出勤考察提供了极大的方便。在考勤机验证指纹成功的一瞬间,会向服务器发送一条职员打卡请求,然后服务器将打卡信息存入数据库,这时人们通过浏览器就能浏览到你的考勤信息。那么,如果我们能把考勤机发送的这条“打卡请求”通过抓包的方式捕获,然后在“适宜”的时间发送出去,是不是就可以实现打卡了。本文根据这个思路,进行了一系列实验。
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来发送打卡信息,实现了远程打卡。