Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Fri, 5 Jun 2015 13:50:36 +0300
From: Solar Designer <solar@...nwall.com>
To: john-dev@...ts.openwall.com
Subject: poor man's fuzzer

Kai, all -

I felt that Kai didn't try hard enough to trigger crashes in hash
encoding parsing and such.  I expected to hear of many more crashes on
invalid salt encodings that I actually did.  Maybe much of this was
discussed in GitHub issues only, though?

Anyway, not being familiar with afl and for us to have a sanity-check
for our uses of afl, I went ahead and wrote the attached simple fuzzer.

In just a few minutes, it found segfaults in vtp and pbkdf2-hmac-md5,
and a "Floating point exception" (possibly actually overflow on integer
division or similar) in django-scrypt.  I still have it running
(currently on super as a test, but should move it elsewhere, if we
revise it to attempt more things).

Another curious detail is that I couldn't get it to use more than ~4 CPU
cores on average, not even with hundreds of simultaneous processes,
until I moved the "run" directory for john to /dev/shm (tmpfs).  I guess
I was bumping into some lock congesion in the kernel, possibly e.g. for
atime updates of john and john.conf.  (If so, remounting the filesystem
with noatime should probably have helped.  I didn't try yet.)  So I am
currently running it in /dev/shm/fuzz, which is a bit risky - in case
the system gets rebooted, work will be lost.  I should revise the script
to write its log and sample files into a directory different than one it
invokes john from.

Anyway, this is it for now.  My goal was to show to Kai that there's
more work on this, and I think I achieved it.

The crashers so far:

$ cat fuzz-sample-*
scrypt$NBGmaGIXijJW$148$$1$64$achPt01SbytSt+F3CcCFgEPr96+/j9iCTdejFdAARZ8mzfejrP64TJ5XBJa3gYwuCKOEGlw2E/lWCWS7LeS6CA==
scrypt$NBGmaGIXijJW$14$$81$64$achPt01SbytSt+F3CcCFgEPr96+/j9iCTdejFdAARZ8mzfejrP64TJ5XBJa3gYwuCKOEGlw2E/lWCWS7LeS6CA==
scrypt$NBGmaGIXijJW$14$81$$64$achPt01SbytSt+F3CcCFgEPr96+/j9iCTdejFdAARZ8mzfejrP64TJ5XBJa3gYwuCKOEGlw2E/lWCWS7LeS6CA==
scrypt$NBGmaGIXijJW$14$8$$164$achPt01SbytSt+F3CcCFgEPr96+/j9iCTdejFdAARZ8mzfejrP64TJ5XBJa3gYwuCKOEGlw2E/lWCWS7LeS6CA==
scrypt$Cj0PzdtT3qS2$148$$1$64$qn4CDnM8CcIBNrpQXHo6ti8vSUoSXj7GBFy7k1bp5wPs8jKjh/gHZ+qM9uk6LbcVHm02yBaI5WCbDm/Shq/MXA==
scrypt$Cj0PzdtT3qS2$14$$81$64$qn4CDnM8CcIBNrpQXHo6ti8vSUoSXj7GBFy7k1bp5wPs8jKjh/gHZ+qM9uk6LbcVHm02yBaI5WCbDm/Shq/MXA==
scrypt$Cj0PzdtT3qS2$14$81$$64$qn4CDnM8CcIBNrpQXHo6ti8vSUoSXj7GBFy7k1bp5wPs8jKjh/gHZ+qM9uk6LbcVHm02yBaI5WCbDm/Shq/MXA==
scrypt$Cj0PzdtT3qS2$14$8$$164$qn4CDnM8CcIBNrpQXHo6ti8vSUoSXj7GBFy7k1bp5wPs8jKjh/gHZ+qM9uk6LbcVHm02yBaI5WCbDm/Shq/MXA==
$pbkdf2-hmac-md5$19salt$f31afb6d931392daa5e3130f47f9a9b6
$vtp$2$196$14000107000105dc000186a164656661756c740014000105000505dc000186a56368656e6100000010000103000605dc000186a6666666001800020c03ea05dc00018a8a666464692d64656661756c743000030d03eb117800018a8b74726372662d64656661756c7400000001010ccc040103ed0701000208010007090100072000040f03ec05dc00018a8c666464696e65742d64656661756c7400030100012400050d03ed117800018a8d74726272662d64656661756c740000000201000f03010002$80$0201019c646f6d61696e313233343536000000000000000000000000000000000000000000000015000000003134313030393134333631376010913064949d6f47a53b2ad68ef06b0000000106010002$6010913064949d6f47a53b2ad68ef06b
$vtp$2$196$14000107000105dc000186a164656661756c740014000105000505dc000186a56368656e6100000010000103000605dc000186a6666666001800020c03ea05dc00018a8a666464692d64656661756c743000030d03eb117800018a8b74726372662d64656661756c7400000001010ccc040103ed0701000208010007090100072000040f03ec05dc00018a8c666464696e65742d64656661756c7400030100012400050d03ed117800018a8d74726272662d64656661756c740000000201000f03010002$80$020101c0646f6d61696e313233343536000000000000000000000000000000000000000000000015000000003134313030393134333631376010913064949d6f47a53b2ad68ef06b0000000106010002$6010913064949d6f47a53b2ad68ef06b
$vtp$1$184$14000107000105dc000186a164656661756c740014000105000505dc000186a568656c6c6f0000002000020c03ea05dc00018a8a666464692d64656661756c7401010000040100002800031203eb05dc00018a8b746f6b656e2d72696e672d64656661756c74000001010000040100002400040f03ec05dc00018a8c666464696e65742d64656661756c740002010000030100012400050d03ed05dc00018a8d74726e65742d64656661756c740000000201000003010002$77$0101019c646f6d61696e313233343536000000000000000000000000000000000000000000000010000000003134313030393134313432372212dd93025abc600281d74ddda8a21c0101000200$2212dd93025abc600281d74ddda8a21c
$vtp$1$184$14000107000105dc000186a164656661756c740014000105000505dc000186a568656c6c6f0000002000020c03ea05dc00018a8a666464692d64656661756c7401010000040100002800031203eb05dc00018a8b746f6b656e2d72696e672d64656661756c74000001010000040100002400040f03ec05dc00018a8c666464696e65742d64656661756c740002010000030100012400050d03ed05dc00018a8d74726e65742d64656661756c740000000201000003010002$77$010101c0646f6d61696e313233343536000000000000000000000000000000000000000000000010000000003134313030393134313432372212dd93025abc600281d74ddda8a21c0101000200$2212dd93025abc600281d74ddda8a21c

Alexander

#!/usr/bin/perl

use Errno;

# Processes per logical CPU
$factor = 4;

$workdir = '/dev/shm/fuzz';
$pwfile = $workdir . '/pw';
$session = $workdir . '/s';

die unless (mkdir($workdir, 0700) || $!{EEXIST});

$ENV{'OMP_NUM_THREADS'} = '1';
setpriority(PRIO_PROCESS, 0, 19);

sub try
{
	print "Trying format $f, hash $c\n";

	open(PW, "> $pwfile") || die;
	print PW "$c\n";
	close(PW);

	open(JOHN, "| ./john --nolog --encoding=raw --stdin --session=$session --format=$f $pwfile") || die;
	print JOHN "wrong password 1\n";
	print JOHN "wrong password 2\n";
	close(JOHN);

	die if ($? == 256 || $? == 2 || $? == 15); # exit(1) or INT or TERM

	if ($? != 0) {
		open(LOG, ">> fuzz-err.log") || die;
		print LOG "$f $c $?\n";
		close(LOG);

		open(SAMPLE, "> fuzz-sample-$f-$cpu-$seq") || die;
		print SAMPLE "$c\n";
		close(SAMPLE);
		$seq++;
	}
}

open(TESTS, './john --list=format-tests --format=cpu |') || die;
while (<TESTS>) {
	($f, $c) = /^([\w\d-]+)\t[^\t]+\t([^\t]+)\t/;
	if ($f && $c) {
		$fs[$#fs + 1] = $f;
		$cs[$#cs + 1] = $c;
	}
}
close(TESTS);

die unless ($#fs >= 0 && $#fs == $#cs);

printf "%u test vectors\n", $#fs + 1;

$cpus = `grep -c ^processor /proc/cpuinfo`;
chomp $cpus;
$cpus = 1 if (!$cpus);

print "$cpus CPUs\n";

$cpus *= $factor;

for ($cpu = 0; $cpu < $cpus - 1; $cpu++) {
	last if (fork() == 0);
}

$from = int(($#fs + 1) * $cpu / $cpus);
$to = int(($#fs + 1) * ($cpu + 1) / $cpus) - 1;

$session .= "-$cpu";
$pwfile .= "-$cpu";

$seq = 0;

for ($t = $from; $t <= $to; $t++) {
	$f = $fs[$t];
	$c = $cs[$t];
	$o = $c;

	try;

	for ($i = 0; $i < length($c); $i++) {
		vec($c, $i, 8) = ord('9');
		next if ($c eq $o);
		try;
		$c = $o;
	}

	for ($i = 0; $i < length($c); $i++) {
		vec($c, $i, 8) = ord('$');
		next if ($c eq $o);
		try;
		$c = $o;
	}

	for ($i = 0; $i < length($c) - 1; $i++) {
		my $x = vec($c, $i, 8);
		vec($c, $i, 8) = vec($c, $i + 1, 8);
		vec($c, $i + 1, 8) = $x;
		next if ($c eq $o);
		try;
		$c = $o;
	}

	$j = 1;
	for ($i = 0; $i < 5; $i++) {
		$c = $o . chr(vec($o, length($o) - 1, 8)) x $j;
		try;
		$j *= ($j + 1);
	}
}

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