freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

老瓶装新酒:认识IBM符号链接攻击及防御手段
2018-12-11 09:00:54

*本文原创作者:yolandamo,本文属于FreeBuf原创奖励计划,未经许可禁止转载

前言

IBM下有两款大型关系型数据库,分别是Informix和DB2。早在2001年和2003年两款数据库就被爆出存在符号链攻击提权的问题。尤其2003年Snosoft一口气发布了DB2数个关键工具存在符号链接攻击提权的问题。

符号链攻击虽然是一种本地攻击,但符号链攻击会造成非常严重的安全问题。例如:替换SSH公钥文件、操作系统敏感信息泄露甚至直接夺取操作系统root权限。

经过十余年的发展IBM本应该消灭了符号链攻击问题。但根据我们安华金和攻防实验室研究,发现各种“姿势”的IBM数据库符号链接漏洞。我们发现的典型漏洞分别是CVE-2017-1508、CVE-2018-1799、CVE-2018-1780、CVE-2018-1781和CVE-2018-1784。

一、符号链接简介

符号链接最早出现在4.2的BSD版本中,发展至今日,基本所有的主流操作系统都在某种程度上支持符号链接。符号链接(也称为软链接)是用来让用户创建指向另一个文件或目录的文件或目录。例如管理员可以创建一个名为test的符号链指向系统文件/etc/hosts文件。管理员访问test,等于访问/etc/hosts文件。

符号链接文件实际上是一种文件系统中的特殊小文件。他们的inode(简单可以认为是linux系统中文件的唯一编号)被标为符号链接类型。他们的实际文件内容其实是文件路径。当内核解析路径名时,如果遇到符号链接文件,他会读取符号链接中的文件路径,跟随一层一层的符号链接文件路径,最终到达文件。从而获得到目标文件的路径。

整个符号链接流程如下图所示:第一步访问符号链接test.txt。第二步从符号链接中读取到文件的路径。第三步基于第二步拿到的路径访问下一个软链接或文件。第四步经过层层抽丝剥茧最终获得真实路径。第五步在获得真实路径后根据真实路径跳转到上级目录。第六步再从上层目录跳入下层目录访问到要访问的真实文件。

图片1.png

二、符号链接攻击

符号链接攻击的本质就是欺骗程序访问不应该访问的文件。最常见的是用来获取敏感信息。有时候经过精妙的设计可以突破权限的限制,最终达到覆盖文件或夺取更高权限的效果。

假设有如下一段代码,此代码是用来在主目录中查看该用户是否有.optconfig文件。如果文件存在,程序将打开该文件并读入配置条目。大多数程序员会认为只要parse_opt_file()的文件解析功能是安全的,这种行为就是安全可靠的:

void start_processing(char *username)

