Android Pentest - Part 1
Abstract
Bài viết này mình tập trung nói về:
- Cách set up môi trường Android Pentest
- Bypass SSL Pinning
Set up môi trường
Chuẩn bị
Mình đã cài đặt sẵn các ứng dụng:
- LDPlayer9
- Burp Suite
Cài đặt Burp Suite Certificate vào Android
Để bắt được request ứng dụng Android, mình thực hiện cài đặt chứng chỉ của Burp Suite vào system cert của Android.
Mở Burp → Settings → Tools → Proxy -> Import / export CA certificate.
Sau đó chọn đường dẫn lưu cert -> Next
Android yêu cầu cert trong /system/etc/security/cacerts/ phải theo định dạng hash.0:
openssl x509 -inform DER -subject_hash_old -in cert.der | head -1
mv cert.der 9a5ba575.0
Lưu file cert vào Android
Nếu bạn chưa thêm adb vào PATH -> Thêm vào system environments trên Windows.
Nếu bạn chưa có Android Studio -> Thay đường dẫn bằng C:\LDPlayer\LDPlayer9
Sau đó bật quyền Root trên LDPlayer
Đẩy file vào máy ảo và vào shell của Android + quyền root
adb push 9a5ba575.0 /data/local/tmp/
adb shell
su
Remount phân vùng /system với quyền đọc-ghi để có thể chỉnh sửa:
mount -o rw,remount /system
Nếu báo lỗi thì remount /
mount -o rw,remount /
Di chuyển cert vào system cert
mv /data/local/tmp/9a5ba575.0 /system/etc/security/cacerts/
Thiết lập quyền cho cert và reboot
chmod 644 /system/etc/security/cacerts/9a5ba575.0
reboot
Thêm Burp Proxy
Đầu tiên chạy lệnh ipconfig
trên Windows:
Mình thấy ip 192.168.56.1
-> Burp proxy là 192.168.56.1:8080
Sao đó vào android, mở Wifi, bấm biểu tượng bánh răng -> Edit
Vào trình duyệt truy cập trang web bất kỳ, nếu thấy Proxy Burp Suite bắt được -> OK
Bypass SSL Pinning
SSL Pinning (hay Certificate Pinning) là một cơ chế bảo mật trong ứng dụng di động và web, giúp ngăn chặn tấn công Man-in-the-Middle (MITM) khi giao tiếp qua HTTPS.
Bình thường: Khi app kết nối HTTPS đến server, nó sẽ tin tưởng bất kỳ CA nào được cài trên hệ thống nếu CA đó đã ký chứng chỉ cho server.
Vấn đề: Nếu attacker cài một CA giả mạo (như Burp/ZAP) vào máy, app sẽ coi như hợp lệ → attacker có thể giải mã và thay đổi dữ liệu.
Giải pháp: SSL Pinning.
App “pin” (ghim) sẵn một hoặc nhiều chứng chỉ cụ thể (certificate) hoặc public key của server. Khi kết nối, app không chỉ kiểm tra “chứng chỉ hợp lệ” mà còn so sánh với chứng chỉ/khóa đã pin. Nếu không khớp → chặn kết nối, báo lỗi.
Các kiểu SSL Pinning:
- Certificate Pinning: Ghim nguyên file cert (dễ triển khai, nhưng phải update app khi cert hết hạn).
- Public Key Pinning: Ghim key từ cert (ít thay đổi hơn, an toàn hơn khi cert được renew).
- Hash Pinning: Ghim SHA-256 hash của cert hoặc key.
Tóm lại: SSL Pinning là cơ chế buộc app chỉ tin vào chứng chỉ/khoá được nhà phát triển chỉ định, thay vì tin toàn bộ CA trên hệ thống :v
=> Bypass SSL Pinning = Làm cho app bỏ qua hoặc vô hiệu hóa cơ chế kiểm tra đó, để app chấp nhận chứng chỉ giả.
Cài đặt frida, objection
Có nhiều cách bypass, nhưng mình chọn cách bypass với frida và objection.
Đầu tiên, cài đặt frida server bản 16.7.19 x86_64
https://github.com/frida/frida/releases/tag/16.7.19
Sau đó cài đặt frida và objection qua pip
pip install "frida==16.7.19" frida-tools
pip install frida==16.7.19
pip install objection
Đưa frida server vào Android
Nãy mình vừa cài frida server bản 16.7.19 x86_64, thực hiện giải nén và push vào /data/local/tmp
Sau đó vào shell android, cấp quyền đọc và thực thi cho file này:
chmod 755 frida....
Sau đó lên root và chạy ngầm file này
Cài ứng dụng bất kỳ
Ở đây mình cài ứng dụng Tuya Smart qua file apk
Các bạn có thể kiếm được qua web APKPure,... Sau đó cài bằng lệnh:
adb install <file1.apk> (nếu chỉ có 1 file)
adb install-multiple <file1.apk> <filen.apk> (nếu có nhiều file apk)
Nếu có thông báo: more than device/emulator...
-> thêm option -s 127.0.0.1:5555
Ví dụ: adb -s 127.0.0.1:5555 install...
Khi cài xong, nếu chưa biết tên package -> chạy lệnh: adb shell pm list packages
Ở đây app của mình là com.tuya.smart
Sau đó chạy lệnh:
objection --gadget "com.tuya.smart" explore
nếu bạn thấy như này thì bypass được
Sau đó gõ lệnh: android sslpinning disable
Sau đó dùng app và vào Burp xem request/response thôi
Như trong Burp, mình thấy postData
và result
đang ở dạng mã hóa.
Bài viết này mình chỉ nói về cách bắt req/res thôi. Cách giải mã mình đang trong quá trình làm =((.