jclehner / bcm2-utils

Utilities for Broadcom-based cable modems
GNU General Public License v3.0
142 stars 23 forks source link

Telnet on tc7200 #31

Open madushan1000 opened 3 years ago

madushan1000 commented 3 years ago

I gained access to the linux running on the above router using the "admin:broadcom" credentials, from there I can dump mtd0, mtd1 and mtd2, mtd4 and mtd5 dumps corrupted I think because race conditions between linux and eCos. I can also dump the complete 128MB ram image using /dev/mem. Looks like it contains eCos symbols too. I can also export and restore Gatewaysettings.bin from from the web ui.

userif secetions are present, but telnet username and password are empty. that section is completely missing from the Gatewaysettings.bin

  userif = {
    http_user = "admin"
    http_pass = "admin"
    http_admin_user = ""
    http_admin_pass = "aDm1n$TR8r"
    remote_acc_methods = telnet | ssh
    remote_acc_user = ""
    remote_acc_pass = ""
    telnet_ipstacks = IP1 | IP2 | IP5
    ssh_ipstacks = IP1 | IP2 | IP5
    remote_acc_timeout = 0
    http_ipstacks = IP1 | IP2 | IP3 | IP5
    http_adv_ipstacks = IP1 | IP2 | IP3
    http_seed = ""
    http_acl_hosts =
    http_idle_timeout = 60
  }

I tried altering mtd2(dynnv) using bcm2cfg and writing it back using dd and openwrt mtd tool, but linux doesn't let me write to mtd2, is there a way around this? Or way of adding userif section to Gatewaysettings.bin and restoring it?

An interesting thing to note is that mtd device is marked in linux as MTD_BIT_WRITEABLE(flag 0x800). I can share the ramdump if it would help.

madushan1000 commented 3 years ago

Tried setting username/password via snmp too but looks like it's locked out Error in packet. Reason: notWritable (That object does not support modification) Failed object: SNMPv2-SMI::enterprises.4413.2.2.2.1.1.1.2.0

madushan1000 commented 3 years ago

Looks like the entire dynnv is mapped to ram, If I dump that section and run it trough bcm2cfg, I can see this.

  userif = {
    http_user = "admin"
    http_pass = "admin"
    http_admin_user = ""
    http_admin_pass = "aDm1n$TR8r"
    remote_acc_methods = telnet | ssh
    remote_acc_user = "admin"
    remote_acc_pass = "admin"
    telnet_ipstacks = IP1 | IP2 | IP5
    ssh_ipstacks = IP1 | IP2 | IP5
    remote_acc_timeout = 0
    http_ipstacks = IP1 | IP2 | IP3 | IP5
    http_adv_ipstacks = IP1 | IP2 | IP3
    http_seed = ""
    http_acl_hosts =
    http_idle_timeout = 60
  }

the telnet credentials doesn't work though. I'm wondering if I have to somehow add IP3 to telnet_ipstacks.

jclehner commented 3 years ago

Hi Madushan,

I can also dump the complete 128MB ram image using /dev/mem. Looks like it contains eCos symbols too.

The ram is shared between the two processors (one running eCos, the other Linux), so this is expected.

userif secetions are present, but telnet username and password are empty. that section is completely missing from the Gatewaysettings.bin. Or way of adding userif section to Gatewaysettings.bin and restoring it?

The userif section in the TC7200's GatewaySettings.bin file uses a special format - basically it'll export and import only a few settings from that group. This is why you can't do stuff like enabling telnet using a crafted GatewaySettings.bin file.

I tried altering mtd2(dynnv) using bcm2cfg and writing it back using dd and openwrt mtd tool, but linux doesn't let me write to mtd2, is there a way around this? An interesting thing to note is that mtd device is marked in linux as MTD_BIT_WRITEABLE(flag 0x800).

As far as I remember, the Linux flash driver on this device is just a virtual one, while the heavy lifting is done by eCos. The two communicate using some form of IPC. Writing to the nvram may have been intentionally disabled (if it has been implemented at all). What errors do you get? Also, can you post your dmesg?

Looks like the entire dynnv is mapped to ram.

This could also be just a buffer from the eCos side storing the nvram contents. What physical address?

The telnet credentials doesn't work though. I'm wondering if I have to somehow add IP3 to telnet_ipstacks.

