我的服务器上有一些垃圾邮件问题,在查找并删除了一些Perl和PHP脚本后,我要检查他们真正做了什么,虽然我是一名高级PHP程序员,但我对Perl的经验很少,任何人都可以在这里给我一个脚本:
(这是一长串代码,脚本名为list.pl)
脚本的开头是:
$??s:;s:s;;$?::s;(.*); ]="&\%[=.*.,-))'-,-#-*.).<.'.+-<-~-#,~-.-,.+,~-{-,.<'`.{'`'<-<--):)++,+#,-.{).+,,~+{+,,<)..})<.{.)-,.+.,.)-#):)++,+#,-.{).+,,~+{+,,<)..})<*{.}'`'<-<--):)++,+#,-.{).+:,+,+,',~+*+~+~+{+<+,)..})<'`'<.{'`'<'<-}.<)'+'.:*}.*.'-|-<.+):)~*{)~)|)++,+#,-.{).+:,+,+,',~+*+~+~+{+<+,)..})
直到最后,它继续使用极少数非标点字符:
0-9\;\\_rs}&a-h;;s;(.*);$_;see;
答案 0 :(得分:26)
将s;(.*);$_;see;
替换为print
以获取this。在有效负载的前半部分再次使用s;(.*);$_;see;
替换print
以获取this,这是解密代码。有效载荷的后半部分是要解密的代码,但我不能再深入了解它,因为如你所见,解密代码正在寻找envvar或cookie中的密钥(这样只有脚本的创建者可以控制它或解码它,大概是),我没有那把钥匙。这实际上是相当巧妙的。
答案 1 :(得分:17)
对于那些对细节感兴趣的人......第一部分,当解缠结时看起来像这样:
$? ? s/;s/s;;$?/ :
s/(.*)/...lots of punctuation.../;
行开头的$?
是预定义的变量containing the child error,毫无疑问它仅用作混淆。它将是未定义的,因为此时可能没有子错误。
其后的问号是三元运算符的开始
CONDITION ? IF_TRUE : IF_FALSE
这也简单地添加到混淆中。返回true的表达式是替换正则表达式,其中/
斜杠分隔符已替换为冒号s:pattern:replacement:
。在上面,我已经放回斜线。另一个表达式,即将要执行的表达式也是替换正则表达式,尽管是一个非常长的表达式。分隔符是分号。
此替换替换了.*
中的$_
- 默认输入和模式搜索空间 - 带有相当大量的标点字符,代表了大部分代码。由于.*
匹配任何字符串,即使是空字符串,它也会简单地插入到$_
中,并且用于所有意图和目的,只需将字符串分配给$_
,这就是我做了:
$_ = q;]="&\%[=.*.,-))'-,-# .......;;
以下行是transliteration和另一个替代。 (我插入注释以指出分隔符)
y; -"[%-.:<-@]-`{-}#~\$\\;{\$()*.0-9\;\\_rs}&a-h;;
#^ ^ ^ ^
#1 2 3
(1,2,3是分隔符,2到3之间的分号是逃逸的)
它的基本要点是各种字符和范围-"
(空格到双引号),以及看起来像字符类(带范围)[%-.:<-@]
的东西,但不是,得到音译变得更易读的字符,例如花括号,美元符号,括号,0-9
等
s;(.*);$_;see;
下一个替代是神奇发生的地方。它也是混淆分隔符的替代,但有三个modifers: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
。我们没有。
答案 2 :(得分:6)
让B::Deparse模块让它(更多一点)可读。