有人可以解释这个混淆的perl regexp脚本吗?

hug*_*ugo 3 perl

此代码摘自Phineas Fisher 的HackBack DIY指南,用于抢劫银行。它输出一个长文本(Lacandon丛林的第六宣言)。它在哪里获取?我根本看不到任何字母数字字符。这里发生了什么?-r开关有什么作用?似乎没有记录。

perl -Mre=eval <<\EOF
                                   ''                                     
                                  =~(                                     
                                  '(?'                                    
                                 .'{'.(                                   
                                '`'|'%'                                   
                                ).("\["^                                  
                               '-').('`'|                                 
                              '!').("\`"|                                 
                              ',').'"(\\$'                                
                             .':=`'.(('`')|                               
                            '#').('['^'.').                               
                            ('['^')').("\`"|                              
 ',').('{'^'[').'-'.('['^'(').('{'^'[').('`'|'(').('['^'/').('['^'/').(   
'['^'+').('['^'(').'://'.('`'|'%').('`'|'.').('`'|',').('`'|'!').("\`"|   
  '#').('`'|'%').('['^'!').('`'|'!').('['^'+').('`'|'!').('['^"\/").(     
     '`'|')').('['^'(').('['^'/').('`'|'!').'.'.('`'|'%').('['^'!')       
        .('`'|',').('`'|'.').'.'.('`'|'/').('['^')').('`'|"\'").          
          '.'.('`'|'-').('['^'#').'/'.('['^'(').('`'|('$')).(             
             '['^'(').('`'|',').'-'.('`'|'%').('['^('(')).                
                '/`)=~'.('['^'(').'|</'.('['^'+').'>|\\'                  
                   .'\\'.('`'|'.').'|'.('`'|"'").';'.                     
                     '\\$:=~'.('['^'(').'/<.*?>//'                        
                     .('`'|"'").';'.('['^'+').('['^                       
                    ')').('`'|')').('`'|'.').(('[')^                      
                   '/').('{'^'[').'\\$:=~/('.(('{')^                      
                   '(').('`'^'%').('{'^'#').('{'^'/')                     
                  .('`'^'!').'.*?'.('`'^'-').('`'|'%')                    
                 .('['^'#').("\`"|    ')').('`'|'#').(                    
                 '`'|'!').('`'|          '.').('`'|'/')                   
                .'..)/'.('['               ^'(').'"})')                   
                ;$:="\."^                     '~';$~='@'                  
               |'(';$^=                          ')'^'[';                 
              $/='`'                                |'.';                 
              $,=                                      '('           
EOF
Run Code Online (Sandbox Code Playgroud)

Dad*_*ada 6

您发布的代码的基本思想是,每个字母数字字符已由两个非字母数字字符之间的按位运算代替。例如,

'`'|'%'
Run Code Online (Sandbox Code Playgroud)

(代码中“星号”的第5行)是按位排列或在反引号和取模之间,其代码点分别为96和37,其“或”为101,这是字母“ e”的代码点。以下几行都显示相同的内容:

say '`' | '%' ;
say chr( ord('`' | '%') );
say chr( ord('`') | ord('%') );
say chr( 96 | 37 );
say chr( 101 );
say "e"
Run Code Online (Sandbox Code Playgroud)

您的代码始于(忽略无关紧要的空格):

'' =~ (
Run Code Online (Sandbox Code Playgroud)

对应的结束括号是在28行之后:

^'(').'"})')
Run Code Online (Sandbox Code Playgroud)

(请参见此模式在网页上查看;我使用了编辑器的匹配括号突出显示来找到它)

我们可以将左括号和右括号之间的所有内容分配给一个变量,然后可以打印该变量:

