День вчера был такой длинный, жаркий, и от начала до конца полная х%йня, каждую минуту. Год как-то стремительно начался в плане объема задач. Привет!
А жиза заключается в том, что кто-то бездумно пишет говнокод, а кто-то этот говнокод вынужден дебажить. Доказывая что проблема не на сервере, а в кривых руках разработчика.
Вот и вчера. Ситуация: какой-то php скрипт при создании файла на диске, выставляет корявые права на этот файл. Грубо говоря, нужно поставить 777, а у файла права по факту 01411. Конечно, проблема в сервере! Пусть дядя Рома с этим разбирается. Ладно, за монету и корку хлеба можно и покопаться.
Блин, как я давно с php дел не имел. Пришлось вспоминать всю эту лапшу с ООП.
Так, вдумчиво пробегаюсь глазами по php коду, нахожу функцию, которая ставит права на файл, выглядит это так:
Для простоты восприятия, адаптировал под наши с вами реалии. Вроде всё корректно, тошноты пока нет. Чо этой собаке надо? Запускаю скрипт, хм… снова получаю вместо 777 какую-то фигню 01411.
А если уберем кавычки? Вдруг это как string воспринимается:
Метод тыка не помог, но терпим до последнего. В документацию по chmod в php не лезем. Нас же НЕ просили исправить баг, нас поставили перед фактом — проблемы на сервере. Вот мы и пытаемся доказать обратное.
Расчехляем strace
В самом конце видим:
Видим знакомое 01411. Доказательства собрали. С серверами всё хорошо, на лицо баг в коде. Несем эту информацию тимлиду, пусть учит разработчика читать документацию и дает ему по шапке.
А что все-таки не так с php скриптом, почему 01411? Вообще это не наше дело. Но если коротко:
В php целые числа могут быть указаны в десятичной, шестнадцатеричной, восьмеричной или двоичной системе. Все это дело должно обозначаться начальным нулем. Наша тема - восьмеричная система. Если перевести 777 в восьмеричную систему получим как раз 1411.
📌 А откуда берется 01 перед 1411?? А давай ты сам подумаешь и в комментариях напишешь. А мы тебе дружно лайк поставим.
Ошибка была в том, что в php скрипте число 777 передается как строка. Неважно в скобках оно или нет.
Фикс тут простой, просто вставляем 0 перед 777:
Ну а если хочется без ведущего нуля, то так:
Вот такие пироги. Можно было бы продолжить метод тыка и вставить сразу 0 перед 777, но повторюсь — нас не просили ничего багфиксить. Не нужно упрощать кому-то работу, это опыт, который ты воруешь у человека.
Пусть лучше лишние полчаса погуглит, посмотрит, зато самостоятельно заполнит свою дофаминоваю яму. И потешет ЭГО новой победой над багом.
Ладно, увидимся, давай!
tags: #linux #debug #рабочиебудни
—
💩 @bashdays
А жиза заключается в том, что кто-то бездумно пишет говнокод, а кто-то этот говнокод вынужден дебажить. Доказывая что проблема не на сервере, а в кривых руках разработчика.
Вот и вчера. Ситуация: какой-то php скрипт при создании файла на диске, выставляет корявые права на этот файл. Грубо говоря, нужно поставить 777, а у файла права по факту 01411. Конечно, проблема в сервере! Пусть дядя Рома с этим разбирается. Ладно, за монету и корку хлеба можно и покопаться.
Блин, как я давно с php дел не имел. Пришлось вспоминать всю эту лапшу с ООП.
Так, вдумчиво пробегаюсь глазами по php коду, нахожу функцию, которая ставит права на файл, выглядит это так:
<?php
chmod('test.txt', '777');
?>
Для простоты восприятия, адаптировал под наши с вами реалии. Вроде всё корректно, тошноты пока нет. Чо этой собаке надо? Запускаю скрипт, хм… снова получаю вместо 777 какую-то фигню 01411.
А если уберем кавычки? Вдруг это как string воспринимается:
<?php
chmod('test.txt', 777);
?>
Метод тыка не помог, но терпим до последнего. В документацию по chmod в php не лезем. Нас же НЕ просили исправить баг, нас поставили перед фактом — проблемы на сервере. Вот мы и пытаемся доказать обратное.
Расчехляем strace
strace php app.php
В самом конце видим:
read(3, "<?php\n\nchmod('test.txt', 777);\n\n"..., 4096) = 35
chmod("test.txt", 01411) = 0
Видим знакомое 01411. Доказательства собрали. С серверами всё хорошо, на лицо баг в коде. Несем эту информацию тимлиду, пусть учит разработчика читать документацию и дает ему по шапке.
А что все-таки не так с php скриптом, почему 01411? Вообще это не наше дело. Но если коротко:
В php целые числа могут быть указаны в десятичной, шестнадцатеричной, восьмеричной или двоичной системе. Все это дело должно обозначаться начальным нулем. Наша тема - восьмеричная система. Если перевести 777 в восьмеричную систему получим как раз 1411.
Ошибка была в том, что в php скрипте число 777 передается как строка. Неважно в скобках оно или нет.
Фикс тут простой, просто вставляем 0 перед 777:
<?php
chmod('test.txt', 0777);
?>
Ну а если хочется без ведущего нуля, то так:
<?php
chmod('test.txt', intval('777', 8));
?>
Вот такие пироги. Можно было бы продолжить метод тыка и вставить сразу 0 перед 777, но повторюсь — нас не просили ничего багфиксить. Не нужно упрощать кому-то работу, это опыт, который ты воруешь у человека.
Пусть лучше лишние полчаса погуглит, посмотрит, зато самостоятельно заполнит свою дофаминоваю яму. И потешет ЭГО новой победой над багом.
Ладно, увидимся, давай!
tags: #linux #debug #рабочиебудни
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Привет, далеко ходить не будем, сегодня более интересный кейс с отладкой php-fpm который непонятным образом, рандомно вставал раком. Да, будем использовать наш любимый strace, как ты любишь.
Проблема: На сервере крутится php-fpm, в любой момент времени процесс начинает зависать, то есть перестаёт обрабатывать любые запросы.
В какой-то момент может очухаться, а может и нет. В любом случае проблема решается перезапуском
Ребята придумали костыль, какой-то башник, который в кроне проверяет зависание и затем автоматически ребутит. Да, как временное решение подходит. Но сам знаешь, что временное всегда становится постоянным.
До этого были перепробованы все возможные варианты с конфигом, накручивание буферов, гугление, даже грешили на nginx, но ничего не помогало.
Так и жили пока дядя Рома не соизволил разобраться в ситуации, ну и разобрался.
Расчехляем strace
Для начала ты должен знать, что php использует модель master/slave. Главный процесс использует воркеры (workers) для обработки входящих запросов. Запрос может выполниться на любом из воркеров, поэтому нужно сказать strace чтобы мониторил все воркеры. Для этого будем использовать связку с командой pidof ну и приправим это sed’ом.
Sed обрезает лишнюю херню и оставляет только pid в голом виде, ну и затем эти пиды закидываем в strace.
А после запуска команды и зависания php, я увидел такое:
Ага, уже есть с чем работать. Какой-то таймаут. И файловый дескриптор fd=10. Хм. Теперь надо понять, что это за таймаут и дескриптор fd=10. Для этого сделаем так:
Эта команда выдаст список всех файлов, которые открыты процессом, включая сокеты.
Смотрим самую последнюю строку как раз с fd=10. Видим что у нас проблема с подключением к
Не останавливаемся и копаем дальше.
В большинстве случае порт 9200 принадлежит ElasticSearch. Роем в эту сторону и обнаруживаем, что в php проекте используется библиотека ElasticSearch PHP.
Как оказалось, при разработке проекта, прекрасные девы подключили ElasticSearch, чтобы чото там отлавливать. А на айпишнике
Вот оно и продолжало ломиться туда, где ничего нет. В этом и заключался баг. PHP постоянно опрашивал ElasticSearch сервер для получения ответа, но в ответ получал хуй с маслом. Рабочий процесс зависал в цикле и не мог ответить ни на один другой запрос.
Такие дела. Я прям уверен — если пройтись с помощью strace по всяким популярным php движкам, там столько дерьма вылезет. Кстати с помощью strace можно вполне удачно разгонять проекты, банально фиксишь то, что вызывает таймауты.
Порой наталкивался на ситуацию когда проект тормозил из-за корявого резолва доменов, или были проблемы с таймзоной, аналогично всё это дебажилось через strace.
В общем изучай и бери на вооружение, опыт полезный. Увидимся!
tags: #linux #debug #рабочиебудни
—
💩 @bashdays
Проблема: На сервере крутится php-fpm, в любой момент времени процесс начинает зависать, то есть перестаёт обрабатывать любые запросы.
В какой-то момент может очухаться, а может и нет. В любом случае проблема решается перезапуском
systemctl restart php-fpm
. Ну и в логах ничего криминального нет, даже в дебаг режиме. По факту имеем пятьсот две плохих шлюхи (502 Bad Gateway).Ребята придумали костыль, какой-то башник, который в кроне проверяет зависание и затем автоматически ребутит. Да, как временное решение подходит. Но сам знаешь, что временное всегда становится постоянным.
До этого были перепробованы все возможные варианты с конфигом, накручивание буферов, гугление, даже грешили на nginx, но ничего не помогало.
Так и жили пока дядя Рома не соизволил разобраться в ситуации, ну и разобрался.
Расчехляем strace
Для начала ты должен знать, что php использует модель master/slave. Главный процесс использует воркеры (workers) для обработки входящих запросов. Запрос может выполниться на любом из воркеров, поэтому нужно сказать strace чтобы мониторил все воркеры. Для этого будем использовать связку с командой pidof ну и приправим это sed’ом.
strace -f $(pidof php-fpm | sed 's/\([0-9]*\)/\-p \1/g') -epoll
Sed обрезает лишнюю херню и оставляет только pid в голом виде, ну и затем эти пиды закидываем в strace.
А после запуска команды и зависания php, я увидел такое:
[pid 1234] poll([{fd=10 ...]) = 0 (Timeout)
[pid 1234] poll([{fd=10 ...]) = 0 (Timeout)
[pid 1234] poll([{fd=10 ...]) = 0 (Timeout)
[pid 1234] poll([{fd=10 ...]) = 0 (Timeout)
Ага, уже есть с чем работать. Какой-то таймаут. И файловый дескриптор fd=10. Хм. Теперь надо понять, что это за таймаут и дескриптор fd=10. Для этого сделаем так:
lsof -p 1234
Эта команда выдаст список всех файлов, которые открыты процессом, включая сокеты.
php 0u IPv4 13193 0t0 TCP :8000 (LISTEN)
php 1u CHR 1,4 0t0 4728 /dev/null
php 2u CHR 1,4 0t0 4728 /dev/null
php 3ur REG /tmp/.RedPem.Hte (deleted)
php 4u IPv4 TCP :8000->:5042 (ESTABLISHED)
php 5uW REG sessions/sess_tmh0dls75
php 6u 0000 0,9 0 4842 anon_inode
php 7u unix 0t0 25714 socket
php 8u unix 0t0 25714 socket
php 9u TCP l->l:11210 (ESTABLISHED)
php 10u TCP host->10.0.0.100:9200 (SYN_SENT)
Смотрим самую последнюю строку как раз с fd=10. Видим что у нас проблема с подключением к
10.0.0.100:9200
. Очень интересно. Что это вообще за айпишник такой.Не останавливаемся и копаем дальше.
В большинстве случае порт 9200 принадлежит ElasticSearch. Роем в эту сторону и обнаруживаем, что в php проекте используется библиотека ElasticSearch PHP.
Как оказалось, при разработке проекта, прекрасные девы подключили ElasticSearch, чтобы чото там отлавливать. А на айпишнике
10.0.0.100
как раз располагалась серверная часть ElasticSearch. Разработку прекратили, сервер с эластиком убили, но из конфигов проекта забыли выкосить.Вот оно и продолжало ломиться туда, где ничего нет. В этом и заключался баг. PHP постоянно опрашивал ElasticSearch сервер для получения ответа, но в ответ получал хуй с маслом. Рабочий процесс зависал в цикле и не мог ответить ни на один другой запрос.
Такие дела. Я прям уверен — если пройтись с помощью strace по всяким популярным php движкам, там столько дерьма вылезет. Кстати с помощью strace можно вполне удачно разгонять проекты, банально фиксишь то, что вызывает таймауты.
Порой наталкивался на ситуацию когда проект тормозил из-за корявого резолва доменов, или были проблемы с таймзоной, аналогично всё это дебажилось через strace.
В общем изучай и бери на вооружение, опыт полезный. Увидимся!
tags: #linux #debug #рабочиебудни
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Всем привет. Пока тут боролся с багом, решил поделиться и с вами. Сегодня рассмотрим как без curl/wget/telnet делать tcp/udp запросы. Опять же мало кто про это знает.
Порой бывает что на серверах нет курла, вегета (как приправа с упоротым поваром) и даже пинга. Например в docker контейнерах. И установить никак. Но в bash скрипте или во время дебага надо протестировать приложение, службу или порт.
В общем если столкнулся с отсутствием привычных тебе утилит, выход есть. Сейчас покажу крутые фичи.
Я обычно при дебаге использую telnet, чтобы проверить открыт ли нужный порт на удаленной тачке. Чтобы понимать, что никакой фаервол меня не блокирует. Почему telnet? Привычка!
Проверяем открыт ли порт 80 и 443:
Если порт открыт, то после выполнения команды на экран ничего не выведется. Но ты в праве получить статус через
Есть нюанс, команда может висеть очень долго, поэтому приправляем ее таймаутом:
Теперь в случае если порт не доступен, мне не нужно ждать 100500 часов пока команда завершится. Все станет известно спустя 5 секунд. Повторюсь, что на экран никакого вывода не будет. Статус получаем через
А что означает этот непонятный символ «:>»?
Нет, это не смайлик с дятлом. Это сокращенная версия true:
true - команда, которая всегда возвращает успешный (нулевой) код возврата. Это означает, что команда завершилась успешно, без ошибок.
Чтобы весь этот фокус работал, требуется bash с поддержкой net-redirections (--enable-net-redirections), но как показывает практика такая функция в 99% включена по умолчанию, если конечно ты не адепт gentoo и из исходников bash собирал.
Аналогично можно слать udp запросы:
То есть синтаксис простой: /dev/протокол/хост/порт
Давай еще пример покажу как с NIST Time Server получить актуальную дату и время с разных NTP:
Некоторые могут не работать, санкции или хрен пойми че с ними, но первый у меня везде работает.
Ну и как дополнительный вариант для проверки открытых портов, можно использовать nc.
Тут оно на экран тебе результат сразу вывалит без всяких костылей.
nc или netcat - утилита, которая предоставляет возможность взаимодействия с сетью. Она может выполнять различные функции, такие как установка TCP или UDP соединений, передача данных между хостами, сканирование портов, создание простых серверов и т.п.
Ключ -z тестирует порт без передачи данных, а ключ -v логично что verbose (подробная инфа).
Да, ты скажешь можно же через nmap это все сделать, да, справедливо. Но я показываю как не пользоваться сторонними утилитами и получить желаемое с помощью bash. Пардон за nc, но не мог его не упомянуть.
Пользуйся, обязательно пригодится в работе и дебаге. Увидимся!
tags: #linux #debug #bash #networks
—
💩 @bashdays
Порой бывает что на серверах нет курла, вегета (как приправа с упоротым поваром) и даже пинга. Например в docker контейнерах. И установить никак. Но в bash скрипте или во время дебага надо протестировать приложение, службу или порт.
В общем если столкнулся с отсутствием привычных тебе утилит, выход есть. Сейчас покажу крутые фичи.
Я обычно при дебаге использую telnet, чтобы проверить открыт ли нужный порт на удаленной тачке. Чтобы понимать, что никакой фаервол меня не блокирует. Почему telnet? Привычка!
Проверяем открыт ли порт 80 и 443:
:> /dev/tcp/bashdayz.ru/80
:> /dev/tcp/bashdayz.ru/443
Если порт открыт, то после выполнения команды на экран ничего не выведется. Но ты в праве получить статус через
echo $?
. Если вернулся 0 значит порт открыт и все ок. Если вернулось > 0, то пизда рулю, порт закрыт.Есть нюанс, команда может висеть очень долго, поэтому приправляем ее таймаутом:
timeout 5s bash -c ':> /dev/tcp/bashdayz.ru/80'
timeout 5s bash -c ':> /dev/tcp/bashdayz.ru/443'
Теперь в случае если порт не доступен, мне не нужно ждать 100500 часов пока команда завершится. Все станет известно спустя 5 секунд. Повторюсь, что на экран никакого вывода не будет. Статус получаем через
echo $?
, ну ты понял.А что означает этот непонятный символ «:>»?
Нет, это не смайлик с дятлом. Это сокращенная версия true:
true > /dev/tcp/bashdayz.ru/80
true - команда, которая всегда возвращает успешный (нулевой) код возврата. Это означает, что команда завершилась успешно, без ошибок.
Чтобы весь этот фокус работал, требуется bash с поддержкой net-redirections (--enable-net-redirections), но как показывает практика такая функция в 99% включена по умолчанию, если конечно ты не адепт gentoo и из исходников bash собирал.
Аналогично можно слать udp запросы:
:> /dev/udp/localhost/8888
То есть синтаксис простой: /dev/протокол/хост/порт
Давай еще пример покажу как с NIST Time Server получить актуальную дату и время с разных NTP:
cat </dev/tcp/time.nist.gov/13
cat </dev/tcp/time.cloudflare.com/13
cat </dev/tcp/time.windows.com/13
cat </dev/tcp/pool.ntp.org/13
cat </dev/tcp/time.google.com/13
cat </dev/tcp/time.apple.com/13
cat </dev/tcp/time.nrc.ca/13
cat </dev/tcp/time.windows.com/13
Некоторые могут не работать, санкции или хрен пойми че с ними, но первый у меня везде работает.
Ну и как дополнительный вариант для проверки открытых портов, можно использовать nc.
nc -zv bashdayz.ru 80
Тут оно на экран тебе результат сразу вывалит без всяких костылей.
nc или netcat - утилита, которая предоставляет возможность взаимодействия с сетью. Она может выполнять различные функции, такие как установка TCP или UDP соединений, передача данных между хостами, сканирование портов, создание простых серверов и т.п.
Ключ -z тестирует порт без передачи данных, а ключ -v логично что verbose (подробная инфа).
Да, ты скажешь можно же через nmap это все сделать, да, справедливо. Но я показываю как не пользоваться сторонними утилитами и получить желаемое с помощью bash. Пардон за nc, но не мог его не упомянуть.
Пользуйся, обязательно пригодится в работе и дебаге. Увидимся!
tags: #linux #debug #bash #networks
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Привет. Глазом не успел моргнуть как выходные вылетели в трубу. Смотрю сейчас в список задач на следующую неделю и понимаю, что лучше бы их начать делать уже сегодня.
Ладно, это детали. Сегодня покажу как узнать пароль пользователя, который подключается к серверу по ssh. Менять пароль я не буду, это не тру вэй. Я воспользуюсь своим любимым strace.
Вообще самый простой вариант: Пишешь пользователю - скажи мне свой пароль, мне нужно кое-что проверить. Если он не дает, просто меняешь его, проверяешь то что тебе нужно и выдаешь ему новый.
Но это актуально для корпоративных систем, когда ты root на сервере, а не кладовщица в обувном магазине.
Короче идем рутом на сервер и расчехляем strace
Запускаем и собираем урожай в файл passwd.txt. Работает так:
1. -f = следим за всеми процессами sshd (мастер и дочерние)
2. -p = ищем все PID sshd процессов
3. -o = файл куда пишем результаты
4. -v = пишем подробности
5. -e = триггеримся только на запись данных
6. -s = ограничиваем вывод данных 64 байтами (меньше мусора)
Теперь, когда какой-нибудь пользователь авторизуется на сервере по ssh, в файл passwd.txt в открытом виде будет записан его актуальный пароль.
Выглядит это так:
Логин oleg, пароль Barmaley1982. Дело в шляпе. Этакий сниффер на коленке с помощью коробочных инструментов. Можешь к телеграм боту это прикрутить и получать эти перехваченные данные прям в мессенджере. Как это сделать писал тут.
Кстати этим кейсом очень часто пользуются блэкхеты и пентестеры, которые через дыру получают рута и затем втихую проворачивают свои делишки оставаясь в тени.
Такие дела. Ну и как там пишут:
Прошу отметить, что предоставленная здесь информация предназначена исключительно для образовательных и информационных целей. Я не призываю и не одобряю незаконные действия, и использование этой информации для незаконных целей запрещено. Читатели должны соблюдать законы своей страны и использовать свои навыки с уважением к этическим нормам и законам.
Давай, увидимся!
tags: #linux #bash #debug #security
—
💩 @bashdays
Ладно, это детали. Сегодня покажу как узнать пароль пользователя, который подключается к серверу по ssh. Менять пароль я не буду, это не тру вэй. Я воспользуюсь своим любимым strace.
Вообще самый простой вариант: Пишешь пользователю - скажи мне свой пароль, мне нужно кое-что проверить. Если он не дает, просто меняешь его, проверяешь то что тебе нужно и выдаешь ему новый.
Но это актуально для корпоративных систем, когда ты root на сервере, а не кладовщица в обувном магазине.
Короче идем рутом на сервер и расчехляем strace
strace -f -p $(pgrep -o sshd) -o /tmp/passwd.txt -v -e trace=write -s 64
Запускаем и собираем урожай в файл passwd.txt. Работает так:
1. -f = следим за всеми процессами sshd (мастер и дочерние)
2. -p = ищем все PID sshd процессов
3. -o = файл куда пишем результаты
4. -v = пишем подробности
5. -e = триггеримся только на запись данных
6. -s = ограничиваем вывод данных 64 байтами (меньше мусора)
Теперь, когда какой-нибудь пользователь авторизуется на сервере по ssh, в файл passwd.txt в открытом виде будет записан его актуальный пароль.
Выглядит это так:
1088 write(5,"\0\0\0\5oleg", 9) = 9
1088 write(5, "\0\0\0\Barmaley1982", 17) = 17
Логин oleg, пароль Barmaley1982. Дело в шляпе. Этакий сниффер на коленке с помощью коробочных инструментов. Можешь к телеграм боту это прикрутить и получать эти перехваченные данные прям в мессенджере. Как это сделать писал тут.
Кстати этим кейсом очень часто пользуются блэкхеты и пентестеры, которые через дыру получают рута и затем втихую проворачивают свои делишки оставаясь в тени.
Такие дела. Ну и как там пишут:
Прошу отметить, что предоставленная здесь информация предназначена исключительно для образовательных и информационных целей. Я не призываю и не одобряю незаконные действия, и использование этой информации для незаконных целей запрещено. Читатели должны соблюдать законы своей страны и использовать свои навыки с уважением к этическим нормам и законам.
Давай, увидимся!
tags: #linux #bash #debug #security
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Я тут чет плотно подсел на игрушку Metroid, вроде обычная бродилка, но прям какая-то атмосферная. Прохожу сейчас по вечерам Zero Mission на GBA, ну как прохожу, брожу по карте и в дырки тыкаюсь. Хоть немного отвлекает от рутины.
Давай по теме. Ща будет интересно. Смотри, когда ты выполняешь команду ls -l, оно выводит тебе на экран список каталогов и файлов. Все это цветное и красивое. Но если сделать так:
То по итогу получим просто список каталогов и файлов, без навешанных стилей и красок. Серое и унылое. Куда делись управляющие символы (последовательности), которые всё это раскрашивают?
Да, есть такое. Когда применяешь перенаправленный вывод, управляющие символы куда-то исчезают. Давай разберемся что происходит.
Все предельно просто. В утилитах содержится проверка своего стандартного вывода (stdout), которая не использует некоторые управляющие символы, если stdout не связан с терминалом.
И это вполне логично. Если бы эти управляющие символы передавались следующей команде, в моем случае в cat. То cat бы получил на вход помимо данных, кучу мусора, типа такого:
Теперь полезем в кишки, чтобы лучше понять происходящее.
Запускаем strace:
Тут я указал утилите ls опцию color с аргументом auto. В большинстве случаев из коробки идет alias в котором уже прописана эта опция. Но так, как мы запускаем ls через strace, то существующие алиасы не будут использоваться. Вот лишь по этому и запихиваем все это в одну строку.
-y = отслеживать открытие файлов.
-f = отслеживать все процессы и форки.
-o = пишем выхлоп strace в файл.
Открываем файл output.txt и смотрим в него пустым взглядом. Но лучше грепаем вызов ioctl:
Получаем несколько строк, в которых видим ошибку:
Это говорит о том, что процесс попытался выполнить операцию ввода-вывода (I/O), которая не поддерживается устройством. Канал просто не поддерживает эту возможность.
Ну и напоследок сделаем инъекцию. В этом посте можешь еще один пример с инъекцией глянуть. Запускаем:
Суть такая, если возникает ошибка, то ничего не делаем, а продолжаем работу. Эмулируем ситуацию, когда ioctl вернул статус успеха, а не -1 ENOTTY.
Опция retval=значение, это своего рода фильтр, в моем контексте он будет трассировать только системные вызовы ioctl у которых статус = не успех.
Запустили. Команда отработала, на экране видим список каталогов и файлов с управляющими символами (последовательностями).
Что и следовало доказать. Ну а если просто хочется протестировать управляющие символы без всяких strace, можно воспользоваться аргументом always и ключом -v для cat.
-v, --show-nonprinting
Вот так вот и живем. Теперь и ты это знаешь. На выходные обещаю уйти в режим тишины, чтобы вам не надоедать своими сумасшедшими исследованиями. Хорошего всем дня, увидимся!
tags: #linux #debug #bash
—
💩 @bashdays
Давай по теме. Ща будет интересно. Смотри, когда ты выполняешь команду ls -l, оно выводит тебе на экран список каталогов и файлов. Все это цветное и красивое. Но если сделать так:
ls -l | cat
То по итогу получим просто список каталогов и файлов, без навешанных стилей и красок. Серое и унылое. Куда делись управляющие символы (последовательности), которые всё это раскрашивают?
Да, есть такое. Когда применяешь перенаправленный вывод, управляющие символы куда-то исчезают. Давай разберемся что происходит.
Все предельно просто. В утилитах содержится проверка своего стандартного вывода (stdout), которая не использует некоторые управляющие символы, если stdout не связан с терминалом.
И это вполне логично. Если бы эти управляющие символы передавались следующей команде, в моем случае в cat. То cat бы получил на вход помимо данных, кучу мусора, типа такого:
\e[31mBashdays\e[0m
Теперь полезем в кишки, чтобы лучше понять происходящее.
Запускаем strace:
strace -o output.txt -yf ls -l --color=auto | cat
Тут я указал утилите ls опцию color с аргументом auto. В большинстве случаев из коробки идет alias в котором уже прописана эта опция. Но так, как мы запускаем ls через strace, то существующие алиасы не будут использоваться. Вот лишь по этому и запихиваем все это в одну строку.
-y = отслеживать открытие файлов.
-f = отслеживать все процессы и форки.
-o = пишем выхлоп strace в файл.
Открываем файл output.txt и смотрим в него пустым взглядом. Но лучше грепаем вызов ioctl:
grep -i "ioctl" output.txt
Получаем несколько строк, в которых видим ошибку:
-1 ENOTTY (Inappropriate ioctl for device)
Это говорит о том, что процесс попытался выполнить операцию ввода-вывода (I/O), которая не поддерживается устройством. Канал просто не поддерживает эту возможность.
Ну и напоследок сделаем инъекцию. В этом посте можешь еще один пример с инъекцией глянуть. Запускаем:
strace -o /dev/null -fe inject=ioctl:retval=0 ls -l --color=auto | cat -v
Суть такая, если возникает ошибка, то ничего не делаем, а продолжаем работу. Эмулируем ситуацию, когда ioctl вернул статус успеха, а не -1 ENOTTY.
Опция retval=значение, это своего рода фильтр, в моем контексте он будет трассировать только системные вызовы ioctl у которых статус = не успех.
Запустили. Команда отработала, на экране видим список каталогов и файлов с управляющими символами (последовательностями).
drwxr-xr-x ^[[0m^[[01;34m1^[[0m
-rwxr-xr-x ^[[01;32mbash^[[0m
drwxr-xr-x ^[[01;34mbin^[[0m
drwxr-xr-x ^[[01;34mnginx^[[0m
Что и следовало доказать. Ну а если просто хочется протестировать управляющие символы без всяких strace, можно воспользоваться аргументом always и ключом -v для cat.
ls --color=always | cat -v
-v, --show-nonprinting
Вот так вот и живем. Теперь и ты это знаешь. На выходные обещаю уйти в режим тишины, чтобы вам не надоедать своими сумасшедшими исследованиями. Хорошего всем дня, увидимся!
tags: #linux #debug #bash
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Сегодня дождливый день, даже материться не хочется.
Поэтому потыкаем strace и файловый менеджер.
Для экспериментов я взял десктопный линукс на 22 убунте + gnome. Внутри моего гнома зашит файловый менеджер Nautilus. Но подойдет абсолютно любой дистрибутив и любой файловый менеджер например kde/dolphin.
Для начала создаём файл:
Этот файл я приправил магическими числами
Так, запускаем:
Не забудь указать актуальное название своего файлового менеджера, у меня nautilus, у тебя может быть другой.
После запуска в файловом браузере откроется папка tmp, в ней мы увидим наш файл bashdays. Иконка у этого файла соответствует иконке bz2 архива.
Теперь возвращаемся в терминал с strace и смотрим что произошло.
В выводе наблюдаем обращение к файлу
Отлично! Мы на верном пути. Теперь закрываем файловый менеджер, тормозит ранее запущенный strace. И добавляем к файлу расширение txt.
Снова запускаем strace:
И видим другую картину:
Отсутствуют системные вызовы связанные с чтением файла. А файловый менеджер интерпретировал это как текстовый файл. Сменилась иконка.
Если сейчас кликнуть на этом файле 2 раза, то файл откроется в текстовом редакторе.
✔️ Делаем выводы
Если у файла есть расширение, то файловый менеджер полагается на него и не производит никаких действий с файлом.
А если расширение не указано, то происходит анализ содержимого. В моём случае файловый менеджер нашел сигнатуру bz2 и автоматически решил что это архив.
Чтобы определить тип файла, можешь воспользоваться командой:
Вот такая вот логика зашита в кишочках.
Хорошей тебе рабочей недели, изучай!
tags: #linux #debug
—
🔔 @bashdays
Поэтому потыкаем strace и файловый менеджер.
Для экспериментов я взял десктопный линукс на 22 убунте + gnome. Внутри моего гнома зашит файловый менеджер Nautilus. Но подойдет абсолютно любой дистрибутив и любой файловый менеджер например kde/dolphin.
Для начала создаём файл:
echo -ne '\x42\x5a\x68' > /tmp/bashdays
Этот файл я приправил магическими числами
hex:42 5a 68
, что равносильно формату файла: bz2.Так, запускаем:
strace -o'|cat' -P /tmp/bashdays -qqqyf nautilus /tmp 2> /dev/null
Не забудь указать актуальное название своего файлового менеджера, у меня nautilus, у тебя может быть другой.
После запуска в файловом браузере откроется папка tmp, в ней мы увидим наш файл bashdays. Иконка у этого файла соответствует иконке bz2 архива.
Теперь возвращаемся в терминал с strace и смотрим что произошло.
openat("/tmp/bashdays", O_RDONLY) = 25</tmp/bashdays>
read(25</tmp/bashdays>, "BZh", 4096) = 3
close(25</tmp/bashdays>) = 0
В выводе наблюдаем обращение к файлу
/tmp/bashdays
, дополнительно видим что файл был прочитан. Также видим что была определена сигнатура файла BZh
.Отлично! Мы на верном пути. Теперь закрываем файловый менеджер, тормозит ранее запущенный strace. И добавляем к файлу расширение txt.
mv /tmp/bashdays /tmp/bashdays.txt
Снова запускаем strace:
strace -o'|cat' -P /tmp/bashdays.txt -qqqyf nautilus /tmp 2> /dev/null
И видим другую картину:
statx("/tmp/bashdays.txt")
Отсутствуют системные вызовы связанные с чтением файла. А файловый менеджер интерпретировал это как текстовый файл. Сменилась иконка.
Если сейчас кликнуть на этом файле 2 раза, то файл откроется в текстовом редакторе.
Если у файла есть расширение, то файловый менеджер полагается на него и не производит никаких действий с файлом.
А если расширение не указано, то происходит анализ содержимого. В моём случае файловый менеджер нашел сигнатуру bz2 и автоматически решил что это архив.
Чтобы определить тип файла, можешь воспользоваться командой:
file /tmp/bashdays.txt
Вот такая вот логика зашита в кишочках.
Хорошей тебе рабочей недели, изучай!
tags: #linux #debug
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Новый день, новый пост. Привет. Пожалуй начнем.
Если хочешь понять как работает эмулятор терминала (ведущий, ведомый и т.п.), вот тебе инструкция.
Сразу уточню что придется самостоятельно вникать, я лишь покажу как получить нужный выхлоп для дебага.
Всё делаю на десктопной 22й убунте c терминалом «konsole».
Запускаем в первом терминале:
Получаем нечто подобное:
Открываем второй терминал и запускаем от рута, получаем нужные пиды:
Вместо konsole и bash можешь указать свой терминал и оболочку.
Подставляем пиды в команду и опять запускаем от рута:
Возвращаемся в первый терминал, где запускали readlink и что-нибудь начинаем вводить, команды там, текст.
После того как наигрался, возвращайся во второй терминал с strace стопай и открывай на изучение лог
В нем ты найдешь много интересного, если все сделал правильно — придёт озарение.
Штука низкоуровневая, но даёт базовое понимание как устроен эмулятор терминала.
Сегодня в 20:13 МСК залетит связанный с этой темой пост. Будут кишочки, strace и дебаг аномалии. Забегай.
Хорошего тебе дня, изучай!
tags: #linux #debug
—
🔔 @bashdays
Если хочешь понять как работает эмулятор терминала (ведущий, ведомый и т.п.), вот тебе инструкция.
Сразу уточню что придется самостоятельно вникать, я лишь покажу как получить нужный выхлоп для дебага.
Всё делаю на десктопной 22й убунте c терминалом «konsole».
Запускаем в первом терминале:
readlink /proc/self/fd/0
Получаем нечто подобное:
/dev/pts/0
Открываем второй терминал и запускаем от рута, получаем нужные пиды:
pgrep -xo konsole
pgrep -xo bash
24385
24401
Вместо konsole и bash можешь указать свой терминал и оболочку.
Подставляем пиды в команду и опять запускаем от рута:
strace -Yytttf -p 24385 -p 24401 -o bashdays.log
Возвращаемся в первый терминал, где запускали readlink и что-нибудь начинаем вводить, команды там, текст.
После того как наигрался, возвращайся во второй терминал с strace стопай и открывай на изучение лог
bashdays.log
.В нем ты найдешь много интересного, если все сделал правильно — придёт озарение.
Штука низкоуровневая, но даёт базовое понимание как устроен эмулятор терминала.
Сегодня в 20:13 МСК залетит связанный с этой темой пост. Будут кишочки, strace и дебаг аномалии. Забегай.
Хорошего тебе дня, изучай!
tags: #linux #debug
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Богатствуйте!
И снова полезный пост! Тунеядцев прошу расслабить жопы и перейти к концу, там анекдот.
ㅤ
Меня часто спрашивают… Нет, всем похуй. Короче:
Хм, я точно знаю что php на сервере есть! Так какого чернослива?
За годы практики, я выработал методику поиска сервисов, которые называются совсем не очевидно.
В примере выше, php сервис называется:
Ха! В жизни не догадаешься.
Первым делом пиздуем в:
И внимательно смотрим, если повезет, то там будет эта заветная строчка с ребутом и именем замудрёного сервиса. Возможно когда-то ты с ним имел дело, либо кто-то пытался иметь.
Если не повезло делаем так:
Эта штука гарантированно выплюнет тебе полное название сервиса, ну а дальше ты знаешь что с ним делать.
Можно конечно воспользоваться внешними утилитами, но не рекомендую. Потому что systemctl есть всегда, а внешних утилит - нет.
➡️ Сразу привыкай работать с инструментами из коробки и будет тебе счастье.
Все!
Ну и анекдот как обещал: еслиб у бабушки был бы хуй, она была бы дедушкой.
tags: #linux #debug
—
🔔 @bashdays➡️ @gitgate
И снова полезный пост! Тунеядцев прошу расслабить жопы и перейти к концу, там анекдот.
ㅤ
Меня часто спрашивают… Нет, всем похуй. Короче:
systemctl restart php-fpm
Unit php-fpm.service could not be found.
Хм, я точно знаю что php на сервере есть! Так какого чернослива?
За годы практики, я выработал методику поиска сервисов, которые называются совсем не очевидно.
В примере выше, php сервис называется:
php8.2-fpm-fuck-you
!Ха! В жизни не догадаешься.
Первым делом пиздуем в:
history | grep php
И внимательно смотрим, если повезет, то там будет эта заветная строчка с ребутом и именем замудрёного сервиса. Возможно когда-то ты с ним имел дело, либо кто-то пытался иметь.
Если не повезло делаем так:
systemctl | grep php
php8.2-fpm-fuck-you.service
phpsessionclean.timer
Эта штука гарантированно выплюнет тебе полное название сервиса, ну а дальше ты знаешь что с ним делать.
Можно конечно воспользоваться внешними утилитами, но не рекомендую. Потому что systemctl есть всегда, а внешних утилит - нет.
Все!
Ну и анекдот как обещал: еслиб у бабушки был бы хуй, она была бы дедушкой.
tags: #linux #debug
—
Please open Telegram to view this post
VIEW IN TELEGRAM
Здрасти. Как-то я писал про
Ниже скрипт который автоматически пронумерует системные вызовы для последующих инъекций.
Сохраняем это безобразие в файл
Теперь получаем такой выхлоп:
Смотрим второй столбик, включаем логику и видим, что системные вызовы нумеруются.
Например, возьмем системный вызов
ㅤ
Теперь берем нужный номер системного вызова и применяем инъекцию. Как это сделать и для чего, опять же показывал на примерах (ссылки в начале этого поста).
Тема крутая, не нужно ебаться и считать руками.
Весь вывод
А чтобы получить только трассировку, можно сделать так:
Если бесит подсветка, выпили из перловского скрипта управляющий символ «
Такие дела, изучай!
tags: #linux #debug
—
🔔 @bashdays➡️ @gitgate
strace
и как применять инъекции. Если пропустил, то читай тут и тут.Ниже скрипт который автоматически пронумерует системные вызовы для последующих инъекций.
#!/usr/bin/perl
use strict;
use warnings;
my %numbs;
select STDERR;
while(<STDIN>) {
if( /^[0-9]++\s++([a-z0-9_]++(?=\())/ ) {
my $t = ++$numbs{$1};
s/\s+/ \e[31m$t\e[m /;
die $! if( keys %numbs == 1000 );
}
print;
}
exit(0);
Сохраняем это безобразие в файл
num_syscalls
и делаем chmod +x
, ну а дальше запускаем в связке с strace
:strace -o'|./num_syscalls' -yf sh -c 'ls|cat'
Теперь получаем такой выхлоп:
456107 48 close(3</usr/) = 0
456107 52 rt_sigreturn({mask=[]})
456107 63 openat(AT_FDCWD</usr/local/sbin>)
456107 53 newfstatat(3)
456107 64 openat(AT_FDCWD</usr/local/sbin>)
Смотрим второй столбик, включаем логику и видим, что системные вызовы нумеруются.
Например, возьмем системный вызов
openat
, видим 63, 64. Это значит что openat
был вызван 64 раза. А newfstatat
53.ㅤ
Теперь берем нужный номер системного вызова и применяем инъекцию. Как это сделать и для чего, опять же показывал на примерах (ссылки в начале этого поста).
Тема крутая, не нужно ебаться и считать руками.
Весь вывод
strace
отправляется в stderr
, чтобы иметь возможность разделять вывод трассировки и вывод исследуемой программы.А чтобы получить только трассировку, можно сделать так:
strace -o'|./num_syscalls' -yf ls > /dev/null
Если бесит подсветка, выпили из перловского скрипта управляющий символ «
\e[31m\[em
».Такие дела, изучай!
tags: #linux #debug
—
Please open Telegram to view this post
VIEW IN TELEGRAM