EagleEyes is a remote control and monitoring application developed by AVTECH, designed to connect with a wide range of AVTECH-branded CCTV devices. It allows users to access and manage their surveillance systems remotely via mobile devices.
This report presents the results of static and dynamic analysis that identified two major security issues in the application's HTTPS communication process:
Improper Certificate Validation (CWE-295), Improper Validation of Certificate with Host Mismatch (CWE-297), ****and Cleartext Transmission of Sensitive Information (CWE-319).
These vulnerabilities may expose users to serious risks such as man-in-the-middle (MitM) attacks and credential leakage.
push.lite.avtech.com
Category | Description |
---|---|
Improper Certificate Validation (CWE-295) | The application accepts certificates with mismatched CN/SAN through a custom HostnameVerifier , and uses a custom X509TrustManager that only checks certificate expiration without validating the trust chain. |
Improper Validation of Certificate with Host Mismatch (CWE-297) | Usage of SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER has been identified, disabling domain name validation. |
Cleartext Transmission of Sensitive Information (CWE-319) | HTTPS requests include sensitive data such as ID, password, and token in plaintext query parameters. |
GetHttpsResponse(String)
public static String GetHttpsResponse(String str) {
if (SDK_API_26) {
return GetHttpsUrlResponse(str);
}
try {
iResponseStatusCode = 0;
X509HostnameVerifier x509HostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
SchemeRegistry schemeRegistry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
X509HostnameVerifier x509HostnameVerifier2 = x509HostnameVerifier;
socketFactory.setHostnameVerifier(x509HostnameVerifier);
schemeRegistry.register(new Scheme("https", socketFactory, 443));
BasicHttpParams basicHttpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(basicHttpParams, 15000);
HttpConnectionParams.setSoTimeout(basicHttpParams, 15000);
defaultHttpClient.setParams(basicHttpParams);
HttpResponse execute = new DefaultHttpClient(new SingleClientConnManager(defaultHttpClient.getParams(), schemeRegistry), defaultHttpClient.getParams()).execute(new HttpPost(str));
int statusCode = execute.getStatusLine().getStatusCode();
iResponseStatusCode = statusCode;
if (statusCode == 200) {
return EntityUtils.toString(execute.getEntity());
}
return null;
} catch (RuntimeException | Exception unused) {
return null;
} catch (SocketTimeoutException unused2) {
iResponseStatusCode = 408;
return null;
} catch (ConnectTimeoutException unused3) {
iResponseStatusCode = 408;
return null;
}
}
GetHttpsResponse(String, int)
public static String GetHttpsResponse(String str, int i) {
if (SDK_API_26) {
try {
try {
iResponseStatusCode = 0;
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) new URL(str).openConnection();
httpsURLConnection.setConnectTimeout(i);
httpsURLConnection.setReadTimeout(i);
httpsURLConnection.setRequestMethod(HttpGet.METHOD_NAME);
httpsURLConnection.setRequestProperty("Connection", "Keep-Alive");
httpsURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
httpsURLConnection.setRequestProperty(HttpHeaders.ACCEPT, "*/*");
httpsURLConnection.setDoInput(true);
int responseCode = httpsURLConnection.getResponseCode();
iResponseStatusCode = responseCode;
if (responseCode == 200) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
while (true) {
try {
String readLine = bufferedReader.readLine();
if (readLine == null) {
break;
}
sb.append(readLine + "\\n");
} catch (Exception unused) {
}
}
bufferedReader.close();
return sb.toString();
}
return httpsURLConnection.getResponseCode() + "\\n" + httpsURLConnection.getResponseMessage();
} catch (SocketTimeoutException unused2) {
iResponseStatusCode = 408;
return null;
} catch (ConnectTimeoutException unused3) {
iResponseStatusCode = 408;
return null;
}
} catch (RuntimeException | Exception unused4) {
return null;
}
}
try {
iResponseStatusCode = 0;
X509HostnameVerifier x509HostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
SchemeRegistry schemeRegistry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
X509HostnameVerifier x509HostnameVerifier2 = x509HostnameVerifier;
socketFactory.setHostnameVerifier(x509HostnameVerifier);
schemeRegistry.register(new Scheme("https", socketFactory, 443));
BasicHttpParams basicHttpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(basicHttpParams, i);
HttpConnectionParams.setSoTimeout(basicHttpParams, i);
defaultHttpClient.setParams(basicHttpParams);
HttpResponse execute = new DefaultHttpClient(new SingleClientConnManager(defaultHttpClient.getParams(), schemeRegistry), defaultHttpClient.getParams()).execute(new HttpPost(str));
int statusCode = execute.getStatusLine().getStatusCode();
iResponseStatusCode = statusCode;
if (statusCode == 200) {
return EntityUtils.toString(execute.getEntity());
}
} catch (RuntimeException | Exception unused5) {
} catch (SocketTimeoutException unused6) {
iResponseStatusCode = 408;
} catch (ConnectTimeoutException unused7) {
iResponseStatusCode = 408;
}
return null;
}