Host header differs from Target in handshake request for WebSocket

Question:

I am intercepting WebSocket traffic from the garage door opener app called Linear (iOS/Android) and it looks to use Azure guessing by the domain names (trafficmanager.net, cloudapp.net, etc…).

When it makes it’s initial HTTP request to upgrade to WebSocket, it sends this request to https://linr-cs-tm-prod.trafficmanager.net:8080 though the Host header is 11323322-00AC-55F0-C09E-A903E123A25C:

picture of burp repeater showing HTTP request to upgrade to websocket

When I try to replicate this in Python:

SERVICE_URL = "ws://linr-cs-tm-prod.trafficmanager.net:8080/Message.svc"
class Linear:
    """Class used for a Linear account."""

    message_id = 0

    async def login(self: Linear, email: str, password: str):
        """Login to a linear account."""
        async with websockets.connect(
            SERVICE_URL,
            origin="LinAccess-Android/1.3.16",
            open_timeout=30,
        ) as websocket:
            print("connected!")

    async def get_sites():
        """Get sites available under this account."""

It just results in a TimeoutError.

What do I set as Host?
Why is Host set this way?
Is the random ID as a Host an artifact of Burp?
Or is this a requirement for Azure?

I’ve tried extracting the CA certificate and using that as SSL context, removing the Host header, setting SSL to false, and changing ws to wss.

Asked By: IceBotYT

||

Answers:

I solved this by switching from the websockets library to aiohttp‘s websocket library.

Answered By: IceBotYT