Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
pyrmax — وحدة فك تشفير/ترميز لإطارات بروتوكول AirMAX اللاسلكي من Ubiquiti؛ تحليل التقاطات pcap أو الالتقاط المباشر، اكتشاف الأجهزة، فحص البرامج الثابتة المعرضة للثغرات، صياغة حزم مشوهة، ومحاكاة أهداف AirMAX AC/M. | Kitploit
أدوات/GitHubGitHub/infobyte/pyrmax
ماسحات الثغرات الأمنيةالهندسة العكسيةالاختبار العشوائيأمن الشبكاتأمن الشبكات اللاسلكية
GitHubinfobyte/pyrmax

pyrmax

وحدة فك تشفير/ترميز لإطارات بروتوكول AirMAX اللاسلكي من Ubiquiti؛ تحليل التقاطات pcap أو الالتقاط المباشر، اكتشاف الأجهزة، فحص البرامج الثابتة المعرضة للثغرات، صياغة حزم مشوهة، ومحاكاة أهداف AirMAX AC/M.

عرض المستودع
3منذ 13 أياملم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

pyrmax

وحدة فك ترميز وترميز لإطارات بروتوكول Ubiquiti AirMAX، تغطي كلا سلسلتي AC (البرنامج الثابت WA) وM (البرنامج الثابت XW/XM).

  • فك الترميز للرؤوس الخارجية ذات النص الصريح يتم عبر مخططات Kaitai Struct الموجودة ضمن ksy/. أما حمولة AC (المقيّدة بالإصدار، والتي تتبدّل حسب msg_type، مع إزالة قناع XOR لـ deauth) فهي مكتوبة يدويًا في ac.py — وهذا المنطق لا يناسب Kaitai المخصص للتحليل فقط.
  • الترميز مكتوب يدويًا ليعكس مسار فك الترميز حقلًا بحقل.

الحالة

النسخةفك الترميزالترميزتكرار pcap
AC✅ جميع أنواع الرسائل الخمسة (beacon، assoc req/resp، probe req، deauth)✅ معكوس مطابق للبايت + دوال البناء (builders) + seal✅
Mجزئي (9 بايتات موثقة؛ والباقي كـ unknown_rest)✅ يعيد الرأس الموثّق + unknown_rest بلا فقدان✅
Routerboard.com IE (مرافق لـ M)✅ اسم الجهاز + قائمة sub-IEغير متاح✅

تنسيق إطار AC على الشبكة يتبع docs/ac_wire_format.md (مؤكَّدة مقابل ubnt_poll_host.ko وفقًا لـ [P]). جميع الأعداد الصحيحة متعددة البايت في AC big-endian.

المهام المتبقية

  • pyrmax.ac.encode(AcPacket) -> bytes — مكتوب يدويًا ومطابق للبايت معكوس decode() (إلى جانب seal() وto_ie() والمنشئات build_*).
  • pyrmax.m.encode(MPacket) -> bytes — نفس الشيء لـ M (+ build_m، seal, to_ie).
  • تحديد حقول AC [open] نهائيًا — خريطة البتات الدقيقة لـ cap_flags، mixed_mode، / (assoc_req)، / (assoc_resp)، و الخاص بـ deauth (قابل للاستخراج لكن مفتاحه لم يُهندَس عكسيًا بعد، لذا لا يمكن التحقق منه). انظر §11-§12.

أداة سطر الأوامر

توفر الحزمة واجهة CLI تعتمد على أوامر فرعية. شغّلها كالتالي: python -m pyrmax COMMAND ....``` usage: python -m pyrmax [-h] [--version] COMMAND ...

COMMAND parse Print each AirMAX frame in detail. discover Summarize devices observed in the capture. scan Live-scan for AirMAX devices and flag vulnerable firmware. emulate Emulate AirMAX AC/M devices (fake targets for scanners).

root@kitploit:~
تأخذ `parse` و`discover` **إما** ملف pcap/pcapng (موضعي)
**أو** واجهة لاسلكية حية عبر `-i / --iface IFACE`. الاثنان
متنافيان. يقبل `scan` نفس خيارات المصدر (بالإضافة إلى
وضع `--active` الذي ينطبق فقط على الواجهة الحية)؛ `emulate`
خاص بالواجهة الحية فقط.```sh
python -m pyrmax parse     capture.pcap          # offline
python -m pyrmax discover  capture.pcap

