背景
近来发觉一个命令执行风险;
一开始提供修补建议linux伊甸园,是对特殊字符进行过滤,并且业务侧没有办法过滤,由于输入点是没有办法限制的,之后提供另一个方案是将用户的输入讲到配置文件中,之后再进行操作,而不是直接拼接用户的输入;并且提供的方案没有被采纳,所以就有了下文的剖析;
C的命令执行漏洞剖析漏洞简介
wiki百科上描述:任意代码执行(简称ACE)是指功击者才能让目标笔记本或目标进程中执行任意命令或代码[1]。若果系统有地方可以被黑客借助以执行任意代码,则此处被称为任意代码执行漏洞。非常设计借助此一漏洞的程式,称为任意代码执行漏洞借助。可以通过网路(尤其是通过互联网等广域网)让目标笔记本(远程笔记本)执行任意代码的能力称为远程代码执行(RCE)。
wiki的描述比较偏于云端的场景linux shell,这儿场景就是指用户通过浏览器或则其他辅助程序递交数据,因为执行端没有针对执行函数进行过滤,致使在没有指定绝对路径的情况下执行命令。
漏洞动因
在了解漏洞动因之前先看一下C语言在Linux环境中可以执行shell命令的函数;分别是system,popen和exec家族函数。
exec() # 在当前进程中执行命令,其后所有的代码将被清空,不能执行
system() = fork + exec # 在子进程中执行指令
popen() = fork + exec + pipe # 重定向子进程的标准输入或输出,提供控制子进程输入或输出的能力
关于exec()家族
execl ("/bin/sh", "sh", "-c", command, (char *) 0);
char *argv[] = {"sh", "-c", command, (char *) 0};
execv("/bin/sh", argv);
execlp ("sh", "sh", "-c", command, (char *) 0);
char *env_init[] = { "USER=unknown", NULL };
execle("/bin/sh", "sh", "-c", command, (char *) 0, env_init);
实例代码
#include
#include
#include
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("usage: %s param1 [param2 ...[param n]]n", argv[0]);
return -1;
}
char cmdbuf[128] = {0};
snprintf(cmdbuf, sizeof(cmdbuf), "ls %s", argv[1]);
char cmd[128] = {0};
snprintf(cmd, sizeof(cmdbuf), argv[1]);
puts("call system function:");
system(cmdbuf);
puts("ncall popen function:");
FILE *fp = popen(cmdbuf, "r");
char readbuf[2048] = {0};
fread(readbuf, 1, 2048, fp);
puts(readbuf);
pclose(fp);
int pid = fork();
if (pid > 0) {
sleep(1);
} else if (pid == 0) {
//puts("call execl function:");
//execl("/bin/sh", "sh", "-c", cmdbuf, NULL);
//puts("call execl function:");
//execl("/bin/ls", cmd, NULL);
//puts("call execve function:");
//execve("/bin/ls", argv, NULL);
puts("call execvp function:");
execvp("/bin/ls", argv);
}
return 0;
}
测试结果linux c执行shell命令,
一开始以为参考文章说的没错,自己测试也确实如文章示例一样,之后我试了一下别的playload发觉可以绕开了,文章中说通过execve参数注入命令是不会解析执行的,跟自己测试的情况是对不上的;研究此的背景是,研制不采用我提供的修补方案,使用文章中所说的这些修补方法,由于不了解,所以学习一下;
这么假如使用execve的方法不能完全修补,针对这种情况有哪些较好的修补方案呢;
命令执行修补方案
在执行命令前,对入参进行过滤,对敏感字符进行通配符处理;
虽然按理说linux c执行shell命令,只要参数是用户可控的都应当如此处理;
之后有些特殊场景,难以过滤的,可以看一下能够讲到配置文件中,之后在进行配置的方法,而不是通过拼接命令执行用户输入的内容;
命令执行常见的绕开形式管线符“;”
WIndows:
Linux:
“|”
“||”
“&”
“&&”
linux下绕开空格
{cat,flag.txt}
cat${IFS}flag.txt
cat$IFS$9flag.txt
cat<flag.txt
catflag.txt
cat flag.txt
命令注入漏洞介绍(上篇)-FreeBuf网路安全行业门户
命令注入漏洞介绍(下篇)-FreeBuf网路安全行业门户
C语言执行shell命令的三种形式总结_lylhw13_的博客-CSDN博客_c执行命令