# Intercept Flutter Traffic (Android)

<figure><img src="/files/QceJLyJKsMofu7aDvM6q" alt=""><figcaption></figcaption></figure>

เมื่อ Fulttter ได้ถือกำเนิดขึ้น ทำให้ชาวโปรแกรมเมอร์ สามารถสร้างโลกขึ้นมาได้หลายใบด้วยการเขียนโค้ดแค่ชุดเดียว เพราะการใช้ Flutter มัน Build ได้ทั้ง Android และ iOS โครตสะดวก 🙏🙏🙏🙏

<figure><img src="/files/uSs91hdyMyNgt12FTHoI" alt=""><figcaption></figcaption></figure>

แต่แอปที่เขียนด้วย Flutter เวลาที่เราจะดักข้อมูล ที่มีการรับ-ส่ง ระหว่าง แอป กับ API มักจะเจอปัญหาหลักๆอยู่ 2 อย่าง คือ Proxy และ Certificate Pinning

{% hint style="info" %}
เอาจริงๆปัญหานี้คนธรรมดาจะไม่เจอนะ แต่ Pentester (นักทดสอบเจาะระบบ) จะต้องเจอ 🥲🥲🥲🥲
{% endhint %}

## ⭐️ Proxy ⭐️

Flutter มี Proxy เป็นของตัวเอง หมายความว่า แอปที่เขียนด้วย Flutter เราจะไม่สามารถตั้งค่า Proxy ผ่านเมนูการตั้งค่าของ Android ได้&#x20;

{% hint style="success" %}
วิธีแก้ไขปัญหา
{% endhint %}

