Brute forcing Passwords in Android

Jyotishgher Astrology
By -
0

 Brute forcing Passwords in Android

A brute force attack is a hacking method that uses trial and error to crack passwords, login credentials, and encryption keys. It is a simple yet reliable tactic for gaining unauthorized access to individual accounts and organizations’ systems and networks. The hacker tries multiple usernames and passwords, often using a computer to test a wide range of combinations, until they find the correct login information.

Brute forcing Passwords in Android

The name "brute force" comes from attackers using excessively forceful attempts to gain access to user accounts. Despite being an old cyberattack method, brute force attacks are tried and tested and remain a popular tactic with hackers.

Let's understand in the Android App

To prevent brute force attacks without deleting anything in the given code, you can implement several key strategies such as limiting login attempts, introducing exponential backoff, logging suspicious activity, and using CAPTCHAs or additional multi-factor authentication mechanisms. Below are the specific steps applied to your existing code:

  1. Rate Limiting & Account Lockout: Limit the number of failed login attempts to a certain threshold and lock the account for a period of time after the limit is reached. You can store the number of failed attempts in SharedPreferences or a server-side database.

  2. Add a CAPTCHA: After a certain number of failed login attempts, display a CAPTCHA for human verification before proceeding further.

  3. Delay Mechanism (Exponential Backoff): Add a delay (increasing over time) after each failed login attempt to slow down brute-force attacks.

Supppose you are making a login dashboard with username and password

Step 1: Define Shared Preferences to Track Failed Attempts


SharedPreferences loginPrefs = getSharedPreferences("LoginPrefs", 0); int failedAttempts = loginPrefs.getInt("failed_attempts", 0); long lockTime = loginPrefs.getLong("lock_time", 0);

Step 2: Check Failed Attempts and Lock Time

Modify the start of the checkLogin() method to check if the account is locked due to too many failed attempts.


// Check if the account is locked long currentTime = System.currentTimeMillis(); if (failedAttempts >= 3 && currentTime < lockTime) { long remainingTime = (lockTime - currentTime) / 1000; Toast.makeText(Login.this, "Account locked. Try again after " + remainingTime + " seconds.", Toast.LENGTH_LONG).show(); return; }

Step 3: Apply Exponential Backoff

After multiple failed attempts, lock the account for a specific duration that increases after each failed attempt.


// If the login is successful, reset failed attempts if (success == 1) { SharedPreferences.Editor editor = loginPrefs.edit(); editor.putInt("failed_attempts", 0); editor.apply(); } else { failedAttempts++; SharedPreferences.Editor editor = loginPrefs.edit(); editor.putInt("failed_attempts", failedAttempts); // Apply exponential backoff: 10 seconds * (failedAttempts - 2)^2 if (failedAttempts >= 3) { long lockDuration = 10000 * (failedAttempts - 2) * (failedAttempts - 2); editor.putLong("lock_time", System.currentTimeMillis() + lockDuration); Toast.makeText(Login.this, "Too many failed attempts. Account locked for " + lockDuration / 1000 + " seconds.", Toast.LENGTH_LONG).show(); } editor.apply(); }

Step 4: Introduce CAPTCHA after multiple failed attempts

If you want to add a CAPTCHA after, say, 3 failed attempts:


if (failedAttempts >= 3) { // Show CAPTCHA here (you can use Google's reCAPTCHA or other solutions) validateCaptcha(); // Call your captcha validation method }

Step 5: Add CAPTCHA Validation (Placeholder)

You can add a placeholder for the CAPTCHA validation function:


private void validateCaptcha() { // Implement CAPTCHA validation logic here // You can integrate Google reCAPTCHA for this purpose }

Step 6: Reset Failed Attempts After Successful Login

Once the login is successful, reset the failed_attempts counter:

SharedPreferences.Editor editor = loginPrefs.edit();
editor.putInt("failed_attempts", 0); editor.apply();

Step 7: Logging Suspicious Activity

Log failed login attempts on the server side or locally to analyze patterns that may indicate brute force attempts.

By following this approach, you can prevent brute-force attacks while keeping all your original logic intact.

Have an Example here-I am here writing the logic only

public class Login extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.login1);
login = (Button) findViewById(R.id.login); // continue on hit
loginPrefsBF = getSharedPreferences("loginPrefsBruteforce", MODE_PRIVATE);
long lockEndTime = loginPrefsBF.getLong("lock_time_count", 0);
long currentTime = System.currentTimeMillis();
Log.d("CHECKIKLOCKING", "onCreate: lockEndTime=" + lockEndTime + " currentTime=" + currentTime);


if (lockEndTime > currentTime) {
long remainingLockTime = lockEndTime - currentTime;
Log.d("remainingLockTime", "Remaining lock time: " + remainingLockTime);

if (remainingLockTime > 0) {

lockLoginButton(remainingLockTime);
} else {
Log.e("CountDownTimer", "Remaining lock time is negative or zero.");
}

}
private void checkLogin() {
EMPNO = mobile_number.getText().toString();
CODE = password.getText().toString();
SharedPreferences.Editor editor = loginPrefsBF.edit();
editor.putInt("failed_attempts", 0); // Reset failed attempts
editor.apply();
StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.forget_password,
        new Response.Listener<String>() {
@Override
public void onResponse(String response) {
loading.dismiss();
Log.d("forget_response:", "onResponse: " + response);
try {
//Creating the json object from the response
JSONObject jsonResponse = new JSONObject(response);
int msg = jsonResponse.getInt("success");
String suucess= jsonResponse.getString("1");
if(suucess)
{
write your code to call the intent
} else {
Log.d("FAILURE", "onResponse: "+success);
// Login failure (Invalid credentials)
Log.d("Login Failure", "Invalid credentials or other failure."); // Log this case
failedAttempts++;


// Apply exponential backoff after 3 failed attempts
if (failedAttempts >= 3) {
long lockDuration = 10000 * (failedAttempts - 2) * (failedAttempts - 2); // 10s * (failedAttempts - 2)^2
long lockEndTime = System.currentTimeMillis() + lockDuration;

SharedPreferences.Editor editor = loginPrefsBF.edit();
editor.putInt("failed_attempts", failedAttempts);
editor.putLong("lock_time_count", lockEndTime);
boolean isSaved = editor.commit(); // Use commit for synchronous saving
Log.d("SaveStatus", "Saved lockEndTime: " + lockEndTime + ", Status: " + isSaved);

// Disable the login button
lockLoginButton(lockDuration);
Toast.makeText(Login.this, "Too many failed attempts. Account locked for " + lockDuration / 1000 + " seconds.", Toast.LENGTH_LONG).show();
}

if (failedAttempts >= 3) {
// Show CAPTCHA here
validateCaptcha();
} else {
Toast.makeText(Login.this, "Invalid Credentials", Toast.LENGTH_LONG).show();
}
}
}
}
private void lockLoginButton(long lockDuration) {
login.setEnabled(false); // Disable the button
login.setTextColor(Color.RED);

// Using CountDownTimer instead of Handler for better performance and handling long delays
new CountDownTimer(lockDuration, 1000) {
public void onTick(long millisUntilFinished) {
// You can update the UI every tick if needed
login.setText("Locked for " + millisUntilFinished / 1000 + "s");
}

public void onFinish() {
login.setEnabled(true); // Enable the button after lock duration
login.setText("Login"); // Reset text
login.setTextColor(Color.YELLOW);
Toast.makeText(Login.this, "You can now attempt to login again.", Toast.LENGTH_SHORT).show();
}
}.start();
}
}

Tags:

Post a Comment

0Comments

Post a Comment (0)