Статья Введение в Bash для хакеров. Часть 1

В 1989 году компания Brain Fox разработала bash как проект с открытым исходным кодом. Brain Fox поддерживал bash до 1994 года, а руководил им Чет Роми (Chet Romey). Сегодня bash является сценарием оболочки по умолчанию в Linux и MacOS10, что делает использование bash очень распространенным.

На момент написания этой статьи последняя версия bash - 5.1. В других операционных системах могут использоваться другие версии. Более подробную информацию об этом проекте можно найти на сайте Чета Рэйми:


[Расширения]
В bash есть эффективные сочетания клавиш, с которыми вы наверняка знакомы. Если вы используете символ Tilde(~) для перехода в домашний каталог, то вы использовали расширение Tilde.
Символ ~ указывает на домашний каталог.
Еще одно эффективное расширение - фигурные скобки: {}. Такое расширение используется для выполнения итеративных задач. Или, другими словами, оно используется для вставки определенного диапазона. Предположим, вы хотите создать список файлов с помощью функции touch. Для этого вы можете использовать данное расширение:
1741074391015.webp

Как видите, мы создали четыре файла с помощью touch и фигурной скобки. Затем мы выводим список файлов с помощью команды ls. Конечно, мы можем выполнить эту задачу и без фигурных скобок, но и с ними можно легко справиться. Но, тем не менее, это может быть скучно, когда мы хотим создать сотню или, может быть, тысячу файлов, и это отнимает много времени. Так что же нам делать? Мы можем просто сделать это с помощью фигурных скобок за секунду. Посмотрите на следующий пример:
1741074449699.webp

В этом примере мы уже создали сто файлов, начинающихся с logfile_n. Вы можете изменить диапазон чисел в соответствии с вашими потребностями. Если мы хотим удалить файлы, просто измените первую команду:
1741074494783.webp

Мы можем даже настроить диапазон, чтобы удалить четные числа. Для этого мы добавим еще один параметр между фигурными скобками:
1741074532644.webp

Последний параметр означает сложение двух к двум. Еще одна функция, которую мы можем сделать, - это использовать алфавит вместо цифр:
1741074660617.webp

В данном случае сначала я удалил предыдущие файлы с помощью расширения со звездочкой. Затем я создал диапазон файлов от a до z. Это может быть очень полезно для создания списков паролей. Для наглядности посмотрите на этот пример:
1741074814836.webp

Как вы знаете, мы создали список списков пользователей, каждый из которых начинается с user_{a,z}{a,z}. Это может быть три или четыре символа или что-то еще. Этот символ > означает, что нужно поместить вывод первой команды в файл ulist.txt. А команды echo покажет выражения. Команда cat показывает содержимое файла.
Другие случаи можно увидеть ниже:
1741074857253.webp

Еще одна полезная работа, которая является всеобъемлющей и распространенной, - это арифметическое расширение. Арифметическое расширение позволяет проанализировать арифметическое выражение и подставить результат. Формат арифметического расширения показан ниже:
1741074933542.webp

Подробнее о выражениях мы поговорим в следующих разделах.
[Grep]
В bash есть эффективный инструмент под названием grep, который можно использовать для поиска в файлах на основе регулярных выражений. Это поможет нам искать за файлами журнала или даже искать в результатах с помощью пайпов. Пайпы- это способ передачи вывода команды другой команде с помощью символа «|».
Вот основной пример использования grep:
1741075026341.webp

Первая команда - ping с опцией -c, что означает просто отправку одного пакета. Затем мы передаем вывод ping в grep. grep просто возвращает каждую строку, содержащую 'icmp_seq'. Снова передаем вывод команде cut. Команда cut получит строку и разделит ее с помощью разделителя «:». В конце она покажет вторую часть разбиения.
В предыдущем разделе мы создали файл ulist.txt, содержащий несколько имен пользователей. Теперь мы хотим показать имена пользователей, начинающиеся с user_c. Итак, посмотрите на этот пример:
1741075089324.webp

Параметр -o показывает только совпадающую часть строки. По умолчанию grep показывает только те строки, которые соответствуют регулярному выражению:
1741075095782.webp

