### 你用它上网,我用它进你内网! 中华电信数据机远端代码执行漏洞
# 前言
身为DEVCORE的研究团队,我们的工作就是研究最新的攻击趋势、挖掘最新的弱点、找出可以影响整个世界的漏洞,回报给厂商避免这些漏洞流至地下黑市被黑帽骇客甚至国家级骇客组织利用,让这个世界变得更加安全!
把「漏洞研究」当成工作,一直以来是许多资讯安全技术狂热份子的梦想,但大部分的人只看到发表漏洞、或站上研讨会时的光鲜亮丽,注意到背后所下的苦工,事实上,「漏洞研究」往往是一个非常朴实无华,且枯燥的过程。
漏洞挖掘并不像
Capture the Flag (CTF),一定存在着漏洞以及一个正确的解法等着你去解出,在题目的限定范围下,只要根据现有的条件、线索去推敲出题者的意图,十之八九可以找出问题点。虽然还是有那种清新、优质、难到靠北的比赛例如HITCON CTF或是Plaid CTF,不过「找出漏洞」与「如何利用漏洞」在本质上已经是两件不同的事情了!
CTF很适合有一定程度的人精进自己的能力,但缺点也是如果经常在限制住的小框框内,思路及眼界容易被局限住,真实世界的攻防往往更复杂、维度也更大!要在一个成熟、已使用多年,且全世界资安人员都在关注的产品上挖掘出新弱点,可想而知绝对不是简单的事!一场CTF竞赛顶多也就48小时,但在无法知道目标是否有漏洞的前提下,你能坚持多久?
在我们上一个研究中,发现了三个知名SSL VPN厂商中不用认证的远端代码执行漏洞,虽然成果丰硕,但也是花了整个研究组半年的时间(加上后续处理甚至可到一年),甚至在前两个月完全是零产出、找不到漏洞下持续完成的。所以对于一个好的漏洞研究人员,除了综合能力、见识多寡以及能否深度挖掘外,还需要具备能够独立思考,以及兴趣浓厚到耐得住寂寞等等特质,才有办法在高难度的挑战中杀出一条血路!
漏洞研究往往不是一间公司赚钱的项目,却又是无法不投资的部门,有多少公司能够允许员工半年、甚至一年去做一件不一定有产出的研究?更何况是将研究成果无条件的回报厂商只是为了让世界更加安全?这也就是我们DEVCORE不论在渗透测试或是红队演练上比别人来的优秀的缘故,除了平日军火库的累积外,当遇到漏洞时,也会想尽办法将这个漏洞的危害最大化,利用骇客思维、透过各种不同组合利用,将一个低风险漏洞利用到极致,这也才符合真实世界骇客对你的攻击方式!
# 影响范围
故事回到今年初的某天,我们DEVCORE的情资中心监控到全台湾有大量的网路地址开着3097连接埠,而且有趣的是,这些地址并不是什么伺服器的地址,而是普通的家用电脑。一般来说,家用电脑透过数据机连接上网际网路,对外绝不会开放任何服务,就算是数据机的SSH及HTTP管理介面,也只有内部网路才能访问到,因此我们怀疑这与ISP的配置失误有关!我们也成功的在这个连接埠上挖掘出一个不用认证的远端代码执行漏洞!打个比喻,就是骇客已经睡在你家客厅沙发的感觉!
透过这个漏洞我们可以完成:
1. 窃听网路流量,窃取网路身分、PTT 密码,甚至你的信用卡资料
2. 更新劫持、水坑式攻击、内网中继攻击去控制你的电脑甚至个人手机
3. 结合红队演练去绕过各种开发者的白名单政策
4. 更多更多…
而相关的CVE 漏洞编号为:
- [CVE-2019-13411](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13411)
- [CVE-2019-13412](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13412)
- [CVE-2019-15064](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-15064)
- [CVE-2019-15065](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-15065)
- [CVE-2019-15066](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-15066)
相较于以往对家用数据机的攻击,这次的影响是更严重的!以往就算漏洞再严重,只要家用数据机对外不开放任何连接埠,攻击者也无法利用,但这次的漏洞包含中华电信的配置失误,导致你家的数据机在网路上裸奔,攻击者仅仅「只要知道你的IP便可不需任何条件,直接进入你家内网」,而且,由于没有数据机的控制权,所以这个攻击一般用户是无法防御及修补的! 经过全网IPv4的扫瞄,全台湾约有25万台的数据机存在此问题,「代表至少25万个家庭受影响」,不过这个结果只在「扫描当下有连上网路的数据机才被纳入统计」,所以实际受害用户一定大于这个数字!
而透过网路地址的反查,有高达九成的受害用户是中华电信的动态IP,而剩下的一成则包含固定制IP及其他电信公司,至于为何会有其他电信公司呢?我们的理解是中华电信作为台湾最 电信商,所持有的资源以及硬体设施也是其他电信商远远不及的,因此在一些比较偏僻的地段可能其他电信商到使用者的最后一哩路也还是中华电信的设备!由于我们不是厂商,无法得知完整受影响的数据机型号列表,但笔者也是受害者╮(╯_╰)╭,所以可以确定最多人使用的
中华电信光世代GPON数据机
也在受影响范围内!

