【免责声明】本文仅限个人自有设备学习使用,违规操作后果自负,严禁用于任何非法用途。


环境:

  • 光猫型号:ZXHN F6610M
  • 移动宽带
  • windows10

为了在家庭网络中配置光猫桥接,使用路由器拨号,需要获取到光猫超管密码。

准备工作

  1. Windows 开启 telnet
  2. 通过光猫背后铭牌中的 user 账户登录光猫后台,最重要的是记录 LOID 信息。另外也可以记录下 VLAN ID(可能没有)、PASSWORD认证、SN认证 等信息,能截图的都截下图。
  3. 宽带账户密码。如果不知道就问客服
  4. 下载工具:

如果没有记录下 LOID,也可以用光猫背后铭牌信息试试,一般 LOID 与 GPON SN 号相同。也可以问客服

步骤

1、解锁tlenet

移动/联通/电信常见默认超管账户(仅供参考)

  • 移动:CMCCAdmin/aDm8H%MdA
  • 联通:CUAdmin/CUAdmin
  • 电信:telecomadmin/nE7jA%5m

光猫注册后运营商会下发配置修改超管密码,并且 telnet 端口也会被关闭。

首先需要重置光猫,这样就能使用 zteOnu 工具进行 telnet 连接:

  1. 使用网线连接电脑和光猫 LAN1口 或 LAN3口

  2. 将电脑网卡的MAC地址改为 000729553557。Windows控制面板 -> 网络和共享中心 -> 更改适配器设置 -> 双击以太网 -> 属性 -> 配置 -> 高级 -> “网络地址”中填写(无需冒号)

    image-20260415075420211

  3. 在cmd窗口中运行 zteOnu

    C:\Users\Administrator>F:\test\delete\zteOnu_0.0.7_windows_386\zteOnu.exe  --telnet --user CMCCAdmin --pass aDm8H%MdA --ip 192.168.1.1 --port 80
    ZteONU 0.0.7, built at 2024-10-13T08:29:47Z
    source: https://github.com/thank243/zteOnu
    -----------------------------------
    step [0] reset factory: ok
    step [1] request factory mode: ok
    step [2] send sq: ok
    step [3] check login auth: ok
    step [4] enter factory mode: ok
    -----------------------------------
    Permanent Telnet succeed
    user: root, pass: Zte521
    wait reboot..
    
  4. 重启光猫,用 telnet 连接光猫,账户是上面获取到的 root/Zte521

    C:\Users\Administrator>telnet 192.168.1.1
    
    F6610M
    Login: root
    Password:
    
    BusyBox v1.17.2 (2023-11-22 19:30:56 CST) built-in shell (ash)
    Enter 'help' for a list of built-in commands.
    
    / #
    

也可以用工具进行解锁: 中兴Telnet开启工具(第一款)来源

2、固化 telnet

zteOnu 有固化的逻辑,使用 zteOnu 解锁 telnet 的可以忽略本步骤

zteOnu固化的相关源码:

// github.com/Septrum101/zteOnu/blob/master/app/telnet/telnet.go
func (t *Telnet) modifyDB() error {
    // set DB data
    prefix := "sendcmd 1 DB set TelnetCfg 0 "
    lanEnable := prefix + "Lan_Enable 1"
    tsLanUser := prefix + "TSLan_UName root"
    tsLanPwd := prefix + "TSLan_UPwd Zte521"
    maxConn := prefix + "Max_Con_Num 3"
    initSecLvl := prefix + "InitSecLvl 3"

    // save DB
    save := "sendcmd 1 DB save"

    if err := t.sendCmd(lanEnable, tsLanUser, tsLanPwd, maxConn, initSecLvl, save); err != nil {
        return err
    }

    return nil
}

进入 telnet 先查看下 TelnetCfg 数据库:

/ # sendcmd 1 DB p TelnetCfg
<Tbl name="TelnetCfg" RowCount="1">
        <Row No="0">
                <DM name="Wan_Enable" val="0"/>
                <DM name="Lan_Enable" val="0"/>
                <DM name="TS_Port" val="23"/>
                <DM name="TSLan_Port" val="23"/>
                <DM name="TS_UName" val="******"/>
                <DM name="TS_UPwd" val="******"/>
                <DM name="TSLan_UName" val="******"/>
                <DM name="TSLan_UPwd" val="******"/>
                <DM name="Max_Con_Num" val="2"/>
                <DM name="ProcType" val="0"/>
                <DM name="WanWebLinkToTS" val="0"/>
                <DM name="ExitTime" val="5"/>
                <DM name="InitSecLvl" val="0"/>
                <DM name="CPMode" val="0"/>
                <DM name="SepMode" val="0"/>
        </Row>
