Insecure Data Storage - Part 2
Source Code
package jakhar.aseem.diva;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
/* loaded from: classes.dex */
public class InsecureDataStorage2Activity extends AppCompatActivity {
private SQLiteDatabase mDB;
@Override // android.support.v7.app.AppCompatActivity, android.support.v4.app.FragmentActivity, android.support.v4.app.BaseFragmentActivityDonut, android.app.Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
this.mDB = openOrCreateDatabase("ids2", 0, null);
this.mDB.execSQL("CREATE TABLE IF NOT EXISTS myuser(user VARCHAR, password VARCHAR);");
} catch (Exception e) {
Log.d("Diva", "Error occurred while creating database: " + e.getMessage());
}
setContentView(R.layout.activity_insecure_data_storage2);
}
public void saveCredentials(View view) {
EditText usr = (EditText) findViewById(R.id.ids2Usr);
EditText pwd = (EditText) findViewById(R.id.ids2Pwd);
try {
this.mDB.execSQL("INSERT INTO myuser VALUES ('" + usr.getText().toString() + "', '" + pwd.getText().toString() + "');");
this.mDB.close();
} catch (Exception e) {
Log.d("Diva", "Error occurred while inserting into database: " + e.getMessage());
}
Toast.makeText(this, "3rd party credentials saved successfully!", 0).show();
}
}
Analysis
해당 코드에서는 우선 usr와 pwd를 저장할 DB를 Create한다. DB의 이름은 “ids2”로 생성이 된다.
EditText에 usr와 pwd가 입력되면, 해당 값들은 SAVE 버튼이 눌리게 되면 db에 저장이 되고 성공 메세지가 Toast로 화면에 출력된다.
우선 다음과 같이 diva 앱 내의 databases 폴더에 ids2라는 파일이 있음을 볼 수 있다.

ids2 폴더는 sqlite 포맷으로 저장이 되어있기 때문에 파일내용을 조회하기 위해서는 sqlite3 ids2 명령어를 통해 확인이 가능하다. 하지만 adb shell내에서 확인이 불가능하기 때문에, ids2 파일을 로컬 머신의 파일로 직접 작성하는 방법으로 확인을 해볼 수 있다. (여러 방법이 있는 것 같지만,, 나는 아래와 같은 명령어를 통한 방법으로 가능했다)
adb exec-out run-as jakhar.aseem.diva cat /data/user/0/jakhar.aseem.diva/databases/ids2 > ./ids2
내용을 읽어서 로컬에서 다시 파일을 작성해서 확인한 ids2 파일의 내용은 다음과 같다.

사실 여기서도 입력했던 usr와 pwd의 값인 test test를 확인할 수 있지만, sqlite3 ids2 명령어를 통해 쿼리문을 통해서 해당 값들을 확인해 볼 수 있다.

Insecure Data Storage - Part3
Source Code
package jakhar.aseem.diva;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import java.io.File;
import java.io.FileWriter;
/* loaded from: classes.dex */
public class InsecureDataStorage3Activity extends AppCompatActivity {
/* JADX INFO: Access modifiers changed from: protected */
@Override // android.support.v7.app.AppCompatActivity, android.support.v4.app.FragmentActivity, android.support.v4.app.BaseFragmentActivityDonut, android.app.Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_insecure_data_storage3);
}
public void saveCredentials(View view) {
EditText usr = (EditText) findViewById(R.id.ids3Usr);
EditText pwd = (EditText) findViewById(R.id.ids3Pwd);
File ddir = new File(getApplicationInfo().dataDir);
try {
File uinfo = File.createTempFile("uinfo", "tmp", ddir);
uinfo.setReadable(true);
uinfo.setWritable(true);
FileWriter fw = new FileWriter(uinfo);
fw.write(usr.getText().toString() + ":" + pwd.getText().toString() + "\n");
fw.close();
Toast.makeText(this, "3rd party credentials saved successfully!", 0).show();
} catch (Exception e) {
Toast.makeText(this, "File error occurred", 0).show();
Log.d("Diva", "File error: " + e.getMessage());
}
}
}
Analysis
해당 코드를 분석해보면, 이전 3,4번 문제와는 다르게 new File()을 통해 새로운 임시 파일을 만들고, uinfo와 tmp라는 스트링을 붙인 이름의 파일을 생성해 저장하는 것을 확인할 수 있다. EditText 를 통해 usr, pwd를 입력 받고 해당 값들을 uinfo 변수명의 파일에 write를 할 때에는 “usr : pwd” 포맷으로 작성이 되고 SAVE 버튼을 누르면 실제로 앱 디렉토리에 해당 파일이 생성되는 되는 로직으로 짜여져 있다.
실제로 usr와 pwd 부분에 test, test를 입력하게 되면


