如何获取Tenda AX18系列的Telnet密码

IoT 3年前 (2022) admin
810 0 0

0x10 前言

要调试溢出漏洞肯定得需要shell的啦,没shell,没监控,没办法的fuzz溢出的啦

0x20 分析

总所周知 Tenda 路由器是可以通过 goform/telnet 这个接口来开一个请求的,而且这个密码是

用户名是root,密码是Fireitup

但在AX18系列虽然接口存在,但这个密码已经登录不了路由器了。因此我们需要找到他更新过的密码或者验证流程 这里我们先全局搜索一下字符串

如何获取Tenda AX18系列的Telnet密码

发现需要重点关注的文件是这几个 而当我们尝试连接这款路由器的Telnet的时候,我们发现 不同于我们连接其他设备的Telnet, Tenda 会有一个 BCM9%x Broadband Routern 类似于这样的信息打印出来,我们尝试后全局搜索 Broadband Router 发现只有 libcms_cli.so 调用了他

如何获取Tenda AX18系列的Telnet密码

我们尝试去找到这个函数

如何获取Tenda AX18系列的Telnet密码

我们发现cmsCli_printWelcomeBanner 这个函数名,我们尝试去找哪个文件调用了他

如何获取Tenda AX18系列的Telnet密码

我们发现telnetd 调用了他,分析telnetd我们发现

如何获取Tenda AX18系列的Telnet密码

cmsCli_authenticate 这时我们猜测,这个函数就是验证的主流程 我们查询一下这个函数在哪里实现的

如何获取Tenda AX18系列的Telnet密码

同样实现于libcms_cli 我们具体分析一下这个函数

int __fastcall cmsCli_authenticate(int a1, int a2)
{
  int v3; // r0
  int String; // r4
  int v5; // r0
  int CurrentLoginCfg; // r0
  int result; // r0
  int v8; // r9
  int v9; // r4
  int v10; // r3
  int v11; // r1
  char *v12; // r0
  size_t v13; // r0
  int v14; // r0
  char v15; // r3
  char *s; // [sp+1Ch] [bp-8h]
  int v18; // [sp+20h] [bp-4h] BYREF
  int v19[7]; // [sp+24h] [bp+0h] BYREF
  char v20[256]; // [sp+40h] [bp+1Ch] BYREF
  char dest[256]; // [sp+140h] [bp+11Ch] BYREF

  memset(v19, 0sizeof(v19));
  v18 = 0;
  exitOnIdleTimeout = a2;
  v3 = cmsLck_acquireLockWithTimeoutTraced("cmsCli_authenticate"6000);
  String = v3;
  if ( v3 )
  {
    v5 = log_log(3"cmsCli_authenticate"118"failed to get lock, ret=%d", v3);
LABEL_20:
    cmsLck_dumpInfo(v5);
    return String;
  }
  CurrentLoginCfg = cmsDal_getCurrentLoginCfg(&glbWebVar);
  String = CurrentLoginCfg;
  if ( CurrentLoginCfg )
  {
    log_log(3"cmsCli_authenticate"125"failed to get login info, ret=%d", CurrentLoginCfg);
    return String;
  }
  cmsLck_releaseLockTraced("cmsCli_authenticate");
  if ( a1 != 3 || (result = j_cli_readString((int)v20, 0x100u)) == 0 )
  {
    v8 = 0;
    while ( 1 )
    {
      v20[0] = 0;
      dest[0] = 0;
      printf("Login: ");
      fflush((FILE *)stdout);
      String = j_cli_readString((int)v20, 0x100u);
      if ( String )
        return String;
      v12 = getpass("Password: ");
      if ( v12 )
      {
        s = v12;
        strcpy(dest, v12);
        v13 = strlen(s);
        memset(s, 0, v13);
      }
      v14 = cmsLck_acquireLockWithTimeoutTraced("cmsCli_authenticate"6000);
      ++v8;
      String = v14;
      if ( v14 )
      {
        v5 = log_log(3"cmsCli_authenticate"191"failed to get lock, ret=%d", v14);
        goto LABEL_20;
      }
      v9 = cmsDal_authenticate((int)&v18, a1, (int)v20, (int)dest);
      cmsLck_releaseLockTraced("cmsCli_authenticate");
      v19[4] = (int)v20;
      v19[2] = (int)&currAppName;
      v10 = v19[6];
      v19[6] |= 0x28u;
      if ( currAppPort )
      {
        v19[1] = (unsigned __int16)currAppPort;
        v19[6] = v10 | 0x2E;
        v19[3] = (int)&currIpAddr;
      }
      if ( v9 == 1 )
        break;
      if ( v8 <= 2 )
      {
        cmsLog_security(4, v19, 0);
        puts("Login incorrect. Try again.");
        fflush((FILE *)stdout);
      }
      else
      {
        v11 = v8;
        v8 = 0;
        printf("Authorization failed after trying %d times!!!.n", v11);
        fflush((FILE *)stdout);
        cmsLog_security(6, v19, 0);
        sleep(3u);
        cmsLog_security(7, v19, 0);
      }
    }
    cmsLog_security(3, v19, 0);
    cmsUtl_strncpy(currUser, v20, 64);
    if ( !strcmp(currUser, byte_2D9D0) )
    {
      v15 = 0x80;
    }
    else
    {
      if ( strcmp(currUser, &byte_2D9D0[64]) )
      {
        if ( !strcmp(currUser, &byte_2D9D0[128]) )
          currPerm = 1;
        else
          log_log(3"cmsCli_authenticate"226"unrecognized user %s, unable to set permission", currUser);
        goto LABEL_30;
      }
      v15 = 64;
    }
    currPerm = v15;
LABEL_30:
    log_log(7"cmsCli_authenticate"244"current logged in user %s perm=0x%x", currUser, (unsigned __int8)currPerm);
    return 0;
  }
  return result;
}

我们发现我们输入的账户和密码被交给这个函数来验证了,我们查询这个函数的位置 v9 = cmsDal_authenticate((int)&v18, a1, (int)v20, (int)dest);

如何获取Tenda AX18系列的Telnet密码

我们发现libcms_dal.so 实现了这个函数 我们去查看这个函数发现

如何获取Tenda AX18系列的Telnet密码


如何获取Tenda AX18系列的Telnet密码

可以看到账户和密码被硬编码写在这里了

用户名:telecomadmin

密码:nE7jA%5m

使用这个账户名和密码,然后登录后输入sh 就可以拿到AX18系列设备的shell了

如何获取Tenda AX18系列的Telnet密码

0x30 总结

对于AX18系列设备,Telnet的认证流程如下:

tphttpd: goform/telnet
telnetd: cmsCli_printWelcomeBanner -> cmsCli_authenticate
libcms_cli.so: cmsCli_authenticate-> cmsDal_authenticate
libcms_dal.so: cmsDal_authenticate()

涉及到4个文件来完成认证,用户名以及密码采取硬编码写入。


end


招新小广告

ChaMd5 Venom 招收大佬入圈

新成立组IOT+工控+样本分析 长期招新

欢迎联系[email protected]



如何获取Tenda AX18系列的Telnet密码

原文始发于微信公众号(ChaMd5安全团队):如何获取Tenda AX18系列的Telnet密码

版权声明:admin 发表于 2022年5月29日 上午8:01。
转载请注明:如何获取Tenda AX18系列的Telnet密码 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...