Firmware Archaeology II: Return of the Devshell

In my last blog post I went through the GS108Tv2 / GS110TPv2 firwamre images. These are ProSafe-family switches manufacturered by Netgear. In this post we will look at the devshell we identitifed in the last post in order to determine any security impact of this devshell being available in production builds.

The devshell is available through the web interace of the switch at the URL path /base/devshell.html. Both the GET request which retrieves the UI and the POST request which actually executes the supplied command require a valid session identifier in the form of a SID cookie. This effectively means authentication is required to access the devshell.

Normally, this sort of developer shell should only be used in test environments and not compiled into the release builds. However, most of the time these sorts of shells execute OS commands; the devshell we are considering here does not execute OS commands but instead runs a predetermined list of commands that the developers chose. It appears this is mainly a diagnostic tool and not an arbitrary command execution shell. As such, does having this devshell available have any security impact on the device?

Enumeration

Let’s enumerate all the commands available through the devshell by analyzing the firmware. For this post we will focus on the latest firmware version, which is 5.4.2.33 as of this writing.

I can enumerate all the commands and their corresponding handler functions by doing a search for on of the commands in the Ghidra String search. I chose upTime, but any command from the list we enumerated in the last blog post will work.

When I navigate to the upTime string reference, I see the following disassembly output:

                             PTR_s_cablediag_80ef1390                        XREF[1]:     FUN_803bf9c8:803bfa1c (R)   
        80ef1390 80  9e  ec  5c    addr       s_cablediag_809eec5c                             = "cablediag"
                             PTR_LAB_80ef1394                                XREF[1]:     FUN_803bf9c8:803bfa38 (R)   
        80ef1394 80  07  81  4c    addr       LAB_8007814c
                             PTR_DAT_80ef1398                                XREF[1]:     FUN_803bf9c8:803bfa1c (R)   
        80ef1398 80  9e  ec  68    addr       DAT_809eec68                                     = 63h    c
        80ef139c 80  3c  06  ac    addr       FUN_803c06ac
        80ef13a0 80  9e  ec  6c    addr       s_changeMallocDebug_809eec6c                     = "changeMallocDebug"
        80ef13a4 80  3b  e0  5c    addr       LAB_803be05c
        80ef13a8 80  9e  ec  80    addr       s_cliInfoDump_809eec80                           = "cliInfoDump"
        80ef13ac 80  36  76  68    addr       FUN_80367668
        80ef13b0 80  9e  ec  8c    addr       s_cnfgrDump_809eec8c                             = "cnfgrDump"
        80ef13b4 80  29  e8  e0    addr       LAB_8029e8e0
        80ef13b8 80  9e  ec  98    addr       s_configClear_809eec98                           = "configClear"
        80ef13bc 80  2f  38  88    addr       LAB_802f3888
        80ef13c0 80  9e  ec  a4    addr       s_configDump_809eeca4                            = "configDump"
        80ef13c4 80  2e  8c  34    addr       LAB_802e8c34
        80ef13c8 80  9e  ec  b0    addr       s_configSave_809eecb0                            = "configSave"
        80ef13cc 80  2f  38  b0    addr       FUN_802f38b0
        80ef13d0 80  9e  ec  bc    addr       s_crashPrint_809eecbc                            = "crashPrint"
        80ef13d4 80  3b  c4  5c    addr       FUN_803bc45c
        80ef13d8 80  9e  ec  c8    addr       s_flashLogPrint_809eecc8                         = "flashLogPrint"
        80ef13dc 80  3b  c4  84    addr       FUN_803bc484
        80ef13e0 80  9e  ec  d8    addr       s_debugEwaSessionTableDump_809eecd8              = "debugEwaSessionTableDump"
        80ef13e4 80  3a  6e  5c    addr       FUN_803a6e5c
        80ef13e8 80  9e  ec  f4    addr       s_debugPolicyGroup_809eecf4                      = "debugPolicyGroup"
        80ef13ec 80  05  aa  c8    addr       LAB_8005aac8
        80ef13f0 80  9e  ed  08    addr       s_debugPolicyTable_809eed08                      = "debugPolicyTable"
        80ef13f4 80  05  4e  ec    addr       LAB_80054eec
        80ef13f8 80  9e  ed  1c    addr       s_debugTftp_809eed1c                             = "debugTftp"
        80ef13fc 80  3c  f3  9c    addr       LAB_803cf39c
        80ef1400 80  9e  ed  28    addr       DAT_809eed28                                     = 64h    d
        80ef1404 80  3c  00  08    addr       FUN_803c0008
        80ef1408 80  9e  ed  2c    addr       DAT_809eed2c                                     = 64h    d
        80ef140c 80  04  d5  4c    addr       FUN_8004d54c
        80ef1410 80  9e  ed  30    addr       DAT_809eed30                                     = 64h    d
        80ef1414 80  3b  fe  74    addr       LAB_803bfe74
        80ef1418 80  9e  ed  34    addr       s_dnsCfgDump_809eed34                            = "dnsCfgDump"
        80ef141c 80  2b  02  10    addr       FUN_802b0210
        80ef1420 80  9e  ed  40    addr       s_dnsClientTraceModeSet_809eed40                 = "dnsClientTraceModeSet"
        80ef1424 80  2b  01  f0    addr       LAB_802b01f0
        80ef1428 80  9e  ed  58    addr       s_dnsCountersDump_809eed58                       = "dnsCountersDump"
        80ef142c 80  2b  05  5c    addr       LAB_802b055c
        80ef1430 80  9e  ed  68    addr       s_dnsOperDataDump_809eed68                       = "dnsOperDataDump"
        80ef1434 80  2b  0c  b0    addr       LAB_802b0cb0
        80ef1438 80  9e  ed  78    addr       DAT_809eed78                                     = 64h    d
        80ef143c 80  2b  75  ac    addr       FUN_802b75ac
        80ef1440 80  9e  ed  80    addr       s_dtlDebug_809eed80                              = "dtlDebug"
        80ef1444 80  3b  98  08    addr       LAB_803b9808
        80ef1448 80  9e  ed  8c    addr       s_dtlEndStats_809eed8c                           = "dtlEndStats"
        80ef144c 80  3b  aa  b4    addr       FUN_803baab4
        80ef1450 80  9e  ed  98    addr       s_dtlMacToPortShow_809eed98                      = "dtlMacToPortShow"
        80ef1454 80  3b  bf  64    addr       LAB_803bbf64
        80ef1458 80  9e  ed  ac    addr       s_dtlNetDebugSet_809eedac                        = "dtlNetDebugSet"
        80ef145c 80  3b  94  0c    addr       LAB_803b940c
        80ef1460 80  9e  ed  bc    addr       s_dumpFdbStats_809eedbc                          = "dumpFdbStats"
        80ef1464 80  49  f8  84    addr       FUN_8049f884
        80ef1468 80  9e  ed  cc    addr       s_dumpMemory_809eedcc                            = "dumpMemory"
        80ef146c 80  3c  92  58    addr       FUN_803c9258
        80ef1470 80  9e  ed  d8    addr       s_dump_snmp_engine_id_809eedd8                   = "dump_snmp_engine_id"
        80ef1474 80  45  83  60    addr       LAB_80458360
        80ef1478 80  9e  ed  ec    addr       s_ecos_net_stats_809eedec                        = "ecos_net_stats"
        80ef147c 80  3c  5b  80    addr       FUN_803c5b80
        80ef1480 80  9e  ed  fc    addr       s_emwebDebugAccessSet_809eedfc                   = "emwebDebugAccessSet"
        80ef1484 80  3a  7e  c4    addr       FUN_803a7ec4
        80ef1488 80  9e  ee  10    addr       s_getBoardId_809eee10                            = "getBoardId"
        80ef148c 80  08  b3  70    addr       FUN_8008b370
        80ef1490 80  9e  ee  1c    addr       s_hapiBroadDebugPkt_809eee1c                     = "hapiBroadDebugPkt"
        80ef1494 80  04  6c  b8    addr       LAB_80046cb8
        80ef1498 80  9e  ee  30    addr       s_hapiBroadDebugPktFilterGet_809eee30            = "hapiBroadDebugPktFilterGet"
        80ef149c 80  04  6c  ec    addr       FUN_80046cec
        80ef14a0 80  9e  ee  4c    addr       s_hapiBroadDebugPktFilterSet_809eee4c            = "hapiBroadDebugPktFilterSet"
        80ef14a4 80  04  6d  1c    addr       FUN_80046d1c
        80ef14a8 80  9e  ee  68    addr       s_hapiBroadPolicyDebug_809eee68                  = "hapiBroadPolicyDebug"
        80ef14ac 80  07  49  c8    addr       FUN_800749c8
        80ef14b0 80  9e  ee  80    addr       DAT_809eee80                                     = 69h    i
        80ef14b4 80  2f  6d  74    addr       LAB_802f6d74
        80ef14b8 80  9e  ee  84    addr       s_ifconfig_809eee84                              = "ifconfig"
        80ef14bc 80  2f  6d  74    addr       LAB_802f6d74
        80ef14c0 80  9e  ee  90    addr       DAT_809eee90                                     = 6Ah    j
        80ef14c4 80  3b  fa  58    addr       LAB_803bfa58
        80ef14c8 80  9e  ee  98    addr       s_logClear_809eee98                              = "logClear"
        80ef14cc 80  2d  4c  d0    addr       FUN_802d4cd0
        80ef14d0 80  9e  ee  a4    addr       s_logConsole_809eeea4                            = "logConsole"
        80ef14d4 80  2d  04  b0    addr       FUN_802d04b0
        80ef14d8 80  9e  ee  b0    addr       s_logError_809eeeb0                              = "logError"
        80ef14dc 80  3c  98  48    addr       FUN_803c9848
        80ef14e0 80  9e  ee  bc    addr       s_logShow_809eeebc                               = "logShow"
        80ef14e4 80  2d  4f  a8    addr       LAB_802d4fa8
        80ef14e8 80  9e  ee  c4    addr       s_mbufFree_809eeec4                              = "mbufFree"
        80ef14ec 80  30  82  2c    addr       FUN_8030822c
        80ef14f0 80  9e  ee  d0    addr       s_mbufHistoryClear_809eeed0                      = "mbufHistoryClear"
        80ef14f4 80  30  74  44    addr       LAB_80307444
        80ef14f8 80  9e  ee  e4    addr       s_mbufHistoryDelete_809eeee4                     = "mbufHistoryDelete"
        80ef14fc 80  30  73  bc    addr       LAB_803073bc
        80ef1500 80  9e  ee  f8    addr       s_mbufHistoryDump_809eeef8                       = "mbufHistoryDump"
        80ef1504 80  30  74  bc    addr       LAB_803074bc
        80ef1508 80  9e  ef  08    addr       s_mbufHistoryInit_809eef08                       = "mbufHistoryInit"
        80ef150c 80  30  72  a0    addr       LAB_803072a0
        80ef1510 80  9e  ef  18    addr       s_mbufShow_809eef18                              = "mbufShow"
        80ef1514 80  30  76  08    addr       FUN_80307608
        80ef1518 80  9e  ef  24    addr       s_memCheck_809eef24                              = "memCheck"
        80ef151c 80  3b  d4  74    addr       LAB_803bd474
        80ef1520 80  9e  ef  30    addr       s_memShow_809eef30                               = "memShow"
        80ef1524 80  3b  ee  24    addr       LAB_803bee24
        80ef1528 80  9e  ef  38    addr       s_mmuConfig_809eef38                             = "mmuConfig"
        80ef152c 80  04  ec  a0    addr       FUN_8004eca0
        80ef1530 80  9e  ef  44    addr       s_mmuCount_809eef44                              = "mmuCount"
        80ef1534 80  05  21  a8    addr       LAB_800521a8
        80ef1538 80  9e  ef  50    addr       s_mmuState_809eef50                              = "mmuState"
        80ef153c 80  05  13  9c    addr       LAB_8005139c
        80ef1540 80  9e  ef  5c    addr       s_modMemory_809eef5c                             = "modMemory"
        80ef1544 80  3c  94  44    addr       FUN_803c9444
        80ef1548 80  9e  ef  68    addr       DAT_809eef68                                     = 6Dh    m
        80ef154c 80  3c  37  84    addr       FUN_803c3784
        80ef1550 80  9e  ef  70    addr       s_msgQprint_809eef70                             = "msgQprint"
        80ef1554 80  3c  3b  74    addr       LAB_803c3b74
        80ef1558 80  9e  ef  7c    addr       s_msgQshow_809eef7c                              = "msgQshow"
        80ef155c 80  3c  38  2c    addr       FUN_803c382c
        80ef1560 80  9e  ef  88    addr       s_nimDebugDump_809eef88                          = "nimDebugDump"
        80ef1564 80  2d  94  4c    addr       FUN_802d944c
        80ef1568 80  9e  ef  98    addr       s_nimPortDump_809eef98                           = "nimPortDump"
        80ef156c 80  2d  a4  14    addr       LAB_802da414
        80ef1570 80  9e  ef  a4    addr       s_nsdpDebugSet_809eefa4                          = "nsdpDebugSet"
        80ef1574 80  2e  88  d8    addr       LAB_802e88d8
        80ef1578 80  9e  ef  b4    addr       s_osapiDebugMallocDetail_809eefb4                = "osapiDebugMallocDetail"
        80ef157c 80  3b  dc  60    addr       LAB_803bdc60
        80ef1580 80  9e  ef  cc    addr       s_osapiDebugMallocDetailEnable_809eefcc          = "osapiDebugMallocDetailEnable"
        80ef1584 80  3b  db  7c    addr       LAB_803bdb7c
        80ef1588 80  9e  ef  ec    addr       s_osapiDebugMallocSummary_809eefec               = "osapiDebugMallocSummary"
        80ef158c 80  3b  d1  b0    addr       FUN_803bd1b0
        80ef1590 80  9e  f0  04    addr       s_osapiDebugMemoryInfo_809ef004                  = "osapiDebugMemoryInfo"
        80ef1594 80  3b  da  54    addr       LAB_803bda54
        80ef1598 80  9e  f0  1c    addr       s_osapiDebugMemoryStats_809ef01c                 = "osapiDebugMemoryStats"
        80ef159c 80  3b  d8  24    addr       FUN_803bd824
        80ef15a0 80  9e  f0  34    addr       s_osapiDebugMsgQueuePrint_809ef034               = "osapiDebugMsgQueuePrint"
        80ef15a4 80  3c  37  84    addr       FUN_803c3784
        80ef15a8 80  9e  f0  4c    addr       s_osapiMemShow_809ef04c                          = "osapiMemShow"
        80ef15ac 80  3b  d1  b0    addr       FUN_803bd1b0
        80ef15b0 80  9e  f0  5c    addr       s_osapiMsgQueueShow_809ef05c                     = "osapiMsgQueueShow"
        80ef15b4 80  3c  38  2c    addr       FUN_803c382c
        80ef15b8 80  9e  f0  70    addr       s_osapiRedir_809ef070                            = "osapiRedir"
        80ef15bc 80  3b  cf  8c    addr       LAB_803bcf8c
        80ef15c0 80  9e  f0  7c    addr       s_osapiTaskShow_809ef07c                         = "osapiTaskShow"
        80ef15c4 80  3c  91  20    addr       FUN_803c9120
        80ef15c8 80  9e  f0  8c    addr       s_phyDump_809ef08c                               = "phyDump"
        80ef15cc 80  04  d5  78    addr       FUN_8004d578
        80ef15d0 80  9e  f0  94    addr       s_phyget_809ef094                                = "phyget"
        80ef15d4 80  0b  e6  a4    addr       FUN_800be6a4
        80ef15d8 80  9e  f0  9c    addr       s_physet_809ef09c                                = "physet"
        80ef15dc 80  0b  ea  a4    addr       FUN_800beaa4
        80ef15e0 80  9e  f0  a4    addr       s_poeCfgDump_809ef0a4                            = "poeCfgDump"
        80ef15e4 80  2e  bb  34    addr       LAB_802ebb34
        80ef15e8 80  9e  f0  b0    addr       s_policy_809ef0b0                                = "policy"
        80ef15ec 80  07  49  c8    addr       FUN_800749c8
        80ef15f0 80  9e  f0  b8    addr       s_policyTable_809ef0b8                           = "policyTable"
        80ef15f4 80  07  44  a8    addr       LAB_800744a8
        80ef15f8 80  9e  f0  c4    addr       s_poolShow_809ef0c4                              = "poolShow"
        80ef15fc 80  29  bb  e0    addr       FUN_8029bbe0
        80ef1600 80  9e  f0  d0    addr       s_reboot_809ef0d0                                = "reboot"
        80ef1604 80  04  63  10    addr       FUN_80046310
        80ef1608 80  9e  f0  d8    addr       s_regDump_809ef0d8                               = "regDump"
        80ef160c 80  04  e4  30    addr       LAB_8004e430
        80ef1610 80  9e  f0  e0    addr       s_routePrint_809ef0e0                            = "routePrint"
        80ef1614 80  3c  5b  48    addr       LAB_803c5b48
        80ef1618 80  9e  f0  ec    addr       s_rxShow_809ef0ec                                = "rxShow"
        80ef161c 80  04  9c  60    addr       FUN_80049c60
        80ef1620 80  9e  f0  f4    addr       s_setdhcp_809ef0f4                               = "setdhcp"
        80ef1624 80  2f  37  bc    addr       FUN_802f37bc
        80ef1628 80  9e  f0  fc    addr       s_shadowDump_809ef0fc                            = "shadowDump"
        80ef162c 80  28  74  b4    addr       LAB_802874b4
        80ef1630 80  9e  f1  08    addr       s_showCS_809ef108                                = "showCS"
        80ef1634 80  3c  97  ec    addr       FUN_803c97ec
        80ef1638 80  9e  f1  10    addr       s_sntpDebugCurrentTime_809ef110                  = "sntpDebugCurrentTime"
        80ef163c 80  2f  f1  d4    addr       FUN_802ff1d4
        80ef1640 80  9e  f1  28    addr       s_sntpDebugMode_809ef128                         = "sntpDebugMode"
        80ef1644 80  2f  f1  c8    addr       LAB_802ff1c8
        80ef1648 80  9e  f1  38    addr       s_sntpStatusShow_809ef138                        = "sntpStatusShow"
        80ef164c 80  2f  eb  c8    addr       FUN_802febc8
        80ef1650 80  9e  f1  48    addr       s_soc_property_get_809ef148                      = "soc_property_get"
        80ef1654 80  24  00  04    addr       FUN_80240004
        80ef1658 80  9e  f1  5c    addr       s_ssltDebugLevelSet_809ef15c                     = "ssltDebugLevelSet"
        80ef165c 80  43  e3  e4    addr       LAB_8043e3e4
        80ef1660 80  9e  f1  70    addr       s_sysShow_809ef170                               = "sysShow"
        80ef1664 80  30  1d  d4    addr       FUN_80301dd4
        80ef1668 80  9e  f1  78    addr       s_taskShow_809ef178                              = "taskShow"
        80ef166c 80  3b  ef  3c    addr       FUN_803bef3c
        80ef1670 80  9e  f1  84    addr       s_upTime_809ef184                                = "upTime"
        80ef1674 80  3b  e6  1c    addr       FUN_803be61c

Note that this list contains commands that are not present in the list from the last blog post. That may be because the commands did not exist before this version, or perhaps they were omitted from the help command list in the last version that supported the help command (5.4.2.29). Let’s execute a few of these commands and see what we can see.

debugEwaSessionTableDump

debugEwaSessionTableDump screenshot

This appears to be the session information for authenticated clients. It includes the username (in this case admin) and the privilege level. Most importantly, it includes the session identifier that can be used as the value for the SID cookie. With this value, we can masquerade as another user, should they currently be authenticated to the switch.

By default, the switch uses a local configuration database, but it does have options to connect to TACAS+ and RADIUS for additional user authentication. If one of those latter two options is configured, more than one admin can authenticate to the switch, in which case admins could steal other admins sessions. The bad news here is it makes it possible for admins to perform actions as other admins. Obviously undesireable behavior, but it is not clear whether or not there is an escalation of privilege.

Home