Skip to content

Commit

Permalink
Use UDP (DGRAM) instead of TCP (SOCK_STREAM)
Browse files Browse the repository at this point in the history
Changed max length of input password to 24 characters
  • Loading branch information
insanid committed Feb 1, 2015
1 parent 8ec2909 commit 445c972
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions telnetenable.py 100644 → 100755
Expand Up @@ -59,8 +59,8 @@ def GeneratePayload(mac, username, password=""):
assert(len(username) <= 0x10)
just_username = username.ljust(0x10, "\x00")

assert(len(password) <= 0x10)
just_password = password.ljust(0x10, "\x00")
assert(len(password) <= 0x18)
just_password = password.ljust(0x18, "\x00")

cleartext = (just_mac + just_username + just_password).ljust(0x70, '\x00')
md5_key = MD5.new(cleartext).digest()
Expand All @@ -73,7 +73,7 @@ def GeneratePayload(mac, username, password=""):


def SendPayload(ip, payload):
for res in socket.getaddrinfo(ip, TELNET_PORT, socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_IP):
for res in socket.getaddrinfo(ip, TELNET_PORT, socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_IP):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
Expand Down

9 comments on commit 445c972

@Robertof
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about allowing passwords up to 24 characters? The original structure of the packet is:

struct payload
{
    char signature[0x10];
    char mac[0x10];
    char username[0x10];
    char password[0x10];
    char reserved[0x40];
};

Does this mean that the reserved portion of the payload changed from being 0x40 bytes to 0x38 (since the packet length is always the same)?

@insanid
Copy link
Owner Author

@insanid insanid commented on 445c972 Feb 9, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With older Netgear routers the password was always 'Geardog', which is 7 characters, or not even close to the max limit of 16 or 0x10. This was fine until Netgear changed the daemon that listens for the payload to 1) only accept a payload over UDP and 2) use the password that is set for the web interface. For a stock Netgear router, the default password is 'password' in most cases, and this would work just fine with the max len being 0x10; however, considering the majority using telnetenable.py are advanced users who most likely have complicated passwords (either near or over the original 16 0x10 max len), I changed the max len to 0x18, or 24 characters. Without this change, if you have a password over 16 characters, the telnetenable.py will error out and not send a payload. With this change, it now works with passwords greater than 16 characters (which I personally have).

@Robertof
Copy link

@Robertof Robertof commented on 445c972 Feb 9, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@insanid
Copy link
Owner Author

@insanid insanid commented on 445c972 Feb 9, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, I am not really familiar with Python too much. I just figured out why the telnetenable.py wasn't working with my password that is greater than 16 characters: which was because of the limit of 16 characters in the password array and made the change after calculating an appropriate hex value for a max of 24--which is just an arbitrary limit to compensate for longer passwords. So as far as the payload is concerned, either the size of the payload is increasing because of the increase in characters from 16 to 24, and the reserved stays the same, or the reserved is being truncated to always remain the same size. One would have to use a packet sniffer to see what is actually occurring. Either way, it just works, and having access to longer passwords is always a good thing :)

@Robertof
Copy link

@Robertof Robertof commented on 445c972 Feb 9, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Robertof
Copy link

@Robertof Robertof commented on 445c972 Feb 9, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick update: it looks like what I said is correct. Here's the hexadecimal dump of the packet when a password longer than 16 chars is used (obviously the packet is not crypted in this dump, otherwise it'd be pointless).

As you can see, the reserved part (the highlighted one) gets indeed overwritten by the password. But if it works well then!

@insanid
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey nice work figuring that out! From your packet hex dump, it appears that reserved is not so "reserved" as we once thought it was, lol.

@Robertof
Copy link

@Robertof Robertof commented on 445c972 Feb 11, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so I did a couple more tests and here are my final deductions.

First, let's have a look at a standard, unencrypted, packet:

As it can be seen, each field has a length of 0x10 bytes (that is 16 bytes in decimal), while the mysterious reserved field has a length of 0x40 bytes (64 bytes). Everything is fine though, each field is within its maximum length.

Now, the problem is that since recent updates, Netgear requires the usage of the administrator credentials to create the packet. But what's the maximum length of the admin password? The Netgear admin interface tells us that it's 33 characters:

As we saw before, the password field must not be longer than 16 characters, otherwise it'd overflow in the reserved field. What happens, though, if we still try to increase the maximum password length? The result is this "abnormal" packet:

Now the password, long exactly 33 characters, has overflown in the "reserved area" zone, and this should be a problem. I say should because, when we try to use that packet...

It works! The conclusion may be:

  • Netgear changed the packet parsing method with the new firmwares, allowing packets with longer passwords, or...
  • The password field has always been designed to be longer, but for some reason the C structure specified in the original packet limited its length to 16 characters.

Either way, using packets with longer passwords should be safe. Older firmwares used the superuser's "Gearguy" credentials, and they were always shorter than 16 characters.

@insanid
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roberto, I am impressed at how much work you put into finding out what is going on with the payload packet being sent to unlock telnet. Thank you very much for finding out exactly what is going on with the packet now that the max password has been increased. BTW, I went ahead and updated the telnetenable.py script again to increase max password length to 33 characters or 0x21 hex.

Please sign in to comment.