Skip to main content

Use of an insecure channel - Telnet

Need

Secure transmission of customer information

Context

  • Usage of Python 3 for developing applications and scripts
  • Usage of telnetlib for establishing and managing Telnet connections

Description

Non compliant code

import telnetlib
def send_data(host, user, password, data):
telnet = telnetlib.Telnet(host)
telnet.read_until(b"login: ")
telnet.write(user.encode('ascii') + b"\\n")
telnet.read_until(b"Password: ")
telnet.write(password.encode('ascii') + b"\\n")
telnet.write(data.encode('ascii') + b"\\n")
telnet.write(b"exit\\n")
print(telnet.read_all().decode('ascii'))

The above code is a simple example of how data can be sent over an insecure channel using telnet in Python. Here, the function send_data is used to send the data to a specified host.

The host, username, password, and data are passed as parameters to the send_data function. The telnetlib.Telnet(host) is used to connect to the host. The read_until function is used to wait until the specified byte string is received, in this case "login: " and "Password: ". The write function is used to send the username, password, and data over the telnet connection.

The main vulnerability in this code lies in the use of the insecure telnet protocol for transmitting sensitive information. Telnet does not use encryption, so all the data sent over the telnet connection, including the username and password, are sent in plain text. This makes it possible for an attacker who is able to intercept the communication to easily read and capture the data. This is a serious security risk, especially when transmitting sensitive information like customer data or login credentials.

Steps

  • Replace the Telnet protocol with a secure protocol such as SSH. SSH provides strong password and public key authentication, secure data communications, and data integrity.
  • Use a library that supports SSH, such as Paramiko in Python.
  • Ensure that the data is encrypted before it is sent over the network. This can be done using the encryption features provided by the SSH protocol.
  • Validate the server's identity to prevent man-in-the-middle attacks. This can be done by checking the server's public key against a list of known keys.
  • Ensure that the user's credentials are securely stored and not hard-coded into the application. They should be retrieved from a secure location at runtime.

Compliant code

import paramiko

def send_data(host, user, password, data):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=user, password=password)

stdin, stdout, stderr = ssh.exec_command(data)
print(stdout.read().decode('ascii'))
ssh.close()

The above code uses the Paramiko library, which is a Python implementation of the SSHv2 protocol. This provides secure channels for data communication, replacing the insecure Telnet protocol.

Here's a breakdown of the changes:

  1. Import Paramiko: We import the Paramiko library, which allows us to establish SSH connections.

  2. Create SSH Client: We create an SSH client object. This will allow us to interact with the remote server using SSH.

  3. Set Missing Host Key Policy: We set the missing host key policy to AutoAddPolicy(). This means that Paramiko will automatically add the server's public key if it's not already known. This is not the most secure option, as it leaves you vulnerable to man-in-the-middle attacks. In a production environment, you should have a list of known host keys and check the server's key against this list.

  4. Connect to Server: We connect to the server using the user's credentials. These should be securely stored and retrieved from a secure location at runtime.

  5. Execute Command: We execute the command on the server and print the output. The command is sent over the secure SSH channel, so it can't be intercepted in plain text.

  6. Close Connection: Finally, we close the SSH connection.

This code ensures that customer information is transmitted over a secure channel, protecting it from being captured in plain text.

References