You definitely don't want telnet enabled on IP3, which is the modem's public IP address. IP2 and IP5 both refer to the modem's local IP (192.168.100.1 and 192.168.0.1, respectively).

Tried setting username/password via snmp too but looks like it's locked out.

Before doing SNMP stuff, make sure you unplug the coaxial cable, and then reset the device to factory settings. Also, have you tried the following MIBs?

cmTelnetUserName.0 / 1.3.6.1.4.1.2863.205.1.1.75.2.0 (STRING) cmTelnetPassword.0 / 1.3.6.1.4.1.2863.205.1.1.75.3.0 (STRING)

On my TC7200, the firmware would ignore the telnet credentials set in userif, only accepting those set via SNMP (which is usually done by your ISP once the modem has registered on their network - this is why you should unplug the coax).

madushan1000 commented 3 years ago

I actually tried writing back to the ram region that looked like nvram section is mapped to, it turned out it's actually a buffer, and it changes the address every reboot.

I'm just trying these on a router bought on ebay and not connected to cable network at all(wouldn't work anyway since the old ISP has provisioned it it there is no way to clean up the certificates to provision with my ISP).

Just to be clear, when I disable the firewall, I can access both telnet and ssh servers running on eCos side from the local network, so they're both enabled. I just don't know the credentials. I'll try your mibs(I'm not sure if they will work since I tried a couple of mibs I found in the ram dump already) and get the dmesg. Thank you for the help :)

jclehner commented 3 years ago

No problem. Which firmware version is this? Also, can't you snmpget those MIBs, even if modifying them isn't supported?

EDIT: yes, I'd be interested in a RAM dump. The eCos image is loaded at offset 0x4000 (physical address), and is likely < 32 megabytes in size.

madushan1000 commented 3 years ago

Firmware version listed on the webui is STDC.01.31 I think the firmware image name is TC7200.20-DC.01.31-170802-F-5FF.bin the string was in the ram dump.

When I try the mibs, I get errors like this, tried using the "public" string too.

snmpget -v2c -c private 192.168.6.1 1.3.6.1.4.1.2863.205.1.1.75.2.0                                                                                      130 ↵
SNMPv2-SMI::enterprises.2863.205.1.1.75.2.0 = No Such Object available on this agent at this OID

 snmpset -v2c -c private 192.168.6.1 1.3.6.1.4.1.2863.205.1.1.75.3.0  s "admin"                                                                             
Error in packet.
Reason: notWritable (That object does not support modification)
Failed object: SNMPv2-SMI::enterprises.2863.205.1.1.75.3.0

What's your email address? I'll share the ram dump on google drive or something.

madushan1000 commented 3 years ago

Meanwhile I realized that router is vulnerable to cablehunt, I'm trying to adopt one of the exploits out there, hopefully that might work.

jclehner commented 3 years ago

What's your email address?

See here.

Meanwhile I realized that router is vulnerable to cablehunt.

True. With the ram dump, and r/w access to /dev/mem, getting/modifying the telnet credentials should be a piece of cake in any case though!

madushan1000 commented 3 years ago

I actually figured out how to bypass the login prompts of telnet server by directly writing to the program memory. I'll write a blog post or something soon. I'll send you an actual firmware dump when I figure out how to set an actual password for telnet server and get rid of this spam log

Scanning DS Channel at 624250000 Hz...(ExhaustiveA.250)
Scanning DS Channel at 623250000 Hz...(ExhaustiveA.250)
Scanning DS Channel at 622250000 Hz...(ExhaustiveA.250)
Scanning DS Channel at 621250000 Hz...(ExhaustiveA.250)
Scanning DS Channel at 620250000 Hz...(ExhaustiveA.250)
Scanning DS Channel at 619250000 Hz...(ExhaustiveA.250)
Scanning DS Channel at 618250000 Hz...(ExhaustiveA.250)
Scanning DS Channel at 617250000 Hz...(ExhaustiveA.250)
Scanning DS Channel at 616250000 Hz...(ExhaustiveA.250)
jclehner commented 3 years ago

At the eCos prompt, type

Console> su 
brcm
CM> /docsis_ctl/scan_stop
madushan1000 commented 3 years ago

