如何正确deobfusacte Perl脚本?

Bio*_*eek 55 perl deobfuscation

我正在尝试反混淆以下Perl代码(源代码):

#!/usr/bin/perl
(my$d=q[AA                GTCAGTTCCT
  CGCTATGTA                 ACACACACCA
    TTTGTGAGT                ATGTAACATA
      CTCGCTGGC              TATGTCAGAC
        AGATTGATC          GATCGATAGA
          ATGATAGATC     GAACGAGTGA
            TAGATAGAGT GATAGATAGA
              GAGAGA GATAGAACGA
                TC GATAGAGAGA
                 TAGATAGACA G
               ATCGAGAGAC AGATA
             GAACGACAGA TAGATAGAT
           TGAGTGATAG    ACTGAGAGAT
         AGATAGATTG        ATAGATAGAT
       AGATAGATAG           ACTGATAGAT
     AGAGTGATAG             ATAGAATGAG
   AGATAGACAG               ACAGACAGAT
  AGATAGACAG               AGAGACAGAT
  TGATAGATAG             ATAGATAGAT
  TGATAGATAG           AATGATAGAT
   AGATTGAGTG        ACAGATCGAT
     AGAACCTTTCT   CAGTAACAGT
       CTTTCTCGC TGGCTTGCTT
         TCTAA CAACCTTACT
           G ACTGCCTTTC
           TGAGATAGAT CGA
         TAGATAGATA GACAGAC
       AGATAGATAG  ATAGAATGAC
     AGACAGAGAG      ACAGAATGAT
   CGAGAGACAG          ATAGATAGAT
  AGAATGATAG             ACAGATAGAC
  AGATAGATAG               ACAGACAGAT
  AGACAGACTG                 ATAGATAGAT
   AGATAGATAG                 AATGACAGAT
     CGATTGAATG               ACAGATAGAT
       CGACAGATAG             ATAGACAGAT
         AGAGTGATAG          ATTGATCGAC
           TGATTGATAG      ACTGATTGAT
             AGACAGATAG  AGTGACAGAT
               CGACAGA TAGATAGATA
                 GATA GATAGATAG
                    ATAGACAGA G
                  AGATAGATAG ACA
                GTCGCAAGTTC GCTCACA
])=~s/\s+//g;%a=map{chr $_=>$i++}65,84,67,
71;$p=join$;,keys%a;while($d=~/([$p]{4})/g
){next if$j++%96>=16;$c=0;for$d(0..3){$c+=
$a{substr($1,$d,1)}*(4**$d)}$perl.=chr $c}
             eval $perl;
Run Code Online (Sandbox Code Playgroud)

运行时,会打印出来 Just another genome hacker.

运行代码槽Deparseperltidy(perl -MO=Deparse jagh.pl | perltidy)之后代码如下所示:

( my $d =
"AA...GCTCACA\n" # snipped double helix part
) =~ s/\s+//g;
(%a) = map( { chr $_, $i++; } 65, 84, 67, 71 );
$p = join( $;, keys %a );
while ( $d =~ /([$p]{4})/g ) {
    next if $j++ % 96 >= 16;
    $c = 0;
    foreach $d ( 0 .. 3 ) {
        $c += $a{ substr $1, $d, 1 } * 4**$d;
    }
    $perl .= chr $c;
}
Run Code Online (Sandbox Code Playgroud)

这就是我自己能够解读的内容.

( my $d =
"AA...GCTCACA\n" # snipped double helix part
) =~ s/\s+//g;
Run Code Online (Sandbox Code Playgroud)

删除$d(双螺旋)中的所有空格.

(%a) = map( { chr $_, $i++; } 65, 84, 67, 71 );
Run Code Online (Sandbox Code Playgroud)

使得散列与作为键A,T,CG和作为值0,1,23.我通常使用Python编写代码,因此这将转换为{'A': 0, 'B': 1, 'C': 2, 'D': 3}Python中的字典.

$p = join( $;, keys %a );
Run Code Online (Sandbox Code Playgroud)

加入与散列的键$;下标分离器,用于多维数组仿真.文档说默认为"\ 034",与awk中的SUBSEP相同,但是当我这样做时:

my @ascii = unpack("C*", $p);
print @ascii[1];
Run Code Online (Sandbox Code Playgroud)

我得到了价值28?此外,我不清楚这是如何模拟多维数组的.是$p现在有点像[['A'], ['T'], ['C'], ['G']]在Python?

    while ( $d =~ /([$p]{4})/g ) {
Run Code Online (Sandbox Code Playgroud)

只要$d匹配([$p]{4}),就执行while块中的代码.但由于我不完全了解结构$p是什么,我也很难理解这里发生了什么.

next if $j++ % 96 >= 16;
Run Code Online (Sandbox Code Playgroud)

如果$j模数96大于或等于16 $j,则为while循环的每次通过增量(?).

$c = 0;
foreach $d ( 0 .. 3 ) {
    $c += $a{ substr $1, $d, 1 } * 4**$d;
}
Run Code Online (Sandbox Code Playgroud)

对于$d范围从03提取一些子,但在这一点上,我完全失去了.最后几行连接所有内容并评估结果.

Mat*_*Mat 50

注意:不要盲目的跑混淆perl的,尤其是如果有一个eval,反引号,system,open等打电话的地方在里面,并且可能不会太明显*.在了解正在发生的事情之前,必须先对其进行去模糊处理,Deparse然后小心地用eval打印语句替换它.应该考虑在沙箱中运行/使用非特权用户/在VM中运行.

*s&&$_ⅇ评估意见$_.


第一个观察:034是八进制.它等于28(十进制)或0x1c(十六进制),所以没有什么可钓的.

$;事纯属混淆,无法找到一个理由来使用,在特定的.$p将只是一个字符串A.T.C.G(.替换为$;,无论它是什么).
所以在正则表达式中[$p]匹配任何一个{'A', 'T', 'C', 'G', $;}.既然$;从未出现过$d,那就没用了.反过来[$p]{4}匹配上面集合中的四个字母的任何序列,就好像这已被使用(忽略无用$;):

while ( $d =~ /([ATCG]{4})/g ) { ... }
Run Code Online (Sandbox Code Playgroud)

如果你必须自己写这个,删除空格后,你只需要抓住$d长度为4的每个连续子串(假设没有其他字符$d).

现在这部分很有趣:

foreach $d ( 0 .. 3 ) {
    $c += $a{ substr $1, $d, 1 } * 4**$d;
}
Run Code Online (Sandbox Code Playgroud)
  • $1拥有当前的四字母代码点.substr $1, $d, 1返回该代码点的每个连续字母.
  • %a映射A到00b(二进制),T01b,C到10b和G11b.

    A   00
    T   01
    C   10
    G   11
    
    Run Code Online (Sandbox Code Playgroud)
  • 乘以4**$d将等于0,2,4和6的按位左移.

所以这个有趣的结构允许你用base ATCG作为数字在base-four系统中构建任何8bit值!

即它执行以下转换:

         A A A A
AAAA -> 00000000

         T A A T
TAAT -> 01000001 -> capital A in ascii

         T A A C
CAAT -> 01000010 -> capital B in ascii

CAATTCCTGGCTGTATTTCTTTCTGCCT -> BioGeek
Run Code Online (Sandbox Code Playgroud)

这部分:

next if $j++ % 96 >= 16;
Run Code Online (Sandbox Code Playgroud)

使上述转换仅针对前16个"代码点"运行,跳过接下来的80个,然后转换为接下来的16个,跳过下一个80,等等.它基本上只是跳过部分椭圆(垃圾脱粒系统).


这是一个丑陋的文本到DNA转换器,你可以用它来产生任何东西来代替螺旋(不处理80跳过的东西):

use strict;
use warnings;
my $in = shift;

my %conv = ( 0 => 'A', 1 => 'T', 2 => 'C', 3 => 'G');

for (my $i=0; $i<length($in); $i++) {
    my $chr = substr($in, $i, 1);
    my $chv = ord($chr);
    my $encoded ="";
    $encoded .= $conv{($chv >> 0) & 0x3};
    $encoded .= $conv{($chv >> 2) & 0x3};
    $encoded .= $conv{($chv >> 4) & 0x3};
    $encoded .= $conv{($chv >> 6) & 0x3};
    print $encoded;
}
print "\n";
Run Code Online (Sandbox Code Playgroud)
$ perl q.pl 'print "BioGeek\n";'
AAGTCAGTTCCTCGCTATGTAACACACACAATTCCTGGCTGTATTTCTTTCTGCCTAGTTCGCTCACAGCGA
Run Code Online (Sandbox Code Playgroud)

坚持$d使用而不是螺旋(并删除解码器中的跳过部分).

  • 文本到DNA脚本(所以未经过混淆,它看起来不像正确的perl)提供:) (12认同)
  • 现在提出一个非常有趣的问题:如何编写将文本转换为DNA的代码?=) (8认同)
  • +1非常好:)关于你的警告的一件事:`eval`部分也可以被混淆.我在主要评论中提到的代码使用了类似`;; s ;; $ _; see`,这是`$ _`的双重eval. (5认同)