Перенаправление вывода в зависимости от grep regex

Я не вижу, как это может относиться sudo.

Для setuid сценариев идея - это:

Предположите, что у Вас есть a /usr/local/bin/myscript это - корень setuid и запускается с #! /bin/sh. Ни у кого нет доступа для записи к /usr/local/bin или myscript, но кто-либо может сделать:

ln -s /usr/local/bin/myscript /tmp/-i

И /tmp/-i также становится setuid сценарием, и даже при том, что у Вас все еще не будет доступа для записи к нему, у Вас действительно есть доступ для записи к /tmp.

В системах, где setuid сценарии не выполняются посредством /dev/fd, когда Вы выполняетесь cd /tmp && -i, setuid укусил средства, которые он выполнит: /bin/sh -i как корень:

  1. Процесс изменяет euid на владельца файла
  2. Система анализирует хижину
  3. Система выполняется (все еще как корень), /bin/sh -i

Теперь, для того особого случая, легкая работа вокруг должна записать хижине рекомендуемый путь: #! /bin/sh -, но даже затем, существует состояние состязания. Теперь это становится:

  1. Процесс изменяет euid на владельца файла
  2. Система анализирует хижину
  3. Система выполняется (все еще как корень), /bin/sh - -i
  4. "sh" открывает "-i" файл в текущем каталоге (прекрасный, Вы думали бы).

Но между 3 и 4 выше, у Вас есть много времени для изменения "-i" или ("любой-файл", поскольку это - другой вектор атаки здесь) к некоторому злу "-i" файл, который содержит, например, просто "sh", и Вы получаете корневую оболочку (для корневого сценария setuid).

С более старыми версиями ksh, Вы не должны были даже делать этого, потому что в 4, ksh сначала искал "-i" в $PATH, таким образом, было достаточно поместить Ваше зло "-i" в $PATH (ksh открыл бы тот вместо того в /tmp).

Все те векторы атаки фиксируются если, когда Вы делаете: cd /tmp; -i, система делает вместо этого (все еще в execve системном вызове):

  1. атомарно: узнайте, что файл является setuid, и откройте файл на некотором дескрипторе файла x из процесса.
  2. обработайте изменения euid во владельце файла.
  3. Выполненный /bin/sh /dev/fd/x
  4. sh открывается /dev/fd/x который может только относиться к файлу, который был execved.

Дело в том, что файл открыт как часть execve, таким образом, мы знаем, что это - код с доверяемым содержанием, которое будет интерпретируемым с измененным priviledges.

Теперь, когда не относится sudo потому что sudo политика на основе path.

Если sudo в правиле говорится, что можно выполнить/usr/local/bin/myscript как корень, затем можно сделать:

sudo /usr/local/bin/myscript

Но Вы не можете сделать:

sudo /tmp/any-file

Даже если "любой-файл" является hardlink или символьной ссылкой на /usr/local/bin/myscript. sudo не использует /dev/fd AFAICT.

8
07.07.2014, 16:34
2 ответа

В Bash вы можете использовать замену процесса на tee:

tee >(grep XXX > err.log) | grep -v XXX > all.log

Это приведет к тому, что все строки, соответствующие XXX, будут помещены в err.log, а все строки - в all.log. >( ... ) создает процесс в круглых скобках и соединяет его стандартный вывод с трубой. Это работает как в zsh, так и в других современных оболочках.

Также можно использовать команду pee из moreutils:

pee "grep XXX > err.log" "grep -v XXX > all.log"

pee перенаправляет стандартный вход на несколько команд ("тройник для труб").

Еще одна альтернатива - awk:

awk '{ if (/^([0-9]{1,3}\.){3}[0-9]{1,3}/) { print > "err.log" } else { print > "all.log" } }'

, который просто проверяет каждую строку на предмет соответствия выражению и записывает все это в err. log если он совпадает и all.log если нет.

Регулярное выражение awk тоже подходит для grep -E (хотя оно и совпадает с некоторыми плохими адресами - 999.0.0.0 и так далее - но это, скорее всего, не проблема)

.
8
27.01.2020, 20:11

Итак, похоже, что gradle run не соответствует tee, pee, grep и io-redirection. Она всегда перестает читать после 4096 байт.

Чтобы обойти этот вопрос, я прочитал каждую строку gradle run. Я еще не проверял, но думаю, что чтение строки длиной более 4k символов тоже не пройдет.

Во всяком случае, вот код для решения моего вопроса, а именно:

#!/bin/bash
STDOUTLOG="/log/stdout.txt"
STDERRLOG="/log/stderr.txt"
while read -r line; do
    [[ $line =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.* ]] && printf '%s\n' "$line" >> "$STDERRLOG" && continue
    printf '%s\n' "$line" >> "$STDOUTLOG"
done < <(gradle run)
4
27.01.2020, 20:11

Теги

Похожие вопросы