这段代码取自菲尼亚斯·费舍尔(Phineas Fisher(的HackBack DIY抢劫银行指南。它输出一个很长的文本(拉坎顿丛林的第六宣言(。它从哪里取来?我根本没有看到任何字母数字字符。这是怎么回事?-r 开关有什么作用?它似乎没有记录在案。
perl -Mre=eval <<EOF
''
=~(
'(?'
.'{'.(
'`'|'%'
).("["^
'-').('`'|
'!').("`"|
',').'"(\$'
.':=`'.(('`')|
'#').('['^'.').
('['^')').("`"|
',').('{'^'[').'-'.('['^'(').('{'^'[').('`'|'(').('['^'/').('['^'/').(
'['^'+').('['^'(').'://'.('`'|'%').('`'|'.').('`'|',').('`'|'!').("`"|
'#').('`'|'%').('['^'!').('`'|'!').('['^'+').('`'|'!').('['^"/").(
'`'|')').('['^'(').('['^'/').('`'|'!').'.'.('`'|'%').('['^'!')
.('`'|',').('`'|'.').'.'.('`'|'/').('['^')').('`'|"'").
'.'.('`'|'-').('['^'#').'/'.('['^'(').('`'|('$')).(
'['^'(').('`'|',').'-'.('`'|'%').('['^('(')).
'/`)=~'.('['^'(').'|</'.('['^'+').'>|\'
.'\'.('`'|'.').'|'.('`'|"'").';'.
'\$:=~'.('['^'(').'/<.*?>//'
.('`'|"'").';'.('['^'+').('['^
')').('`'|')').('`'|'.').(('[')^
'/').('{'^'[').'\$:=~/('.(('{')^
'(').('`'^'%').('{'^'#').('{'^'/')
.('`'^'!').'.*?'.('`'^'-').('`'|'%')
.('['^'#').("`"| ')').('`'|'#').(
'`'|'!').('`'| '.').('`'|'/')
.'..)/'.('[' ^'(').'"})')
;$:="."^ '~';$~='@'
|'(';$^= ')'^'[';
$/='`' |'.';
$,= '('
EOF
您发布的代码的基本思想是,每个字母数字字符都已替换为两个非字母数字字符之间的按位运算。例如
'`'|'%'
(代码中"星号"的第 5 行( 是反引号和模之间的位或,其码位分别为 96 和 37,其"or"为 101,是字母"e"的码位。以下几行都打印相同的内容:
say '`' | '%' ;
say chr( ord('`' | '%') );
say chr( ord('`') | ord('%') );
say chr( 96 | 37 );
say chr( 101 );
say "e"
您的代码以 (忽略无关紧要的空格( 开头:
'' =~ (
相应的右括号是后面的 28 行:
^'(').'"})')
(C-f此模式在网页上看到它;我使用编辑器的匹配括号突出显示来找到它(
我们可以将左括号和右括号之间的所有内容分配给一个变量,然后我们可以打印该变量:
$x = '(?'
.'{'.(
'`'|'%'
).("["^
'-').('`'|
'!').("`"|
',').'"(\$'
.':=`'.(('`')|
'#').('['^'.').
('['^')').("`"|
',').('{'^'[').'-'.('['^'(').('{'^'[').('`'|'(').('['^'/').('['^'/').(
'['^'+').('['^'(').'://'.('`'|'%').('`'|'.').('`'|',').('`'|'!').("`"|
'#').('`'|'%').('['^'!').('`'|'!').('['^'+').('`'|'!').('['^"/").(
'`'|')').('['^'(').('['^'/').('`'|'!').'.'.('`'|'%').('['^'!')
.('`'|',').('`'|'.').'.'.('`'|'/').('['^')').('`'|"'").
'.'.('`'|'-').('['^'#').'/'.('['^'(').('`'|('$')).(
'['^'(').('`'|',').'-'.('`'|'%').('['^('(')).
'/`)=~'.('['^'(').'|</'.('['^'+').'>|\'
.'\'.('`'|'.').'|'.('`'|"'").';'.
'\$:=~'.('['^'(').'/<.*?>//'
.('`'|"'").';'.('['^'+').('['^
')').('`'|')').('`'|'.').(('[')^
'/').('{'^'[').'\$:=~/('.(('{')^
'(').('`'^'%').('{'^'#').('{'^'/')
.('`'^'!').'.*?'.('`'^'-').('`'|'%')
.('['^'#').("`"| ')').('`'|'#').(
'`'|'!').('`'| '.').('`'|'/')
.'..)/'.('[' ^'(').'"})';
print $x;
这将打印:
(?{eval"($:=`curl -s https://enlacezapatista.ezln.org.mx/sdsl-es/`)=~s|</p>|\n|g;$:=~s/<.*?>//g;print $:=~/(SEXTA.*?Mexicano..)/s"})
代码的其余部分是一堆对一些变量的赋值;可能这里只是为了完成模式:星号的末尾是:
$:="."^'~';
$~='@'|'(';
$^=')'^'[';
$/='`'|'.';
$,='(';
它只是将简单的单字符字符串分配给某些变量。
回到主代码:
(?{eval"($:=`curl -s https://enlacezapatista.ezln.org.mx/sdsl-es/`)=~s|</p>|\n|g;$:=~s/<.*?>//g;print $:=~/(SEXTA.*?Mexicano..)/s"})
这段代码位于正则表达式中,该正则表达式与空字符串匹配(不要忘记我们首先'' =~ (...)
(。 正则表达式中的(?{...})
运行...
中的代码。使用一些空格,并删除 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
您可以使用B::Deparse
自动执行此取消混淆过程:运行
perl -MO=Deparse yourcode.pl
将产生类似以下内容的内容:
'' =~ 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';
$, = '(';