看题目是跟PATH环境变量有关
看cmd1.c
#include <stdio.h>
#include <string.h>
int filter(char* cmd){
int r=0;
r += strstr(cmd, "flag")!=0;
r += strstr(cmd, "sh")!=0;
r += strstr(cmd, "tmp")!=0;
return r;
}
int main(int argc, char* argv[], char** envp){
putenv("PATH=/thankyouverymuch");
if(filter(argv[1])) return 0;
system( argv[1] );
return 0;
}
定义了一个filter函数做简单的过滤,
不允许出现flag、sh、tmp字符
想到的第一个绕过方法自然是利用通配符
看了网上的wp意识到自己压根就没思考程序里面改path变量的意义,
平时在使用 rm、rmdir、ls 等命令时,无论当前位于哪个目录,都可以直接使用,
而无需指明命令的执行文件所在的位置(绝对路径),
其实这是 PATH 环境变量在起作用。
而题目中改了path变量之后,
就需要通过绝对路径才能使用之前的命令,
然后就了解到了which命令,
可以判断当前使用的命令所在的绝对路径
还有其他的一些绕过方法
base64,
$() 小括号里面是 Linux 命令,作用就是执行里面的命令后返回执行的结果;和 ``(反引号)作用一样。
而${}则是变量替换
引号绕过
反斜杠转义
利用环境变量,
这里才意识到单引号和双引号在shell里是不同的,
不过,引号有单引号和双引号之分,二者的主要区别在于,
被单引号括起来的字符都是普通字符,就算特殊字符也不再有特殊含义;
而被双引号括起来的字符中,"$"、"\"和反引号是拥有特殊含义的,"$"代表引用变量的值,
而反引号代表引用命令。
以及,filter函数通过检测字符‘sh’来禁止调用shell,
简单对比bash和sh,发现这里sh拥有更高的权限
然而这个权限似乎不是从sh来的,看到sh实际上是指向dash的软连接
应该是cmd1的sgid导致的
试了一圈下来,除了bash和实际指向busybox的static-sh,
其他的shell都能继承到egid
懵了,
也查不到是什么东西导致了这种差异
还可以调用vim来读写文件,
./cmd1 '/usr/bin/vim'
然后输入:e flag