Как мы видим, grep показал все имена пользователей, потому что в файле ulist.txt всего одна строка. Поэтому grep показывает эту строку.
Теперь мы собираемся разделить файл. Итак, будет выполнена приведенная выше команда:
1741075123149.webp

Не волнуйтесь. Все не так сложно, как кажется. Прежде всего, мы прочитали файл ulist.txt. Затем с помощью sed заменили все (с помощью ключа g в конце выражения) символы пробела на «\n» или новую строку. Результаты были перенаправлены в файл rep_ulist.txt по символу >. На следующем шаге мы используем выражение AND(&&) для создания нового файла. В конце мы передали содержимое rep_ulist.txt в grep, чтобы найти все строки, которые совпадают с регулярным выражением.
В этой команде мы использовали круглые скобки в качестве приоритетов.
Мы можем использовать опцию -c, чтобы показать количество результатов:
1741075257903.webp

Еще одна опция, которая может оказаться полезной, -n, показывающая номера строк:
1741075313464.webp

Вы можете использовать цвета, чтобы лучше показать результаты:
1741075333427.webp

[Скриптинг]
bash указывает на оболочку, и вы можете выполнить свою команду непосредственно в командной строке. Но наша цель - автоматизировать наши скрипты, а для этого нам нужно выполнять множество команд одновременно. Для этого нам нужно записать команды в файл сценария и запустить его.
Каждый файл сценария должен начинаться с решетки и восклицательного знака и пути к бинарному файлу bash:
Bash:
#!/bin/bash
ping google.com -c 1 | grep 'icmp_seq' | cut -d ":" -f 2
Комментарии в bash начинаются с #. А постфикс файлов в bash - sh.
Создайте файл, запишите в него код и сохраните его под именем icmp-ttl-time.sh. Чтобы запустить скрипт, имени файла недостаточно. Поэтому необходимо использовать интерпретатор. Так, если мы напишем следующую команду, наш скрипт будет выполнен:
1741075455087.webp

Чаще всего мы не хотим каждый раз писать bash перед именем файла. Linux автоматически определяет расширение файла. Как? Мы написали в первой строке путь, который bash использует для запуска кода:
#!/bin/bash
Поэтому, если мы запустим скрипт без указания имени интерпретатора, bash будет знать, что скрипт должен выполняться программой /bin/bash. Неважно, с постфиксом .sh или нет.
Но прежде чем запускать скрипт, нам нужно изменить права доступа к файлу:
1741075538721.webp

Но все же у нас есть некоторые ограничения. Если мы хотим запустить скрипт, мы должны находиться в директории скрипта, либо необходимо указать путь к скрипту. Как мы можем запустить наш скрипт как команду? Например, grep?
Для этого сначала удалите postfix из имени скрипта, затем скопируйте его в каталог /usr/bin, после чего вы сможете запускать скрипт везде, где захотите:
1741075569539.webp

[Echo]
Одной из самых распространенных команд в сценариях bash является команда echo. Команда echo обычно используется для печати выражения в стандартный вывод (STDOUT), но вывод можно изменять. Команда echo очень проста. Просто передайте ей значение. Но есть несколько замечаний по поводу кавычек, которые вам необходимо знать. Существует три варианта использования команды echo:
Bash:
#!/bin/bash
name="Jack"
echo Hey $name?
echo 'Hey $name?'
echo "Hey $name?"
Теперь посмотрите на вывод этого кода, чтобы понять, в чем разница между этими режимами:
1741075698308.webp

Первый режим - без кавычек. Как видите, переменная была обнаружена.
Во второй команде, в которой мы использовали одну кавычку, переменная не была обнаружена, или, другими словами, печатается все, что находится между кавычками. Третья команда похожа на первую.
Еще одна функция, которая может быть полезной, - создавать новые строки:
1741075748736.webp

[Переменные]
Как и в любом другом языке, в скриптах необходимо использовать переменные. Имена переменных должны состоять из последовательности цифровых и буквенных символов, а сама переменная должна начинаться с букв английского алфавита или подчеркивания.
Чтобы определить переменную в скрипте, сначала введите имя переменной, а затем, сразу после знака равенства, введите ее значение. Обратите внимание, что между знаком равенства и именем переменной не должно быть пробела. В противном случае это приведет к ошибке. Следует отметить, что имена переменных чувствительны к регистру:
1741075792512.webp

