Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sun, 23 Mar 2014 01:13:14 +0400
From: Aleksey Cherepanov <lyosha@...nwall.com>
To: john-dev@...ts.openwall.com
Subject: proof of concept converter of rexgen-like syntax into john rules

I heard about possibility to pull rexgen into john. I know nothing
about rexgen but I saw some examples.

I think rexgen-like syntax could be a part of rules and performed at
preprocessor level like []. For instance
-s x** rexgen"\0o(n|ff)" }
would be translated into
-s x** Az"on" }
-s x** Az"off" }
I do not propose exactly rexgen"..." as the syntax.

I saw some examples and I wrote simple script to implement the syntax.
It does not seem very hard.

The script converts rexgen-like expression into john's rules. It does
not support '(' inside [], there is no way to escape '(', '|' and ')'.
But it correctly expands groups and it could handle multiple \0. It
lacks correct user interface.

I used M and X0zz rules to support multiple \0 so generated rules
change memorized value. It would be a problem combining it with other
rules.

I expand groups, then I expand \0 into rules. Though I have a problem
with
$rule = "b(\\|a)(0|1)e";
Because first branches together give me \0 that was not on input. It
should not be hard to implement it right.

Implementation at the preprocessor level could have drawbacks. I do
not know them.

I will not continue the work but if you have questions about the
script I will answer them.

Thanks!

-- 
Regards,
Aleksey Cherepanov

# A draft of program to convert rexgen rule into John the Ripper rules

use strict;
use warnings;

my $rule = "\\0([123]|[oO]ne|[tT](wo|hree))";
# $rule = "\\0(1|[oO]no|ONE)(2|[tT]wo|TWO)(3|[tT]hree|THREE)";
# $rule = "\\0(1|[oO]no\\0|ONE)(2|[tT]wo|TWO)(3|[tT]hree|THREE\\0)";
# $rule = "(A|B)(1|2)";
# $rule = "asdf\\0qwer";
# TODO: \0 is evaluated as from input. Bad.
# $rule = "b(\\|a)(0|1)e";

sub to_tokens {
    # TODO: Handle \ and things in [] .
    $_[0] =~ /([(|)]|[^(|)]+)/g
}

# Usage: mul(["a", "b"], ["1", "2"]) -> qw/a1 a2 b1 b2/
# The first list could be empty, the second list could not be empty.
sub combine {
    # warn "combine 0: @{$_[0]}\n";
    # warn "combine 1: @{$_[1]}\n";
    my @a = @{shift()};
    my @b = @{shift()};
    if (@a) {
        map {
            my $a = $_;
            map {
                $a . $_
            } @b;
        } @a
    } else {
        @b
    }
}

# Rename combine into combine_i to use this
# sub combine {
#     my @r = combine_i @_;
#     warn "combine r: @r\n";
#     @r
# }

sub parse_part;

sub parse_group {
    # warn "parse_group: @{$_[0]}\n";
    my @all;
    my @current_branch;
    while (@...[0]} && $_[0][0] ne ')') {
        while (@...[0]} && $_[0][0] ne '|' && $_[0][0] ne ')') {
            my @p = parse_part($_[0]);
            @current_branch = combine [@...rent_branch], [@...
        }
        if (@...[0]} && $_[0][0] eq '|') {
            shift @{$_[0]};
        }
        push @all, @current_branch;
        @current_branch = ();
    }
    shift @{$_[0]};
    @all
}

sub parse_part {
    # warn "parse_part: @{$_[0]}\n";
    die unless @_;
    my $p = shift @{$_[0]};
    $p eq '(' ? parse_group($_[0]) : $p
}

sub expand_braces {
    my @a;
    while (@_) {
        my @b = parse_part \@_;
        # warn "top\n";
        @a = combine [@... [@...
    }
    @a
}

# Expand \0
sub expand_0 {
    map {
        my @l = split /\\0/;
        if (/\\0$/) {
            push @l, "";
        }
        my $f = shift @l;
        # TODO: Don't screw current memorized value.
        local $_ = qq/M A0"$f" /;
        $_ .= join " X0zz ", map { 'Az"' . $_ . '"' } @l;
        s/^M A0"" /M /;
        s/ Az""$//;
        # Don't use M if there is only one \0.
        s/^M // if $#l < 1;
        $_
    } @_
}

print "$_\n" for expand_0 expand_braces to_tokens $rule;

Powered by blists - more mailing lists

Your e-mail address:

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