Cách lấy file tracklog từ app iOS trong lab MITM được cấp quyền

Cập nhật 08/2026: Bài này viết lại từ một ghi chú nghiên cứu về tracklog trên iOS. Mình giữ phần debug proxy và chuyển GeoJSON sang GPX, nhưng bỏ URL private/UUID thật và không hướng dẫn bypass certificate pinning, patch IPA, jailbreak hay lấy dữ liệu từ app không được phép. Flow bên dưới chỉ dành cho app, build, thiết bị và dữ liệu mà bạn sở hữu hoặc được ủy quyền kiểm thử.

Hồi trước, mình tìm tracklog cho một chuyến đi mà file trên mạng thì ít, file cũ lại lệch. App trên điện thoại có bản đồ, có đường đi, nhưng nút export lại không nằm ở chỗ mình cần. Câu hỏi “file nằm ở đâu?” nghe đơn giản, nhưng đụng tới network traffic là đã bước vào vùng phải có quyền và có cách giữ dữ liệu cho đàng hoàng.

Trong bài này, “lấy tracklog” được hiểu là debug luồng export của app do mình kiểm soát, hoặc xử lý một file GeoJSON đã được cấp quyền. Man-in-the-Middle (MITM) là mô hình quan sát trong phòng lab, không phải chìa khóa để mở private API của một ứng dụng bất kỳ.

Trước khi bắt đầu: phạm vi nào là được phép?

Chỉ làm thí nghiệm khi bạn có ít nhất một trong các điều kiện sau:

  • app là của bạn hoặc bạn có văn bản/ủy quyền kiểm thử;
  • thiết bị iPhone/simulator và tài khoản test thuộc phạm vi của team;
  • traffic, response và file tracklog được phép lưu, phân tích và chuyển đổi;
  • môi trường là Wi-Fi lab hoặc máy ảo riêng, không phải mạng công cộng.

Không dùng hướng dẫn này để xem token, cookie, tin nhắn, dữ liệu vị trí hay API private của người khác. Đừng đưa URL bucket, UUID, Authorization header hoặc response thật vào bài viết, issue và Git. Bài cũ có một URL dữ liệu cụ thể; bản này đã loại hoàn toàn.

MITM lab hoạt động ra sao?

Một proxy như mitmproxy đứng giữa client và server trong phiên test. Thiết bị gửi request tới proxy, proxy chuyển tiếp tới upstream rồi trả response về thiết bị. Với HTTPS, client chỉ xem được nội dung khi nó tin CA của proxy và app không áp dụng một cơ chế xác thực danh tính chặt hơn.

Sơ đồ tối giản:

iPhone hoặc Simulator
        |
        |  Wi-Fi lab / proxy settings
        v
mitmproxy hoặc mitmweb trên máy debug
        |
        v
API staging của app do team sở hữu

Sơ đồ proxy trung gian giữa iPhone test và API staging

MITM trong bài chỉ là một phiên debug có kiểm soát, không phải cách vượt qua bảo vệ của app production.

mitmproxy gọi các bản ghi request/response là flow. Bạn có thể xem method, host, path, status, headers và body theo quyền của client. Hãy coi flow như dữ liệu nhạy cảm: một file capture có thể chứa cookie, token, tọa độ, email và nội dung người dùng.

Chuẩn bị máy, thiết bị và mạng lab

Bạn cần:

  1. Một máy macOS, Linux hoặc Windows để chạy mitmproxy/mitmweb.
  2. iPhone hoặc iOS Simulator của chính bạn, cài debug/staging build.
  3. Một mạng Wi-Fi lab mà bạn kiểm soát được client và firewall.
  4. Một file tracklog mẫu hoặc tài khoản test không chứa dữ liệu thật.
  5. Nơi lưu tạm có mã hóa; sau buổi test phải có checklist xóa.

Simulator thường dễ lặp lại hơn vì bạn có thể reset profile và dữ liệu. Nếu dùng iPhone thật, tránh đăng nhập tài khoản cá nhân, tắt đồng bộ không cần thiết và ghi rõ lúc nào certificate debug được cài.

