Level 01——环境变量的利用

详情:

以下程序中存在一个允许任意程序执行的漏洞,你能找到它吗?要执行此级别,请使用 level01 帐户和密码登录。此级别的文件位于 /home/flag01。

flag01的源码官方已经提供,这道题目是让我们分析该代码,找出代码中存在的一处可执行任意文件漏洞。题目提供的代码如下:

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
gid_t gid;
uid_t uid;
gid = getegid();
uid = geteuid();

setresgid(gid, gid, gid);
setresuid(uid, uid, uid);

system("/usr/bin/env echo and now what?");
}

Solution

在Kali中ssh连接level01@nebula:

image-20250602131944280

分析可执行任意文件漏洞的重点是先找到程序中执行命令的地方。通过分析上面的源码中可以看到程序调用了system函数,system函数可以执行指定的Shell命令,在这里system执行的/usr/bin/env命令,注意system的参数是一个字符串而非变量,所以我们不能直接控制system函数的行为。那重点就放在了env命令上,通过man env得到的帮助如下:

env - run a program in a modified environment

/usr/bin/env 是一个用来在当前环境中查找并执行命令的工具。

简单来说,env的参数是要执行的Shell命令,env会遍历PATH环境变量中的路径来寻找要执行的命令。env命令常出现在脚本文件的第一行,比如

#!/usr/bin/env python

#! 是什么?

  • 被称为 shebang(或 hashbang),是 Unix/Linux 系统对脚本文件的一种约定。
  • 它告诉系统:用哪个程序来解释运行这个脚本

/usr/bin/env 是什么?

  • env 是一个程序,可以在当前环境变量中查找并执行命令
  • 它通过 PATH 环境变量自动查找你系统中 python3 的位置。

python 是什么?

  • 指定使用 python 作为脚本解释器。
  • 也就是说,这个脚本会被当作 Python 代码来执行。

这样写的好处是为了防止把位置写死,如果写成#!/usr/bin/python的话,在其他一些系统中,~python~命令未必在/usr/bin目录中。用了env,不管python在哪个目录中,只要目录列在PATH环境变量中,就可以被找到。

所以,真正的问题是出现在PATH变量上,虽然调用的参数无法被控制,但它执行命令受限于外部PATH变量,而PATH变量是可控的。env是依次遍历PATH变量中的目录,只要我们让env优先找到伪装的echo命令,就起到了劫持作用。

并且可以看到flag01为rwsr,说明被设置了SUID,所以会以flag01用户运行程序,

image-20250602173833992

我们可以让/tmp/echo链接到/bin/getflag上,然后修改PATH环境变量,把/tmp放在最前面,这样env会首先在/tmp下找到echo并执行(并且是以flag01身份运行)。

image-20250602174703978

命令部分 含义
ln 创建链接(link)
-s 创建符号链接(symbolic link),也叫软链接
/bin/getflag 目标文件,链接所指向的文件(原文件)
/tmp/echo 链接文件的路径,即你要创建的“快捷方式”

执行 /tmp/echo,系统会自动跳转去执行 /bin/getflag

PATH=/tmp:$PATH将当前 PATH 变量设置为:/tmp:<原来的PATH值>