在 Unix 中,IFS 变量经常被用来破坏系统完整性。
它是如何修复的?
我在维基百科页面中找到了唯一的答案
http://en.wikipedia.org/wiki/Internal_field_separator 它表示:
“通过使 shell 不继承 IFS 变量,此问题已得到修复。”
我可以在我的 Debian 6 系统中验证它:
$ export IFS=/
$ printf "%s" "$IFS" | od -bc
0000000 057
/
0000001
$ bash
bash-$ printf "%s" "$IFS" | od -bc
0000000 040 011 012 # default values
\t \n
0000003
bash-$ exit
exit
$
$ printf "%s" "$IFS" | od -bc
0000000 057
/
0000001
$
这足以避免特权升级吗?如何使用 IFS 打破 system() 调用中的绝对路径名?
答案1
进行 system() 调用的可执行文件要么已经将路径名转换为组件(我认为这就是您所说的“break”)并使用 $IFS 元素(通常是空格)来分隔组件,要么 system() 调用的 shell 脚本将自行操作 $IFS。
可执行文件分解路径的示例:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_TOKENS 100
#define COMMAND "echo "
int main() {
char path[] = "/file/system/path";
char *delims = "/";
int i = 1;
char *token;
char broken_path[sizeof(COMMAND) + sizeof(path) + 3*MAX_TOKENS];
strcpy(broken_path, COMMAND);
token = strtok(path, delims);
while(i < MAX_TOKENS) {
if (token == NULL) {
break;
}
strcat(broken_path,"'");
strcat(broken_path, token);
strcat(broken_path, "' ");
token = strtok(NULL, delims);
}
printf("%s\n", broken_path);
return system(broken_path);
}
调用脚本“破坏”路径的示例:
#include <stdlib.h>
#include <stdio.h>
#define MAX_TOKENS 100
#define COMMAND "./my_script.sh "
int main() {
char path[] = "/file/system/path";
char broken_path[sizeof(COMMAND) + sizeof(path) + 2];
sprintf(broken_path, "%s %s", COMMAND, path);
return system(broken_path);
}
...使用 ./my_script.sh 包含
#!/bin/sh
oldIFS="$IFS"
declare -a elements
IFS="/"
# break $1 into path components
elements=($1)
echo "${elements[@]}"
IFS="$oldIFS"