Расшифровать обфускацию perl script
Если на моем сервере возникли проблемы со спамом, и после выяснения и удаления некоторых скриптов Perl и PHP я не могу проверить, что они на самом деле делают, хотя я старший программист PHP, у меня мало опыта работы с Perl, может кто угодно дайте мне руку с script здесь:
http://pastebin.com/MKiN8ifp
(Это была одна длинная строка кода, script была вызвана list.pl)
Начало script:
$??s:;s:s;;$?::s;(.*); ]="&\%[=.*.,-))'-,-#-*.).<.'.+-<-~-#,~-.-,.+,~-{-,.<'`.{'`'<-<--):)++,+#,-.{).+,,~+{+,,<)..})<.{.)-,.+.,.)-#):)++,+#,-.{).+,,~+{+,,<)..})<*{.}'`'<-<--):)++,+#,-.{).+:,+,+,',~+*+~+~+{+<+,)..})<'`'<.{'`'<'<-}.<)'+'.:*}.*.'-|-<.+):)~*{)~)|)++,+#,-.{).+:,+,+,',~+*+~+~+{+<+,)..})
Он продолжает с драгоценными немногими символами без пунктуации до самого конца:
0-9\;\\_rs}&a-h;;s;(.*);$_;see;
Ответы
Ответ 1
Замените s;(.*);$_;see;
на print
, чтобы получить this. Замените s;(.*);$_;see;
снова на print
в первой половине полезной нагрузки, чтобы получить this, который является кодом дешифрования. Вторая половина полезной нагрузки - это код для дешифрования, но я не могу идти дальше, потому что, как видите, код дешифрования ищет ключ в envvar или cookie (так что только script создатель может управлять им или расшифровывать его, предположительно), и у меня нет этого ключа. Это действительно разумно сделано.
Ответ 2
Для тех, кто заинтересован в nitty gritty... Первая часть, когда де-запутанная выглядит следующим образом:
$? ? s/;s/s;;$?/ :
s/(.*)/...lots of punctuation.../;
$?
в начале строки находится предопределенная переменная содержащая дочернюю ошибку, которая, без сомнения, служит только как обфускация, Это будет undefined, так как в этот момент не может быть дочерней ошибки.
После этого вопросительный знак представляет собой начало тройного оператора
CONDITION ? IF_TRUE : IF_FALSE
который также добавляется просто для запутывания. Выражение, возвращаемое для true, представляет собой подменю regex, где разделитель /
слэша заменен двоеточием s:pattern:replacement:
. Выше, я вернул косые черты. Другое выражение, которое будет выполняться, также является подменю regex, хотя и невероятно длинным. Разделитель - это двоеточие.
Эта подстановка заменяет .*
в $_
- пространство ввода по умолчанию и шаблонное пространство - с довольно большим количеством символов пунктуации, который представляет основную часть кода. Поскольку .*
соответствует любой строке, даже пустой строке, она просто будет вставлена в $_
, и для всех целей и целей идентична просто присваиванию строки $_
, что я и сделал:
$_ = q;]="&\%[=.*.,-))'-,-# .......;;
Следующие строки представляют собой транслитерация и другую подстановку. (Я добавил комментарии, чтобы указать разделители)
y; -"[%-.:<[email protected]]-`{-}#~\$\\;{\$()*.0-9\;\\_rs}&a-h;;
#^ ^ ^ ^
#1 2 3
(1,2,3 - разделители, полуколония между 2 и 3 избегает)
Основной смысл в том, что различные символы и диапазоны -"
(пробел для двойной кавычки) и что-то похожее на классы символов (с диапазонами) [%-.:<[email protected]]
, но это не так, переводятся на более четкие символы например фигурные скобки, знак доллара, круглые скобки, 0-9
и т.д.
s;(.*);$_;see;
Следующая подстановка - это то, где происходит волшебство. Это также замена с запутанными разделителями, но с тремя модификаторами : see
. s
ничего не делает в этом случае, так как он позволяет символу подстановки .
соответствовать новой строке. ee
означает, что для вычисления выражения требуется дважды.
Чтобы посмотреть, что я оцениваю, я выполнил транслитерацию и напечатал результат. Я подозреваю, что я где-то вдоль линии получил некоторые символы, поврежденные, потому что были тонкие ошибки, но вот короткая (очищенная) версия:
s;(.*);73756220656e6372797074696f6e5f6 .....;; # very long line of alphanumerics
s;(..);chr(hex($1));eg;
s;(.*);$_;see;
s;(.*);704b652318371910023c761a3618265 .....;; # another long line
s;(..);chr(hex($1));eg;
&e_echr(\$_);
s;(.*);$_;see;
Длинные регулярные выражения снова являются контейнерами данных и вставляют данные в $_
для оценки как кода.
s/(..)/chr(hex($1))/eg;
начинает выглядеть довольно разборчивым. Он в основном считывает два символа в то время от $_
и преобразует его из шестнадцатеричного в соответствующий символ.
Рядом с последней строкой &e_echr(\$_);
время от времени меня озадачивало, но это подпрограмма, которая определена где-то в этом оцениваемом коде, поскольку hobbs настолько умело удалось декодировать. Знак доллара имеет префикс обратной косой черты, что означает ссылку на $_
: I.e. что подпрограмма может изменить глобальную переменную.
После целого ряда оценок $_
выполняется через эту подпрограмму, после чего все, что содержится в $_
, оценивается в последний раз. Предположительно на этот раз выполнение кода. Как сказал hobbs, требуется ключ, который берется из среды %ENV
машины, на которой выполняется script. Которых у нас нет.
Ответ 3
Задайте B:: Deparse модуль, чтобы сделать его (немного более) читаемым.