ヤバい Python、ヤバイソン
#coding:L1
import zlib,hashlib
b=bytes("""x<9c><dd>X<cd>n^[7^P<be><fb>)<b6><be>D^B^R<83><e4><90>C<d2>@^N}<8e><c4>(<e6><d7>^R<ea>Ȇ<ec><b4>E<83><bc>{gm^Cɽ{0<b2>^W<ed>r9<c3>o<be><f9><d5>^^\\<bf><ܟ<9f><96>^C=^^<ee><8e>|<f1><fa>x<b6><8b><c3><f2>q<f9><f4>砪^D<99>r<e9>ZY\\r<ad>B^BpD<a6>ҫ^P'<e3>n<9c><a5>'<93><9a>k*<ec>X:<a8><8e>w<ef><97>wD4c\\r<b1>z<a6><9a><bd><c6>v<96>Vd<ce> ƈd^L<88><98><ca>l<c3>Չ<ca>\\0<ee> ٰ*<e7>^B<ab>^N<b5><ae><99>{ ^T<96>^P
w<f1>TM<bd>%(2L<dc>i<fa><a4>4<ea>,<b9>^U<9e>^E<e3><b4>F<dd>:6<dace>T<81>z^^= <b7>^X^G<95>F<ca>^A<9c>]<b4>I*-<a0><e4>,<a1>-t <f8>,M<93><85>6#^*<f3>^YG<b1>B<ea>=<f7>Ν^F<b9>*K.<9a>^Q<aa>x^A<a3>^\\g<a4><92>^\\)C^Z<a9>'<ca>XSrư<cd>V^][p
<de>'s<e7>
<8d>S<83><92><b1>e%s<85>^PVQU^R^F<95><d8>,<96>^L^F@<e7>1<84>RE5Zu<94><e0><b4>H^B<9a>-u<b2>^R[<c5>^[7h8F<a3>^F0<81>JxEK<cd>0<eb><9c>=<f6><84><81>A<9b><b9><e0>f<be> ݀<d3>*)>^R<bb>Mh֓<84>c<a5>^K^A<b9><f4>&<96>4 ^U<9f><83>[-<c5>R<1a>%%A<ed><9e>=nIq+[<b6><88><b1><H<c0>:T<f0><94>q<cc>$-<a7><b0><ce><c3><02>9<e3><d4>i<e0>\\r[^E<ac>e^NHN<9e>&T<af>><ac>n<c5>ii<c5>s<92>^A^Xdz<84>DjS^R<93><8d>Қ<f1><ca>jc<ab><9a><b5><b3>8<8d><a9><bd><d4>A<a3><e8><f4><9c><f3><aa>^C<9b><84><e1><b9>^Q^N^Lj<99><91><d9><e7>^Z<d7>u<d6><c8>^G^^)<e1>HP<83><90>I<93><b4>F<ca>dNCbKѲ<ea><a8>ag<9d>^V<de><f3><d4><ca><ec>yf#<cd>`%+(<b7>^R. 6<8f><9b><80>U'V^^Ź<e4><e0>(<b2>1oŇh<8a><cc>^]\\rs<ed><8c>Ҹ<ba>GҨ<9b>5<8d><a4>'<82> ^FҜ<e6><99>âJbZ\\0d<92>[<99>[<f1>AB2P<92>a<9a>B3<c2>iM<de>dEID8 E<8d><8a>^E,ﻙ^[6<b1><a8>3#"2b^H=m<e5><db>-<ea>G挜C^D^FGa<d7>5<a9><ba>)<f3>hB<d4>SKZQr^]^Y"ғ^G<b2><91>|^T<c0>.<<b7><f2><cb>&<f1>A<b3><8f><9c>K<b0>ɬBNR 3L*<a0>^R<bd><ab>^O4<f7>^Q0<a5>ZT<98>^Yjzt<8d>\\0Z<a3>*m<d5><e7><de>J<bf>ݢ<cf>mQO^?<a5><dc><df>B<c7>^V<b6>lQ<83>ފo<b7><98><e9><b6><f0><cb>^V}<ff><ad>p<fa>V<f2><e5><cd><f4><ca>7^R<a7>[<d4><e4>-<fa>^\\^V<89><b3>:5<d5>ud<cf>^U<c3><c5>1D^H<d4>j\\r<e2><bc>h9-½<87><f0><a8>^U<c4>&^V^Fb<8d>M<ed>eN<ae>Cm<c6>C<a7>^Z<e4>Ok(:cB<a7><d6>jt<a2>>j'紆^CZ.Ne<92>tU^O^K<82><85><ad>f<98>Mr^?<83>9h<8b><ff>/o<e5><bb><c3><ff><f6><ed> ͅ<df><d1><ed><f2>q9<9e>^^<be>><ed>.<ed><f4>d<e7>e]<bb>^.<f7>W<8f>O<e7><e3><c3>n^?q<f4><e5>t<bf>~<bb><b9><f2><af>ww_<e8>I^N<bb><f3><e5><ef>w^OQ8>^?<fb>D^*<fe><fd><e3><e6>^[<e2><f7><cf><df>/<df>?Kﯗ<87><f3><f1>^T^Z<8f><a7><bf><e8>ߟCn<b9><de>]<ee>/<ec><ee>Ѯ/<96><b8>^O*^?><f5><eb>^O<f9><e6>e<f5><fe><bc>^\\^C<d2>r<a6>ӭ<ed>^P<f7>/<bb><d7>+<a0><bc>~Q<ba>z<<84><eb>p<f7>,|<bc><b9><b2><93>ܫ<ed><f6><fb><ab><83><fd><a3><c7>[{|<da><ed><97><df>>.<87>x<fb>C<c1>z<bd>b<fb><fb>|^?<ba>}<81><f4><f3>[>^[<fd><f9><bc><f2>^C<e8>ORr^?><9b><<fd>^VR<ff>^A^Ob&o""",'L1')
assert hashlib.md5(b).hexdigest()=='c0c42cbe7318e7e7d9c58ca4800e9681','corrupted, you may have broke it during re-saving'
exec(zlib.decompress(b))
配布された Python スクリプトは、#coding:L1(latin-1)前提で バイナリ同等のデータを文字列に埋め込み、それを zlib.decompress して exec() に渡す形式でした。
この形式は エディタで普通に開いて保存するだけで内容が破損しやすく、実際に assert(MD5チェック)で「壊れている」と判定されて先に進めなくなることがあります。
解凍されたコードでは Alpaca{...} の中身 66 文字を 1文字ずつ sha256 して配列と照合する実装になっており、逆引き表を一回作れば即座に復元できます。
埋め込み部は bytes(""" ... """, 'L1') のように 文字列を latin-1 としてバイト化しており、理屈としては「1文字=1バイト」で元データが復元できる前提です。
しかしエディタが UTF-8 として読み込むと、解釈不能なバイトが 置換文字 �(U+FFFD) に置き換わり、そのまま保存されてしまいます。
この � は UTF-8 では EF BF BD になるため、元のバイト列(例:78 9c dd 58...)が 78 ef bf bd ef bf bd 58... のように変化し、MD5が一致しなくなります。
方法① エディタで開かずに編集
例 sedでexec → print
sed -i 's/exec/print/' crazython.py
方法② バイナリモードで開いて編集