Allow arbitrary command to be issued as hex

- Confirmed working on TP-Link Archer C9 on both W-LAN and LAN
- Changed -c switch to allow arbitrary two-character hex commands to be sent, e.g. -c 0E
- Preliminary Archer C9 commands and return data documented in comments
This commit is contained in:
softScheck GmbH 2016-10-10 16:06:04 +02:00 committed by GitHub
parent e342b7d688
commit 336b0dc46f
1 changed files with 31 additions and 22 deletions

View File

@ -29,8 +29,9 @@ import argparse
import socket
import struct
import binascii
import string
version = 0.1
version = 0.2
# Default username and password
username = "admin"
@ -44,30 +45,30 @@ def validIP(ip):
parser.error("Invalid IP Address.")
return ip
# Check if command is two hex chars
def validHex(cmd):
ishex = all(c in string.hexdigits for c in cmd)
if len(cmd) == 2 and ishex:
return cmd
else:
parser.error("Please issue a two-character hex command, e.g. 0A")
# Parse commandline arguments
parser = argparse.ArgumentParser(description="Experimental TP-Link TDDPv2 Client v" + str(version))
parser.add_argument("-v", "--verbose", help="Verbose mode", action="store_true")
parser.add_argument("-t", "--target", metavar="<ip>", required=True, help="Target IP Address", type=validIP)
parser.add_argument("-u", "--username", metavar="<username>", help="Username (default: admin)")
parser.add_argument("-p", "--password", metavar="<password>", help="Password (default: admin)")
# We only allow three different CMD_SPE_OPR commands that read out values from the target device
# Other values can potentially be write commands and modify the device
commands = {'test1':"0A", 'test2':"12", 'test3':"14"}
parser.add_argument("-c", "--command", metavar="<command>", help="Preset command to send. Choices are: "+", ".join(commands), choices=commands)
parser.add_argument("-c", "--command", metavar="<hex>", required=True, help="Command value to send as hex (e.g. 0A)", type=validHex)
args = parser.parse_args()
# Set Target IP, username and password to calculate DES decryption key for data and command to execute
ip = args.target
cmd = args.command
if args.username:
username = args.username
if args.password:
password = args.password
if args.command is None:
cmd = "12"
else:
cmd = commands[args.command]
# TDDP runs on UDP Port 1040
# Response is sent to UDP Port 61000
@ -151,6 +152,15 @@ tddp_id = "0001"
# 0x06 changes MAC
# 0x13 changes deviceID
# 0x15 changes deviceID
#
# Subtypes that seem to work for an Archer C9 Router:
# 0x0E returns physical status of WAN link:
# wan_ph_link 1 0 = disconnected
# wan_ph_link 1 1 = connected
# 0x0F returns logical status of WAN link: wan_logic_link 1 0
# 0x0A returns \x00\x09\x00\x01\x00\x00\x00\x00
# 0x15 returns \x01\x00\x00\x00\x00\x00\x00\x00
# 0x18 returns 1
tddp_subtype = cmd
# Reserved
@ -206,4 +216,3 @@ print "Reply Data:\tVersion", r[0:2], "Type", r[2:4], "Status", r[6:8], "Length"
recv_data = r[56:]
if recv_data:
print "Decrypted:\t" + key.decrypt(binascii.unhexlify(recv_data))