* เราสามารถใช้แอปที่ชื่อว่า [ProxyDroid](https://play.google.com/store/apps/details?id=org.proxydroid) (Android) ในการ route ตัว traffic ไปที่ Proxy ได้ โดยหลักการของ ProxyDroid ก็คือใช้ iptables ทำการ route ตัว traffic  ครับ&#x20;

<figure><img src="/files/xTuRq3UvdmGvyYTi7SVw" alt=""><figcaption><p><a href="https://play.google.com/store/apps/details?id=org.proxydroid">https://play.google.com/store/apps/details?id=org.proxydroid</a></p></figcaption></figure>

* ถ้าใครเก๋าพอจะใช้ ip tables แบบเพียวๆ ก็ไม่ว่ากัน ดูตัวอย่างได้ที่

{% embed url="<https://alijujara.medium.com/proxying-traffic-on-android-flutter-applications-d3f70655df66>" %}
<https://alijujara.medium.com/proxying-traffic-on-android-flutter-applications-d3f70655df66>
{% endembed %}

* อีกท่านึงเราสามารถใช้  Tool ตัวนึงซึ่งเจ๋งมากๆ ชื่อว่า [reFlutter](https://github.com/Impact-I/reFlutter) หลักการของ Tool ตัวนี้คือมันจะดัดแปลงการทำงานตัว Flutter Engine (libflutter.so) เพื่อให้เราสามารถตั้งค่า Proxy ได้อย่างง่ายดาย เพียงแค่เราโยนไฟล์ APK ให้มัน เราก็สามารถตั้งค่า IP Proxy ที่ต้องการได้เลย (ไม่ต้องทำอะไรแล้วชีวิตนี้ 🤖🤖🤖🤖)

```bash
$ reflutter main.apk

Please enter your Burp Suite IP: 127.0.0.1.   c 
SnapshotHash: 8ee4ef7a67df9845fba331734198a953
The resulting apk file: ./release.RE.apk
Please sign the apk file

Configure Burp Suite proxy server to listen on *:8083
Proxy Tab -> Options -> Proxy Listeners -> Edit -> Binding Tab

Then enable invisible proxying in Request Handling Tab
Support Invisible Proxying -> true
```

* สร้าง VPN Server ขึ้นมา จากนั้นเอามือถือต่อ VPN แล้วใช้ iptables ทำการ route ตัว traffic  ให้เข้า Proxy อีกที

ใครถนัดวิธีไหนเลือกใช้กันตามสะดวกครับ

## ⭐️ Certificate Pinning ⭐️

หากแอปพลิเคชันมีการทำ Certificate Pinning การที่เราจะดักข้อมูลได้ เราจะต้อง Bypass กระบวนการการตรวจสอบ  Certificate ก่อน ซึ่งกระบวนการ Bypass ขึ้นอยู่กับว่าแอปพลิเคชัน ทำ Certificate Pinning  ด้วยวิธีไหน ??

{% hint style="success" %}
Flutter ทำ  Certificate Pinning  ด้วยวิธีการไหนได้บ้าง
{% endhint %}

แนวทางการทำ Certificate Pinning จะทำได้หลักๆ 2 วิธีคือ

1. เรียกใช้ Dart API SecurityContext โดยการเขียนโค้ดภาษา Dart เพื่อทำ Certificate Pinning    ผ่าน method setTrustedCertificatesBytes()
2. ทำ Certificate Pinning  ผ่าน Native Programming ของแต่ละ OS เช่น Android ก็เขียนเป็น Java, Kotlin ส่วน iOS ก็เขียน Swift, Objective C จากนั้นทำเป็น Flutter packages ไว้เรียกใช้&#x20;

ยกตัวอย่าง Flutter packages ที่ทำ Certificate Pinning  ที่เหล่า Dev นิยมใช้งานกัน

{% embed url="<https://pub.dev/packages/http_certificate_pinning>" %}
<https://pub.dev/packages/http_certificate_pinning>
{% endembed %}

{% embed url="<https://github.com/macif-dev/ssl_pinning_plugin>" %}
<https://github.com/macif-dev/ssl_pinning_plugin>
{% endembed %}

{% hint style="success" %}
เทคนิคดูว่าแอปทำ Certificate Pinning  ด้วยเทคนิคอะไร
{% endhint %}

โดยปกติแล้วการที่เราจะรู้ว่าแอปพลิเคชัน ทำ Certificate Pinning  ด้วยวิธีไหน สามารถทำได้หลายวิธี แต่ผมขอแนะนำวิธีที่ผมใช้ประจำล่ะกันครับ แฮะๆ

แอปพลิเคชันที่เขียนด้วย Flutter เมื่อ Bulid ออกมาเป็นไฟล์ APK แล้วถ้าเราลอง Unzip ดูจะพบว่ามันมีไฟล์ libapp.so (Dart code)

```
├── AndroidManifest.xml
├── assets
│   └── flutter_assets
│       └── AssetManifest.json
├── classes.dex ──── //  Java (Dalvik Executable)
├── kotlin ──── //  kotlin Metadata
├── lib
│   └── arm64-v8a
│       ├── libapp.so ──── //  Dart code (App AOT Snapshot)
│       └── libflutter.so ──── //  Flutter Engine (stripped version of Dart VM)
├── META-INF
├── res
└── resources.arsc
```

&#x20;ซึ่ง code logic ของแอปพลิเคชันจะถูกจัดเก็บที่ไฟล์นี้ และเมื่อเรารู้แนวทางหลักๆในการทำ Certificate Pinning  เราสามารถให้คำสั่ง strings + grep เพื่อหาว่าแอปทำ Certificate Pinning  ด้วยวิธีไหนใช้  Flutter packages หรือเปล่า

คำสั่งที่ผมใช้ประจำก็ประมาณนี้ครับ&#x20;

```
$ strings libapp.so | grep -e "http_certificate_pinning"
http_certificate_pinning // (เจอแล้ว)
$ strings libapp.so | grep -e "ssl_pinning_plugin"
$ strings libapp.so | grep -e "SecurityContext_SetTrustedCertificatesBytes"
$ strings libapp.so | grep -e "pinning"
```

## Bypass Certificate Pinning

ถ้าเราเจอแล้วว่าแอปพลิเคชันทำ Certificate Pinning ด้วยวิธีไหน ทีนี้เรามาดูวิธี Bypass กันครับ

{% hint style="success" %}
วิธี Bypass  Certificate Pinning&#x20;
{% endhint %}

\[1] หากแอปพลิเคชันทำ Certificate Pinning ด้วยการใช้ Dart API SecurityContext  วิธีนี้ Bypass ค่อนข้างง่ายครับ ผมแนะนำให้ไปใช้ [reFlutter](https://github.com/Impact-I/reFlutter) (ของเขาดีจริง) เพราะเขาจัดการ Bypass ให้เราแล้ว ไม่เชื่อลองดูโค้ดก็ได้ 😝

<figure><img src="/files/6iYUnf3gKhoJ9tNPDnPJ" alt=""><figcaption><p><a href="https://github.com/Impact-I/reFlutter/blob/main/src/__init__.py#L267-L268">https://github.com/Impact-I/reFlutter/blob/main/src/__init__.py#L267-L268</a></p></figcaption></figure>

หรือจะใช้ Frida Hook ก็ได้ ดูตัวอย่างได้จาก&#x20;

{% embed url="<https://github.com/horangi-cyops/flutter-ssl-pinning-bypass>" %}

\[2] หากแอปพลิเคชันทำ Certificate Pinning ด้วยการใช้ http\_certificate\_pinning  หรือ ssl\_pin nning\_plugin ให้ใช้ [objection](https://github.com/sensepost/objection) hook method checkConnexion() แล้ว set return\_value เป็นค่า true เพียงเท่านี้แอปก็จะเชื่ออย่างสนิทใจแล้ว 🤩🤩🤩🤩

```bash
$ objection --gadget {app_package_name} explore

// http_certificate_pinning
$ android hooking set return_value diefferson.http_certificate_pinning.checkConnexion true

// ssl_pinning_plugin
$ android hooking set return_value com.macif.plugin.sslpinningplugin.checkConnexion true

// แต่ใช้ได้เฉพาะกรณีที่แอปไม่โดน obfuscate ถ้าโดน obfuscate ต้องลองใช้ JADX Decomplie หา method ในการ hook เอง 
```

จริงๆมันมีเทคนิคคูลๆ อีก แต่ผมขอเก็บไว้ก่อน ไว้จะมาเล่าอีกทีละกัน 😁😁😁😁


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://research.xpwn.dev/flutter/intercept-flutter-traffic-android.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
