小米手环3 NFC 自定义 门禁卡数据

时间:2024-02-18 17:26:44

摸索了好久,最后还是从网络安全下手,篡改数据包。

最终的效果,点击添加小米空白卡便可生成一张自定义数据的门禁卡。【最终测试,可以突破2张限制,最多添加5张门禁卡】

思路:

因为门卡模拟的通道必须要读取一张未加密的卡才能触发向服务器发送添加卡片及卡片信息的请求,

所以我不在门禁卡模拟那里添加,太麻烦了。

我选择添加小米空白卡的选项,然后手机就会向服务器发送添加小米空白卡的请求。

我通过fiddler抓包神器拦截这个POST请求,并将数据包篡改成添加门禁卡的类型,同时将想添加的UID和扇区数据同时篡改。

至此,便实现向服务器发送添加自定义NFC卡数据的功能,服务器便会返回一些命令,手机再使用这些命令自动写入手环。

上面是大概思路,我自己肯定成功了。

我编写了一个fiddler脚本,自动拦截数据包并篡改成想要的UID和数据块。

上代码:

 

//自定义代码
        // 自定义的UID在这里修改
        var UID = "1A2B3C4D";//卡ID
        var isMusicRequest = 0;
        // 判断是否为目标请求
        if ((oSession.host == "api-mifit.huami.com")&&(oSession.fullUrl.Contains("nfc/accessCard/script/init")||oSession.fullUrl.Contains("nfc/accessCard/script/request")))
        {
            isMusicRequest = 1;
        }
        // 修改请求体JSON串
        if (isMusicRequest == 1)
        {
            // 1, 获取Request Body中字符串
            var requestStringOriginal =  oSession.GetRequestBodyAsString();
            //FiddlerObject.log(responseStringOriginal);    // 可在控制台中输出Log
           
            // 2, 转换为可编辑的JSONObject变量
            var requestJSON = Fiddler.WebFormats.JSON.JsonDecode(requestStringOriginal)
            
            // 3, 修改JSONObject变量
            // 3.1修改字段
            requestJSON.JSONObject[\'fareCardType\'] = "0";
            requestJSON.JSONObject[\'fetch_adpu_mode\'] = "SYNC";
            requestJSON.JSONObject[\'sak\'] = "08";
            requestJSON.JSONObject[\'uid\'] = UID;
            requestJSON.JSONObject[\'aid\'] = "";
            requestJSON.JSONObject[\'atqa\'] = "0400";
            requestJSON.JSONObject[\'action_type\'] = "copyFareCard";
             // 自定义的UID和扇区内容在这里修改
            requestJSON.JSONObject[\'blockContent\'] = UID + "b208040062636465666768690000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff";
            
            // 4, 重新设置Request Body
            var requestStringDestinal = Fiddler.WebFormats.JSON.JsonEncode(requestJSON.JSONObject);
            
            oSession.utilSetRequestBody(requestStringDestinal);
        }        

 

 

 

上面的代码请添加到flidder的规则->自定义规则-> 这个函数中static function OnBeforeRequest(oSession: Session) {} 

 

 

 

 代码添加好后效果如下:static function OnBeforeRequest(oSession: Session) 

 

static function OnBeforeRequest(oSession: Session) {
        // Sample Rule: Color ASPX requests in RED
        // if (oSession.uriContains(".aspx")) {    oSession["ui-color"] = "red";    }

        // Sample Rule: Flag POSTs to fiddler2.com in italics
        // if (oSession.HostnameIs("www.fiddler2.com") && oSession.HTTPMethodIs("POST")) {    oSession["ui-italic"] = "yup";    }

        // Sample Rule: Break requests for URLs containing "/sandbox/"
        // if (oSession.uriContains("/sandbox/")) {
        //     oSession.oFlags["x-breakrequest"] = "yup";    // Existence of the x-breakrequest flag creates a breakpoint; the "yup" value is unimportant.
        // }

        if ((null != gs_ReplaceToken) && (oSession.url.indexOf(gs_ReplaceToken)>-1)) {   // Case sensitive
            oSession.url = oSession.url.Replace(gs_ReplaceToken, gs_ReplaceTokenWith); 
        }
        if ((null != gs_OverridenHost) && (oSession.host.toLowerCase() == gs_OverridenHost)) {
            oSession["x-overridehost"] = gs_OverrideHostWith; 
        }

        if ((null!=bpRequestURI) && oSession.uriContains(bpRequestURI)) {
            oSession["x-breakrequest"]="uri";
        }

        if ((null!=bpMethod) && (oSession.HTTPMethodIs(bpMethod))) {
            oSession["x-breakrequest"]="method";
        }

        if ((null!=uiBoldURI) && oSession.uriContains(uiBoldURI)) {
            oSession["ui-bold"]="QuickExec";
        }

        if (m_SimulateModem) {
            // Delay sends by 300ms per KB uploaded.
            oSession["request-trickle-delay"] = "300"; 
            // Delay receives by 150ms per KB downloaded.
            oSession["response-trickle-delay"] = "150"; 
        }

        if (m_DisableCaching) {
            oSession.oRequest.headers.Remove("If-None-Match");
            oSession.oRequest.headers.Remove("If-Modified-Since");
            oSession.oRequest["Pragma"] = "no-cache";
        }

        // User-Agent Overrides
        if (null != sUA) {
            oSession.oRequest["User-Agent"] = sUA; 
        }

        if (m_Japanese) {
            oSession.oRequest["Accept-Language"] = "ja";
        }

        if (m_AutoAuth) {
            // Automatically respond to any authentication challenges using the 
            // current Fiddler user\'s credentials. You can change (default)
            // to a domain\\username:password string if preferred.
            //
            // WARNING: This setting poses a security risk if remote 
            // connections are permitted!
            oSession["X-AutoAuth"] = "(default)";
        }

        if (m_AlwaysFresh && (oSession.oRequest.headers.Exists("If-Modified-Since") || oSession.oRequest.headers.Exists("If-None-Match")))
        {
            oSession.utilCreateResponseAndBypassServer();
            oSession.responseCode = 304;
            oSession["ui-backcolor"] = "Lavender";
        }
        
        //自定义代码
        // 自定义的UID在这里修改
        var UID = "1A2B3C4D";//卡ID
        var isMusicRequest = 0;
        // 判断是否为目标请求
        if ((oSession.host == "api-mifit.huami.com")&&(oSession.fullUrl.Contains("nfc/accessCard/script/init")||oSession.fullUrl.Contains("nfc/accessCard/script/request")))
        {
            isMusicRequest = 1;
        }
        // 修改请求体JSON串
        if (isMusicRequest == 1)
        {
            // 1, 获取Request Body中字符串
            var requestStringOriginal =  oSession.GetRequestBodyAsString();
            //FiddlerObject.log(responseStringOriginal);    // 可在控制台中输出Log
           
            // 2, 转换为可编辑的JSONObject变量
            var requestJSON = Fiddler.WebFormats.JSON.JsonDecode(requestStringOriginal)
            
            // 3, 修改JSONObject变量
            // 3.1修改字段
            requestJSON.JSONObject[\'fareCardType\'] = "0";
            requestJSON.JSONObject[\'fetch_adpu_mode\'] = "SYNC";
            requestJSON.JSONObject[\'sak\'] = "08";
            requestJSON.JSONObject[\'uid\'] = UID;
            requestJSON.JSONObject[\'aid\'] = "";
            requestJSON.JSONObject[\'atqa\'] = "0400";
            requestJSON.JSONObject[\'action_type\'] = "copyFareCard";
             // 自定义的UID和扇区内容在这里修改
            requestJSON.JSONObject[\'blockContent\'] = UID + "b208040062636465666768690000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff";
            
            // 4, 重新设置Request Body
            var requestStringDestinal = Fiddler.WebFormats.JSON.JsonEncode(requestJSON.JSONObject);
            
            oSession.utilSetRequestBody(requestStringDestinal);
        }        
    
    }

 

 

最后简单讲一下步骤:

1.电脑和手机连到同一个局域网;

2.电脑安装Fiddler并运行,代理端口设置成8888(若不懂自行学习fiddler基础使用方法);

3.手机连电脑代理,保证Fiddler能抓到手机的数据包(iOS 和安卓都要信任Fiddler的证书);

4.在Fiddler中,左上角选项卡,第3个,规则->自定义规则;

5.打开后,是javascript代码,你找到static function OnBeforeRequest(oSession: Session) 这个函数,把我的代码放在里面,保存即可;(代码里面的UID和扇区数据肯定得改成你自己想要改的

6.手机蓝牙连接手环嘛,打开小米运动哇,直接添加一张小米空白卡,等待即可。

 

说在最后面的话,本来我买了几张CUID的空白卡,可以直接用我女朋友的小米8写卡。真没想到我女朋友的小米8前天在春熙路被可恶的小偷偷走了,卡今天才到货。

【大神完全可以通过代理的功能把端口暴露在公网上面,给其它朋友添加自定义数据的卡】

【此教程仅供自己小米手环数据使用,切勿用于违法行为】

【最后放点数据包笔记,以下内容不重要,无需理会】

 

1.初始化请求
https://api-mifit.huami.com/nfc/accessCard/script/init?r=894C7E51-A833-4AE6-B369-61A238788F43&t=1542653294011

删除 request 数据包
{"fareCardType":0,"fetch_adpu_mode":"SYNC","sak":"","uid":"","aid":"A0000003964D344D1004283E3B644B05","atqa":"","size":1024,"action_type":"deleteapp","blockContent":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF078069FFFFFFFFFFFF"}


空白卡 request 数据包
{"fareCardType":1,"fetch_adpu_mode":"SYNC","sak":"","uid":"","aid":"","atqa":"","size":0,"action_type":"copyFareCard","blockContent":""}
{"fareCardType":1,"fetch_adpu_mode":"SYNC","sak":"","uid":"","aid":"","atqa":"","size":0,"action_type":"copyFareCard","blockContent":""}

门禁卡 request 数据包
{"fareCardType":0,"fetch_adpu_mode":"SYNC","sak":"08","uid":"9ab273e9","aid":"","atqa":"0400","size":1024,"action_type":"copyFareCard","blockContent":"9ab273e9b208040062636465666768690000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff"}


2.请求脚本服务
https://api-mifit.huami.com/nfc/accessCard/script/request?r=894C7E51-A833-4AE6-B369-61A238788F43&t=1542653297773
门禁卡 request 数据包
{"blockContent":"11223344b208040062636465666768690000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff078069ffffffffffff", "atqa":"0400", "fetch_adpu_mode":"SYNC", "action_type":"copyFareCard", "sak":"08", "fareCardType":"0", "command_results":{"results":[{"index":"1", "command":"00A4040008A000000151000000", "result":"6F108408A000000151000000A5049F6501FF9000", "checker":"^(9000|6283)$"}, {"index":"2", "command":"8050200008D2D8E32B3FCF71C7", "result":"000081841616969471152002003B62C50CBD6FD6E93D11C9C386A8409000", "checker":"^(9000)$"}], "succeed":true}, "session":"0871-260938047-94201481349", "size":1024, "aid":"", "current_step":"1", "uid":"11223344"}

空白卡 request 数据包
{"uid":"","fareCardType":1,"session":"851-4110831269-94201228953","blockContent":"","fetch_adpu_mode":"SYNC","size":0,"atqa":"","current_step":"1","sak":"","action_type":"copyFareCard","aid":"","command_results":{"succeed":true,"results":[{"result":"6F108408A000000151000000A5049F6501FF9000","checker":"^(9000|6283)$","command":"00A4040008A000000151000000","index":"1"},{"result":"000081841616969471152002003CD0C715650812529A2FA03735A0B19000","checker":"^(9000)$","command":"80502000081B4F460C59035575","index":"2"}]}}

{"uid":"","fareCardType":1,"session":"851-4110831269-94201228953","blockContent":"","fetch_adpu_mode":"SYNC","size":0,"atqa":"","current_step":"1","sak":"","action_type":"copyFareCard","aid":"","command_results":{"succeed":true,"results":[{"result":"9000","checker":"^(9000)$","command":"848201001037A3E488255DCE5C1ABE1570D118C5C6","index":"1"}]}}

 

 【转载请注明出处】