# 漏洞挖掘
只是一个配置失误并不能说是什么大问题,所以接下来我们希望能在这个服务上挖掘出更严重的漏洞! 软体漏洞的挖掘,根据原始码、执行档以及API 文件的有无可依序分为:
- 黑箱测试
- 灰箱测试
- 白箱测试
在什么都没有的的状况下,只能依靠经验以及对系统的了解去猜测每个指令背后的实作、并找出漏洞。
## 黑箱测试
3097 连接埠提供了许多跟电信网路相关的指令,推测是中华电信给工程师远端对数据机进行各种网路设定的除错介面!

其中,可以透过
```
HELP
```
指令列出所有功能,其中我们发现了一个指令叫做
```
MISC
```
,看名字感觉就是把一堆不知道怎么分类的指令归类在这,而其中一个叫做
```
SCRIPT
```
吸引了我们!它的参数为一个档案名称,执行后像是会把档案当成Shell Script来执行,但在无法在远端机器留下一个可控档案的前提下,也无法透过这个指令取得任意代码执行。不过有趣的是,
```
MISC SCRIPT
```
这个指令会将
```
STDERR
```
给显示出来,因此可以透过这个特性去完成任意档案读取!
## 从黑箱进化成灰箱
在漏洞的利用上,无论是记忆体的利用、或是网路的渗透,不外乎都围绕着对目标的读(Read)、写(Write)以及代码执行(eXecute)三个权限的取得,现在我们取得了第一个读的权限,接下来呢?
除错介面貌似跑在高权限使用者下,所以可以直接透过读取系统密码档得到系统使用者管理登入的密码杂凑!

透过对
```
root
```
使用者密码杂凑的破解,我们成功的登入数据机SSH将「黑箱」转化成「灰箱」!虽然现在可以成功控制自己的数据机,但一般家用数据机对外是不会开放SSH服务的,为了达到可以「远端」控制别人的数据机,我们还是得想办法从3097这个服务拿到代码的执行权限。

整个中华电信的数据机是一个跑在MIPS处理器架构上的嵌入式Linux系统,而3097服务则是由一个在
```
/usr/bin/omcimain
```
的二进位档案来处理,整个档案大小有将近5MB,对逆向工程来说并不是一个小数目,但与黑箱测试相较之下,至少有了东西可以分析了,真棒!
```
$ uname -a
Linux I-040GW.cht.com.tw 2.6.30.9-5VT #1 PREEMPT Wed Jul 31 15:40:34 CST 2019
[luna SDK V1.8.0] rlx GNU/Linux
$ netstat -anp | grep 3097
tcp 0 0 127.0.0.1:3097 0.0.0.0:* LISTEN
$ ls -lh /usr/bin/omcimain
-rwxr-xr-x 1 root root 4.6M Aug 1 13:40 /usr/bin/omcimain
$ file /usr/bin/omcimain
ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked
```
## 从灰箱进化成白箱
现在,我们可以透过逆向工程了解每个指令背后的原理及实作了!不过首先,逆向工程是一个痛苦且烦闷的经过,一个小小的程式可能就包含几万、甚至十几万行的组合语言代码,因此这时挖洞的策略就变得很重要!从功能面来看,感觉会存在命令注入相关的漏洞,因此先以功能实作为出发点开始挖掘!
整个3097服务的处理核心其实就是一个多层的IF-ELSE选项,每一个小框框对应的一个功能的实作,例如
```
cli_config_cmdline
```
就是对应
```
CONFIG
```
这条指令,因此我们搭配着
```
HELP
```
指令的提示一一往每个功能实作挖掘!

研究了一段时间,并没有发现到什么严重漏洞:(不过我们注意到,当所有指命都匹配失败时,会进入到了一个
```
with_fallback
```
的函数,这个函数的主要目的是把匹配失败的指令接到
```
/usr/bin/diag
```
后继续执行

```
with_fallback
```
大致逻辑如下,由于当时Ghidra尚未出现,所以这份原始码是从阅读MIPS组合语言慢慢还原回来的!其中
```
s1
```
为输入的指令,如果指令不在定义好的列表内以及指令中出现问号的话,就与
```
/usr/bin/diag
```
拼凑起来丢入
```
system
```
执行!理所当然,为了防止命令注入等相关弱点,在丢入
```
system
```
前会先根据
```
BLACKLISTS
```
的列表检查是否存在有害字元。
```
char *input = util_trim(s1);
if (input[0] == '\0' || input[0] == '#')
return 0;
while (SUB_COMMAND_LIST[i] != 0) {
sub_cmd = SUB_COMMAND_LIST[i++];
if (strncmp(input, sub_cmd, strlen(sub_cmd)) == 0)
break;
}
if (SUB_COMMAND_LIST[i] == 0 && strchr(input, '?') == 0)
return -10;
// ...
while (BLACKLISTS[i] != 0) {
if (strchr(input, BLACKLISTS[i]) != 0) {
util_fdprintf(fd, "invalid char '%c' in command\n", BLACKLISTS[i]);
return -1;
}
i++;
}
snprintf(file_buf, 64, "/tmp/tmpfile.%d.%06ld", getpid(), random() % 1000000);
snprintf(cmd_buf, 1024, "/usr/bin/diag %s > %s 2>/dev/null", input, file_buf);
system(cmd_buf);
```
而
```
BLACKLISTS
```
定义如下:
```
char *BLACKLISTS = "|<>(){}`;";
```
如果是你的话,能想到如何绕过吗?
答案很简单!命令注入往往就是这么的简单且朴实无华!

暂无评论