首先看一下源码:
#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;
}
这题有三个函数:putenv
、system
、strstr
。
petenv()函数原型:
int _putenv(
const char *envstring
);
功 能:
putenv()
用来改变或增加环境变量的内容。参数envvar
的格式为envvar
=value
,如果该环境变量原先存在,则变量内容会依参数envvar
改变,否则此参数内容会成为新的环境变量。参数envvar
指定的字符串会变成环境变量的一部分,如果修改这个字符串,环境变量也会跟着被修改。
system()函数原型:
int system(const char *command);
功能:
函数会执行一个shell命令。
strstr()函数原型:
extern char *strstr(char *str1, const char *str2);
参数:
str1:被查找目标
str2:要查找对象
返回值:若str2
是str1
的子串,则返回str2
在str1
的首次出现的地址;如果str2
不是str1
的子串,则返回NULL。
本题的意思是更改PATH
,然后过滤传入的参数,参数里面不能有*“flag”、“tmp”、“sh”*。然后执行这个参数所代表的命令。因为PATH
的值被更改了,所以直接输入命令是不行的,得输入命令的绝对路径(但是echo
命令就不用,不知道为什么)
这里用来一个变量r
来表示过滤的结果,如果r
为0
,就能执行,否则退出。而r
的值取决于下面的三个式子
r += strstr(cmd, "flag")!=0;
r += strstr(cmd, "sh")!=0;
r += strstr(cmd, "tmp")!=0;
首先用strstr
查看flag
等关键字是不是在参数里,如果在,返回关键字首次出现的地址, 这样就会导致!=0
这个判断为真,返回一个不为零的数,导致程序退出。
这里我在/tmp
目录下创建了一个自己的目录,/tmp/casuall
,然后通过软连接将/home/cmd1
目录下的flag
连接到了我的目录下casuall
文件。这么做的理由就是程序过滤了’flag’关键字,不能在当前目录直接cat
flag的值。也过滤了’tmp‘,但是我们可以直接在/tmp/casuall
目录下执行程序。