sudo python -m pyrmax parse     -i wlan0mon      # live (needs root)
sudo python -m pyrmax discover  -i wlan0mon

الالتقاط المباشر يفترض أن الواجهة في وضع المراقبة بالفعل على القناة محل الاهتمام — لا يهيئ pyrmax أيًا منهما. يتطلب الأمر الامتداد الاختياري [live] (pip install pyrmax[live]) الذي يجلب pcapy-ng. اضغط Ctrl-C للتوقف: يُبلّغ parse عن عدد الإطارات التي عالجها؛ ويطبع discover ملخص الأجهزة المجمّع عند الخروج.

رموز الخروج (مشتركة بين الأمرين وكلا نمطي المصدر): 0 عند النجاح (بما في ذلك "لا توجد إطارات AirMAX" — وهي نتيجة صحيحة)، 1 لأخطاء تنسيق الالتقاط (نوع رابط خاطئ، ملف تالف، تعذّر فتح الواجهة)، 2 لملف مفقود أو وسائط مصدر غير صالحة.

parse — تفريغ لكل إطار```sh

python -m pyrmax parse capture.pcap

root@kitploit:~
كل إطار إدارة 802.11 يحمل IE خاص ببائع AirMAX ينتج
كتلة واحدة: حزمة AC، وحزمة M، وأي IE مصاحب من Routerboard.com
موجود في نفس الإطار.```
Found 1 AirMAX frame(s) in capture.pcap: 0 AC, 1 M (1 with Routerboard companion).

=== Frame #0  [M]  ts=1765494974.955358 ===
  802.11   src=04:18:d6:0e:0c:42  dst=24:a4:3c:88:d8:22  bssid=04:18:d6:0e:0c:42
  AirMAX M
    version      15
    msg_type     BEACON  (raw=1)
    src_mac      04:18:d6:0e:0c:42
    enable       1
    unknown_rest b700000000000000000000040418d60e0c420000000000  (23B)
  Routerboard.com IE
    oui_type     0
    unknown      0000
    device_name  'AP Sur HY1315'
    sub_ie       subtype=1  (30B) 040000001f660902ff0f4150205375722048593133313500000000000000

نفس أداة الاجتياز أحادية المرور متاحة برمجيًا باسم pyrmax.pcap.iter_airmax(path) — تُنتج سجلًا واحدًا من نوع AirmaxRecord(meta, ac, m, routerboard) لكل إطار يحمل AirMAX، وبالتالي لن تحتاج إلى مطابقة عناصر معلومات M وRouterboard يدويًا.

discover — ملخّص الجهاز```sh

python -m pyrmax discover capture.pcap

root@kitploit:~
تُجمَّع الإطارات حسب عنوان MAC المصدر لمعيار 802.11، وتتراكم الأقران، وتندمج ملاحظات حمولة AC / حمولة M / اسم جهاز Routerboard في كتلة واحدة لكل جهاز.```
2 device(s) observed in capture.pcap across 12 AirMAX frame(s).

  24:5a:4c:44:57:fd  (AC)
    radioname    'LB1'
    ssid         'labalUBI2'
    ac_msg_types BEACON
    ac_version   9
    cap_flags    0x0000003e
    mixed_mode   0
    frames       8
    first seen   1767046123.708745
    last seen    1767046129.012448
    peers        (broadcast only)

  04:18:d6:0e:0c:42  (M)
    device_name  'AP Sur HY1315'
    msg_types    BEACON
    m_version    15
    m_enable     1
    frames       4
    first seen   1765494974.955358
    last seen    1765494980.341110
    peers        24:a4:3c:88:d8:22

نفس التجميع هو أيضًا دالة عامة:```python from pyrmax.devices import summarize from pyrmax.pcap import iter_airmax

devices = summarize(iter_airmax("capture.pcap")) for mac, dev in devices.items(): print(mac.hex(":"), dev.device_name or dev.radioname, dev.peers)

root@kitploit:~
## الاستخدام

### فك ترميز رسالة AirMAX AC واحدة

يتوقع المُفكِّك وحدات البايت الخاصة بـ Vendor Specific IE في 802.11 **بدءًا من
OUI** — يجب أن يكون غلاف IE (معرّف العنصر `0xDD` + الطول) قد أُزيل
بالفعل. يتم استخراج `src_mac` / `dst_mac` من SA / DA لإطار 802.11
الخارجي.```python
from pyrmax import ac