와 같이 앱 디렉토리 내에 uinfo~tmp 파일이 생성되게 되고, cat 명령어를 통해 확인하면 해당 값들을 확인할 수 있다. 3,4번 문제들과 다르게 앱 디렉토리 내에 파일을 생성해 그 파일 내에 정보들을 저장한 것이 취약점으로 보인다.
Insecure Data Storage - Part 4
Source Code
package jakhar.aseem.diva;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import java.io.File;
import java.io.FileWriter;
/* loaded from: classes.dex */
public class InsecureDataStorage4Activity extends AppCompatActivity {
/* JADX INFO: Access modifiers changed from: protected */
@Override // android.support.v7.app.AppCompatActivity, android.support.v4.app.FragmentActivity, android.support.v4.app.BaseFragmentActivityDonut, android.app.Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_insecure_data_storage4);
}
public void saveCredentials(View view) {
EditText usr = (EditText) findViewById(R.id.ids4Usr);
EditText pwd = (EditText) findViewById(R.id.ids4Pwd);
File sdir = Environment.getExternalStorageDirectory();
try {
File uinfo = new File(sdir.getAbsolutePath() + "/.uinfo.txt");
uinfo.setReadable(true);
uinfo.setWritable(true);
FileWriter fw = new FileWriter(uinfo);
fw.write(usr.getText().toString() + ":" + pwd.getText().toString() + "\n");
fw.close();
Toast.makeText(this, "3rd party credentials saved successfully!", 0).show();
} catch (Exception e) {
Toast.makeText(this, "File error occurred", 0).show();
Log.d("Diva", "File error: " + e.getMessage());
}
}
}
Analysis
해당 코드를 분석해보면, 이번에는 앱 내에 접근하는 것이 아니라, getExternealStorageDirectory() 메소드를 보고 내부 저장소가 아닌 외부 저장소에 usr, pwd 값이 저장된다는 것을 알 수 있었다.
내부 저장소와 외부 저장소?
내부 저장소는 설치된 앱마다 가지고 있는 영역으로 다른 앱이 침범할 수 없지만, 반면에 외부 저장소는 다른 말로 SD카드라고 부르며 모든 앱이 접근할 수 있다. 만약 외부 저장소에 중요한 정보를 저장하도록 구현되어 있다면 모든 앱이 접근 가능하여 민감한 정보가 노출될 수 있다. 경로 - /sdcard
아래 그림과 같이 앱 내부 저장소로 접근하는 것이 아닌 sdcard 경로에서 숨겨진 파일들까지 볼 수 있는 ls -a 명령어를 통해, “.uinfo.txt” 파일을 확인할 수 있었고, test:test로 저장되어 있는 usr, pwd 값들을 확인할 수 있었다.


사실 문제를 풀던 중 아래와 같은 문제를 직면했다.

이 문제는, credential를 저장하려고 할 때 diva 앱에서 sdcard에 파일을 만들 수 있는 권한이 없기 때문에 발생한다. 이 문제를 해결하기 위해서는 다음 과정을 거친다.
1. 휴대폰 환경 설정 접속 후 Apps & notifications 접속

2. Diva 클릭

3. Permissions 클릭

4. Files and media 클릭

5. Allow management of all files로 변경 (해당 오류가 있었다면, Deny가 되어 있었을 것이다.)

6. 다시 시도 후 해결 확인

'Hacker > APP' 카테고리의 다른 글
| Insecurebankv2 - Insecure Content Provider access (취약한 컨텐트 프로바이더 접근) (0) | 2024.08.21 |
|---|---|
| drozer 환경 구축 (0) | 2024.08.20 |
| Insecurebankv2 - Local Encryption issues, Hardcoded secret, Weak Cryptography implementation (0) | 2024.08.12 |
| InsecureBankv2 환경 구축 (0) | 2024.08.09 |
| Diva 풀이 1~3번 (Insecure logging ~ Insecure Data Storage - Part 1) (0) | 2024.08.08 |