Cài và chạy mitmproxy/mitmweb

Theo tài liệu chính thức, macOS có thể cài mitmproxy bằng Homebrew:

brew install --cask mitmproxy

Linux và Windows nên dùng installer/binary từ tài liệu cài đặt mitmproxy. Đừng lấy một binary không rõ nguồn rồi đưa vào máy đang chứa credential.

Khởi động giao diện web trên mạng lab:

mitmweb --listen-host 0.0.0.0 --listen-port 8080

Lệnh này mở listener trên cổng 8080 để thiết bị trong mạng lab kết nối. Chỉ chạy khi đã giới hạn firewall/SSID cho thiết bị test; không port-forward ra Internet, không dùng trên Wi-Fi quán cà phê. Khi xong việc, dừng process ngay.

Bạn cũng có thể chạy “mitmproxy” ở terminal nếu không cần GUI. Getting Started của mitmproxy mô tả ba giao diện: terminal, web và dump không tương tác.

Cấu hình proxy và CA trên iPhone test

1. Trỏ Wi-Fi proxy về máy debug

Tìm địa chỉ IP nội bộ của máy chạy mitmweb. Trên iPhone, vào Wi-Fi đang dùng, chọn cấu hình proxy thủ công, nhập IP máy debug và cổng 8080.

Màn hình cấu hình proxy Wi-Fi trên thiết bị iOS thử nghiệm

Ảnh minh họa cần được che IP/SSID thật trước khi publish.

Nếu không thấy flow, kiểm tra ba việc trước: iPhone và máy debug có cùng mạng không, firewall có cho phép cổng 8080 từ đúng IP thiết bị không, và app có dùng proxy hệ thống hay tự mở socket riêng.

2. Cài CA của mitmproxy trong lab

Khi proxy đã chạy, mở Safari trên thiết bị test và truy cập “http://mitm.it”. Chọn profile iOS, cài profile rồi vào Settings → General → About → Certificate Trust Settings để bật full trust cho root certificate của mitmproxy. Đây là quy trình được mô tả trong mitmproxy Certificates.

Màn hình cài CA của proxy trên iOS test device

Chỉ bật trust trên simulator/test device. Đừng cài CA debug lên iPhone dùng cho ngân hàng, email, tài khoản khách hàng hoặc công việc hằng ngày. Sau buổi lab phải gỡ profile và tắt full trust.

3. Kiểm tra bằng một website vô hại

Trước khi mở app, truy cập “https://mitmproxy.org”. Nếu flow xuất hiện trong mitmweb và TLS không báo lỗi, đường proxy cơ bản đã hoạt động. Nếu chỉ HTTP hiện còn HTTPS lỗi, thường là CA chưa được cài/trust đúng.

Nếu app có certificate pinning thì sao?

Đây là chỗ nhiều bài hướng dẫn bỏ qua. App có thể dùng certificate pinning, custom trust store, mTLS hoặc network stack không tuân theo proxy hệ thống. Khi đó, cài CA của mitmproxy vẫn chưa đủ; app sẽ từ chối certificate do proxy tạo ra.

Apple có cấu hình “NSPinnedDomains” để pin CA hoặc leaf certificate cho domain. OWASP MASVS-NETWORK cũng xem identity pinning là một phần của bảo vệ network traffic. Vì vậy, việc app không hiện flow có thể là một tín hiệu bảo mật đúng, không phải lỗi cần tìm cách vượt qua.

Nếu app là của team bạn, cách an toàn là tạo debug/staging build:

  • endpoint staging và tài khoản test riêng;
  • logging có chủ đích, không log token/PII;
  • cơ chế trust debug được bật bằng build flag, không ảnh hưởng production;
  • tài liệu hóa ai được bật và cách tắt.

Nếu app không thuộc quyền của bạn, dừng ở đây. Không patch IPA, không jailbreak, không dùng tool bypass pinning và không cố lấy private response. Có thể dùng API/export chính thức hoặc xin quyền từ owner.

Lọc flow, redaction và lưu bằng chứng