packet = ac.decode(
    data,                              # bytes starting at b"\x00\x27\x22"
    src_mac="aa:bb:cc:dd:ee:ff",       # accepts str ("aa:bb:..." or "aa-bb-..."
                                       # or "aabbcc...") and raw 6-byte bytes
    dst_mac="ff:ff:ff:ff:ff:ff",       # optional — defaults to broadcast
)

packet.msg_type          # <MsgType.BEACON: 1>
packet.version           # 9 (the wire-format epoch / version gate)
packet.src_mac           # b'\xaa\xbb\xcc\xdd\xee\xff'  (integrity-checked)
packet.radioname         # "lab-rx-1"   (convenience prop, delegates to body)
packet.ssid              # "NetA"
packet.cap_flags         # 0x3e  (None for msg types that have no cap_flags)

# The per-message-type fields live on packet.body, one of:
#   BeaconBody | AssocReqBody | AssocRespBody | ProbeReqBody | DeauthBody
body = packet.body
if isinstance(body, ac.BeaconBody):
    body.mac_0c          # the radio's own MAC / BSSID
    body.cap_flags       # u32 capability bitfield (§11)
    body.mixed_mode      # u32 [open]

msg_type هو أحد القيم BEACON / ASSOC_REQ / ASSOC_RESP / PROBE_REQ / DEAUTH. حقول الذيل المرتبطة بالإصدار (field_9c, rssi, fwname, txpower, …) تكون قيمتها None عندما يكون version الخاص بالإطار أقل من عتبتها. يقوم إطار Deauth بإلغاء XOR على src_mac باستخدام nonce الخاص بـ jiffies قبل فحص السلامة ويُظهر enc_token ذو الـ 16 بايت كبايتات معتمة (مفتاحه لم يُعكس بعد، لذا لا يمكن التحقق منه).

اجتياز قائمة AC TLV

الهيئات التي تحمل TLVs للأسماء (beacon, assoc_req) تحافظ على التدفق — بما في ذلك إدخال Padding الختامي — حرفيًا على body.tlvs. يتم إبراز radioname, ssid و fwname كخصائص تسهيلية على الحزمة؛ كل شيء آخر يبقى خامًا.```python body = packet.body for tlv in getattr(body, "tlvs", ()): if tlv.tag == ac.TlvTag.PADDING: continue print(f"{tlv.tag.name:<10} ({len(tlv.data)} bytes): {tlv.data!r}")

root@kitploit:~
### فك ترميز رسالة AirMAX M واحدة

نفس الشكل، سطح أصغر — فقط 9 بايتات من حمولة M موثقة؛ أما الباقي فيُحفظ حرفيًا في `unknown_rest`. **ملاحظة:** حمولة M نفسها لا تحتوي على حقل SSID — لذلك، انظر إلى عنصر معلومات SSID القياسي في 802.11 في المنارة أو استجابة الفحص المحيطة (يظهر كـ `FrameMeta.ssid` عند التكرار عبر `pyrmax.pcap`).```python
from pyrmax import m

packet = m.decode(data, src_mac="aa:bb:cc:dd:ee:ff")

packet.version           # 1
packet.msg_type          # <MsgType.BEACON: 1>
packet.src_mac           # b'\xaa\xbb\xcc\xdd\xee\xff'
packet.enable            # 1
packet.unknown_rest      # b'\xde\xad\xbe\xef...'   # opaque, RE pending

إنشاء الرسائل (ترميز)

encode(packet, dst_mac=…) هو المعكوس الحرفي البايتي لـ decode — encode(decode(x)) == x لإطار مكتمل البنية. يقوم بتسلسل الجسم (مع إعادة تطبيق بوابات الإصدار، وبالنسبة لـ deauth، قناع src_mac XOR)، ويحشو إلى كتلة AES، ويشفر باستخدام المفتاح المشتق من packet.src_mac، ثم يُخرج البايتات من OUI فصاعدًا. لفه باستخدام to_ie() للحصول على IE بائع كامل بصيغة 0xDD.

بُنيات build_* توفر عليك تجميع الأجسام المتداخلة يدويًا:```python from pyrmax import ac

A beacon (mac_0c defaults to src_mac; broadcast key, as beacons use)

pkt = ac.build_beacon(src_mac="24:5a:4c:44:57:fd", radioname="LB1", ssid="labalUBI2", cap_flags=0x3e) ie = ac.to_ie(ac.encode(pkt)) # full 802.11 vendor IE, ready to embed

An authenticated deauth — the encoder XOR-masks the src with the jiffies nonce

deauth = ac.build_deauth(src_mac="24:5a:4c:44:57:fd", jiffies_nonce=0xdeadbeef) raw = ac.encode(deauth, dst_mac="24:a4:3c:88:d8:22")

Others: ac.build_assoc_req / build_assoc_resp / build_probe_req, and m.build_m

root@kitploit:~
بالنسبة للفيزينغ / إثباتات المفهوم، تقوم `seal()` بتشفير نص عادي **اعتباطي** وتبني الترويسة الخارجية — لذا يمكنك صياغة حمولات مشوّهة عمدًا (`msg_type` زائف، أطوال خاطئة، أجسام فرعية) لا يمكن للمشفّر المنظّم أن ينتجها أبدًا:```python
frame = ac.seal(b"\xde\xad\xbe\xef", src_mac="aa:bb:cc:dd:ee:ff",
                dst_mac="ff:ff:ff:ff:ff:ff", msg_type=0xEE)  # zero-padded to 16

يرفع encode المنظّم EncodeError على أي شيء لا يمكن إرساله عبر الشبكة (قيمة TLV أكبر من 255 بايتًا، نص مشفّر ≥ 0x101)؛ بينما يكون seal متسامحًا بطبيعة تصميمه.

دفق الحزم من ملف pcap أو pcapng

pyrmax.pcap يبحث عن IEs الخاصة ببائع AirMAX داخل إطارات إدارة 802.11، ويستخرج عناوين MAC من ترويسة 802.11 الخارجية، ويغذّي كل شيء إلى مفكك الترميز الصحيح. يتم الكشف التلقائي عن كل من .pcap و .pcapng. الإطارات التي تفشل في فك الترميز (مفتاح خاطئ، بيانات مشوّهة، عنصر IE لبائع غير ذي صلة) يتم تخطيها بصمت — وتتوقف التكرارات فقط عند نهاية الملف (EOF).```python from pyrmax import pcap

for meta, packet in pcap.iter_ac("capture.pcap"): print( f"{meta.timestamp:.3f} " f"{meta.src_mac.hex(':')} → {meta.dst_mac.hex(':')} " f"{packet.msg_type.name:<10} " f"radio={packet.radioname!r} ssid={packet.ssid!r}" )

for meta, packet in pcap.iter_m("capture.pcapng"): print( f"{meta.timestamp:.3f} " f"{packet.msg_type.name:<10} " f"src={packet.src_mac.hex(':')} enable={packet.enable}" )

root@kitploit:~
`meta` هو `FrameMeta(timestamp, src_mac, dst_mac, bssid)`. استخراج القناة/مؤشر RSSI من radiotap موجود في قائمة TODO.

### استرجاع اسم الجهاز من IE الخاص بـ Routerboard.com

أطر AirMAX M تكون مصحوبة دائمًا تقريبًا بـ IE بائع من Mikrotik / Routerboard.com (OUI `00:0C:42`) في نفس إطار إدارة 802.11. يحمل الفرعي subtype-1 من IE اسم الجهاز.```python
from pyrmax import pcap

for meta, packet in pcap.iter_routerboard("capture.pcap"):
    print(f"{meta.src_mac.hex(':')}  →  {packet.device_name!r}")
    # "AP Sur HY1315"

وحدة فك ترميز Routerboard متاحة أيضًا بشكل مستقل — مرّر بيانات IE ابتداءً من OUI:```python from pyrmax import routerboard

packet = routerboard.decode(ie_data) packet.device_name # "AP Sur HY1315" packet.sub_ies # tuple of SubIe(subtype, data)

root@kitploit:~
قم بربط حزم Routerboard مع حزم M في نفس الالتقاط من خلال
مطابقة `meta.timestamp` + `meta.src_mac`.

### `scan` — ابحث عن الأجهزة الضعيفة

قم بفحص واجهة وضع المراقبة (أو ملف pcap) بحثًا عن أجهزة AirMAX وعلّم
أي منها ضعيف. يتطلب هذا الإضافة `[scan]` (`scapy`) وللالتقاط المباشر،
صلاحيات الجذر.```sh
# offline — scan a capture (no root)
python -m pyrmax scan capture.pcap

# live, passive — read versions only from traffic that happens to fly
sudo python -m pyrmax scan -i wlan0mon --channel 36

# live, active — force AirMAX AC APs to disclose their firmware
sudo python -m pyrmax scan -i wlan0mon --channel 36 --active

تحدد النسخة قابلية التأثر بشكل مختلف حسب النوع. رقما إصدار متورطان: إصدار بروتوكول تنسيق الإرسال المحمول في كل AirMAX IE (بما في ذلك الإشارات)، وإصدار البرنامج الثابت للـ AC (fwname) الذي ينتقل فقط في تبادل الارتباط.``` AirMAX AC ──> proto < 9 ? ──yes──────────────┐ │no ├──> VULNERABLE ▼ │ fw <= 8.7.20 ? ──yes───────────┘ ├──no───────> PATCHED └──unknown──> UNDETERMINED

AirMAX M ───> proto < 15 ? ──yes──> VULNERABLE └──no───────────> UNDETERMINED

root@kitploit:~
نظرًا لأن `proto` موجود في الـ beacon، يتم رصد الأجهزة **القديمة** (AC epoch < 9, M
version < 15) **بشكل سلبي**. يتطلب الوصول إلى حكم `PATCHED` لـ
AC إصدار البرنامج الثابت، لذا يحتاج إما إلى association ملتقطة
أو `--active` (المصافحة النشطة — auth → assoc → قراءة assoc-resp
`fwname` — هي تبادل محطة Ubiquiti كامل ومطابق بايتًا ببايت).

الخيارات: `--channel N` (تثبيت قناة واحدة، وإلا التنقل بين القنوات)، `--seconds N`،
`--cutoff X.Y.Z` (عرضة للثغرة إذا كان `fw <= cutoff`، الافتراضي `8.7.20`)،
`--src MAC` (المصدر للاستقصاء النشط، مثل نظير PTP)، `--vuln-only`،
`--no-set-channel`. رمز الخروج هو **3** عند العثور على أي جهاز عرضة للثغرة
(مفيد للبرمجة النصية)، وإلا يكون `0`.```
AirMAX: 5 device(s) (3 AC, 2 M), 2 vulnerable (AC fw <= 8.7.20 or protocol version below the fixed epoch).

  1c:6a:1b:00:00:01  AC  VulnAC            ch36   v8.7.19    VULNERABLE     rssi=-40dBm  peers=0
  1c:6a:1b:00:00:04  M   VulnM             ch36   v14        VULNERABLE     rssi=-42dBm  peers=0
  1c:6a:1b:00:00:03  AC  PatchedAC         ch36   v8.7.24    patched        rssi=-41dBm  peers=0
  1c:6a:1b:00:00:02  AC  UndetAC           ch36   epoch9     undetermined   rssi=-41dBm  peers=0
  1c:6a:1b:00:00:05  M   UndetM            ch36   v15        undetermined   rssi=-43dBm  peers=0

emulate — محاكاة أهداف AirMAX

قم ببث Beacon كجهاز واحد أو أكثر من أجهزة AirMAX AC/M الوهمية، وبالنسبة إلى AC، قم بالرد على مصافحة الاكتشاف بحيث يقرأ الماسح النشط إصدار البرنامج الثابت المُحاكى. يتطلب ذلك المكوّن الإضافي [emulate] (scapy)، وواجهة بوضع المراقبة، وصلاحيات الجذر. مفيد لاختبار scan دون أجهزة حقيقية.```sh sudo python -m pyrmax emulate -i wlan1mon --channel 36
-d ac/8.7.19/VulnAC -d ac/9/UndetAC -d ac/8.7.24/PatchedAC
-d m/14/VulnM -d m/15/UndetM

root@kitploit:~
كل `-d` (قابل للتكرار) هو `TYPE/VERSION[/SSID[/MAC]]`، مفصول بعلامة `/` بحيث تكون النقطتان في MAC آمنتين:

- `ac/8.7.19` — AC حديث، البرنامج الثابت `8.7.19` (الحقبة 9، يكشف `fwname`)
- `ac/9` — حقبة AC الحديثة، **بدون** سلسلة البرنامج الثابت → يرى الماسح
  `undetermined`
- `ac/7` — **قديم** AC، حقبة تنسيق الراديو 7 (< 9) → معرّض للخطر، يُكتشف من
  المنارة
- `m/14` — AirMAX M، الإصدار 14 (< 15) → معرّض للخطر
- `m/15` — AirMAX M عند الحقبة الثابتة → undetermined

بدون `-d`، تتم محاكاة أسطول تجريبي. `--no-respond` منارات فقط (AC
لن يكشف البرنامج الثابت عندها). إصدار برنامج AC الثابت موجود فقط في
`assoc-resp`، ولهذا السبب يوجد المُجيب.

### اختبار الاثنين معًا على جهاز واحد

`scripts/hwsim_testbed.sh` ينشئ راديين افتراضيين عبر `mac80211_hwsim`
بحيث يمكنك تشغيل `emulate` على أحدهما و`scan` على الآخر دون أي عتاد:```sh
sudo ./scripts/hwsim_testbed.sh up 36    # prints EMU_IFACE / SCAN_IFACE
# ...run emulate on EMU_IFACE and scan on SCAN_IFACE (two terminals)...
sudo ./scripts/hwsim_testbed.sh down

scripts/demo_5_devices.sh يقوم بالعملية كاملة من البداية إلى النهاية — يشغّل أجهزة الراديو، ويحاكي أسطول الأجهزة الخمسة أعلاه، وينفّذ scan --active، ثم يوقف كل شيء:```sh sudo ./scripts/demo_5_devices.sh 36

root@kitploit:~
### معالجة الأخطاء

تؤدي حالات عدم تطابق المخطط وفشل السلامة إلى إثارة `pyrmax.DecodeError`. السبب
الأكثر شيوعًا هو مفتاح خاطئ (عنوان `src_mac` / `dst_mac` خاطئ مُقدَّم إلى
`decode()` للإطار المعني).```python
from pyrmax import ac, DecodeError

try:
    packet = ac.decode(data, src_mac=src, dst_mac=dst)
except DecodeError as exc:
    print(f"skipping frame: {exc}")

إضافات اختيارية

  • pip install pyrmax[pcap] (أو uv sync --extra pcap) — يجلب dpkt بحيث يمكن لـ pyrmax.pcap.iter_ac(path) / iter_m(path) بثّ الحزم من ملفات الالتقاط .pcap أو .pcapng (نوع الرابط DLT_IEEE802_11_RADIO). يتم اكتشاف الصيغة تلقائيًا من الرقم السحري للملف.
  • pip install pyrmax[live] — يضيف pcapy-ng للالتقاط المباشر من واجهة لاسلكية بوضع المراقبة. يُستخدم بواسطة خيار -i / --iface في CLI ومولّد pyrmax.pcap.iter_airmax_live(iface) البرمجي.
  • pip install pyrmax[scan] — يضيف scapy لأمر scan (الالتقاط/فك التشفير المباشر + مصافحة force-assoc النشطة).
  • pip install pyrmax[emulate] — يضيف لأمر (حقن إشارات beacon + الرد على مصافحة الاكتشاف كأجهزة مزيفة).

ثبّت عدة إضافات معًا، مثل: uv sync --extra scan --extra emulate.

التخطيط```

pyrmax/ ├── ksy/ # Kaitai Struct source schemas │ ├── airmax_ac.ksy # AC cleartext outer header (payload decode is hand-written in ac.py) │ ├── airmax_m.ksy # M outer (OUI marker + encrypted blob) │ ├── airmax_m_payload.ksy # M decrypted payload (9 documented bytes) │ └── routerboard.ksy # Mikrotik / Routerboard.com vendor IE ├── src/pyrmax/ │ ├── init.py │ ├── ac.py # AC decode/encode API + AcPacket dataclass │ ├── m.py # M decode/encode API + MPacket dataclass │ ├── routerboard.py # Routerboard IE decoder + RouterboardPacket │ ├── pcap.py # iter_ac / iter_m / iter_routerboard / iter_airmax / iter_airmax_live │ ├── devices.py # summarize() — per-device aggregation │ ├── vuln.py # firmware-version parse + is_vulnerable() │ ├── scan.py # Scanner — live/pcap discovery + active handshake + vuln verdict │ ├── emulate.py # Emulator — fake AC/M targets (scapy) │ ├── main.py # python -m pyrmax CLI │ ├── exceptions.py │ ├── _crypto.py # AES-128-ECB + HMAC-SHA1 KDF (internal) │ └── _generated/ # kaitai-struct-compiler output (committed) ├── scripts/ │ ├── hwsim_testbed.sh # two virtual radios (mac80211_hwsim) for scan<->emulate │ └── demo_5_devices.sh # end-to-end 5-device emulate + scan demo └── tests/ ├── samples/ # raw frame captures (currently empty) ├── test_ac.py ├── test_m.py ├── test_crypto.py ├── test_pcap.py ├── test_routerboard.py ├── test_devices.py ├── test_cli.py └── test_integration.py # real-capture round-trips

root@kitploit:~
## التطوير```sh
uv sync                    # create .venv and install runtime + dev deps
uv run pytest              # run tests
uv run ruff check          # lint
uv run pyright             # static type check

التكوين موجود في pyproject.toml ([tool.pyright]):

  • typeCheckingMode = "basic" — يكتشف المشاكل البنيوية دون الاصطدام بحدود dpkt / kaitaistruct / pycryptodome (هذه الحزم لا توفر كعوب أنواع).
  • src/pyrmax/_generated/ مستبعد — الملفات المولّدة بواسطة Kaitai تحمل بالفعل # type: ignore وتُستبدل في كل تشغيل لـ kaitai-struct-compiler.
  • الحدود مع dpkt التي تلمس سمات ديناميكية (مثل MGMT_Frame.src) يتم عبورها باستخدام ترميز Any على الربط المحلي بدلاً من تعليقات ignore المتناثرة.

إعادة توليد محللات Kaitai

ملفات Python المولّدة تحت src/pyrmax/_generated/ مضمّنة في المستودع حتى تُثبَّت الحزمة دون سلسلة أدوات Kaitai. لإعادة التوليد بعد تعديل ملف .ksy:```sh kaitai-struct-compiler -t python --outdir src/pyrmax/_generated/ ksy/*.ksy

root@kitploit:~
تنزيل الأداة
field_14
field_9c
sta_field_68
ic_6b8
enc_token
docs/ac_wire_format.md
  • التحقق من مفككات AC ذات version < 9 مقابل التقاطات حقيقية — مُنشئ الإرسال (TX builder) يُصدر الإصدار 9 فقط، لذا المسارات ذات الإصدار الأقل (اسم غير موسوم، وحقول ذيل مفقودة) مطبَّقة وفق المواصفات لكن غير مُتحقَّق منها على الشبكة.
  • هندسة بقية حمولة M عكسيًا (البايتات من 9 فما فوق في unknown_rest) — معتمة حاليًا.
  • إظهار بيانات radiotap الوصفية في pcap.FrameMeta: القناة، RSSI، المعدل. حاليًا يتم تعبئة الطابع الزمني/عناوين MAC/BSSID فقط.
  • نماذج التقاط حقيقية (fixtures) في tests/samples/ — حاليًا: airmax_ac_beacon.pcap (إطار واحد، beacon) و airmax_m_probe_response.pcap (إطار واحد، استجابة probe). المزيد من الأنواع (assoc req/resp، التقاطات متعددة الإطارات) ما زالت مرحّبًا بها.
  • إرسال الحزم — أمرا scan (فرض الارتباط النشط force-assoc) وemulate يحقنان الحزم عبر scapy (إضافتا [scan] / [emulate]). انظر scan.py / emulate.py.
  • scapy
    emulate