</Tbl>

依次设置进行固化操作,最后保存并重启光猫:

# 开启LAN侧telnet功能,允许局域网访问
sendcmd 1 DB set TelnetCfg 0 Lan_Enable 1
# 设置 telnet 登录后的权限等级,0-最低权限、3-最高权限
sendcmd 1 DB set TelnetCfg 0 InitSecLvl 3
# 设置最大同时连接数
sendcmd 1 DB set TelnetCfg 0 Max_Con_Num 5
# 上面设置入库
sendcmd 1 DB save
# 重启光猫
reboot

对应的恢复命令:

sendcmd 1 DB set TelnetCfg 0 Lan_Enable 0
sendcmd 1 DB set TelnetCfg 0 InitSecLvl 0
sendcmd 1 DB set TelnetCfg 0 Max_Con_Num 2
sendcmd 1 DB save
reboot

可以修改 LAN 侧telnet账户密码以提高安全性:

# 替换成实际密码
sendcmd 1 DB set TelnetCfg 0 TSLan_UPwd ******
sendcmd 1 DB save

3、光猫注册

进入光猫管理页面 http://192.168.1.1,使用默认超管登录,我这里是移动宽带

需要配置LOID、以及Internet连接中的宽带账户密码:

image-20260415133217091

image-20260415133326088

配置好后插入光纤,重启,等待注册

4、获取超管密码

下载 ztecfg.exe 工具,用于对中兴光猫配置文件进行解密

将光猫中的telnet配置文件下载到本地并解密:

在windows 端开启 tftp 服务,进入光猫 telnet 并运行:

# 光猫telnet执行。替换成windows以太网ip地址
tftp -p -l /userconfig/cfg/db_user_cfg.xml -r db_user_cfg.xml 192.168.1.3

image-20260415082548450

对下载的配置文件进行解密:

ztecfg.exe -d AESCBC -i ./db_user_cfg.xml -o break.cfg

打开 break.cfg 文件,搜索 DevAuthInfo 即可查看光猫后台账号相关配置信息:

<Tbl name="DevAuthInfo" RowCount="6">
<Row No="0">
<DM name="ViewName" val="IGD.AU1"/>
<DM name="Enable" val="1"/>
<DM name="AppID" val="1"/>
<DM name="User" val="CMCCAdmin"/>
<DM name="Pass" val="aDm8H%MdA"/>
<DM name="Level" val="1"/>
<DM name="Extra" val=""/>
<DM name="ExtraInt" val="0"/>
<DM name="ForceCheck" val="0"/>
</Row>

至此,就能获取到光猫注册后的超密了。我这里的超管密码仍然是默认的,暂时还没被修改。

其他

db_user_cfg.xml

db_user_cfg.xml 是中兴光猫(ZXHN 系列,如 F650、F660、F677、G7615 等)的核心用户配置数据库文件,存储设备所有用户级配置(WAN、LAN、WiFi、账户、TR069、Telnet、端口映射等),默认路径:/userconfig/cfg/db_user_cfg.xml

  • 原始文件:加密的二进制格式,不是明文 XML,需解密解压后才是标准 XML 树结构。
  • 明文结构:根节点为<DB>,内部以<Tbl>(表)、<Row>(行)、<DM>(数据项)三层组织,是中兴设备的配置数据库导出格式。

核心层级:Tbl → Row → DM(标准结构)

所有配置都遵循这个固定三层结构,无自定义嵌套标签

<Tbl name="表名" RowCount="数据总行数">
  <Row No="行号(从0开始)">
    <DM name="参数名" val="参数值"/>
    <DM name="参数名" val="参数值"/>
    ...
  </Row>
  <Row No="1">...</Row>
  ...
