Расшифровать запутанный скрипт на Perl - PullRequest
14 голосов
/ 07 марта 2012

У меня были некоторые проблемы со спамом на моем сервере, и после того, как я обнаружил и удалил некоторые Perl и PHP-скрипты, я приступил к проверке того, что они действительно делают, хотя я старший PHP-программист, у меня мало опыта работы с Perl, может кто-нибудь дайте мне руку со сценарием здесь:

http://pastebin.com/MKiN8ifp

(Это была одна длинная строка кода, скрипт назывался list.pl)


Начало скрипта:

$??s:;s:s;;$?::s;(.*); ]="&\%[=.*.,-))'-,-#-*.).<.'.+-<-~-#,~-.-,.+,~-{-,.<'`.{'`'<-<--):)++,+#,-.{).+,,~+{+,,<)..})<.{.)-,.+.,.)-#):)++,+#,-.{).+,,~+{+,,<)..})<*{.}'`'<-<--):)++,+#,-.{).+:,+,+,',~+*+~+~+{+<+,)..})<'`'<.{'`'<'<-}.<)'+'.:*}.*.'-|-<.+):)~*{)~)|)++,+#,-.{).+:,+,+,',~+*+~+~+{+<+,)..})

Это продолжается с очень немногими непунктуативными символами до самого конца:

0-9\;\\_rs}&a-h;;s;(.*);$_;see;

Ответы [ 3 ]

26 голосов
/ 07 марта 2012

Замените s;(.*);$_;see; на print, чтобы получить это . Замените s;(.*);$_;see; снова на print в первой половине полезной нагрузки, чтобы получить this , который является кодом дешифрования. Вторая половина полезной нагрузки - это код для расшифровки, но я не могу идти дальше с этим, потому что, как вы видите, код дешифрования ищет ключ в envvar или cookie (так что только создатель сценария может предположительно), и у меня нет этого ключа. Это действительно разумно сделано.

17 голосов
/ 07 марта 2012

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

$?  ?  s/;s/s;;$?/ :
       s/(.*)/...lots of punctuation.../;

$? в начале строки является предопределенной переменной содержит дочернюю ошибку , которая, без сомнения, служит только для запутывания.Он будет неопределенным, так как в этот момент не может быть дочерней ошибки.

Знак вопроса, следующий за ним, является началом троичного оператора

CONDITION ? IF_TRUE : IF_FALSE

, который также добавляется просто для запутывания.Выражение, возвращаемое для true, является регулярным выражением подстановки, где разделитель косой черты / заменен на двоеточие s:pattern:replacement:.Выше я положил обратно косые черты.Другое выражение, которое будет выполнено, также является подстановочным регулярным выражением, хотя и невероятно длинным.Разделитель - точка с запятой.

Эта подстановка заменяет .* в $_ - пространстве ввода по умолчанию и поиска по шаблону - на довольно большое количество знаков пунктуации, представляющих основную часть кода.Поскольку .* соответствует любой строке, даже пустой строке, она будет просто вставлена ​​в $_ и для всех намерений и целей идентична простому назначению строки для $_, что я и сделал:

$_ = q;]="&\%[=.*.,-))'-,-# .......;;

Следующие строки представляют собой транслитерацию и другую подстановку.(Я вставил комментарии, чтобы указать разделители)

y; -"[%-.:<-@]-`{-}#~\$\\;{\$()*.0-9\;\\_rs}&a-h;;
#^                       ^           ^          ^
#1                       2                      3

(1,2,3 - разделители, точка с запятой между 2 и 3 экранирована)

Основная суть этогов том, что различные символы и диапазоны -" (пробел в двойных кавычках) и что-то, похожее на классы символов (с диапазонами) [%-.:<-@], но не транслитерируются в более разборчивые символы, например в фигурные скобки, знак доллара, скобки, 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(\$_); на некоторое время озадачила меня, но это подпрограмма, которая определенагде-то в этом оцененном коде Хоббс так удачно смог расшифровать.Знак доллара начинается с обратной косой черты, это означает, что это ссылка на $_: то есть, что подпрограмма может изменить глобальную переменную.

После довольно многих оценок, $_ запускается через эту подпрограмму, послечто бы ни содержалось в $_, оценивается в последний раз.Предположительно в этот раз выполняется код.Как сказал Хоббс, требуется ключ, который берется из среды %ENV машины, на которой выполняется скрипт.Которого у нас нет.

6 голосов
/ 07 марта 2012

Попросите модуль B :: Deparse сделать его (немного больше) читабельным.

...