带分号的 C 参数似乎被截断了
C argument with semicolon appears truncated
我正在做一个与 OWASP 命令注入有点相关的作业 Example 1。简而言之,我接受一个参数(一个文件名),然后将其附加到字符串 "cat ",因此我的程序会捕获提供的文件。如果我将用户输入直接传递给 system()
函数,用户可以潜入另一个用分号 ;
分隔的命令。例如:
./commandinject Story.txt;whoami
将 cat Story.txt
并打印当前用户。
我只是被要求检测一个分号,如果找到,错误并请求另一个文件 - 循环直到给出有效输入。
这对于 strchr()
来说非常简单,至少应该如此。 我的问题是,在处理字符串 argv[1]
时,从分号开始的任何内容都是不可见的。 我有一些打印出所有 argv 数组值的调试代码,我逐步执行了 gdb
据我所知,注入的命令是不可见的。
例如,当给出上面的输入时,代码
printf ("This is the command->%s\n", argv[1]);
会打印出来
This is the command->Story.txt
真正奇怪的是
system(argv[1]);
仍然执行注入的代码。我确信这是我所缺少的一个简单的 c-ism,但我将不胜感激对此的一些帮助。
我应该注意,如果我在参数周围使用引号,我的代码可以正常工作并捕获分号。
#include <stdio.h>
#include <unistd.h>
#define COMMAND_SIZE 4096
int main(int argc, char **argv) {
char cat[] = "cat ";
char *command;
char *commandRepeat;
size_t commandLength;
commandLength = strlen(cat) + strlen(argv[1]) + 1;
command = (char *) malloc(commandLength);
strncpy(command, cat, commandLength);
strncat(command, argv[1], (commandLength - strlen(cat)) );
// Search command string for ';'
while(strchr(command, ';') != NULL){
// ERROR, ask for filename again.
// Use temporary buffer for user input
commandRepeat = (char *) malloc(COMMAND_SIZE);
printf("You used an invalid character ';'\nPlease enter the filename again: ");
fgets(commandRepeat, COMMAND_SIZE, stdin);
// Trim newline that fgets includes
commandRepeat[strcspn(commandRepeat, "\n")] = '[=14=]';
// Prepare command string
commandLength = strlen(cat) + strlen(commandRepeat) + 1;
free(command);
command = (char *) malloc(commandLength);
strncpy(command, cat, commandLength);
strncat(command, commandRepeat, (commandLength - strlen(cat)) );
free(commandRepeat);
}
printf ("This is the command->%s\n", command);
system(command);
return (0);
}
shell 正在解释 ;
和 运行 下一个命令。如果你想把它发送到你的程序,你需要把它放在引号里。
如果您的程序正常结束,您应该会看到 ;
执行后的位。
./commandinject "Story.txt;whoami"
我正在做一个与 OWASP 命令注入有点相关的作业 Example 1。简而言之,我接受一个参数(一个文件名),然后将其附加到字符串 "cat ",因此我的程序会捕获提供的文件。如果我将用户输入直接传递给 system()
函数,用户可以潜入另一个用分号 ;
分隔的命令。例如:
./commandinject Story.txt;whoami
将 cat Story.txt
并打印当前用户。
我只是被要求检测一个分号,如果找到,错误并请求另一个文件 - 循环直到给出有效输入。
这对于 strchr()
来说非常简单,至少应该如此。 我的问题是,在处理字符串 argv[1]
时,从分号开始的任何内容都是不可见的。 我有一些打印出所有 argv 数组值的调试代码,我逐步执行了 gdb
据我所知,注入的命令是不可见的。
例如,当给出上面的输入时,代码
printf ("This is the command->%s\n", argv[1]);
会打印出来
This is the command->Story.txt
真正奇怪的是
system(argv[1]);
仍然执行注入的代码。我确信这是我所缺少的一个简单的 c-ism,但我将不胜感激对此的一些帮助。
我应该注意,如果我在参数周围使用引号,我的代码可以正常工作并捕获分号。
#include <stdio.h>
#include <unistd.h>
#define COMMAND_SIZE 4096
int main(int argc, char **argv) {
char cat[] = "cat ";
char *command;
char *commandRepeat;
size_t commandLength;
commandLength = strlen(cat) + strlen(argv[1]) + 1;
command = (char *) malloc(commandLength);
strncpy(command, cat, commandLength);
strncat(command, argv[1], (commandLength - strlen(cat)) );
// Search command string for ';'
while(strchr(command, ';') != NULL){
// ERROR, ask for filename again.
// Use temporary buffer for user input
commandRepeat = (char *) malloc(COMMAND_SIZE);
printf("You used an invalid character ';'\nPlease enter the filename again: ");
fgets(commandRepeat, COMMAND_SIZE, stdin);
// Trim newline that fgets includes
commandRepeat[strcspn(commandRepeat, "\n")] = '[=14=]';
// Prepare command string
commandLength = strlen(cat) + strlen(commandRepeat) + 1;
free(command);
command = (char *) malloc(commandLength);
strncpy(command, cat, commandLength);
strncat(command, commandRepeat, (commandLength - strlen(cat)) );
free(commandRepeat);
}
printf ("This is the command->%s\n", command);
system(command);
return (0);
}
shell 正在解释 ;
和 运行 下一个命令。如果你想把它发送到你的程序,你需要把它放在引号里。
如果您的程序正常结束,您应该会看到 ;
执行后的位。
./commandinject "Story.txt;whoami"