手机被公司收回了,只有把自己用的荣耀6给ROOT了做测试,结果公司的打卡APP不能用;想着修改一下。
比较简单,逆向跟踪一下打卡的逻辑,把isRooted(),isLocationSimulation(),isEmulator()等一些环境检测的函数Patch掉。
由于在家里没法测试,想着不如干脆把GPS定位信息也给改了,可以实现在家里打卡。
通过Smali插桩,可以看到打卡时的函数调用关系:
enter startGpsLocation method
[AttendanceManager] doNewPunchRequest is runing!
Enter getNewPunchParams...
0.0
Enter getNewPunchcard...
首先应用调用SecurityUtil类中一些方法进行环境检测,接着分别检测GPS、Network、WIFI是否开启,所有条件都具备了的话,调用getNewPunchParams函数取参数:
{"deviceType":"1","locale":"cn","meapip":"58.251.153.67","employeeNumber":"00294xxx","deviceId":"35714304192xxxx","y":"0.0","ip":"192.168.1.102","x":"0.0"}
包括打卡服务器地址,员工工号,设备号等,其中x和y分别是经纬度。
getNewPunchcard就是向服务器请求打卡。
清楚了逻辑,很容易看到,只要修改一下getNewPunchParams函数,把里面取的的经纬度改掉就OK了
像这样:
编译好运行,结果提示打卡失败,“您不在打卡有效区域哦,走近点再试试吧”。。。
就这个坑爹的提示,以为自己在地图上定位的GPS位置不准,也确实这样,各个地图同一地点的GPS数据都不一样,跑去打卡的地方实地定位一下,修改GPS值然而还是失败。
后来想到,会不会请求的时候又加了其它数据在里面,进行了校验。burp 抓一下包,请求内容被加密过,但拦截一下请求的Response,发现下面提示:
请求:
搜索“INVALID_USER_SCODE”总算找到原因了,服务端的验证使用了高德API,这个API使用前要申请一个Key,这个Key跟应用签名是绑定的。重打包以后签名变了,服务端校验出错。
有种解决办法,拿我自己的签名去申请一个KEY,不知道服务端本身有没有签名验证。先MARK有时间再试下。
————
附Smali插桩的一个好的方法,不需要额外寄存器,再也不怕程序崩溃了:
crack.smali
.class public Lcrack; .super Ljava/lang/Object; .source "crack.java" .method public static puts(Ljava/lang/String;)V .locals 7 .prologue :try_start_0 const-string v3, "/data/debug.txt" new-instance v2, Ljava/io/FileOutputStream; const/4 v5, 0x1 invoke-direct {v2, v3, v5}, Ljava/io/FileOutputStream;-><init>(Ljava/lang/String;Z)V .line 19 new-instance v4, Ljava/io/OutputStreamWriter; const-string v5, "gb2312" invoke-direct {v4, v2, v5}, Ljava/io/OutputStreamWriter;-><init>(Ljava/io/OutputStream;Ljava/lang/String;)V .line 21 invoke-virtual {v4, p0}, Ljava/io/OutputStreamWriter;->write(Ljava/lang/String;)V const-string v5, "\r\n" invoke-virtual {v4, v5}, Ljava/io/OutputStreamWriter;->write(Ljava/lang/String;)V .line 23 invoke-virtual {v4}, Ljava/io/OutputStreamWriter;->flush()V .line 25 invoke-virtual {v4}, Ljava/io/OutputStreamWriter;->close()V .line 27 invoke-virtual {v2}, Ljava/io/FileOutputStream;->close()V :try_end_0 .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0 .line 37 :cond_0 :goto_0 return-void .line 30 :catch_0 move-exception v0 .line 34 const-string v5, "debug" const-string v6, "file write error" invoke-static {v5, v6}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I goto :goto_0 .end method
使用:
invoke-static {v1}, Lcrack;->puts(Ljava/lang/String;)V