#define BUFSIZE 256
int escape_single_quotes(char *to, char *from, int max)
{ int l= 0;
for (;*from;from++)
{
switch (*from) {
case '\'':
if (l>=max-4) return 0; // not enough space for escaped chars!
// replace ' with '\''
*(to++)= '\'';
*(to++)= '\\';
*(to++)= '\'';
l += 3;
default:
if (l>=max-1) return 0; // not enough space for this char!
*(to++)= *from;
l++;
}
}
*to= 0;
return 1;
}
int main(int argc, char *argv[])
{
FILE *fp;
char buf[BUFSIZE];
char escaped_name[BUFSIZE]; char *filename;
int lines, chars, cpl;
if (argc != 2)
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
filename= argv[1];
printf("Counting %s ... \n", filename);
if (!escape_single_quotes(escaped_name, filename, BUFSIZE)) {
fprintf(stderr, "Escaped filename is too long!\n");
exit(EXIT_FAILURE);
}
if (snprintf(buf, BUFSIZE, "wc -l '%s'", escaped_name)>=BUFSIZE)
{
fprintf(stderr, "Filename %s is too long!\n", filename);
exit(EXIT_FAILURE);
}
fp= popen(buf, "r");}有没有什么方法可以中断单引号并注入命令?
发布于 2013-01-07 15:40:10
如果我没看错的话,它只是在filename参数上调用wc -l。
当您试图转义此文件名时,这可能意味着它来自您不能信任的来源。
鉴于此,有几点:
access()调用检查这样的文件名是否存在,如果存在,你可以将它传递给wc,而不用太担心。wc -l时,你可能会说某些东西是邪恶的,因为有人做了这样的事情:cp evilwc /tmp/wc导出路径=/tmp:$PATH。/您的程序良好文件名
糟了!即使文件名是好的,攻击者仍然能够欺骗你的程序调用恶意代码。
解决方案:
在这种特殊情况下,您可能可以自己实现wc -l,而不调用任何外部函数--毕竟这是一个非常简单的算法。
此外,在调用外部程序时,您应该尝试使用全名来调用它们,如/usr/bin/wc。
如果参数是文件名,最好在传递它们之前检查它们是否确实存在。
您可能希望清理参数中的有效字符,但这很容易出错,例如删除对所有非英语世界至关重要的非ASCII符号。
https://stackoverflow.com/questions/14191428
复制相似问题