2011-03-18 24 views
1

我正在實現一個使用system()函數的echo命令。 echo命令的參數來自命令行參數。但是,當使用';'在參數中顯示目錄列表。 我該怎麼做才能避免它?是因爲我的程序中有命令注入嗎?C編程中的指令注入


更新:從評論

#include<string.h> 
#include<stdio.h> 
#include<stdlib.h> 

int main(int argc, char **argv) { 
    char cmd[50] = "echo "; 
    strcat(cmd,argv[1]); 
    system(cmd); 
} 

我可以編譯代碼添加代碼,但在執行,如果我給命令行參數爲例如:「./a.out你好; LS'然後目錄列表正在發生。

+6

你有沒有不使用'printf()'而不是'system(「echo」);'? – jonescb 2011-03-18 12:50:16

+0

當我嘗試使用printf時,它也會打印相同的錯誤。目錄列表正在發生。 – Bithin 2011-03-18 12:53:54

+0

你能告訴我們一些代碼,所以我們知道你在說什麼嗎? – Starkey 2011-03-18 12:53:56

回答

0

[無法對其他答案做出響應,所以重新發布問題] 「可以在命令行參數中不使用'\'的情況下使用';'來獲取參數。 '從'我的程序得到argv後'?「

不,這是不可能的。對「;」的解釋在進入你的程序之前由shell完成,所以除非你在調用中轉義,否則你的程序永遠不會意識到「;」。即 PROG1 parms; PROG2

將導致外殼(這是解釋您鍵入的內容),執行以下操作:

開始PROG1並把它傳遞參數parms。

PROG1一旦完成,開始PROG2

有一些特殊的字符,該外殼將接管默認情況下,你的程序將永遠不會看到:*爲通配符,|對於管道,&並行執行,等等......這些都不會被正在運行的程序看到,他們只是告訴shell做特殊的事情。 或者使用「\」,你可以用單引號或雙引號括起你的參數(這是不同的,但對你的例子來說都可以)。即: ./a.out「你好; ls」 ./a。out'hello; ls'

請注意,如果您打電話給「system」,這些選項將用於printf選項,告訴C啓動一個shell來運行正在傳入的內容,因此輸入將會再次受shell解釋。

3

你爲什麼要嘗試使用shell訪問(這正是System()所做的),並試圖限制它?

如果您因爲某種原因需要使用'echo',請建立您自己的execve()參數,並直接啓動/ bin/echo。這樣您可以將損害僅限於任務'echo'可以做的。

+0

我已經使用execve()實現了'echo',但是我通過命令行給出了輸入,並且如果命令行指令包含';'然後目錄列表發生。是否因爲linux操作系統的任何屬性? – Bithin 2011-03-18 13:26:53

2

當試圖用命令./a.out hello;ls運行你的程序時,實際上是給shell提供了兩個單獨的命令,它們按順序執行。首先,shell通過argv[1]中的命令行參數"hello"運行a.out,它使用echo將其打印出來。然後你的程序退出,shell運行下一個命令ls,並顯示目錄列表。

如果你想將字符串傳遞給程序的命令行參數,你需要逃跑的特殊字符殼;,所以它給你的程序前的外殼不解析它。爲了逃避一個字符,在它前面加上\

嘗試使用./a.out hello\;ls運行命令,然後使用printf而不是echo。

+0

可以在命令行參數中使用';'而不使用'\'來獲取參數。獲得argv後,我可能在我的程序中包含'\'嗎? – Bithin 2011-03-18 13:46:02

+0

@Bithin如果你只使用printf,那麼就沒有必要轉義你傳遞它的任何字符串。 printf只能打印,它不會在你傳遞的字符串中執行任何命令。如果你想逃避字符串,由於其他原因,你可以用單引號括住字符串''',也稱爲強引號,以防止shell解析它。 'char cmd [50] =「echo'」; strcat(cmd,argv [1]); strcat(cmd,「'」);系統(CMD);' – 2011-03-18 14:25:41

0

system()非常難以安全使用。僅使用exec*函數之一就容易多了。