본문 바로가기

Security Study/Android

[InsecureBankv2] 로컬 암호화 이슈

취약점 개요

취약점 설명

중요 정보가 단말기에 저장될 때 암호화되어 있지 않거나 취약한 암호화 체계 사용, 또는 복호화 힌트가 소스코드 내 노출되어 있는 취약점을 말한다.

발생 위치

/data/data/com.android.insecurebankv2/shared_prefs/

보안 위협

암호화하지 않으면 공격자에게 노출될 가능성이 높아진다.

 

취약점 진단 과정

Step 1) 인시큐어뱅크 애플리케이션의 데이터가 저장되는 곳으로 이동

com.android.insecurebankv2_preferences.xml, mySharedPreferences.xml 파일이 존재하는 것을 확인할 수 있다.

cd /data/data/com.android.insecurebankv2/shared_prefs

Step 2) 파일 내용 출력

com.android.insecurebankv2_preferences.xml

서버의 IP와 포트 정보를 확인할 수 있다.

mySharedPreferences.xml

암호화된 사용자, 패스워드 변수인 EncryptedUsername, superSecurePassword를 확인할 수 있다.

Step 3) DoLogin.java 확인

base64로 인코딩하여 username을 저장하고, CryptoClass 클래스를 통해 password를 aes 암호화하여 저장하는 것을 알 수 있다. base64 형식의 aes 암호화 알고리즘은 key 값을 알아내면 쉽게 복호화할 수 있다.

private void saveCreds(String username, String password) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
    // TODO Auto-generated method stub
    SharedPreferences mySharedPreferences;
    mySharedPreferences = getSharedPreferences(MYPREFS, Activity.MODE_PRIVATE);
    SharedPreferences.Editor editor = mySharedPreferences.edit();
    rememberme_username = username;
    rememberme_password = password;
    String base64Username = new String(Base64.encodeToString(rememberme_username.getBytes(), 4));
    CryptoClass crypt = new CryptoClass();;
    superSecurePassword = crypt.aesEncryptedString(rememberme_password);
    editor.putString("EncryptedUsername", base64Username);
    editor.putString("superSecurePassword", superSecurePassword);
    editor.commit();
}

Step 4) CryptoClass.java 확인

변수 key에 저장되어 있는 aes key 값을 확인할 수 있다. aesEncryptedString 함수는 aes256encrypt 함수를 호출하여 key를 이용하여 패스워드를 aes 암호화한 후 cipherText에 저장하여 반환한다. 반환된 값은 mySharedPreferences.xml 파일에 저장된다.

String key = "This is the super secret key 123";

public static byte[] aes256encrypt(byte[] ivBytes, byte[] keyBytes, byte[] textBytes)
    throws UnsupportedEncodingException,
    NoSuchAlgorithmException,
    NoSuchPaddingException,
    InvalidKeyException,
    InvalidAlgorithmParameterException,
    IllegalBlockSizeException,
    BadPaddingException {

    AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
    SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");
    Cipher cipher = null;
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
    return cipher.doFinal(textBytes);
}

public String aesEncryptedString(String theString) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
    // TODO Auto-generated method stub
    byte[] keyBytes = key.getBytes("UTF-8");
    plainText = theString;
    cipherData = CryptoClass.aes256encrypt(ivBytes, keyBytes, plainText.getBytes("UTF-8"));
    cipherText = Base64.encodeToString(cipherData, Base64.DEFAULT);
    return cipherText;
}

Step 5) 복호화 진행

암호화된 값 key 값을 알고 있으므로 aes 복호화를 진행할 수 있다. https://xy-bios.xyz/enc/encViewMain.do에서 username과 password 복호화를 진행하였다.

 

대응 방안

  • 암복호화에 사용되는 키를 별도의 서버를 두어 안전하게 저장한다.
  • 소스 코드를 난독화 및 바이너리 무결성 검증을 한다.
반응형