</Tbl>
  • <Tbl>:配置表,对应设备一个功能模块(如 WAN、WiFi、用户认证)
    • name:表名(唯一标识,如DevAuthInfoWanConnectionWiFiCfg
    • RowCount:该表下有多少条配置记录
  • <Row>:表中的一条记录(实例),No从 0 递增
  • <DM>:单个配置项(Data Member)
    • name:参数键名(如UserNamePasswordEnableSSID
    • val:参数值(字符串 / 数字 / 十六进制,密码多为加密哈希)

一些重要配置项

  • TelnetCfg:光猫中 telnet 相关配置信息

    <Tbl name="TelnetCfg" RowCount="1">
    <Row No="0">
    <!-- 公网/外部网络:关闭 Telnet -->
    <DM name="Wan_Enable" val="0"/>
    <!-- 内网/LAN口:开启 Telnet -->
    <DM name="Lan_Enable" val="1"/>
    <DM name="TS_Port" val="23"/>
    <DM name="TSLan_Port" val="23"/>
    <!-- WAN 侧账户和密码 -->
    <DM name="TS_UName" val="root"/>
    <DM name="TS_UPwd" val="ZTEGD***"/>
    <!-- LAN 侧账户和密码 -->
    <DM name="TSLan_UName" val="root"/>
    <DM name="TSLan_UPwd" val="Zte521"/>
    <DM name="Max_Con_Num" val="3"/>
    <DM name="ProcType" val="0"/>
    <DM name="WanWebLinkToTS" val="0"/>
    <DM name="ExitTime" val="5"/>
    <DM name="InitSecLvl" val="3"/>
    <DM name="CPMode" val="0"/>
    <DM name="SepMode" val="0"/>
    </Row>
    
  • 设备认证 / 账户管理(登录权限)

    <Tbl name="DevAuthInfo" RowCount="6">
      <Row No="0">
        <DM name="ViewName" val="IGD.AU1" />
        <DM name="Enable" val="1" />
        <DM name="UserName" val="CMCCAdmin" />
        <DM name="PassWord" val="aDm8H%MdA" />
        <DM name="Level" val="1" /> <!-- 1=管理员,2=普通用户 -->
      </Row>
      <!-- 其他账户(如user、guest、维护账户) -->
    </Tbl>
    

命令

# 查看所有地区编号
cat /etc/init.d/regioncode

# 查看当前地区
cat /userconfig/flag_type

中兴光猫通用命令

# 查看光猫cpu使用率
cat /proc/cpuusage
# 查看设备温度
cat /proc/tempsensor
# 查看固件版本
upgradetest getver
# 查看硬件信息
cat /proc/capability/boardtype

# 以十六进制字节显示本机的各种串码等基本信息
setmac show
# 明文显示本机的各种串码等基本信息
setmac show2

sendcmd

中兴光猫(ZXHN系列)的 sendcmd 标准语法是:

sendcmd <instance_id> DB <operation> <table_name> <row_id> <field> <value>
# 查看设备总览
sendcmd 1 DB p DevInfo

wifi相关

# ssid等信息返回的是脱敏信息,可在解密后的光猫配置文件查看

# 查看所有WLAN配置表(含SSID名称、启用状态)
sendcmd 1 DB p WLANCfg

# 查看WiFi密码(PSK密钥)
sendcmd 1 DB p WLANPSK

修改 WiFi 名称(SSID)和密码

# 语法:sendcmd 1 DB set WLANCfg <RowID> <字段名> <新值>
# 查看WLANCfg表,找到你要修改的SSID对应的RowID(一般SSID1对应Row 0,SSID5对应Row 4)

# 修改2.4G SSID名称(替换为你要的名字)
sendcmd 1 DB set WLANCfg 0 SSID "MyWiFi_2.4G"

# 修改5G SSID名称(替换为你要的名字)
sendcmd 1 DB set WLANCfg 4 SSID "MyWiFi_5G"

# 修改2.4G WiFi密码(替换为你要的密码,8-63位)
sendcmd 1 DB set WLANPSK 0 PSK "MyWiFiPass123"

# 修改5G WiFi密码(替换为你要的密码)
sendcmd 1 DB set WLANPSK 4 PSK "MyWiFiPass123"

# 保存配置到闪存
sendcmd 1 DB save
# 重启光猫
reboot

ZTE配置文件解密

ZTE-Patrina 喂给 ai 后得到使用 python 实现的逻辑:

import zlib
import hashlib
from Crypto.Cipher import AES
import os


# -----------------------------------------------------------------------------
# 工具函数:对应 VB 里的 GetAESCBCEncryKey / GetAESCBCEncryIV
# -----------------------------------------------------------------------------
def get_aes_key(password, max_len):
    key_src = password[:max_len].encode('utf-8')
    return hashlib.sha256(key_src).digest()


def get_aes_iv(password, max_len):
    iv_src = password[:max_len].encode('utf-8')
    hash_obj = hashlib.sha256(iv_src)
    return hash_obj.digest()[:16]


# -----------------------------------------------------------------------------
# AES-256-CBC 解密(对应 VB DecryptAES)
# -----------------------------------------------------------------------------
def decrypt_aes(input_bytes, key, iv):
    try:
        header_size = 12
        data_size = len(input_bytes) - header_size
        data_size = (data_size // 16) * 16  # 16字节对齐

        if data_size <= 0:
            return b''

        data_buf = input_bytes[header_size: header_size + data_size]
        cipher = AES.new(key, AES.MODE_CBC, iv)
        decrypted = cipher.decrypt(data_buf)
        return decrypted
    except:
        return b''


# -----------------------------------------------------------------------------
# CRC + Deflate 解压(中兴老格式,对应 VB DecryptCRC)
# -----------------------------------------------------------------------------
def decrypt_crc(input_bytes):
    ms = []
    ptr = 0
    try:
        while ptr >= 0:
            # 读取块头:dataSize, bufSize, offset
            data_size = int.from_bytes(input_bytes[ptr:ptr + 4], 'little')
            buf_size = int.from_bytes(input_bytes[ptr + 4:ptr + 8], 'little')
            offset = int.from_bytes(input_bytes[ptr + 8:ptr + 12], 'little')

            # 解压块:跳过2字节,解压剩余
            compressed = input_bytes[ptr + 12 + 2: ptr + 12 + 2 + (buf_size - 2)]
            decompress = zlib.decompressobj(-zlib.MAX_WBITS)  # 无头部DEFLATE
            out = decompress.decompress(compressed)
            ms.append(out)

            # 下一块
            ptr = offset - 60
    except:
        pass
    return b''.join(ms)


# -----------------------------------------------------------------------------
# 友华异或解密(对应 VB DecryptYouhua)
# -----------------------------------------------------------------------------
def decrypt_youhua(input_bytes):
    return bytes([b - 1 if b != 0 else 255 for b in input_bytes])


# -----------------------------------------------------------------------------
# 主解密逻辑:完全对应 VB LoadConfig
# -----------------------------------------------------------------------------
def decrypt_config_file(input_path, indiv_key=''):
    with open(input_path, 'rb') as f:
        buf = f.read()

    header_size = 60

    while True:
        if len(buf) <= header_size:
            break

        # 已经是明文 XML
        if buf[0] == 0x3C:
            break

        # 中兴加密格式:魔数 01 02 03 04
        # 中兴光猫/路由器加密配置文件(.cfg/.bin)的标准文件头签名,明文XML开头是0x3C(<)
        elif buf[0:4] == b'\x01\x02\x03\x04':
            data_buf = buf[header_size:]  # 跳过60字节固定文件头
            enc_type = buf[7]  # 取第8字节,判断加密类型

            if enc_type == 0:
                # 类型 0:CRC + Deflate
                buf = decrypt_crc(data_buf)

            elif enc_type == 4:
                # 类型 4:AES-256-CBC(官方默认密钥)
                # key和iv是写在固件里的,逆向中兴固件提取得到
                default_key = '8cc72b05705d5c46f412af8cbed55aad'
                default_iv = '667b02a85c61c786def4521b060265e8'

                if indiv_key:
                    tmp_key = hashlib.md5(indiv_key.encode('utf-8')).digest()
                    use_key = tmp_key.hex().lower()
                else:
                    use_key = default_key

                key = get_aes_key(use_key, 31)
                iv = get_aes_iv(default_iv, 31)
                buf = decrypt_aes(data_buf, key, iv)

            else:
                # 其他类型:PON_Dkey
                key = get_aes_key('PON_Dkey', 256)
                iv = get_aes_iv('PON_DIV', 256)
                buf = decrypt_aes(data_buf, key, iv)

        # 友华格式
        elif buf[0] == 0x3D:
            buf = decrypt_youhua(buf)
            break

        else:
            buf = b''
            break

    # 尝试 UTF-8 解码成明文 XML
    try:
        xml_text = buf.decode('utf-8', errors='replace')
        return xml_text
    except:
        return '[解码失败]'


# -----------------------------------------------------------------------------
# 使用示例(直接运行即可)
# -----------------------------------------------------------------------------
if __name__ == '__main__':
    # 把你的配置文件路径放在这里
    input_file = r'your_config.cfg'  # 或 .bin / .xml

    if not os.path.exists(input_file):
        print(f'文件不存在:{input_file}')
    else:
        print('正在解密...')
        plain_xml = decrypt_config_file(input_file)
        print('\n===== 解密后的明文 XML =====\n')
        print(plain_xml)

        # 自动保存到文件
        out_path = f'decrypted_{os.path.basename(input_file)}.xml'
        with open(out_path, 'w', encoding='utf-8') as f:
            f.write(plain_xml)
        print(f'\n✅ 已保存到:{out_path}')

注意:

  1. 安装依赖:pip install pycryptodome
  2. 运行环境:python3
  3. 支持的解密类型:
    • 中兴 01020304 魔数加密
    • 中兴 AES-256-CBC 类型 4
    • 中兴 CRC+Deflate 老格式
    • 友华 0x3D 开头异或加密

参考


YOLO