$x =                              '(?'
                                 .'{'.(
                                '`'|'%'
                                ).("\["^
                               '-').('`'|
                              '!').("\`"|
                              ',').'"(\\$'
                             .':=`'.(('`')|
                            '#').('['^'.').
                            ('['^')').("\`"|
 ',').('{'^'[').'-'.('['^'(').('{'^'[').('`'|'(').('['^'/').('['^'/').(
'['^'+').('['^'(').'://'.('`'|'%').('`'|'.').('`'|',').('`'|'!').("\`"|
  '#').('`'|'%').('['^'!').('`'|'!').('['^'+').('`'|'!').('['^"\/").(
     '`'|')').('['^'(').('['^'/').('`'|'!').'.'.('`'|'%').('['^'!')
        .('`'|',').('`'|'.').'.'.('`'|'/').('['^')').('`'|"\'").
          '.'.('`'|'-').('['^'#').'/'.('['^'(').('`'|('$')).(
             '['^'(').('`'|',').'-'.('`'|'%').('['^('(')).
                '/`)=~'.('['^'(').'|</'.('['^'+').'>|\\'
                   .'\\'.('`'|'.').'|'.('`'|"'").';'.
                     '\\$:=~'.('['^'(').'/<.*?>//'
                     .('`'|"'").';'.('['^'+').('['^
                    ')').('`'|')').('`'|'.').(('[')^
                   '/').('{'^'[').'\\$:=~/('.(('{')^
                   '(').('`'^'%').('{'^'#').('{'^'/')
                  .('`'^'!').'.*?'.('`'^'-').('`'|'%')
                 .('['^'#').("\`"|    ')').('`'|'#').(
                 '`'|'!').('`'|          '.').('`'|'/')
                .'..)/'.('['               ^'(').'"})';
print $x;
Run Code Online (Sandbox Code Playgroud)

这将打印:

(?{eval"(\$:=`curl -s https://enlacezapatista.ezln.org.mx/sdsl-es/`)=~s|</p>|\\n|g;\$:=~s/<.*?>//g;print \$:=~/(SEXTA.*?Mexicano..)/s"})
Run Code Online (Sandbox Code Playgroud)

剩下的代码是一些变量的分配。可能这里只是完成模式:星的结尾是:

$:="\."^'~';
$~='@'|'(';
$^=')'^'[';
$/='`'|'.';
$,='(';
Run Code Online (Sandbox Code Playgroud)

它只是将简单的单字符字符串分配给某些变量。

回到主要代码:

(?{eval"(\$:=`curl -s https://enlacezapatista.ezln.org.mx/sdsl-es/`)=~s|</p>|\\n|g;\$:=~s/<.*?>//g;print \$:=~/(SEXTA.*?Mexicano..)/s"})
Run Code Online (Sandbox Code Playgroud)

这段代码位于一个正则表达式中,该正则表达式与一个空字符串匹配(别忘了我们首先拥有'' =~ (...))。(?{...})正则表达式中的代码运行中的代码...。使用一些空格,并除去eval中的字符串,可以得到:

# fetch an url from the web using curl _quitely_ (-s)
($: = `curl -s https://enlacezapatista.ezln.org.mx/sdsl-es/`)
    # replace end of paragraphs with newlines in the HTML fetched
    =~ s|</p>|\n|g;
# Remove all HTML tags
$: =~ s/<.*?>//g;
# Print everything between SEXTA and Mexicano (+2 chars)
print $: =~ /(SEXTA.*?Mexicano..)/s
Run Code Online (Sandbox Code Playgroud)

您可以使用B::Deparse以下命令来自动化此模糊处理:

perl -MO=Deparse yourcode.pl
Run Code Online (Sandbox Code Playgroud)

会产生类似:

'' =~ m[(?{eval"(\$:=`curl -s https://enlacezapatista.ezln.org.mx/sdsl-es/`)=~s|</p>|\\n|g;\$:=~s/<.*?>//g;print \$:=~/(SEXTA.*?Mexicano..)/s"})];
$: = 'P';
$~ = 'h';
$^ = 'r';
$/ = 'n';
$, = '(';
Run Code Online (Sandbox Code Playgroud)