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

On Fri, Apr 18, 2014 at 12:05:37AM +0200, magnum wrote:
> On 2014-04-17 23:58, magnum wrote:
> >On 2014-04-15 21:26, Rich Rumble wrote:
> >>On Tue, Apr 15, 2014 at 3:11 PM, magnum <john.magnum@...hmail.com> wrote:
> >>
> >>>One side effect when working with this is it makes me want a sed2rules
> >>>generator too, perhaps even in combination with rexgen ;-)  This would
> >>>finally solve the "complex leet permutations" problem (like "replace
> >>>any of
> >>>[aA] with any of [aA4@] *and* any of [eE] with any of [eE3] *and* any of
> >>>...").
> >>>
> >>Just a quick note, I have great success with "1337" rules that don't
> >>replace ALL instances... But I get what you were saying :)
> >>http://www.openwall.com/lists/john-users/2010/08/03/4
> >
> >I bet that's very common. Doing what I describe above, we will create
> >all combinations of "only some instances" as well as "all instances".
> >But it would result in a large number of rules I guess.
> 
> On second thought that won't happen they way I described it. This is a
> complex issue!

I've wrote a script to generate the rules. It is a proof of concept
again.

It creates replacements for some instances, not for all instances.
$max_count controls amount of replacements of one letter.
$max_pos controls variety of positions of the letter.
If $max_count is higher than amount of letters in the word than we
replace all but we could be sure about the condition. Replace all rule
(s) is not used.

Thanks!

-- 
Regards,
Aleksey Cherepanov

#! /usr/bin/perl -l
# John rules generator for combination of 1337-speak substitutions.
# Proof of concept

# Copyright  2014 Aleksey Cherepanov <aleksey.4erepanov@...il.com>
# Redistribution and use in source and binary forms, with or without
# modification, are permitted.

use strict;
use warnings;

# use Data::Dumper;

# TODO: Do we need to replace letter with itself? I guess, no.
my %replacements = qw/s [S5$] e [E3]/;
# Each letter could be replaced in $max_count places
my $max_count = 2;
# Try positions up to $max_pos position
my $max_pos = 5;

my @letters = keys %replacements;
my @letters_counts = (0) x @letters;

sub generate_positions {
    my $c = shift;
    return [] if $c == 0;
    my $mp = shift;
    my @r;
    for my $p ($c .. $mp) {
        my @t = generate_positions($c - 1, $p - 1);
        push @$_, $p for @t;
        push @r, @t;
    }
    @r
}

# warn Dumper [generate_positions 2, 4];

# TODO: We don't replace all. Do that separately.

sub combine {
    my $a = shift;
    my $b = shift;
    # warn Dumper $a, $b;
    my @r;
    for my $i (@... {
        for my $j (@... {
            push @r, [@... $j];
        }
    }
    @r
}

# Unmodified word
print ":";
while (1) {
    # Print variants for given counts
    my @rules = [];
    for (0 .. $#letters) {
        my $letter = $letters[$_];
        my $replacement = $replacements{$letter};
        my $count = $letters_counts[$_];
        my @letter_rules;
        if ($count > 0) {
            my @positions = generate_positions($count, $max_pos);
            # warn Dumper [$count, $max_pos, @positions];
            for (@...itions) {
                # We use positions in back order so first replacement
                # does not change numbers of others.
                # TODO: We may exploit change and simplify rules:
                # %2s op[S5$] %1s op[S5$]  ->  %1s op[S5$] %1s op[S5$]
                push @letter_rules, join " ", map {
                    "%$_$letter op$replacement"
                } reverse @$_;
            }
        }
        @rules = combine [@...es], [@...ter_rules];
    }
    for (@...es) {
        print join " ", @$_;
    }
    # Increase counts like: 0,0,0 -> 0,0,1 -> 0,0,2 -> 0,1,0
    $letters_counts[$#letters_counts]++;
    my $i = $#letters_counts;
    for (; $i > 0 && $letters_counts[$i] > $max_count; $i--) {
        $letters_counts[$i] = 0;
        $letters_counts[$i - 1]++;
    }
    last if $i == 0 && $letters_counts[$i] > $max_count;
}

Powered by blists - more mailing lists

Your e-mail address:

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