Чтобы получить доступ к переменным, просто поставьте перед ними знак $:
1741075812804.webp

Другим способом определения переменных является использование let (обратите внимание, что перед именем переменной не нужно использовать знак $):
1741075830661.webp

Для определения константы можно использовать declare и ключ -r:
1741075846627.webp

Используйте переключатели -l и -u, чтобы перевести переменную в нижний или верхний регистр, соответственно:
1741075904289.webp

В bash есть несколько предопределенных переменных, которые очень полезны.
Переменная $ HOME вызывает отображение домашней папки пользователя Linux.
Переменная $ PWD указывает на текущую папку.
Переменная $ MACHTYPE возвращает тип машины.
Переменная $ HOSTNAME возвращает имя хоста системы.
Переменная $ BASH-VERSION отображает версию BASH.
Переменная $ SECONDS показывает количество секунд, в течение которых выполнялась сессия B. Эта переменная, если она используется в сценарии, возвращает количество секунд, в течение которых был запущен сценарий.
Переменная $ 0 возвращает имя сценария.
Существует множество предопределенных переменных, которые вам не нужно запоминать, но знакомство с ними может помочь вам в разработке сценариев. Список встроенных переменных ASBASH можно прочитать здесь:

1741075936093.webp

[Последовательность команд]
Мы хотим поместить команды bash в скрипт и использовать их вывод напрямую. Или, другими словами, мы хотим получить вывод команды и записать его в переменную. Для этого нам нужно использовать последовательность команд. Последовательность команд должна быть заключена в круглые скобки и начинаться с символа $:
Bash:
#!/bin/bash
p=$(pwd)
echo $p
В приведенном выше примере вывод pwd, который является текущим каталогом, сохраняется в переменной p и печатается в выводе:
1741076016229.webp

Без использования $() скрипт просто выводит 'pwd'. Вот простой пример.
Предположим, нам нужно узнать, сколько времени занимает ответ сервера, и мы хотим написать команду, которая выведет его длительность. Для этого сначала сделаем пинг с одним пакетом:
Код:
ping -c 1 example.com
1741076095527.webp

Затем вы можете передать результат ping в grep, чтобы разделить результат от выражения «bytes from»:
Код:
ping -c 1 example.com | grep 'bytes from'
1741076135516.webp

Далее мы делим строку с помощью cut, чтобы получить четвертое поле, которое содержит время ответа сервера:
Код:
ping -c 1 example.com | grep 'bytes from' | cut -d = -f 4
1741076235497.webp

Наконец, мы получим результат вышеприведенного кода и сохраним его в переменную командой succession:
Код:
ping_time=$(ping -c 1 example.com | grep 'bytes from' | cut -d = -f 4)
Bash:
#!/bin/bash

ping_time=$(ping -c 1 example.com | grep 'bytes from' | cut -d = -f 4)
echo "The ping time is $ping_time"
Затем мы выведем его в виде сообщения:
1741076294832.webp

[Числа]
Работа с числами в bash очень проста. Чтобы выполнить математические вычисления в bash, необходимо заключить математические операции в две круглые скобки.
((5+5))
Если вы хотите, чтобы результат вычислений хранился в переменной, то перед скобками нужно поставить знак $. Значения в круглых скобках могут быть числами или другими переменными.
1741076337055.webp

bash поддерживает шесть основных математических операторов:
Возведение в степень: $a**$b
Умножение: $a*$b
Деление: $a/$b
Вычитание: $a-b
Остаток: $a%b
Сложение: $a+$b
Помимо вышеперечисленных операций, вы также можете использовать операторы инкремента($a++), декремента($a--), равного сложения($a+=5) и т.д. Следующий пример иллюстрирует эти операторы:
1741076383981.webp

Разница между ++n и n++ в том, что в первом случае определяется, что сначала нужно увеличить переменную, а затем ее использовать, а во втором - сначала использовать, а затем увеличить:
1741076459980.webp

