Расшифровать обфускацию 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 модуль, чтобы сделать его (немного более) читаемым.