#! /usr/bin/perl # Wrapper around John the Ripper (part of MJohn) # Sends attack descriptions to the server # !!! Experimental: this all is subject to change very soon !!! # Dependencies: TODO # Usage: wrapper parameters -- john-parameters # TODO: avoid -- between parameters. Maybe other syntax? # TODO: implement ability to use path from cmdline and not from config: # Usage: wrapper parameters [path-to-john] john-parameters # If path-to-john is not listed then path from configuration file is # used. # Limitations: only full names of parameters are supported, order of parameters # should not affect behaviour, and many others not found yet. use strict; use warnings; use File::Copy; use YAML::XS; # Configuration # TODO: the same paragraph as in daemon script. use Config::Simple; my %C; # TODO: why not ~ tilde? How to do it right? # TODO: in config ~ tilde also does not work. Config::Simple->import_from($ENV{HOME} . '/.john/mjohn.conf', \%C); my @args = @ARGV; # TODO: Check that daemon runs. Start it otherwise. # Store parameters into file # Each wrapper has its own store. my $pwd = $ENV{PWD}; # TODO: set store up if there is not one. Or at least exit if so. # Create dir (with path) if there are no one. chdir $C{store}; # Sync store with server. # TODO: conflicts? They should be avoided here, solved somewhere else. # TODO: this fails on very new empty repo. Not important though. # "Your configuration specifies to merge with the ref 'master' from # the remote, but no such ref was fetched." There is no master in # empty bare repo. `git pull`; # Each attack has its own dir in store. # Name of attack # TODO: name from cmdline. # TODO: easier name, maybe with incremental counter. # TODO: this does not reflect real user+attack_name. my $attack_name = "$C{user}_name" . time(); # TODO: check if this attack already exists. mkdir "$attack_name"; # Check that all files are available and copy them into store. for (@args) { # Use only one parameter-value separator. # TODO: does john accept only = and : as separater for parameters? s/(-.*?)[=:]/$1=/; if (/(-.*?=)(.*)/) { # TODO: respect type of parameter! Do not copy file named 'all' # from original dir if we just call --incremental=all . # TODO: use of relative path from store is wrong. We need just # check that file is in store. if (-r $2) { warn "$2 exists here"; } elsif (-r "$pwd/$2") { # TODO: is it correct to use slashes everywhere? warn "$2 exists in original folder"; # Copy file to store # TODO: do files in parameters for wrapper need copies? # TODO: fifos? ('copy' converts fifo into regular file) # TODO: name could interfere with our names (keys, parameters). # TODO: what if our file already in the store? copy "$pwd/$2", "$attack_name"; # Overwrite args with new path. $_ = "$1$attack_name/$2"; # TODO: there will be duplicated files. We should track # them. How? Probably we should remember original pairs.{ # TODO: remember about relative paths (i.e. with ../ inside). # TODO: do we need original file once it was copied to the store? } else { warn "$2 does not exist anywhere"; } } } my $attack_parameters = "$attack_name/parameters"; my $f; open $f, '>', $attack_parameters or die "could not open file $attack_parameters"; # TODO: when we sort parameters we mix parameters for wrapper with parameters for john. # We need to sort parameters (really?) but do not need to mix them. So we # should split them before sort and store in separate files (or # containers in one yaml file). # TODO: what if some options are doubled? print $f Dump sort @args; close $f; # TODO: Check for duplicated commands. # Start john. # TODO: handle parameters for wrapper. # Drop parameters for wrapper. # TODO: here we loose them. shift @args while @args && $args[0] ne '--'; shift @args if @args && $args[0] eq '--'; # TODO: dump john's version here. # TODO: do short test run here. # Push changes to server. # TODO: Pushing to server could be async. # TODO: quoting or restrictions on user/attack names: double quotes # are not allowed for user and attack names, also backslashes are not # allowed. # NOTE: While we do not touch the same file simultaneously from # multiple place we do not have conflict. So while we do not have # collisions in names of attacks we have no problems. # NOTE: we limit commit to only our files, because our other instances # or the daemon could add more files. (There is no atomic add+commit # action.) # TODO: remember that file names could start with dash. Check other places. `git add -- "$attack_name"`; `git commit -m auto1 -o -- "$attack_name"`; # TODO: action here is similar to what the daemon does. Call it. # NOTE: git prefers "bare" repositories for pushes. `git push origin master:master`; # Really run john. # TODO: do not count john without args or with help parameters as attack. # TODO: check if we have command for john. # TODO: It would be nice to say what we are going to run. # TODO: pipes? # TODO: it would be better to craft args list from saved parameters. # TODO: check that --session and --pot were not used before. my $a_n_u = "$attack_name/$C{user}"; # TODO: add session and .pot files to git. The daemon could do it, though. # TODO: interactive status does not work. system $C{john}, @args, "--session=$a_n_u", "--pot=$a_n_u.pot"; # John finished or aborted. # TODO: Report finish or abort