Bash
BASH 和輸入行為
我有一個簡單的問題。
bash(我使用的是 4.4.11)不顯示分隔/以純文字結尾的行/文本是否正常
\r
?看到這種行為我有點驚訝:
$ a=$(printf "hello\ragain\rgeorge\r\n") $ echo "$a" george
但是“你好”文本仍然存在,不知何故“隱藏”:
$ echo "$a" |od -w32 -t x1c 0000000 68 65 6c 6c 6f 0d 61 67 61 69 6e 0d 67 65 6f 72 67 65 0d 0a h e l l o \r a g a i n \r g e o r g e \r \n
只要我們玩 bash 就可以了……但這是否存在潛在的安全風險?如果變數“a”的內容來自外部世界並包含“壞命令”而不是 hello 怎麼辦?
另一個測試,這次有點不安全:
$ a=$(printf "ls;\rGeorge\n") $ echo "$a" George $ eval "$a" 0 awkprof.out event-tester.log helloworld.c oneshot.sh rightclick-tester.py tmp uinput-simple.py <directory listing appears with an error message at the end for command George>
想像一個 hidden
rm
而不是 hiddenls
。使用 echo -e 時的行為相同:
$ a=$(echo -e "ls;\rGeorge\r\n"); echo "$a" George
難道是我做錯了什麼……?
您
echo "$a"
列印“hello”,然後返回到行首(這是什麼\r
),列印“again”,再次返回,列印“george”,再次返回,然後轉到下一行(\n
)。這一切都很正常,但正如chepner指出的那樣,它與 Bash: 沒有任何關係,\r
並且\n
由終端解釋,而不是由 Bash 解釋(這就是為什麼當你將命令傳遞給 時你會得到完整的輸出od
)。你可以更好地看到這一點
$ a=$(printf "hellooooo\r again,\rgeorge\r\n") $ echo "$a"
因為這將留下覆蓋文本的結尾:
georgen,o
但是,您不能真正使用它來隱藏命令,只能使用它們的輸出(並且僅當您可以確保用足夠的字元覆蓋時),除非
eval
按照您顯示的方式使用(但eval
通常不建議使用)。一個更危險的技巧是使用 CSS 來屏蔽要從網站複製和粘貼的命令。