Khi app của mình đã chạy qua proxy, hãy làm một flow nhỏ:

  1. Mở màn hình có chức năng export tracklog đã được phép.
  2. Trong mitmweb, lọc theo hostname staging của app, không tìm theo token hay dữ liệu người dùng.
  3. Ghi lại method, path, status và Content-Type; chỉ giữ body nếu test plan cho phép.
  4. Lưu một response mẫu đã redacted, không lưu cả session nếu không cần.
  5. Đặt thời hạn xóa cho file capture và ghi người được phép truy cập.

Các trường nên xóa hoặc thay bằng placeholder trước khi chia sẻ:

  • Authorization, Cookie, Set-Cookie và refresh token;
  • device ID, account ID, email, số điện thoại;
  • tọa độ thật, timestamp có thể xác định hành trình;
  • URL bucket/object, UUID, query chứa thông tin người dùng;
  • response chứa hình ảnh, tên đường riêng hoặc dữ liệu khách hàng.

Giao diện mitmweb hiển thị flow đã được che dữ liệu

Screenshot publish cần che host, IP, token, cookie và path riêng của app.

MITM cho mình thấy contract thực tế giữa app và API, nhưng không biến response thành tài sản được phép sử dụng. Quyền dùng dữ liệu vẫn đến từ owner, hợp đồng và mục đích test.

Chuyển GeoJSON cục bộ sang GPX

Nếu app/export chính thức cho ra một file GeoJSON đã được phép, có thể chuyển nó sang GPX bằng Python. Đoạn dưới đây chỉ đọc “tracklog.geojson” trong thư mục hiện tại; không tự gọi URL và không đụng private endpoint.

Cài thư viện:

python3 -m pip install gpxpy

gpxpy trên PyPI là thư viện parse và manipulate GPX. GeoJSON thường ghi coordinate theo thứ tự longitude, latitude; GPX point lại nhận latitude, longitude, nên cần đổi thứ tự.

Tạo file “geojson_to_gpx.py”:

import json
from pathlib import Path

import gpxpy.gpx


def append_line(segment, coordinates):
    for coordinate in coordinates:
        if len(coordinate) < 2:
            continue
        longitude, latitude = coordinate[:2]
        segment.points.append(
            gpxpy.gpx.GPXTrackPoint(latitude, longitude)
        )


source = Path("tracklog.geojson")
target = Path("tracklog.gpx")
data = json.loads(source.read_text(encoding="utf-8"))

if data.get("type") == "FeatureCollection":
    geometries = [
        feature.get("geometry")
        for feature in data.get("features", [])
        if feature.get("geometry")
    ]
else:
    geometries = [data]

gpx = gpxpy.gpx.GPX()
track = gpxpy.gpx.GPXTrack(name="Authorized tracklog export")
gpx.tracks.append(track)

for geometry in geometries:
    geometry_type = geometry.get("type")
    coordinates = geometry.get("coordinates", [])

    if geometry_type == "LineString":
        segment = gpxpy.gpx.GPXTrackSegment()
        track.segments.append(segment)
        append_line(segment, coordinates)
    elif geometry_type == "MultiLineString":
        for line in coordinates:
            segment = gpxpy.gpx.GPXTrackSegment()
            track.segments.append(segment)
            append_line(segment, line)
    else:
        raise ValueError(
            f"Unsupported geometry type: {geometry_type}"
        )

target.write_text(gpx.to_xml(), encoding="utf-8")
print(f"Wrote {target}")

Chạy và kiểm tra:

python3 geojson_to_gpx.py
python3 - <<'PY'
import gpxpy

with open("tracklog.gpx", encoding="utf-8") as stream:
    parsed = gpxpy.parse(stream)

points = sum(
    len(segment.points)
    for track in parsed.tracks
    for segment in track.segments
)
print(f"segments={len(parsed.tracks)} points={points}")
PY

Nếu đường đi bị lật sang đại dương, gần như chắc là bạn đã đảo latitude/longitude. Nếu file có Polygon, Point hoặc geometry collection, đừng ép nó thành track; hãy xác định semantics trước rồi viết converter tương ứng.

Dọn lab sau khi test

