BASH và hành vi trả lại vận chuyển


11

Tôi có một câu hỏi nhanh.
Có phải bình thường là bash (tôi đang sử dụng 4.4.11) không hiển thị các dòng / văn bản được phân tách / kết thúc bằng chữ thường \r?

Tôi hơi ngạc nhiên khi thấy hành vi này:

$ a=$(printf "hello\ragain\rgeorge\r\n")
$ echo "$a"
george

Nhưng văn bản "xin chào lần nữa" vẫn còn đó, bằng cách nào đó "ẩn":

$ 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

Và ngay khi chúng ta chỉ chơi với bash là ổn .... Nhưng đây có phải là một rủi ro bảo mật tiềm ẩn không? Điều gì xảy ra nếu nội dung của biến "a" đến từ thế giới bên ngoài và bao gồm "các lệnh xấu" thay vì chỉ chào?

Một thử nghiệm khác, một chút không an toàn lần này:

$ 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>

Hãy tưởng tượng một ẩn rmthay vì một ẩn ls.

Hành vi tương tự khi sử dụng echo -e:

$ a=$(echo -e "ls;\rGeorge\r\n"); echo "$a"
George

Có phải tôi làm điều gì đó sai không ...?

Câu trả lời:


20

Bản echo "$a"in của bạn "xin chào", sau đó quay lại đầu dòng (đó là những gì \r), in "lại", quay lại lần nữa, in "george", quay lại lần nữa và đi đến dòng tiếp theo ( \n). Tất cả đều hoàn toàn bình thường, nhưng như chepner chỉ ra, nó không liên quan gì đến Bash: \r\nđược giải thích bởi thiết bị đầu cuối, không phải bởi Bash (đó là lý do tại sao bạn nhận được đầu ra đầy đủ khi bạn chuyển lệnh sang od).

Bạn có thể thấy điều này tốt hơn với

$ a=$(printf "hellooooo\r  again,\rgeorge\r\n")
$ echo "$a"

vì điều đó sẽ để lại phần cuối của văn bản bị ghi đè:

georgen,o

Bạn thực sự không thể sử dụng điều đó để ẩn các lệnh, chỉ đầu ra của chúng (và chỉ khi bạn có thể chắc chắn ghi đè bằng đủ ký tự), trừ khi sử dụng evalnhư bạn hiển thị (nhưng evalthường không được sử dụng ). Một mẹo nguy hiểm hơn là sử dụng CSS để che dấu các lệnh dự định được sao chép và dán từ các trang web.


Rõ ràng đủ rồi, cảm ơn. Tôi đã may mắn / không may mắn khi sử dụng một từ cuối cùng trong bài kiểm tra của mình có khả năng ghi đè hoàn toàn hai từ trước đó.
George Vasiliou

2
Lưu ý rằng điều này thực sự không có gì để làm với bash, mặc dù; hoàn toàn phụ thuộc vào thiết bị đầu cuối làm thế nào để "hiển thị" trở lại vận chuyển, hoặc cách hiển thị các ký tự bị ghi đè. Ví dụ, nó sẽ hoàn toàn hợp lệ khi một thiết bị đầu cuối hiển thị -\r|dưới dạng một cái gì đó tương tự như một dấu cộng, thay vì chỉ là một đường ống.
chepner

@chepner Tốt để biết! Cám ơn vì đã chia sẻ. Tôi nghĩ rằng đây chỉ là một hành vi bash.
George Vasiliou

@GeorgeVasiliou Không, bashchỉ ghi byte vào một tệp; bất cứ ai đọc các byte đó để giải thích chúng.
chepner

Nitpick: printf, mà là một bash built-in lệnh (mặc dù nó cũng tồn tại như một độc thực thi), diễn giải các \r(một chuỗi của hai byte: 0x5c0x72và sản xuất trở về vận chuyển (một byte duy nhất: 0x0d). Sau đó, vâng, nhà ga diễn giải byte 0x0dtheo một cách đặc biệt, nhưng nó không diễn giải chuỗi gốc \r.
Suzanne Dupéron

6

Trong thế giới Unix, lợi nhuận vận chuyển (thường được mã hóa như \rtrong các ngôn ngữ lập trình) là một ký tự điều khiển không đáng kể. Bạn có thể có lợi nhuận vận chuyển bên trong một dòng văn bản, giống như bất kỳ ký tự nào khác ngoài nguồn cấp dữ liệu (còn được gọi là dòng mới ), đánh dấu sự kết thúc của một dòng.

Đặc biệt, trong một tập lệnh bash, trả về vận chuyển là một ký tự cấu thành từ thông thường, như chữ cái và chữ số. Bất kỳ hiệu ứng đặc biệt nào của việc vận chuyển trở lại đến từ thiết bị đầu cuối, không phải từ vỏ.

Một sự trở lại vận chuyển là một nhân vật kiểm soát . Khi bạn in nó ra một thiết bị đầu cuối, thay vì hiển thị glyph , thiết bị đầu cuối thực hiện một số hiệu ứng đặc biệt. Đối với trả lại vận chuyển, hiệu ứng đặc biệt là di chuyển con trỏ đến đầu dòng hiện tại. Do đó, nếu bạn in một dòng có chứa lợi nhuận vận chuyển ở giữa, thì hiệu quả là nửa thứ hai được viết trên nửa đầu.

Một số ký tự điều khiển khác có hiệu ứng đặc biệt: ký tự backspace di chuyển con trỏ sang trái bởi một vị trí. Ký tự chuông làm cho thiết bị đầu cuối phát ra âm thanh hoặc thu hút sự chú ý của người dùng. Nhân vật thoát bắt đầu một chuỗi thoát có thể có tất cả các loại hiệu ứng đặc biệt.

Nếu bạn hiển thị đầu ra không đáng tin cậy, bạn cần xóa hoặc thoát các ký tự điều khiển. Không chỉ vận chuyển trở lại, mà còn một số người khác, đặc biệt là nhân vật thoát hiểm, có thể gây ra tất cả các loại hiệu ứng xấu. Xem Can-cat có thể ăn một tập tin có thể là một rủi ro bảo mật tiềm năng không? Làm thế nào để tránh các cuộc tấn công trình tự thoát trong các thiết bị đầu cuối? để biết thêm về chủ đề.


0

Bạn có thể xem trả về vận chuyển trong một biến bash bằng cách sử dụng printfhàm với %qđịnh dạng.

$ TESTVAR="$(printf ' Version: 1 \r Build: 20180712 \r Test: 1324')"

$ printf %q $TESTVAR
Version:1$'\r'Build:20180712$'\r'Test:1324

Nguồn và đọc thêm:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.