这两天想升级一下家里的网络,换个 Wi-Fi 6 什么的,再用公网 IP 搞搞事情。可是光猫实属一大碍眼之处:联通送的垃圾货自己 PPPoE 拨号霸占了公网地址,只给后面的路由器 192.168.1.0/24
的内网地址。虽然可以配置 DMZ,但一想到流量进出都得 NAT 两层就蛋疼。本来想搞个 EPON 的 SFP 模块起个软路由,但回想起了一些不好的东西,算了算了。
于是改桥接吧!也是老传统艺能了,让光猫当个光转电的交换机,路由器来拨号。这样不仅能让路由器直接拿到公网 IP,还能多拨白嫖带宽。
看了眼型号,轻车熟路谷歌「F477V2 桥接」,输入教程中的申必地址,404,全剧终。一看固件版本「V2.0.0P1T2」,是不是有点新啊。放在一起搜一下,果然,寥寥几篇哀嚎都在叫着后门网址的老办法不管用了。
又搜了一下,按网上的说法,北京联通只要给客服打电话就能改桥接了。但这不是我的作风,能自己日下来的东西何劳客服动手。而且客服能帮忙改光猫的配置,说明光猫上有联通的后门,这不得亲手橄榄?
于是开整。折腾了一个下午,不仅把光猫改成了桥接模式、关掉了联通的后门,还永久开启了真 root 权限的 telnet。
声明:
没有动物在此过程中受到伤害。
注意备份数据,如有故障请致电 10010。
突开 Shell
类似路由器、光猫、AP 的东西,往往在主板上有 TTL 串口,而且像这种低端机型一般直接是 root 权限的 shell。考虑到网上的公开方法都不可行,我也懒得黑盒审计它有没有别的后门,直接物理接入省事得多。
所以首先你需要一个 USB 转 TTL 工具,淘宝上几块钱。焊功好的直接从主板上拉个线出来,但我这种焊点赛绿豆的选择手持杜邦线顶上去。(如果你采用这个姿势,建议先按最后的部分开启 telnet 以防手麻。)
TTL 焊点很好区分,一般是主板上紧密排列的一排四个焊点,然后用万用表找出正负极、试错法找出 RX/TX 端和波特率。但我偷个懒,毕竟不是啥小众型号,直接搜一张 F477V2 的 TTL 图出来:
这是主板正面图,抠开盖子是反面,如果不想拔线抽筋也可以就在反面操作,把位置倒过来就行。波特率是 115200
,用 PuTTY 或者其他顺手玩意连上,用户名、密码都是 root
。
现在你就进入光猫的内部了。说到底就一 ARM32 的嵌入式 Linux,上面还跑着 Java,笑死。
启用管理界面与账号
光猫的系统很有意思,充分展现了低端开发者的浆糊工艺。先不说那纸糊的前端,我写都比它正经;这系统里跑着一个叫 httpd
的程序,可别以为是 Apache 的东西,是他们自己用 C 写的塞了一堆 HTML 的嵌合体,真正的单体 web 应用;httpd
链接了一堆不明所以的动态库,web 请求是调用的它们来配置各种系统功能;后台用 Java 跑着一个 felix.jar
,又接收(或者发出)JSON 指令做一些系统配置;DNS 啥的糅合了 dnsmasq
,估计也负责了 DHCP。
然后是网上已有的信息:光猫的配置存在 /userconfig/cfg/db_user_cfg
,可以用 TFTP 传到本地、用 offzip
解包查看;光猫的命令行工具是 sendcmd
和 setmac
,可以直接修改配置项。
首先需要启用管理界面。这个新版 F477V2 的管理入口依然是 /cu.html
,但(至少在我这)默认是被禁用了的,所以直接访问是 404。而禁用的逻辑也很奇怪,把 httpd
拖进 IDA F5,可以看到是根据配置的地区码来判定的:
只有地区码不是 307 时,/cu.html
的请求才会被处理。地区码存储在 /userconfig/flag_type
中,我的就是 307,应该是初始化时就被配好了,专门防止打开管理界面的。
可以将地区码替换成天津的 303,解除管理界面封印:sed -i 's/307/303/' /userconfig/flag_type
。
注意,只有特定的地区码能够正常使用,别的可能会出问题。我懒得深入研究,如果你没有逆向的癖好建议就用 303。
这个版本的管理员密码依然是默认的 CUAdmin
,但账号被锁了。所以接着使用 sendcmd
工具启用管理员账号。
首先看一下帐号列表:
/ # sendcmd 1 DB p DevAuthInfo
<Tbl name="DevAuthInfo" RowCount="6">
<Row No="0">
<DM name="ViewName" val="IGD.AU1"/>
<DM name="Enable" val="0"/>
<DM name="IsOnline" val="0"/>
<DM name="AppID" val="1"/>
<DM name="User" val="******"/>
<DM name="Pass" val="******"/>
<DM name="Level" val="1"/>
<DM name="Extra" val=""/>
<DM name="ExtraInt" val="0"/>
</Row>
<Row No="1">
<DM name="ViewName" val="IGD.AU2"/>
<DM name="Enable" val="1"/>
<DM name="IsOnline" val="0"/>
<DM name="AppID" val="1"/>
<DM name="User" val="******"/>
<DM name="Pass" val="******"/>
......
喔,多么贴心,多么安全,它竟然打了码。如果显示内容相同,大概是没问题的。下面假设超管账号在 <Row No="0">
里面,并且密码是 CUAdmin
。如果后续有错,可以用前面说的 TFTP 手法拉配置下来解包看看明文。
要做的就两步,启用超管账号 sendcmd 1 DB set DevAuthInfo 0 Enable 1
,保存数据库 sendcmd 1 DB save
。
OK 啦家人们,ps ww | grep httpd
找到进程,然后 kill
之,其会以新配置飞快重启。再次访问 http://192.168.1.1/cu.html
,你就能选择管理员登录了。输入默认密码 CUAdmin
,芜湖起飞!
配置桥接
配置桥接的方式和旧版固件、和其他光猫大同小异。本博客拒绝重复网上已有的东西,所以尽量用一句话说完:上行线路配置里关掉旧的拨号配置,新建一个桥接配置,VLAN 设置成和拨号配置一样,绑定所有 LAN 端口。
保存后,这只猫就成了彻底的工具猫,路由器上配好 PPPoE 就能直接拨号了。光猫的 DHCP 会废掉,不过管理 IP 还在。以后想要进入光猫的管理界面,需要连到光猫上、手动给自己一个 192.168.1.0/24
的 IP。
这里没有考虑 IPTV,因为我没有。如有需要可以参考网上其他资料,只要进了管理界面应该都差不多。
网页上还有其他很多配置,可以玩一玩。这么个快餐盒子还有端口镜像和 samba 我是没想到的。
关闭遥测与远控
Big brother is watching you!光猫都有运营商的后门,而且也会一直往 ISP 上报不明内容。联通甚至有一个 10.0.0.0/8
的大内网专门做这种事情。
首先把大内网关掉。在上行线路配置里禁用名字带「TR069」(应该是第一个)的接口,也就是把「使能」这个框取消再保存。
然后把 TR069 的上报配置也改掉。可以在 web 界面完成,但我喜欢照着配置文件用命令行改:
sendcmd 1 DB set MgtServer 0 Tr069Enable 0
sendcmd 1 DB set MgtServer 0 PeriodicInformEnable 0
-
sendcmd 1 DB set MgtServer 0 URL
http://127.0.0.1/
最后别忘了 sendcmd 1 DB save
,最好再重启一下。虽然不敢说除了这些一定没有别的后门,但多少能爽爽。
开启 telnet
其实这个的意义不大,因为配好之后没啥机会再用 shell。而且改桥接之后,除非路由器是 OpenWrt 之类加个子接口放光猫的网段里,否则有 telnet 也得专门牵根线上去才能连。再说还需要 patch 二进制,所以就放最后面了。
不过呢,如果你和我一样是手握杜邦线戳着 TTL 触点,那最好是一开始就 telnet,否则手真的会残。
首先是要开启 telnet,在 shell 里执行以下命令:
sendcmd 1 DB set TelnetCfg 0 TS_Enable 1
sendcmd 1 DB set
TelnetCfg
0Lan_Enable
1sendcmd 1 DB set
TelnetCfg
0Lan_EnableAfterOlt
1sendcmd 1 DB set
TelnetCfg
0 TS_Port 233sendcmd 1 DB set
TelnetCfg
0 TS_UPwd your_password-
sendcmd 1 DB set
TelnetCfg
0 Max_Con_Num5
最后 sendcmd 1 DB save
保存配置。我忘了是怎么应用的配置,可以先 ps ww | grep telnetd
看看有无进程,如果有直接 kill
,等自动重启就用上了新的配置;如果没有,那就 reboot
大法吧。
大致讲解一下内容,就是设置了在插上光纤之后,内网依然可以 telnet 到光猫。同时修改了密码和最大连接数。密码明文可以用前文的 TFTP 方法获得,我这里密码是 LOID,不过直接改了算了。修改端口到 233 是因为光猫总是被插入一条 drop 23 端口数据包的 iptables 规则,懒得排查是哪个进程的哪个配置干的,直接改 telnet 端口就完事了。
然后是 telnet 最恶心的部分,那就是现在 telnet 上去的 shell 权限是受限的,几乎啥命令都用不了。用 TFTP 把二进制拉下来康康,发现 telnetd
会检查某个配置,然后给 /bin/sh
添加相应的参数。这个配置默认值是 0(传递的参数是 -luser
),就是个废物;只有值是 3(传递的参数是 -lproduction
)才能获得完整的 root 权限。
还好,这最多算一道入门 RE 题。找个 ARM32 的在线汇编工具,把 == 0
和 == 3
的分支颠倒一下就完事了。打完 patch 还是用 TFTP 传回去,覆盖原有的 telnetd
再 chmod +x
,kill
当前的 telnetd
进程等它重启。
不过在这之前要把根目录重挂载为可写:mount -o remount,rw /dev/root /
,完事后最好再恢复 ro
。
事后
调教好光猫,新路由器也到货了。Wi-Fi 6 很顺滑,公网 IP 很舒服,室友的路由器也成功双拨,可惜千兆口只有一个。除了 CPU 少的那几个时钟,带宽多的那一点点速度,一切似乎并没有什么本质的不同。
但我内心还是洋溢着爽快。我还依稀记得某个梦开始的地方,在夏日调出心目中的拓扑时直击内心的美感,还有在深夜踏入不为人知的禁地时颤栗的快感。彼时不似今日,今日不比当初。寡淡如水的日子,简单如此的玩弄也已算予我甘露。
我大概只是在生活里找点仪式感罢了。