Как видно на рисунке выше, в этих операциях нет необходимости использовать знак $.
Другие операции:
1741076487329.webp

Помните, что если вы не заключите операцию или математическое выражение в две скобки, то результатом будет комбинация двух значений:
1741076508854.webp

Еще один момент заключается в том, что математические вычисления в bash поддерживают только числа или целые числа, поэтому, например, выполнение математического вычисления 10/3 возвращает результат три, так как результат является десятичным числом.
1741076526368.webp

[Сравнительные операторы]
Одна из основных причин написания сценария вместо использования команд - добавление сравнительных выражений к командам, а не выполнение их непосредственно в оболочке. Для этого мы используем две открытые и закрытые скобки.
[[ exp ]].
Обратите внимание, что между скобками и выражением должен быть пробел. Как вы уже догадались, на выходе получится 0 и 1, или true и false.
1741076564757.webp

Результаты сравнений были выведены командой echo $? Результат первого сравнения равен 0, что означает успех, а результат второго сравнения равен 1, что означает неудачу.
Но, как вы видите, сравнение не сработало. Это связано с тем, что оператор выполняет строковое сравнение. Если же вы хотите провести математическое сравнение, то делать это нужно по-другому. Для этого нужно использовать другие операторы:
[[ $a -lt $b ]]: меньше, чем
[[ $a -gt $b ]]: больше, чем
[[ $a -le $b ]]: меньше и/или равно
[[ $a -ge $b ]]: больше и равно
[[ $a -eq $b ]]: равно
[[ $a -ne $b ]]: не равно
Другой способ, который мы уже встречали, - заключать выражения в круглые скобки:
1741076605163.webp

Как видите, оно не очень хорошо работает для сравнения строк. Мы не используем это правило для сравнения строк. Лучше использовать это правило для целых чисел и использовать правило скобок для строк.
Мы даже можем использовать логические выражения, такие как:

&&: и
||: или
^: xor

1741076636229.webp

[Манипуляция строками]
bash предоставляет возможности работы со строками, такие как соединение строк вместе или извлечение подпрограмм. Эти слова могут показаться расплывчатыми, но, рассмотрев примеры, вы получите хорошее представление о том, как они работают.
Соединение строк очень простое. Сначала мы определяем две переменные a и b и присваиваем им значение. Затем помещаем их рядом друг с другом, чтобы сохранить результат в переменной c, и, напечатав значение переменной c, вы увидите результат объединения:
1741076694382.webp

Между переменными может быть разделитель:
1741076719543.webp

Или еще точнее:
1741076728313.webp

Если вы хотите получить длину строки, добавьте знак # перед именем переменной:
1741076742253.webp

Вы можете извлекать определенные значения из подстрок. Для этого мы добавляем символ двоеточия : вместе с числом, с которого начинается индекс символа в строке. Например, под значением переменной c мы извлекаем подстроку от индекса 7 до конца строки и сохраняем результат в переменной d:
1741076773121.webp

Вы также можете указать количество символов. Например, начните с позиции 2 и извлеките только 4 символа после этого:
1741076787831.webp

Другой пример начинается с позиции 2 до первого символа из последней:
1741076800579.webp

Если мы хотим удалить одну строку из другой, мы можем использовать Shortest Substring Match. У Shortest Substring Match есть два режима, оба из которых вы увидите ниже:
1741076816441.webp

Первая находит выражения и удаляет их спереди. А второй, как вы можете предположить, начинает с задней части и удаляет совпадения.
В противоположность Shortest Substring Match у нас есть Longest Substring Match:

1741076842389.webp

В чем разница между SSM и LSM? SSM, как следует из названия, находит самую короткую подстроку, а LSM - самую длинную:

1741076857099.webp

 

Вложения

  • 1741074764032.webp
    1741074764032.webp
    29 КБ · Просмотры: 5
  • 1741075068404.webp
    1741075068404.webp
    15,4 КБ · Просмотры: 3
  • 1741076180884.webp
    1741076180884.webp
    5,3 КБ · Просмотры: 3
  • Нравится
Реакции: yetiraki
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!