Đây là phần dễ bị quên nhất:

  1. Tắt proxy thủ công trên iPhone và khôi phục cấu hình Wi-Fi.
  2. Gỡ profile CA của mitmproxy.
  3. Tắt full trust cho root certificate.
  4. Dừng mitmweb/mitmproxy và đóng cổng firewall tạm.
  5. Xóa flow capture, response tạm và file GeoJSON/GPX chứa tọa độ nhạy cảm.
  6. Nếu lỡ capture token của tài khoản test, revoke/rotate token.
  7. Ghi lại build number, test scope và ngày xóa dữ liệu.

Một Cloudflare Tunnel là câu chuyện khác: nó public một service theo route, không phải công cụ để nhìn traffic của app trên iPhone. Đừng trộn tunnel, proxy debug và production credential vào cùng một máy.

Troubleshooting

Hiện tượng Nguyên nhân có thể Cách xử lý an toàn
Không thấy flow nào Sai IP/port, khác mạng, firewall chặn Kiểm tra Wi-Fi lab, cổng 8080 và website test trước khi mở app.
HTTP thấy nhưng HTTPS lỗi CA chưa cài hoặc chưa bật full trust Cài lại profile trên test device; không tắt TLS validation của production app.
Website test chạy nhưng app báo offline Pinning, mTLS, QUIC hoặc app bypass system proxy Dùng debug build/staging của app mình; không bypass app bên ngoài.
Flow có nhưng body trống Content encoding, streaming, app mã hóa payload Xác nhận contract/debug logging ở app mình; đừng đoán body hoặc tìm private key.
GPX mở không có đường GeoJSON không phải LineString, sai thứ tự tọa độ Kiểm tra geometry type, coordinate order và số point.
Screenshot lộ dữ liệu IP, SSID, profile, token hoặc tọa độ còn nguyên Che trước khi publish; nếu token thật đã lộ, revoke ngay.

FAQ

MITM có lấy được traffic của mọi app iOS không?

Không. App có thể pin certificate, dùng mTLS, custom network stack hoặc không tôn trọng system proxy. Đây là giới hạn bảo mật bình thường, không phải lời mời tìm cách bypass.

Có nên cài CA mitmproxy trên iPhone chính không?

Không nên. Dùng simulator hoặc thiết bị test riêng, không có tài khoản nhạy cảm. Gỡ profile và full trust ngay sau phiên lab.

Có thể dùng flow này để lấy file từ app của người khác không?

Không. Cần quyền sở hữu hoặc ủy quyền rõ ràng. Nếu cần dữ liệu, xin API/export chính thức hoặc làm việc với owner.

Vì sao bài không còn URL tracklog thật?

URL cũ chứa bucket và UUID cụ thể. Giữ lại có thể làm lộ dữ liệu hoặc khuyến khích truy cập ngoài phạm vi. Bản mới dùng file local do người đọc sở hữu.

Tracklog có nhất thiết phải là GeoJSON không?

Không. App có thể export GPX, KML, CSV hoặc protobuf. Hãy đọc format được tài liệu hóa; converter chỉ nên chạy trên file đã được phép và phải kiểm tra coordinate semantics.

Kết luận: debug đúng phạm vi, giữ dữ liệu đúng cách

MITM hữu ích nhất khi nó trả lời một câu hỏi cụ thể trong app của mình: request export đi đâu, response có format gì, lỗi nằm ở client hay server. Nó trở nên nguy hiểm khi bị dùng như cách lấy dữ liệu từ một hệ thống không thuộc quyền kiểm soát.

Nếu bạn đang debug một app iOS do mình sở hữu, gửi build debug/staging, format tracklog và mục tiêu export. Mình có thể giúp dựng lab, rà CA/pinning, thiết kế redaction và viết converter GeoJSON/GPX — để dữ liệu đi đúng đường mà không mang theo rủi ro thừa.

Tài liệu tham khảo

Previous Article

So sánh Forward Proxy và Reverse Proxy

Next Article

Tấn công DDoS — Tổng quan và cách phân loại

Subscribe to our Newsletter

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