MASTG-TECH-0100: Logging Sensitive Data from Network Traffic
mitmproxy can be used to intercept network traffic from Android apps. This technique is useful for identifying sensitive data that is sent over the network, as well as for identifying potential security vulnerabilities.
Once mitmproxy is installed and your device is configured to use it, you can create a Python script to filter the traffic and extract the sensitive data. For example, the following script will extract all the data sent in the requests and responses only if the data is considered sensitive. For this example, we consider sensitive data to be any data that contains the strings "dummyPassword" or "sampleUser", so we include them in theSENSITIVE_STRINGS list.
# mitm_sensitive_logger.pyfrommitmproxyimporthttp# This data would come from another file and should be defined after identifying the data that is considered sensitive for this application.# For example, by using the Google Play Store Data Safety section.SENSITIVE_DATA={"precise_location_latitude":"37.7749","precise_location_longitude":"-122.4194","name":"John Doe","email_address":"[email protected]","phone_number":"+11234567890","credit_card_number":"1234 5678 9012 3456"}SENSITIVE_STRINGS=SENSITIVE_DATA.values()defcontains_sensitive_data(string):returnany(sensitiveinstringforsensitiveinSENSITIVE_STRINGS)defprocess_flow(flow):url=flow.request.pretty_urlrequest_headers=flow.request.headersrequest_body=flow.request.textresponse_headers=flow.response.headersifflow.responseelse"No response"response_body=flow.response.textifflow.responseelse"No response"if(contains_sensitive_data(url)orcontains_sensitive_data(request_body)orcontains_sensitive_data(response_body)):withopen("sensitive_data.log","a")asfile:ifflow.response:file.write(f"RESPONSE URL:{url}\n")file.write(f"Response Headers:{response_headers}\n")file.write(f"Response Body:{response_body}\n\n")else:file.write(f"REQUEST URL:{url}\n")file.write(f"Request Headers:{request_headers}\n")file.write(f"Request Body:{request_body}\n\n")defrequest(flow:http.HTTPFlow):process_flow(flow)defresponse(flow:http.HTTPFlow):process_flow(flow)Now you can run mitmproxy with the script:
mitmdump-smitm_sensitive_logger.pyOur example app has this code:
funtestPostRequest(){valthread=Thread{try{valurl=URL("https://httpbin.org/post")valhttpURLConnection=url.openConnection()asHttpURLConnectionhttpURLConnection.requestMethod="POST"httpURLConnection.doOutput=truehttpURLConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded")valuser="sampleUser"valpassword="dummyPassword"valpostData="username=$user&password=$password"valoutputStream=BufferedOutputStream(httpURLConnection.outputStream)valbufferedWriter=BufferedWriter(OutputStreamWriter(outputStream,"UTF-8"))bufferedWriter.write(postData)bufferedWriter.flush()bufferedWriter.close()outputStream.close()valresponseCode=httpURLConnection.responseCodeif(responseCode==HttpURLConnection.HTTP_OK){Log.d("HTTP_SUCCESS","Successfully authenticated.")}else{Log.e("HTTP_ERROR","Failed to authenticate. Response code: $responseCode")}}catch(e:Exception){e.printStackTrace()}}thread.start()}The app sends a POST request tohttps://httpbin.org/post with the bodyusername=sampleUser&password=dummyPassword.httpbin.org is a website that returns the request data in the response body, so we can see the data that was sent in the request.
Run the app and use it as you normally would. The script will log any sensitive data that is sent over the network to thesensitive_data.log file.
Example console output:
[10:07:59.348]Loadingscriptmitm_sensitive_logger.py[10:07:59.351]HTTP(S)proxylisteningat*:8080.[10:08:08.188][127.0.0.1:64701]serverconnecthttpbin.org:443(52.206.94.89:443)[10:08:08.192][127.0.0.1:64709]serverconnectmas.owasp.org:443(104.22.27.77:443)[10:08:08.245][127.0.0.1:64709]ClientTLShandshakefailed.Theclientdoesnottrusttheproxy's certificate for mas.owasp.org (OpenSSL Error([('SSLroutines', '', 'ssl/tlsalertcertificateunknown')]))[10:08:08.246][127.0.0.1:64709]clientdisconnect[10:08:08.246][127.0.0.1:64709]serverdisconnectmas.owasp.org:443(104.22.27.77:443)127.0.0.1:64701:POSThttps://httpbin.org/post<<200OK548bExamplesensitive_data.log output:
REQUESTURL:https://httpbin.org/postRequestHeaders:Headers[(b'Content-Type',b'application/x-www-form-urlencoded'),(b'User-Agent',b'Dalvik/2.1.0 (Linux; U; Android 13; sdk_gphone64_arm64 Build/TE1A.220922.021)'),(b'Host',b'httpbin.org'),(b'Connection',b'Keep-Alive'),(b'Accept-Encoding',b'gzip'),(b'Content-Length',b'42')]RequestBody:username=sampleUser&password=dummyPasswordRESPONSEURL:https://httpbin.org/postResponseHeaders:Headers[(b'Date',b'Tue, 16 Jan 2024 09:08:08 GMT'),(b'Content-Type',b'application/json'),(b'Content-Length',b'548'),(b'Connection',b'keep-alive'),(b'Server',b'gunicorn/19.9.0'),(b'Access-Control-Allow-Origin',b'*'),(b'Access-Control-Allow-Credentials',b'true')]ResponseBody:{"args":{},"data":"","files":{},"form":{"password":"dummyPassword","username":"sampleUser"},"headers":{"Accept-Encoding":"gzip","Content-Length":"42","Content-Type":"application/x-www-form-urlencoded","Host":"httpbin.org","User-Agent":"Dalvik/2.1.0 (Linux; U; Android 13; sdk_gphone64_arm64 Build/TE1A.220922.021)","X-Amzn-Trace-Id":"Root=1-65a64778-78495e9f5d742c9b0c7a75d8"},"json":null,"origin":"148.141.65.87","url":"https://httpbin.org/post"}