L6: Android Mobile Pentest 101¤
Bài 8 & 9: Công cụ hỗ trợ & Thực chiến¤
Bài 8 – Các công cụ hỗ trợ Pentest Android¤
Tổng quan¤
Trong quá trình kiểm thử bảo mật ứng dụng Android, không phải lúc nào cũng có thể reverse engineer hay patch thủ công thành công. Thay vì bỏ cuộc, ta có thể tận dụng các công cụ tự động hóa để bypass ba cơ chế bảo vệ phổ biến:
- Root Detection
- Emulator Detection
- SSL Pinning
1. Bypass Root Detection¤
Khái niệm¤
Root Detection là kỹ thuật mà ứng dụng dùng để phát hiện thiết bị đã bị root, nhằm từ chối hoạt động trên môi trường đó. Các dấu hiệu thường bị kiểm tra:
- Sự tồn tại của binary
su - Các APK như SuperSU, Superuser
- Process đang chạy bởi root
- Kết nối ADB
Công cụ: RootCloak (Xposed Module)¤
RootCloak là một module của Xposed Framework, hoạt động bằng cách hook vào các API của Android để che giấu các dấu hiệu root khỏi ứng dụng mục tiêu.
Xposed Framework là gì?
Xposed Framework là một framework cho phép thay đổi hành vi của hệ thống và ứng dụng Android ở runtime mà không cần sửa đổi APK. Các module Xposed có thể hook vào bất kỳ method Java nào trong hệ thống. Tham khảo: https://github.com/rovo89/Xposed
Cài đặt¤
Bước 1: Cài Xposed Framework bằng script MobSF:
python3 mobsfy.py -i 192.168.56.101:5555 -t 1
# -t 1: thiết bị ảo (emulator)
# -t 2: thiết bị thật
Lưu ý với Genymotion
Genymotion sử dụng ADB riêng, nên cần thay thế đường dẫn adb mặc định trong script bằng adb của Genymotion trước khi chạy lệnh.
Bước 2: Sau khi script chạy, mở Xposed Installer trên điện thoại ảo, nhấn INSTALL/UPDATE để hoàn tất cài đặt framework.
Bước 3: Vào tab Modules, tích chọn RootCloak, sau đó reboot.
Sử dụng¤
- Mở app RootCloak
- Chọn Add/Remove Apps
- Nhấn dấu +
- Chọn ứng dụng cần ẩn root
Từ lúc này, ứng dụng đó sẽ không nhận thấy thiết bị đang bị root.
2. Bypass Emulator Detection¤
Khái niệm¤
Một số ứng dụng kiểm tra xem mình có đang chạy trên máy ảo không (thông qua các giá trị phần cứng, build properties...) để ngăn chặn việc phân tích.
Công cụ: Android Blue Pill (Xposed Module)¤
Tương tự RootCloak, chỉ cần:
- Vào Xposed > Modules
- Tích chọn Android Blue Pill
- Reboot
Thực tế
Công cụ này không phải lúc nào cũng hiệu quả vì nhiều ứng dụng dùng nhiều heuristic phức tạp để detect emulator. Đây chỉ là phương án thử trước.
3. Bypass SSL Pinning¤
Khái niệm SSL Pinning¤
SSL Pinning là kỹ thuật bảo mật mà ứng dụng "ghim" một certificate cụ thể (hoặc public key) vào code, thay vì tin tưởng toàn bộ CA chain của hệ điều hành. Điều này ngăn chặn các công cụ như Burp Suite từ việc intercept HTTPS traffic.
sequenceDiagram
participant App
participant Device CA Store
participant Server
App->>Server: Kết nối HTTPS
Server-->>App: Trả về Certificate
App->>App: So sánh với cert đã ghim trong code
alt Khớp
App->>Server: Tiếp tục giao tiếp
else Không khớp (vd: cert của Burp)
App->>App: Từ chối kết nối
end
Công cụ 1: JustTrustMe (Xposed Module)¤
Hoạt động bằng cách hook vào các class xử lý SSL/TLS của Android (TrustManager, X509TrustManager...) và khiến chúng chấp nhận mọi certificate.
Cách dùng: Tích chọn JustTrustMe trong Xposed Modules, reboot là xong.
Warning
JustTrustMe khá cũ và không hoạt động với tất cả các ứng dụng, đặc biệt là những app dùng certificate pinning tùy chỉnh hoặc native code.
Công cụ 2: Objection (Frida-based)¤
Objection là một runtime mobile exploration toolkit được xây dựng trên nền Frida. Đây là lựa chọn mạnh mẽ và linh hoạt hơn JustTrustMe.
Frida là gì?
Frida là một dynamic instrumentation toolkit cho phép inject JavaScript vào các process native trên Android, iOS, Windows, Linux... Objection là wrapper cấp cao giúp dùng Frida dễ hơn mà không cần tự viết script. Tham khảo: https://frida.re và https://github.com/sensepost/objection
Cài đặt¤
Cơ chế hoạt động¤
Objection cần được inject vào APK thông qua patch APK. Quá trình này:
- Giải nén APK
- Inject
loadLibrarycall vàosmalicủa Activity khởi động - Đưa Frida Gadget (
.sofile) vào thư mụclib/ - Build lại và ký APK
flowchart TD
A[APK gốc] --> B[Giải nén APK]
B --> C[Tìm smali của LoginActivity]
C --> D[Inject loadLibrary Frida Gadget]
D --> E[Thêm frida-gadget.so vào lib/]
E --> F[Build lại APK]
F --> G[Ký APK]
G --> H[APK đã patch]
Patch và cài APK¤
# Patch APK
objection patchapk --source InsecureBankv2.apk
# Output: InsecureBankv2.objection.apk
# Cài APK đã patch lên thiết bị
adb install InsecureBankv2.objection.apk
Kết nối và khám phá¤
Sau khi mở app đã patch trên điện thoại (app sẽ "đứng" chờ Frida kết nối):
Khi vào được Objection shell, có thể thực hiện nhiều thứ:
Kiến thức mở rộng
Objection còn hỗ trợ:
android keystore list– liệt kê keystore entriesandroid root disable/android root simulate– bypass root detection qua Fridamemory search,memory dump– thao tác với bộ nhớ runtimeios sslpinning disable– tương tự cho iOS
Tài liệu đầy đủ: https://github.com/sensepost/objection/wiki
Bài 9 – Thực chiến: Khai thác ứng dụng Fitness¤
Bối cảnh¤
Công ty tổ chức cuộc thi "chạy bộ" dựa trên một ứng dụng di động bên thứ ba (tên app được ẩn đi, gọi tắt là P*). Phần thưởng: 700k/tuần, 2 triệu/tháng. Tác giả quyết định thử nghiệm xem app có thể bị khai thác không, sau đó đã *report lỗ hổng** và xin phép trước khi công bố.
- App: P** v5.9.2
- Mục tiêu: Giả mạo số bước chân để đứng đầu bảng xếp hạng
Dynamic Analysis (Phân tích động)¤
Bước 1: Intercept traffic với Burp Suite¤
Setup Burp Suite làm proxy, mở app và sử dụng các tính năng. Phát hiện chỉ có tính năng Backup/Restore là tạo ra HTTP request thực sự.
Bước 2: Phân tích request Backup¤
Request được gửi lên AWS S3 dưới dạng PUT với body là một file nén:
PUT /c5d143dfe9663c751c1627745e56818b_1540198509.zip HTTP/1.1
Host: pacer-data-backup.s3.amazonaws.com
Content-Type: application/zip
Authorization: AWS4-HMAC-SHA256 Credential=AKIAIOMCFPZIPDOYX3EA/...
Body bắt đầu bằng PK — đây là magic bytes của ZIP file.
Bước 3: Extract và phân tích nội dung¤
Nội dung MDData.db.json chứa toàn bộ activity log dạng JSON:
{
"MDData.db": {
"minutelyActivityLog": [
{
"Id": "1",
"steps": "50000",
"startTime": "1539595739",
"endTime": "1539597538",
"user_id": "70911295-fdad-4fb8-b376-c244a37a269a"
}
]
}
}
Bước 4: Thử sửa và replay¤
Thử sửa steps trong JSON, zip lại và paste vào Burp để replay request — thất bại. Server kiểm tra một hash key được sinh từ nội dung file. Không biết thuật toán sinh key → chuyển sang phân tích tĩnh.
Static Analysis (Phân tích tĩnh)¤
Bước 1: Quét với MobSF¤
Upload APK lên MobSF, phát hiện cảnh báo quan trọng:
Phát hiện: Raw SQL Query
Bước 2: Truy cập trực tiếp SQLite database¤
Cài app, dùng thử để tạo dữ liệu, sau đó truy cập:
adb shell
su
cd /data/data/cc.pacer.androidapp/databases
ls
# MDData.db
# awss3transfertable.db
# google_app_measurement_local.db
Bước 3: Inspect database¤
sqlite3 MDData.db
.tables
# minutelyActivityLog
# dailyActivityLog
# weightLog
# trackpoints
# ...
Xem schema của bảng quan trọng:
CREATE TABLE minutelyActivityLog (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
activetime INTEGER,
activityType INTEGER,
calories FLOAT,
distanceInMeters FLOAT,
endTime INTEGER,
steps INTEGER, -- <-- đây rồi!
user_id VARCHAR NOT NULL
);
Bước 4: Sửa dữ liệu¤
Tắt và mở lại app → UI hiển thị 15,000 steps, level "Highly Active".
Bước 5: Sync lên cloud¤
- Click Backup trong app → dữ liệu giả được upload lên AWS S3
- Mở app trên điện thoại thật
- Click Restore → dữ liệu được sync về thiết bị thật
Kết quả: Số bước chân trên leaderboard tăng vọt (ví dụ: 84,061 bước/ngày).
Tại sao cách này hoạt động dù server check hash?
Khi Backup được trigger từ app chính thức trên thiết bị thật sau khi đã sửa DB, app sẽ tự tính toán hash hợp lệ từ dữ liệu mới và gửi lên. Server nhận được một request hợp lệ hoàn toàn. Kẻ tấn công không cần biết thuật toán hash vì chính app là người tính hộ.
Tóm tắt Attack Chain¤
flowchart TD
A[Cài app trên emulator] --> B[Dùng app để tạo dữ liệu ban đầu]
B --> C[Truy cập SQLite DB qua ADB root shell]
C --> D[Sửa cột steps trong minutelyActivityLog]
D --> E[Mở app, trigger Backup]
E --> F[App tự tính hash và upload lên S3]
F --> G[Restore trên thiết bị thật]
G --> H[Leaderboard hiển thị số bước chân giả]
Kiến thức mở rộng¤
Các lỗ hổng được khai thác
| Lỗ hổng | Mô tả |
|---|---|
| Insecure Local Storage | Dữ liệu nhạy cảm (step count) lưu plaintext trong SQLite |
| Improper Server-side Validation | Server không xác thực tính hợp lệ logic của dữ liệu (vd: 50,000 bước trong 30 phút) |
| Trust in Client Data | Server tin tưởng hoàn toàn vào dữ liệu do client gửi lên |
Cách phòng tránh đúng đắn
- Server-side validation: Kiểm tra tính hợp lý của dữ liệu (bước chân tối đa của con người ~6,000–10,000 bước/giờ)
- Data integrity: Sử dụng HMAC hoặc server-generated token để xác thực mỗi session
- Encrypt local DB: Dùng SQLCipher để mã hóa SQLite database
- Certificate Pinning: Kết hợp với server-side validation để ngăn replay attack
Tài liệu tham khảo thêm: