解密混淆perl脚本

时间:2012-03-06 20:48:59

标签: linux perl security spam

我的服务器上有一些垃圾邮件问题,在查找并删除了一些Perl和PHP脚本后,我要检查他们真正做了什么,虽然我是一名高级PHP程序员,但我对Perl的经验很少,任何人都可以在这里给我一个脚本:

http://pastebin.com/MKiN8ifp

(这是一长串代码,脚本名为list.pl)


脚本的开头是:

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

直到最后,它继续使用极少数非标点字符:

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

3 个答案:

答案 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;

下一个替代是神奇发生的地方。它也是混淆分隔符的替代,但有三个modiferssees在这种情况下不执行任何操作,因为它只允许通配符.匹配换行符。 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模块让它(更多一点)可读。