{

    char *homedir;

    char tmpbuf[PATH_MAX];

    int f;

    homedir=get_users_homedir(username);

    if (homedir)

    {

        snprintf(tmpbuf, sizeof(tmpbuf),

            "%s/.optconfig", homedir);

        if ((f=open(tmpbuf, O_RDONLY))>=0)

        {

            parse_opt_file(tmpbuf);

            close(f);

        }

        free(homedir);

}

...

但如果攻击者在. Optconfig上做一些手脚。使用命令建立到/etc/shadow(存操作系统密码的文件) 的软链接(ln -s /etc/shadow ~/.optconfig)。此时攻击者在使用上述程序。程序会去解析. Optconfig文件。由于. Optconfig是一个符号链接,所以最终文件解析的是存有密码hash值的/etc/shadow文件。攻击者很容易通过这种手段拿到密码的hash值。威胁整个操作系统的安全。

三、提权C位-粘滞位

一次完美的符号链接攻击,除了必须有符号链接外,更重要的是要有提权的渠道。利用程序的粘滞位,是常见的提权方法。粘滞位加符号链接有机会造成一次本地提权攻击。

要解释清楚懂粘滞位。首先简单介绍几个linux权限。SUID 是 Set User ID,作用是让程序执行者具有该程序所有者的权限;如果没有设置,程序执行者具有执行用户的权限。SUID 位可以通过 chmod u+s 设置。

举个例子,在Linux中,所有账号的密码记录在 /etc/shadow文件中,并且只有root可以读写这个文件。那么,一个普通用户通过命令 passwd 修改自己密码的过程中肯定就需要写 /etc/shadow这个文件,之所以能这么做是因为 /usr/bin/passwd 设置了SUID位:

-rwsr-xr-x. 1 root root 30768 Feb 22  2012 /usr/bin/passwd

Linux 内核主要是根据 EUID(effective user id) 和 EGID(effective group id) 来确定进程对资源的访问权限。 如果进程对应的程序没有设置 SUID 或 SGID 位,则 euid=uid egid=gid,分别是执行这个程序的用户的 uid 和 gid;反之,则 euid 和 egid 变为程序所有者的 uid和 gid。

因此如果能拦截有粘滞位的程序在降低权限之前,实施越权访问或操作,就很有可能最终获得root权限或以root身份进行越权操作。

四、经典案例剖析(CVE-2017-1508)

理解了粘滞位和符号链接攻击的原理后,咱们剖析一个informix的符号链接漏洞,来深入理解下这类漏洞的利用“姿势”。CVE-2017-1508是一个标准的,通过低权限用户越权非法写文件,最终夺取操作系统root权限例子。

Informix中使用oninit程序可以启动数据库。Oninit启动数据库的时候会打开一个固定名称为/tmp/jvp.log的文件。如果在这个被我们用符号链替换,就可能造成一次符号链接攻击。更关键的是这个程序有粘滞位(下图中权限S)。粘滞位是为了帮助程序在启动时可以使用root权限完成一些操作。

图片2.png

除了上述两点外最重要的是oninit在访问/tmp/jvp.log时。并未进行降权处理。于是基于粘滞位、符号链接攻击和未及时降权。我们可以对oninit实施符号链接攻击。

根据逆向结果,可以看到访问/tmp/jvp.log需要开启环境变量GLSLOG = “on”。同时在打开fopen的时候未做符号链接文件的判断。通过符号链接攻击我们可以以root权限读取或写入任意文件。

图片3.png

五、符号链接攻击提权

至此符号链接攻击主要还停留在创建、读取和替换文件内容阶段。虽然符号链接可以通过读取/etc/shadow获得hash值。再尝试通过字典来破解root密码,但这种方法极不稳定又麻烦。这里我给大家演示一种稳定提权到root的方法。

Linux 系统有一个特点,为了方便的给基础库或函快速修改的机会。所以在加载器上开了一个后门。加载器除了加载一个程序的动态库外还会额外加载系统文件/etc/ld.so.preload 中的动态库。而如果在额外加载动态库中写入和系统函数同名的函数。又会因为ld.so.preload 比其他库早加载,最终导致ld.so.preload中库的同名函数函数覆盖真正系统上的同名函数。

图片4.png

由于可以覆盖同名库函数,所以我们就可以实现自己想要实现的任意功能。有粘滞位的程序基本都会使用geteuid获取当前euid值。我们只要替换掉系统的geteuid。就可以在系统中实现自己想要执行的任意代码。

如下例利用geteuid实现一个永久的bash_shell:

uid_t geteuid(void) {

static uid_t  (*old_geteuid)();

old_geteuid = dlsym(RTLD_NEXT, "geteuid");

if ( old_geteuid() == 0 ) {

chown("$BACKDOORPATH", 0, 0);

chmod("$BACKDOORPATH", 04777);

printf("Dbsec finishes making root shell.\n");

}

return old_geteuid();

六、符号链接攻击的防护手段

从符号链接漏洞到最终获得root shell。经历了两个关键点:1.存在粘滞位。2.访问文件前,未检查是否是符号链接。

第一点:粘滞位的问题主要看是否存在必要性如果无必要性就不要使用。SUID尤其是 SUID Root 程序是存在很大风险的。如果程序确实需要设置 SUID 位,代码中不再需要高权限时尽快通过调用 setuid() 降低权限,也就是使 euid=uid egid=gid。尽量缩短,危险代码的时间。

第二点:在需要写文件时,应该先判断要写的文件是否是已经存在的符号链接或硬链接文件。如果使用open() 函数,oflag 设置成O_NOFOLLOW。可以保证如果是符号链接文件,函数就会返回失败。防止被符号链接攻击。如果使用fopen()函数就必须在使用之前利用lstat() 判断文件的类型。防止被符号链接攻击。

做到上述两点检查,可以完全避免符号链接的攻击。至少也能把符号链接攻击限定在一个非常有限的范围内。

*本文原创作者:yolandamo,本文属于FreeBuf原创奖励计划,未经许可禁止转载

# IBM # 符号链接攻击
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者