Last active
August 29, 2015 13:57
-
-
Save mwgamera/9774270 to your computer and use it in GitHub Desktop.
CRX header tools, http://developer.chrome.com/extensions/crx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# Analyze header of CRX packages (Chrome extensions). | |
# klg, Feb 2014 | |
use strict; | |
use open IO => ':bytes'; | |
use Digest::SHA 'sha256_hex'; | |
use MIME::Base64; | |
use Crypt::OpenSSL::RSA; | |
use constant CRX_MAGIC => 0x34327243; | |
sub pkid($) { | |
(lc unpack 'a32', sha256_hex @_) =~ y/0-9a-f/a-p/r; | |
} | |
sub pkrsa($) { | |
Crypt::OpenSSL::RSA->new_public_key("-----BEGIN PUBLIC KEY-----\n". | |
encode_base64(shift)."-----END PUBLIC KEY-----"); | |
} | |
do { | |
my $fn = shift // '-'; | |
open my $fh, $fn or die $!; | |
binmode $fh; | |
$fn = $fn eq '-' ? '' : "$fn: "; | |
read $fh, $_, 16 or die $!; | |
my ($crx, $ver, $pklen, $siglen) = unpack 'V4'; | |
die "${fn}Bad format\n" unless $crx == CRX_MAGIC; | |
die "${fn}Unknown version of CRX file\n" unless $ver == 2; | |
read $fh, my $pk, $pklen or die $!; | |
read $fh, my $sig, $siglen or die $!; | |
printf "%sID: %s\n", $fn, pkid($pk); | |
my $rsa = pkrsa($pk); | |
printf "%sRSA %u bits, ", $fn, 8 * $rsa->size; | |
my $zip = do { local $/; <$fh> }; | |
$rsa->use_sslv23_padding; | |
$rsa->use_sha1_hash; | |
printf "signature %s\n", | |
('INCORRECT!', 'correct.')[!!$rsa->verify($zip, $sig)]; | |
close $fh; | |
} while @ARGV; | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# Merge signature with zip to create CRX file. | |
# klg, Feb 2014 | |
use strict; | |
use open IO => ':bytes'; | |
use constant { | |
CRX_MAGIC => 0x34327243, | |
BLOCK_SIZE => 4049 | |
}; | |
die "Usage: $0 pub sig zip > crx\n" if @ARGV < 3; | |
my ($pub, $sig) = map { local (@ARGV, $/) = $_; <> } @ARGV[0,1]; | |
warn "Public key should be DER encoded in X509 SubjectPublicKeyInfo format" | |
unless 0x30 == ord $pub; | |
open my $zip, $ARGV[2] or die $!; | |
print pack 'V4', CRX_MAGIC, 2, length($pub), length($sig); | |
print $pub, $sig; | |
print while read $zip, $_, BLOCK_SIZE; | |
close $zip; | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# Split header of CRX Chrome package. | |
# klg, Feb 2014 | |
use strict; | |
use open IO => ':bytes'; | |
use constant { | |
CRX_MAGIC => 0x34327243, | |
BLOCK_SIZE => 4049 | |
}; | |
do { | |
open my $crx, (my $ncrx = shift) // '-' or die $!; | |
binmode $crx; | |
$ncrx //= 'stdin'; | |
$ncrx =~ s/\.crx$//i; | |
read $crx, $_, 16 or die $!; | |
my ($magic, $ver, $publen, $siglen) = unpack 'V4'; | |
die "$ncrx: bad format\n" unless $magic == CRX_MAGIC; | |
die "$ncrx: Unknown version of CRX file\n" unless $ver == 2; | |
my ($npub, $nsig, $nzip) = map { "$ncrx.$_" } qw/pub sig zip/; | |
do { die "$_: output file exists\n" if -f $_ } for ($npub, $nsig, $nzip); | |
my $i; | |
open my $pub, '>', $npub or die $!; | |
read $crx, $_, $i = $publen or die $!; | |
print $pub $_; | |
close $pub; | |
print STDERR "$i bytes written to $npub\n"; | |
open my $sig, '>', $nsig or die $!; | |
read $crx, $_, $i = $siglen or die $!; | |
print $sig $_; | |
close $sig; | |
print STDERR "$i bytes written to $nsig\n"; | |
$i = 0; | |
open my $zip, '>', $nzip or die $!; | |
print($zip $_), $i += length while read $crx, $_, BLOCK_SIZE; | |
close $zip; | |
print STDERR "$i bytes written to $nzip\n"; | |
close $crx; | |
} while @ARGV; | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# Find RSA key with fingerprint matching a regex. | |
# klg, Feb 2014 | |
use strict; | |
use Crypt::OpenSSL::RSA; | |
use MIME::Base64; | |
use Digest::SHA 'sha256_hex'; | |
use Time::HiRes 'time'; | |
die "Usage: $0 size regex\n" unless @ARGV > 1; | |
my $bits = int $ARGV[0]; | |
my $regex = qr/$ARGV[1]/i; | |
warn "Note: Fingerprint contains only letters in a-p range.\n" | |
if $ARGV[1] =~ /[0-9q-z]/i; | |
Crypt::OpenSSL::RSA->import_random_seed(); | |
sub pkid($) { | |
my ($spk) = shift->get_public_key_x509_string =~ /-\n(.*)\n-/s; | |
(lc unpack 'a32', sha256_hex decode_base64 $spk) =~ y/0-9a-f/a-p/r; | |
} | |
my $rsa; | |
my ($i, $j, $t0, $t1) = (0, 0, time, time); | |
my $dt = 0.1; | |
do { | |
if (time - $t1 > $dt) { | |
printf STDERR "\rRSA %u bits, %.2f kps, total %u in %.1f sec ...\033[K\r", | |
8 * $rsa->size, $i / (time - $t1), $j, time - $t0; | |
$dt += 0.1 if $i < 3; | |
$dt -= 0.1 if $i > 30; | |
$dt = 0.1 if $dt < 0.1; | |
($i, $t1) = (0, time); | |
} | |
$i++, $j++; | |
$rsa = Crypt::OpenSSL::RSA->generate_key($bits); | |
} until pkid($rsa) =~ $regex; | |
printf STDERR "\r\033[KID: %s\n", pkid $rsa; | |
printf STDERR "Found in %.2f seconds, tried %u keys\n", time - $t0, $j; | |
# Note: this must be piped through `openssl pkey` | |
# to convert it into format recognizable by Chrome. | |
print $rsa->get_private_key_string; | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment