postlund / pyatv

A client library for Apple TV and AirPlay devices
https://pyatv.dev
MIT License
838 stars 91 forks source link

Get the UDP random port communication used for screen sharing. #2289

Open pedroposeiro opened 7 months ago

pedroposeiro commented 7 months ago

What to investigate?

I am trying to setup Airplay protocol to be working accross two VLANs and with traffic just going through UDP and TCP proxies. No firewall and DNAT rules. For that reason I need to identify previously all the ports needed for communication. For Screen Sharing I have identified an addicional UDP communication using both source and destination random ports, but I didn't find where the port is being announced in order to estabilish in time the listening port for UDP proxy. image

Do you know if is is possible to intercept and decrypt the traffic providing details about this destination port? It looks related to RTSP and/or RAOP protocols.

Thank you in advance! Best!

Expected outcome

UDP port used for screen sharing

Frostie314159 commented 6 months ago

From what I've seen, a bplist is transmitted in the RTSP SETUP request, which contains a field called timingPort. Do not that this communication was captured from AWDL i.e. airplay-p2p.

Frostie314159 commented 6 months ago

Here is a textual representation of the plist, which I changed the name of for privacy reasons. Note the timingProtocol and timingPort fields.

{
    "et": Integer(
        32,
    ),
    "eiv": Data(
        [
            ...
        ],
    ),
    "timingProtocol": String(
        "NTP",
    ),
    "sessionUUID": String(
        "4A7ECEF3-7BBC-494D-B3C5-8E63284FEFA8",
    ),
    "osName": String(
        "iPhone OS",
    ),
    "osBuildVersion": String(
        "19G82",
    ),
    "sourceVersion": String(
        "620.8.2",
    ),
    "timingPort": Integer(
        61145,
    ),
    "isScreenMirroringSession": Boolean(
        true,
    ),
    "osVersion": String(
        "15.6.1",
    ),
    "ekey": Data(
        [
            ...
        ],
    ),
    "deviceID": String(
        "20:1A:94:C1:B9:C7",
    ),
    "model": String(
        "iPad12,1",
    ),
    "name": String(
        "Frostie314159",
    ),
    "macAddress": String(
        "BE:45:A1:D1:49:B6",
    ),
}
postlund commented 6 months ago

That port is unfortunate the least interesting one. The ones needed here (data and event ports) are communicated once the connection is encrypted.