智慧城市真的安全嗎?看看這款APP的分析報告
今年早些時候,我收到了我們市政府的一個NextDoor訊息,聲稱他們為民眾提供了(購買)一個智慧城市應用程序。在此之前並沒有任何關於這個應用程序的信息,而我也沒有在網上找到其相關的內容,所以對於它我非常有興趣盡興更多地了解。
根據應用程序的描述,Bright City是「為城市和執法機構面向民眾提供服務的專用移動應用程序」。除了NextDoor公告中提到的「財產鎖箱」功能外,該應用還支持接收和提交報告可疑活動,當民眾離開家之後進行財產監控保護,保護公民的家,並可報告市政維護問題。Bright City的網站上還介紹了一些額外的功能,包括公民可以去了解市政費用的去向,許可證等內容。
而我們可以看到應用程序中涉及的信息的性質似乎非常敏感,所以我很有興趣進行仔細觀察。我下載安裝了應用程序,創建了一個帳戶並登錄。這是初始面板:
接下來我開始瀏覽應用中的某些選項,以生成一些API流量,在這一過程中沒有發現到一些非常嚴重的問題 。下面是應用程序在獲取當前用戶的配置文件信息時所做的請求示例:
GET https://api.brightcityapps.com/api/user/getuser/***REMOVED*** HTTP/1.1Host: api.brightcityapps.comConnection: keep-aliveAccept: application/json, text/javascript, */*; q=0.01User-Agent: Mozilla/5.0 (Linux; Android 7.1.2; Pixel XL Build/NHG47L; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.83 Mobile Safari/537.36Accept-Encoding: gzip, deflateAccept-Language: en-USX-Requested-With: com.mobilesciencetech.brightcity
這裡和我最近寫的另一個本地市政應用程序類似,該請求不需要任何身份驗證。毫無疑問這是令人震驚的,因為這會使一切變得更糟。以下是對上述請求的API響應:
{"BusinessWatches": [],
"Carrier": null,"City": null,"CityGroups": [],
"CityGroupPermissions": [],
"DepartmentCallDetails": [],
"EventSignUps": [],
"HomeWatches": [],
"Lockboxes": [],
"Lockboxes1": [],
"LockboxInsurances": [],
"Lookouts": [],
"LookoutInfoes": [],
"Maintenances": [],
"OpenRecords": [],
"PatrolRequests": [],
"Permissions": [],
"Photo": null,"Supports": [],
"SurveyResponses": [],
"UserNotificationSettings": [],
"UserLogins": [],
"UsersDevices": [],
"UserTransactions": [],
"UtilityBills": [],
"id": ***REMOVED***,"cityid": 17,"first": "Randy","mi": null,"last": "Westergren","phone": null,"cell": "***REMOVED***","carrierid": null,"email": "***REMOVED***","dob": null,"username": "rwestergren","password": "***REMOVED***","thumb": null,"created": "2017-05-21T16:57:00","active": 1,"admin": 0,"brainTreeCustomerId": null}
請注意,雖然我從上面的輸出中刪除了它,但用戶的密碼是以純文本形式返回的。顯然,這一點也非常的糟糕。
接下來,我決定反編譯應用程序,看看我是否可以找到更詳盡的API端點列表(以及是否需要任何身份驗證)。這是過程中主要的活動:
package com.mobilesciencetech.brightcity; import android.content.Intent;import android.os.Bundle;import org.apache.cordova.CordovaActivity; public class BrightCity extends CordovaActivity{ public BrightCity() { } public void onCreate(Bundle bundle) { super.onCreate(bundle); bundle = getIntent().getExtras(); if(bundle != null && bundle.getBoolean("cdvStartInBackground", false)) moveTaskToBack(true); loadUrl(launchUrl); }}
由於該應用程序使用Android Cordova,因此幾乎所有代碼都不在Java中。相反,當我轉移到 assets / www 目錄時,我發現了所有使應用程序運行的HTML / JS。
我打開了 editlockbox.js 文件,並查看了一下包含一些API請求的JavaScript:
$.getJSON(url + /api/LockboxInsurance/GetLockboxInsuranceCompanies , function(companiesJsonPayload) { $( #companyid ).append("Select Insurance Company"); $(companiesJsonPayload).each(function(i, item) { $( #companyid ).append( + item.name + ); }); $( #companyid ).append("Add New Company");}); var userid = window.localStorage.getItem("userid");$("#itemid").val(id);$("#userid").val(window.localStorage.getItem("userid")); $.getJSON(url + /api/lockbox/getlockbox/ + id + , function(result) { if (result == null) { $( #result ).append( Item does not exist ); } else { $("#userid").val(window.localStorage.getItem("userid")); $("#name").val(result.name); $.getJSON(url + /api/lockboxcategory/getlockboxcategories , function(categoriesJsonPayload) { $(categoriesJsonPayload).each(function(i, item) { if (item.id == result.categoryid) { $( #categoryid ).append( + item.name + ); } else { $( #categoryid ).append( + item.name + ); } }); }); $.getJSON(url + /api/LockboxInsurance/GetUserPolicies/ + userid + , function(companiesJsonPayload) { $( #insurance ).append("Select an insurance policy (choose one)"); $(companiesJsonPayload).each(function(i, item) { if (item.PolicyID == result.policyid) { $( #insurance ).append( + item.CompanyName + "-" + item.PolicyNumber + ); } else { $( #insurance ).append( + item.CompanyName + "-" + item.PolicyNumber + ); } //$( #insurance ).append( + item.CompanyName + "-" + item.PolicyNumber + ); }); $( #insurance ).append("Add new policy"); }); $("#description").val(result.description); $("#serial").val(result.serial); $("#make").val(result.make); $("#model").val(result.model); $("#caliber").val(result.caliber); $("#additionalinfo").val(result.additionalinfo); $("#room").val(result.roomlocation); $.getJSON(url + /api/lockbox/GetUserLocationRooms/ + userid + , function(companiesJsonPayload) { $( #room ).append("Select location of item (choose one)"); $(companiesJsonPayload).each(function(i, item) { if (item.Name == result.roomlocation) { $( #room ).append( + item.Name + ); } else { $( #room ).append( + item.Name + ); } }); $( #room ).append("Add new location"); }); //$("#insurance").val(result.policyid); $.getJSON(url + /api/photo/getphoto/ + id, function(photoresult) { if (photoresult.name != "") { var image = document.getElementById( thumb ); var imageData = iurl + /upload/lockbox/ + id + /thumb/ + photoresult.name; image.src = imageData; image.style.display = block ; //$( #showthumb ).html( ); } }); $.getJSON(url + /api/photo/getdoc/ + id, function(docresult) { if (docresult != null) { alert(docresult.name); var doc = document.getElementById( doc ); var docData = iurl + /upload/lockbox/ + id + /doc/ + docresult.name; doc.src = docData; doc.style.display = block ; //$( #showdoc ).html( + docresult.name + ); } }); //$.getJSON(url + /api/lockboxinsurance/GetInsuranceDetails/ + id, function (insresult) { // if (insresult != null) { // $("#policynumber").val(insresult.PolicyNumber); // $("#companyid").val(insresult.CompanyID); // } //}); }});
您可以看到,所有請求都以類似的方式進行,沒有任何身份驗證或會話狀態機制。接下來,我寫了一個快速腳本來搜索所有的JavaScript文件,以生成所有端點的列表:
/api/agency/
/api/agency/getagency/
/api/brightcityapp/
/api/brightcityapp/geteventdetails/
/api/brightcityapp/geteventsforagency/
/api/brightcityapp/geteventsforagencybydaterange/
/api/brightcityapp/geteventsforagencybyloadcount/
/api/brightcityapp/geteventsforagencynew/
/api/brightcityapp/geteventsignupdetails/
/api/brightcitypayments/getcitypaymentsbydaterangenew/
/api/brightcitypayments/getcitypaymentsbyloadcountnew/
/api/brightcitypayments/getcitypaymentsnew/
/api/brightcitypayments/getcityutilpaymentsnew/
/api/brightcitypayments/geteventpaymentdetails/
/api/brightcitypayments/geteventpaymentsbydaterangenew/
/api/brightcitypayments/geteventpaymentsbyloadcountnew/
/api/brightcitypayments/geteventpaymentsnew/
/api/brightcitypayments/geteventutilpaymentsnew/
/api/brightcitypayments/getpaymentdetails/
/api/business/getbusinessesbyagency/
/api/businesswatch/
/api/businesswatch/cancelbusinesswatch/
/api/businesswatch/getbusinesswatch/
/api/businesswatch/getbusinesswatchesforagencybydaterangenew/
/api/businesswatch/getbusinesswatchesforagencybyloadcountnew/
/api/businesswatch/getbusinesswatchesforagencynew/
/api/businesswatchstatus/
/api/businesswatchstatus/getbusinesswatchupdates/
/api/city/getcitiesbyagency/
/api/country/
/api/eyecolor/
/api/gender/
/api/glass/
/api/haircolor/
/api/height/
/api/homewatch/
/api/homewatch/cancel/
/api/homewatch/cancelhomewatch/
/api/homewatch/gethomewatch/
/api/homewatch/gethomewatchesforagencybydaterangenew/
/api/homewatch/gethomewatchesforagencybyloadcountnew/
/api/homewatch/gethomewatchesforagencynew/
/api/homewatchstatus//api/homewatchstatus/gethomewatchupdates/
/api/house/gethousesbyagency/
/api/lockbox/
/api/lockbox/deletelockbox/
/api/lockbox/getlockbox//api/lockbox/getlockboxesforagencybydaterangenew/
/api/lockbox/getlockboxesforagencybyloadcountnew/
/api/lockbox/getlockboxesforagencynew/
/api/lockboxcategory/
/api/lockboxcategory/getlockboxcategory/
/api/lookout/
/api/lookout/getlookout/
/api/lookout/getlookoutsforagencybydaterangenew/
/api/lookout/getlookoutsforagencybyloadcountnew/
/api/lookout/getlookoutsforagencynew/
/api/lookoutinfo/
/api/lookoutinfo/getlookoutinfoforlookout/
/api/maintenance/
/api/maintenance/cancel/
/api/maintenance/getmaintenance/
/api/maintenance/getmaintenanceforagencybydaterangenew/
/api/maintenance/getmaintenanceforagencybyloadcountnew/
/api/maintenance/getmaintenanceforagencynew/
/api/maintenance/getpublicmaintenanceforagencybydaterangenew/
/api/maintenance/getpublicmaintenanceforagencybyloadcountnew/
/api/maintenance/getpublicmaintenanceforagencynew/
/api/maintenancestatus/
/api/maintenancestatus/getmaintenancestatusforrequest/
/api/message/
/api/message/getmessage/
/api/message/getmessagesforofficerbydaterangenew/
/api/message/getmessagesforofficerbyloadcountnew/
/api/message/getmessagesforofficernew/
/api/newsfeed/getagencynewsfeedslist/
/api/officer/
/api/officer/getofficer/
/api/openrecord/acceptopenrecordrequest/
/api/openrecord/getopenrecord/
/api/openrecord/getopenrecordsforagency/
/api/openrecord/getopenrecordsforagencybydaterange/
/api/openrecord/getopenrecordsforagencybyloadcount/
/api/patrolrequest/acceptpatrolrequest/
/api/patrolrequest/getpatrolrequest/
/api/patrolrequest/getpatrolrequestsforagencybydaterangenew/
/api/patrolrequest/getpatrolrequestsforagencybyloadcountnew/
/api/patrolrequest/getpatrolrequestsforagencynew/
/api/photo/getdoc/
/api/photo/getmaintenancephoto//api/photo/getphoto/
/api/race/
/api/scamalert/
/api/scamalert/deletescamalert/
/api/scamalert/getscamalert/
/api/scamalert/getscamalertsforagencybydaterangenew/
/api/scamalert/getscamalertsforagencybyloadcountnew/
/api/scamalert/getscamalertsforagencynew/
/api/skintone/
/api/state/
/api/state/getstate/
/api/support//api/trafficalert/
/api/trafficalert/deletetrafficalert/
/api/trafficalert/gettrafficalert/
/api/trafficalert/gettrafficalertsforagencybydaterangenew/
/api/trafficalert/gettrafficalertsforagencybyloadcountnew/
/api/trafficalert/gettrafficalertsforagencynew/
/api/user/
/api/user/getuser/
/api/weatheralert/
/api/weatheralert/deleteweatheralert/
/api/weatheralert/getweatheralert/
/api/weatheralert/getweatheralertsforagencybydaterangenew/
/api/weatheralert/getweatheralertsforagencybyloadcountnew/
/api/weatheralert/getweatheralertsforagencynew/
/api/weight/
此外,我在我的帳戶下設置了一個「鎖箱」,並上傳了一些圖像來測試其功能。而對於我的目錄列表被允許查看這一點我沒有絲毫的意外,這意味著應用程序中所有上傳的文檔和圖像都可以被公開訪問。
風險
毫無疑問,使用此應用程序的公眾面臨的風險非常多並且十分嚴重。應用程序本身存儲的敏感信息,攻擊者可以輕易獲得,進而可以以其他用戶(或警察機構)的身份向系統內提交欺詐性的活動和事件。
沒有基本的認證要求,任何應用程序信息或操作/事件的完整性都不能保證是合法的。必須要清楚的一點是,這個應用程序中包含有用戶密碼(和其他個人信息),可疑人員的常駐報告,公民電子目錄,甚至本系統中存儲和使用的付款信息,而這些都是不安全的。
同樣需要注意的是,其對於用戶的影響可能遠遠超過Bright City系統。用戶在多個系統中使用相同的密碼是常見的,因此以明文形式顯示用戶密碼可能導致其他帳戶(例如電子郵件,銀行,社交媒體)的一一告破。
報告
目前我已經就如何以最有效的方式解決這些問題進行了多次的推敲理論。在我的其他博客文章中,我總是儘力與供應商合作,報告和修補已識別的漏洞 - 但這次有點不同。我積極的向市政府報告了上述問題,我們有一個簡短的通話來對此進行討論。儘管供應商最終將整個應用程序離線以實現身份驗證,但我報告的其他許多問題仍未解決(包括目錄列表問題)。
編者:在各類智慧城市、智慧社區等概念大舉進入我們的生活中時,我們仍然需要時時刻刻的去關注安全問題,智慧化智能化的設備、程序固然能夠使我們的生活更為便捷,但安全出了問題也可能讓我們的生活陷入一片黑暗。
點擊展開全文
※Fuzz 私有協議的經驗分享
※如何對有雙因子認證站點進行釣魚攻擊?
※BlackHat 2017熱點之DefPloreX-大規模網路犯罪取證的機器學習工具
TAG:嘶吼RoarTalk |
※ESPN官方對巴西隊世界盃前景的分析,你怎麼看?
※不清楚怎麼入手CPB?那就看這篇!CPB全系列詳盡分析購買手冊
※食品安全分析報告,看看你吃的的東西里有沒有這些……
※海賊王分析:為什麼只有羅傑到達了ONE PIECE,它的入口在哪裡
※OPPO R15樣張分析,這花、這夜、這妹紙你喜歡嗎?
※FDA不良事件報告數據分析:他汀腎臟安全性
※抖音APP產品分析報告
※刺激戰場:數據帝詳細分析SKS和SLR兩把武器,SKS竟無懸念完勝?
※這可能是關於EOS最全面的分析了
※客觀分析:iPhone X不如三星S9的五大原因,你們知道嗎?
※【市場分析】Micro LED還是OLED?AR-VR頭顯該怎麼選
※PATH—低耗的覆蓋全球+全ISP+全時段的監控節點和性能分析網路
※營銷案例數據分析:OPPO除了明星,還有什麼?
※TWICE最後一彈!簡單分析下MOMO、定延和志效!預祝回歸大發!
※CATIA和UG,兩款數控編程軟體的對比與分析,UG勝了?
※大數據分析直播答題APP會是「一陣風」嗎?
※劍橋分析前CEO:我們撒了謊 的確拿了FB用戶數據
※基於USP理論的「江小白」廣告分析
※誰能贏下NBA總冠軍?看完這分析茅塞頓開,網友熱評:正解!
※傳祺GS7和雪佛蘭探界者哪款好?來看看懂車的是怎麼分析的!