|

楼主 |
发表于 2003-7-20 03:10:39
|
显示全部楼层
楼上的都是狗屁不通 正解在此
NND 这么个小儿科的东西居然花了我这么多时间。
首先异或后的字符串16进制如下:
23 47 33 08 15 45 1d 0a 50 47 3a 19 50 2a 1c 05 1f 5d 72 4e 40 55 41 66 12 4a 72 30 11 17 00 15
50 64 33 10 1c 6f 38 19 1c 4a 72 4d 46 49 52 5e 40 03 61 76 7a 31 1a 05 03 13 3b 0f 50 11 1a 09
50 04 26 14 50 04 1c 02 05 52 3e 5c 23 11 13 18 15 13 3d 1a 50 11 1a 09 50 63 37 0e 1c 45 3d 02
19 5c 3c 5c 03 15 17 09 13 5b 7e 5c 07 0d 17 1e 15 5a 3c 5c 39 45 06 09 1c 5f 72 05 1f 10 52 04
1f 44 72 2c 15 17 1e 4c 19 40 72 18 1f 0c 1c 0b 5e 13 02 19 02 09 52 05 03 13 36 13 19 0b 15 4c
16 5a 3c 19 5c 45 06 04 11 5d 39 5c 09 0a 07 42 50 7d 3d 0b 50 11 1a 0d 04 13 26 14 11 11 55 1f
50 5c 27 08 50 0a 14 4c 04 5b 37 5c 07 04 0b 40 50 7a 75 18 50 09 1b 07 15 13 26 13 50 16 02 09
1e 57 72 08 18 00 52 1e 15 40 26 5c 1f 03 52 18 18 56 72 08 19 08 17 4c 04 56 3e 10 19 0b 15 4c
1a 5c 39 19 03 4b 78 66 24 5b 3b 0f 50 0c 01 4c 04 5b 37 5c 47 11 1a 4c 11 5d 3c 09 11 09 52 3f
04 52 26 19 50 0a 14 4c 04 5b 37 5c 20 00 00 00 50 7c 3c 15 1f 0b 52 1f 00 56 37 1f 18 49 52 1b
18 56 20 19 19 0b 52 25 50 47 37 10 1c 45 0b 03 05 13 3a 13 07 45 22 09 02 5f 72 15 03 45 16 03
19 5d 35 52 50 35 17 1e 1c 13 3b 0f 50 01 1d 05 1e 54 72 1a 19 0b 17 40 50 47 3a 1d 1e 0e 52 15
1f 46 7c 5c 3e 0a 05 4c 04 5b 33 08 50 11 1a 0d 04 14 21 5c 1f 10 06 4c 1f 55 72 08 18 00 52 1b
11 4a 7e 5c 39 42 16 4c 1c 5a 39 19 50 11 1d 4c 03 43 37 12 14 45 06 04 15 13 20 19 03 11 52 03
16 13 26 14 15 45 06 05 1d 56 72 08 15 09 1e 05 1e 54 72 16 1f 0e 17 1f 5e 39 58 35 1e 45 14 0d
13 47 7e 5c 04 0d 17 4c 13 5c 3c 1a 15 17 17 02 13 56 72 13 02 02 13 02 19 49 37 0e 03 45 1a 0d
06 56 72 12 1f 11 1b 0f 15 57 72 08 18 04 06 4c 39 13 21 0c 15 0b 16 4c 1d 5c 21 08 50 0a 14 4c
04 5b 37 5c 04 0c 1f 09 50 47 37 10 1c 0c 1c 0b 50 59 3d 17 15 16 5c 4c 23 5c 72 19 11 06 1a 4c
09 56 33 0e 50 11 1a 09 09 13 35 15 06 00 52 01 15 13 33 5c 1c 0c 06 18 1c 56 72 10 15 16 01 4c
04 5a 3f 19 5c 45 01 03 50 7a 72 14 11 13 17 4c 04 5c 72 1f 18 0a 02 4c 1f 46 26 5c 1d 0a 00 09
50 5c 34 5c 04 0d 17 4c 03 56 20 15 1f 10 01 4c 03 46 30 16 15 06 06 4c 1d 52 26 08 15 17 52 1f
1f 13 33 0f 50 11 1d 4c 1c 56 33 0a 15 45 06 05 1d 56 72 1a 1f 17 52 18 18 56 72 16 1f 0e 17 1f
5e 39 58 39 08 11 00 0d 00 5c 3e 1d 04 0c 1c 0b 50 40 37 0a 15 17 13 00 50 4a 37 1d 02 16 52 05
1e 47 3d 5c 04 0d 17 4c 16 46 26 09 02 00 5e 4c 04 5b 37 05 57 09 1e 4c 15 45 37 12 04 10 13 00
1c 4a 72 1f 18 0a 02 4c 1d 4a 72 08 19 08 17 4c 14 5c 25 12 50 11 1d 4c 04 56 3c 5c 03 00 11 03
1e 57 21 52 50 2c 55 00 1c 13 3a 1d 06 00 52 06 05 40 26 5c 15 0b 1d 19 17 5b 72 08 19 08 17 4c
04 5c 72 0f 11 1c 48 4c 52 7a 75 11 50 17 17 0d 1c 5f 2b 50 50 17 17 0d 1c 5f 2b 5c 15 1d 11 05
04 56 36 5c 11 07 1d 19 04 13 25 14 11 11 52 05 03 13 3a 1d 00 15 17 02 19 5d 35 5c 07 0c 06 04
50 63 37 0e 1c 45 06 04 19 40 72 05 15 04 00 42 50 72 3c 18 50 2c 55 08 50 5f 3b 17 15 45 06 03
50 52 3c 12 1f 10 1c 0f 15 13 26 14 11 11 5e 4c 11 55 26 19 02 45 1e 09 1e 54 26 14 09 45 1c 09
17 5c 26 15 11 11 1b 03 1e 40 7e 5c 37 10 1b 08 1f 13 33 12 14 45 3b 4c 18 52 24 19 50 03 1b 02
11 5f 3e 05 50 01 17 0f 19 57 37 18 5e 4b 5c 4c 4c 54 3d 12 17 5b 52 37 52 67 3b 11 15 42 01 4c
05 43 7c 5c 3e 00 0a 18 50 40 22 19 11 0e 17 1e 50 43 3e 19 11 16 17 4e 2d 39 58 2b 15 09 1e 40
50 4a 3d 09 50 01 1b 08 1e 14 26 5c 02 00 13 00 1c 4a 72 0b 11 0b 06 4c 04 5c 72 17 1e 0a 05 4c
04 5b 33 08 50 04 1c 15 07 52 2b 52 5e 4b 78
Perl程序如下:
[PHP]#!/usr/bin/perl
use strict;
my $DEBUG = 1;
my @CHAR_SET = ("\t", "\r", "\n", map { chr } (32..126));
my $XOR_TABLE = xor_table(@CHAR_SET);
my $ALL_CHARS = join('', @CHAR_SET);
if ($DEBUG) {
foreach my $c (sort keys(%$XOR_TABLE)) {
print "0x", unpack("H*", $c), ": ", $XOR_TABLE->{$c}, "\n";
}
}
my $plain = join('', <DATA>); # 明文在程序后__DATA__里
my $key = 'p3R|perl';
my $crypt = xor_crypt($plain, $key);
if ($DEBUG) {
my $p2 = xor_crypt($crypt, $key);
die "xor error\n" unless $p2 eq $plain;
print "Key = '$key'\n";
print "Crypt:\n", hexdump($crypt);
}
crack_xor($crypt);
exit;
sub xor_table {
my $table = {}; # 联想列表存结果
for (my $i = 0; $i < @_; $i++) {
for (my $j = $i + 1; $j < @_; $j++) {
my $xor = "$_[$i]" ^ "$_[$j]";
if (exists $table->{$xor}) {
$table->{$xor} .= $_[$i].$_[$j];
} else {
$table->{$xor} = $_[$i].$_[$j];
}
}
}
return $table;
}
sub crack_xor {
my ($crypt, $max_key_len) = @_;
defined $max_key_len or $max_key_len = 23;
my $crypt_len = length($crypt);
return if $crypt_len < @CHAR_SET;
$max_key_len = $crypt_len if $max_key_len > $crypt_len;
GUESS: for (my $key_len = 1; $key_len <= $max_key_len; $key_len++) {
print "Try key_len = $key_len ...";
my $count = 0;
my @key_candidates = ();
for (my $i = 0; $i < $key_len; $i++) {
$key_candidates[$i] = "";
my $tested = {};
my $c_i = substr($crypt, $i, 1);
my $xor_i = $XOR_TABLE->{$c_i};
$xor_i = $ALL_CHARS if $c_i eq "\0";
print "c[i=$i]=0x", unpack("H*", $c_i), ": $xor_i\n" if $DEBUG;
CHAR: foreach my $char (split("", $xor_i)) {
next if exists $tested->{$char} and $tested->{$char} == 0;
for (my $j = $i+$key_len; $j < $crypt_len; $j += $key_len) {
my $c_j = substr($crypt, $j, 1);
if ($c_j eq "\0") {
$tested->{$char} = 1;
next;
}
my $xor_j = $XOR_TABLE->{$c_j};
print "c[j=$j]=0x",unpack("H*", $c_j), ": $xor_j <<$char>> " if $DEBUG;
my $regexp = $char;
$regexp =~ s/(\W)/\\$1/g;
if ($xor_j =~ /$regexp/) {
print "found\n" if $DEBUG;
$tested->{$char} = 1;
} else {
print "not found\n" if $DEBUG;
$tested->{$char} = 0;
next CHAR;
}
}
}
print "candidate [" if $DEBUG;
foreach my $char (keys %$tested) {
if ($tested->{$char} == 1) {
$key_candidates[$i] .= $char;
print "$char" if $DEBUG;
}
}
print "]\n" if $DEBUG;
if (length $key_candidates[$i]) {
$count++;
} else {
print "failed at i = $i.\n";
next GUESS;
}
}
if ($count == $key_len) {
print "bingo.\n";
print "Key candidates: ";
for (my $i = 0; $i < $key_len; $i++) {
print "<$key_candidates[$i]>";
}
print "\n";
examine($crypt, @key_candidates);
}
}
}
sub xor_crypt {
my ($crypt, $key) = @_;
my $crypt_len = length($crypt);
my $key_len = length($key);
my $plain = "";
for (my $i = 0; $i < $crypt_len; $i+=$key_len) {
my $block = substr($crypt, $i, $key_len);
$plain .= "$block" ^ substr($key, 0, length($block));
}
$plain;
}
sub examine {
my ($crypt, @key_candidates) = @_;
my $total = 1;
my @keys;
combinations(\@keys, @key_candidates);
foreach my $key (@keys) {
my $plain = xor_crypt($crypt, $key);
if ($plain =~ /[^ -~\n\t\r]/s) {
print "Key '$key' discarded: found junk char\n";
next;
}
if ($plain !~ /\s\S{1,3}\s/s) {
print "Key '$key' discarded: could not find word with 1 to 3 letters\n";
next;
}
if ($plain =~ /\S{20}/s) {
print "Key '$key' discarded: found word with 20 chars\n";
next;
}
print "Key '$key' produces the following text:\n",
'='x79, "\n$plain\n", '='x79, "\n";
}
}
sub combinations {
my ($aref, @cand) = @_;
return unless @cand;
my @chars = split('', shift @cand);
my $count = @$aref;
die "Too many combinations\n" if $count > 1000000;
if ($count == 0) {
push @$aref, @chars;
} else {
for (my $i = 0; $i < $count; $i++) {
my $x = shift @$aref;
foreach my $c (@chars) {
push(@$aref, $x . $c);
}
}
}
combinations($aref, @cand);
}
sub hexdump {
my $str = pop;
return unless defined $str;
my $res = "";
my $len = length($str);
for (my $i = 0; $i < $len; $i += 16) {
my $s = substr($str, $i, 16);
my $hex = unpack('H*', $s);
$s =~ s/[\x00-\x1f]/./g; # 0x00-0x1f will screw up terminal
$hex =~ s/(\w\w)/$1 /g;
$res .= sprintf("%-48s %s\n", $hex, $s);
}
return $res;
}
__DATA__
State of the Onion 2003
by Larry Wall
July 16, 2003
This is the 7th annual State of the Perl Onion speech, wherein I tell you how Perl is doing. Perl is doing fine, thank you. Now that that's out of the way, I'd like to spend the rest of the time telling jokes.
This is the 7th annual State of the Perl Onion speech, wherein I tell you how Perl is doing. Perl is doing fine, thank you. Now that that's out of the way, I'd like to spend the rest of the time telling jokes.
In fact, the conference organizers have noticed that I spend most of the time telling jokes. So each year they give me a little less time, so I have to chop out more of the serious subject matter so as to leave time for the jokes.
Extrapolating several years into the future, they'll eventually chop my time down to ten seconds. I'll have just enough time to say: "I'm really, really excited about what is happening with Perl this year. And I'd like to announce that, after lengthy negotiations, Guido and I have finally decided... <gong> ["Time's up. Next speaker please"]
Well, you didn't really want to know that anyway...
[/PHP] |
|