Yeah, figured it out too ;) I've tried setting a telnet password as described here https://github.com/jclehner/tc7200/blob/bf8d31aef02a91e19bc9072c956e77386d026546/README.md as well as trough snmp, but looks like it doesn't persist.

madushan1000 commented 3 years ago

I wasn't able to successfully set the telnet credentials, looks like they're just disabled outright. Had do so a small modification to bcm2dump to get it to dump the firmware trough a password less telnet prompt. I'll send you the image1 dump via email.

diff --git a/interface.cc b/interface.cc
index c07f50b..9747f8e 100644
--- a/interface.cc
+++ b/interface.cc
@@ -60,7 +60,7 @@ bool is_bfc_prompt(const string& str)
 bool is_bfc_login_prompt(const string& line)
 {
    return contains(line, "Login:") || contains(line, "login:")
-       || contains(line, "Username:") || contains(line, "username:");
+       || contains(line, "Username:") || contains(line, "username:") || contains(line, "Console");
 }

 bool is_char_device(const string& filename)
@@ -477,7 +477,7 @@ bool bfc_telnet::login(const string& user, const string& pass)
    writeln(user);

    have_prompt = foreach_line_raw([] (const string& line) {
-       if (contains(line, "Password:") || contains(line, "password:")) {
+       if (contains(line, "Password:") || contains(line, "password:") || contains(line, "Console")) {
            return true;
        }
madushan1000 commented 3 years ago

BTW I found this partial source of bcm proprietary components here, a lot of important parts are missing though, https//github.com/mlewertTiVo/google-stb.platform.vendor.broadcom.refsw

madushan1000 commented 3 years ago

Any idea if "allow_config/factory mode" nvram parameter will enable the snmp agent to expose rw telnet config on the lan? It's stored in permnv, and I think it's used to be the case that "allow_config" function at /non-vol/snmp_cm would write that config to the nvram, but now it just reboots the modem. I tried patching the nvram write function in program memory to write this bit to nvram but it crashes I think due to some sort of a checksum issue. bcm2-cfg can't read or modify this section in permnv or dynnv either :/

jclehner commented 3 years ago

BTW I found this partial source of bcm proprietary components here

Interesting find though, especially regarding the permnv format of userif, which, according to this file has three fields I wasn't aware of, since they don't show up in the corresponding /show command, namely fPermanentRemoteAccessEnable, fPermanentRemoteAccessUserName and fPermanentRemoteAccessPassword.

I've updated the group definition accordingly, however these fields are undefined on my TC7200 - they are all 0xff. Since this isn't a valid string encoding, I've set their type to nv_data for now, which means that you can't set them as if they were a string. Instead you'll have to specify all 16 bytes as a hex string, i.e. to set the username to foobar, use

bcm2cfg -f perm set permnv.bin userif.remote_access_user 666f6f62617200000000000000000000 permnv_modded.bin

Any idea if "allow_config/factory mode" nvram parameter will enable the snmp agent to expose rw telnet config on the lan?

Can't say, however it does enable some configration options, according to the help text:

CM/NonVol/CM SNMP NonVol> ? allow_config

COMMAND:  allow_config

USAGE:  allow_config  [true|false]

DESCRIPTION:
Enables/disables configuration of various sytem components which are
not normally configurable in standard operational mode.  Also in some
ways affects system behaviour.  This should more properly be called
'factory_mode' because in general it is used to support factory mode
things like US/DS calibration, etc.

Note that setting this to 'true' will set the Broadcom private MIB
object cdPrivateMibEnable to engineering(2), which will expose both
the cableDataPrivateFactory and cableDataPrivateEngineering branches.
Setting it to 'false' will set cdPrivateMibEnable to disabled(0), which
will result in both of these branches being hidden.

EXAMPLES:
allow_config true  -- Enables configuration / factory mode.

It's stored in permnv, and I think it's used to be the case that "allow_config" function at /non-vol/snmp_cm would write that config to the nvram, but now it just reboots the modem.

It appears to work on my device, but it's being reset to false on the next reboot.

CM/NonVol/CM SNMP NonVol> allow_config true

Vendor CM Agent w/ BRCM Factory Support entering factory mode.
Vendor CPE Agent w/ BRCM Factory Support entering factory mode.
Vendor CPE Agent w/ BRCM Factory Support setting V1/V2 view to docsisNmAccessView
Vendor CM Agent w/ BRCM Factory Support populating engineering bridges.
AllowConfiguration = 1
(FYI, cdPrivateMibEnable = 2)

CM/NonVol/CM SNMP NonVol> write perm 

Permanent Non-Vol Settings successfully written to the device.

CM/NonVol/CM SNMP NonVol>

I tried patching the nvram write function in program memory to write this bit to nvram but it crashes I think due to some sort of a checksum issue. bcm2-cfg can't read or modify this section in permnv or dynnv either :/

I'll add support for this group in bcm2cfg in the near future (think 1-2 weeks).

madushan1000 commented 3 years ago

Hmm, I tried writing the modified permnv and I get this error: rwx does not support write capability Do I have to alter the device profile to get working?

jclehner commented 3 years ago

I just remembered, writing is not yet supported from the BFC console, only from the bootloader. However I've tried the modifications myself, to no avail. I still can't login via telnet unless I set the password manually from the eCos console, using

CM> /snmp/set (0-) cmTelnetUserName s username
CM> /snmp/set (0-) cmTelnetPassword s password

Actually, I've successfuly set the login credentials using SNMP from my computer too, after calling

CM> /non-vol/snmp_cm/allow_config true

Note however that this only works when using 192.168.100.1, not 192.168.0.1 or 192.168.1.1:

$ snmpset -v2c -c public 192.168.0.1 1.3.6.1.4.1.2863.205.1.1.75.3.0 s foobar 
Error in packet.
Reason: noAccess
Failed object: iso.3.6.1.4.1.2863.205.1.1.75.3.0

but

$ snmpset -v2c -c public 192.168.100.1 1.3.6.1.4.1.2863.205.1.1.75.2.0 s username
iso.3.6.1.4.1.2863.205.1.1.75.2.0 = STRING: "username"
$ snmpset -v2c -c public 192.168.100.1 1.3.6.1.4.1.2863.205.1.1.75.3.0 s password
iso.3.6.1.4.1.2863.205.1.1.75.3.0 = STRING: "password"

Also, as I've mentioned before, allow_config doesn't appear to be persisted across reboots, so this doesn't really get us any further...

madushan1000 commented 3 years ago

I think the allow_config bit has to be read from permnv, and as far as I saw at least on my firmware, permnv write is hardcoded to write 0 to permnv. Try patching that instruction to write 1. It might work for you. All it did for me was reboot the router. I'll try and see if I can reach 192.168.100.1 when I get some time.

jclehner commented 3 years ago

I'll add support for this group in bcm2cfg in the near future (think 1-2 weeks).

It was a short 1-2 weeks apparently.

However, this still won't help you, unfortunately. At least on my device it isn't the write but the read function that automatically resets the allow_config parameter. So the only way to persist this setting across reboots would be to flash a modified firmware, as live-patching the RAM won't help you.

madushan1000 commented 3 years ago

Hmm, do you know if this device supports flashing unsigned firmware?

jclehner commented 3 years ago

It does. Signatures are only checked during a regular software upgrade, but not by the bootloader.

Also, this is a device where the bootloader serial console is enabled, so you'll just need a USB-TTL adapter and you're good to go. You don't even need bcm2dump - the bootloader has an option to download an image (via TFTP) and run it directly from RAM, or store it on the flash chip.

madushan1000 commented 3 years ago

I already opened up the device and I can see there are two unpopulated uart ports. I'll try soldering a header when I get some time. Meanwhile I got a new router which supports docsis 3.1, technicolor cga4322de. Unfortunately, no telnet/ssh only the web interface(running on RG ip) and stripped down snmp running on the CM ip.

jclehner commented 3 years ago

Meanwhile I got a new router which supports docsis 3.1, technicolor cga4322de. Unfortunately, no telnet/ssh only the web interface(running on RG ip) and stripped down snmp running on the CM ip.

For that device, please open a new issue to keep things separate!

Bananz0 commented 2 years ago

Hello, I'm using a uart spi tool to connect to the router. I could try to flash the unsigned firmware but could use your help. Also is it possible to build an OpenWRT for this router?

maciejopalinski commented 11 months ago

How to enable the eCos console? In my case UART prints the bootlog, but does not show the eCos console.