Попробуйте запустить:
dd if=/dev/urandom count=1000
Затем, как только это будет сделано, нажмите Enter. Я использую Debian Sid и получаю:
user@host$ dd if=/dev/urandom count=1000
<lots of random characters, then I hit enter again>
bash: 62: command not found
bash: 9: command not found
bash: c62: command not found
bash: 9: command not found
bash: c62: command not found
bash: 9: command not found
bash: c: command not found
user@host$
Это кажется неприлично неуместным! Как запись dd в его стандартный вывод может привести к тому, что этот текст попадет в буфер ввода в Bash? Я глубоко озадачен тем, как это может произойти, и как это можно считать приемлемым поведением с точки зрения безопасности.
Ответы:
Не рекомендуется отправлять случайные данные на ваш терминал.
Случайные данные могут содержать escape-последовательности, которые заставляют терминал выполнять какие-либо действия, кроме печати видимых символов.
Простые примеры из определения терминала ECMA-48 (также известного как ANSI или vt100) включают ESC [1 м для входа в полужирный режим, ESC [2 J для очистки экрана и ESC c для сброса терминала.
Некоторые escape-последовательности не просто изменяют состояние терминала - они запрашивают информацию. Они различаются для разных терминалов и эмуляторов. Примером терминала с множеством поддерживаемых escape-последовательностей и хорошей документацией на них является xterm. Его
ctlseqs.ms
документ является хорошим общим справочным материалом, потому что многие более поздние эмуляторы терминала предназначены для совместимости с ним. Вот его веб-версия: http://invisible-island.net/xterm/ctlseqs/ctlseqs.htmlОбратите ваше внимание на эту команду:
Краткое руководство для понимания записи:
CSI
означает либо ESC [, либо0x9b
байт ( ESC с установленным старшим битом).Ps
является числовым параметром, который является необязательным в этой команде (и в большинстве других). Чтобы запустить это действие путем вывода случайных байтов, вам нужен только один0x9b
байт, за которым следует0x63
('c'
) где-то в потоке, что весьма вероятно в 1000 блоках по 512 байт.Эта команда задает терминалу вопрос: "Кто ты?" и терминал отвечает, отправляя escape-последовательность обратно. Есть несколько возможных ответов, которые вы можете прочитать в документе ctlseqs, но мне интересно, что оба
6c
и62
появляются в списке.Эти escape-последовательности запроса / ответа предназначены для использования программой, которая записывает запрос, а затем сразу же читает ответ. Если вместо этого запрос отправляется программой, которая просто извергала мусор и ничего не читала из терминала, ответ может остаться во входном буфере.
Помните, что терминал подключен к компьютеру с помощью последовательной линии (реальной или эмулированной). Он несет один поток байтов в каждом направлении. Не существует заметной разницы между ESC [6c, который прибыл в качестве ответа на запрос атрибутов устройства, и ESC [6c, который прибыл, потому что вы нажали клавиши Esc [ 6 c, за исключением времени.
Итак, что происходит в общем случае, если вы запускаете команду, которая не использует ввод с терминала, и набираете некоторые вещи во время работы? Введенный вами текст остается в буфере tty до тех пор, пока эта программа не будет завершена, а затем ваша оболочка прочитает его.
(Ввод команды для чтения в приглашении, которое еще не было напечатано, называется typeahead и экономит время. Вам не нужно вежливо сидеть на руках и ждать, пока компьютер завершит свою работу, если вы знаете, что хотите сделать дальше, вы можете просто начать печатать!)
источник