Barracuda Spam & Virus Firewall Notes - How to get full root access;
Log in using single users mode - to do this;
a. Power On/reboot
b. At lilo prompt (barracuda splash) quickly hit the tab key
c. Type: Barracuda init=/bin/bash
d. The password is: bimg
You are now booted into single user mode with full root access. Whist
this is limited it will still allow you to remove the barracuda root
password easily. This is done by simply removing it from the /etc/shadow
file for the root user. It can easily be changed afterwards. Be aware
that the Barracuda has a 'recovery' partion (3) and it will make sense to
clear the password on this partion too.
Starting with partion 1 (the main 'running' partition). In single user
mode it may not mount properly. It can often end up as read only yet
mount -l it states rw. This causes all sorts of wiredness when writing
files, so save any heartache and remount it rw like this;
mount -o remount, -rw /dev/ide/host0/bus0/target0/lun0 /
{if you are using SATA drives they are probably going to be under /dev/
scsi/host0/bus0/target0/lun0/ or software raid /md}
The main /etc/shadow file gives write issues the file system is not
properly mounted, so the root user is not able to force overwrite of the
file. The above remount command fixes that. You can now edit it and force
the writing with the ! operator.
Here is how to edit it;
vim /etc/shadow
move cursor to first line for the root user.
Switch to insert mode by pressing the [i] key
Put cursor at start of password and use the delete key to remove the
encrypted password between the first and second colon - typically
looking like this- $1$2NVlp7G0$EoDgfwGBkSb/LOe7VgfQP/
Make sure you leave the the two colons in place, so the line looks
similar to this- root::12277:0:99999:7:::
Switch VIM to command mode by pressing [ESC]
Write the file with the override option by typing
:w!
Then quit
:q
If you cant do this, check you remounted the file system correctly as
detailed above.
Next we do the same for the recovery partition 3 /etc/shadow password
file. Mount partition 3 so we can edit the file. The mount directory /mnt/
hd should already exist from the building of the appliance (ls -l /mnt to
check - if not mkdir /mnt/hd)
Mount it (again assuming IDE here - modify you path accordingly)
mount /dev/ide/host0/bus0/target0/lun0/part3 /mnt/hd
Repeat the editing on this file /mnt/hd/etc/shadow
When you are done you can unmount it;
umount /dev/ide/host0/bus0/target0/lun0/part3
Finally, stop the barracuda with this command:
halt -fp
When you reboot the unit normally you will be able to log in with
username 'root' and no password at the Barracuda log-in prompt. To set a
fresh root password after logging in as root, just issue the 'passwd'
command and set it to something suitable. Upgrading firmware does not
currenlty overwrite this hack so it's a set and forget (tested up to
version 4.0.0.31)
Your Barracuda is now fully open an unlocked for root access. What
follows is a list of changes you can make and some security notifcations:
--------------------------------------------------------------------------------------
First of all Barracuda and the 'port 25' redirect. Old versions of the
Barracuda left a nice back door open for support. Port 25 was redirected
to port 22 SSH and 8000 for a Barracuda ranges. As you are not really
likely to have port 25 closed it was a serious back door to leave open.
This has been removed (other back doors may be open) but check by looking
at this file:
/etc/sysconfig/iptables
You don't want to see this;
-A PREROUTING -s 205.158.110.61 -p tcp -m tcp --dport 25 -j REDIRECT --to-
ports 22
-A PREROUTING -s 205.158.107.65 -p tcp -m tcp --dport 25 -j REDIRECT --to-
ports 8000
If you do comment them out with a #
Whilst in this file you can block all port 22 access from Barracuda by
commenting (#) out:
-A INPUT -s 205.158.110.0/255.255.255.0 -p tcp -m tcp --dport 22 -j
ACCEPT
-A INPUT -s 205.158.110.0/255.255.255.0 -p tcp -m tcp --dport 22 --tcp-
flags SYN,RST,ACK SYN -j ACCEPT
You can also alter the ranges to allow *you* port 22 ssh access from your
local or remote network, just edit one of these line to suit or add your
own;
-A INPUT -s 192.168.200.0/255.255.255.0 -p tcp -m tcp --dport 22 -j
ACCEPT
-A INPUT -s 192.168.200.0/255.255.255.0 -p tcp -m tcp --dport 22 --tcp-
flags SYN,RST,ACK SYN -j ACCEPT
When updating firmware these changes are *lost* so don't forget to put
them back if you don't want strangers poking aroung in your Barracuda.
To restart IP tables on the barracuda, just do this;
/etc/init.d/iptables stop; /etc/init.d/iptables start;
--------------------------------------------------------------------------------------
To read or reset the GUI password
READ:
config_read system_password
CHANGE:
config_change system_password chosen_new_password
--------------------------------------------------------------------------------------
To add features to a lower spec machine GUI just 'touch' ' any of these
files; This will add the feature.
EXAMPLE;
touch /etc/barracuda/multiple_ip
/etc/barracuda/syslog (Advanced -> Syslog tab)
/etc/barracuda/explicit_user_config (Advanced -> Explicit Users tab)
/etc/barracuda/exchange_accelerator (MS Exchange Accelerator)
/etc/barracuda/trusted_relays (Advanced -> Rate Control tab)
/etc/barracuda/multiple_ip (Advanced -> Advance IP Configuration tab)
// static routes etc
/etc/barracuda/clustering (Advanced -> Clustering tab)
/etc/barracuda/auth (Advanced -> Single Sign-On)
/etc/barracuda/api (Basic -> Administration -> API/SNMP section)
/etc/barracuda/plugin (Basic -> Bayesian/Fingerprinting -> Mail plug-in)
/etc/barracuda/per_domain (Domains tab)
/etc/barracuda/per_user_scores (Per-User scoring)
/etc/barracuda/ldap_routing (Advanced -> LDAP Routing) (3.5.11 and
above only) (600s and above only)
--------------------------------------------------------------------------------------
To change the serial number / identity.
The backend Barracuda system is really lame at this time. Almost like it
was written by a couple of dickheads in their dens. This means you can
pretty much try random five and six figure serial numbers and get free
updates when you hit a good one. TIP; keep a lookout on eBay for people
stupid enough to sell them showing the serial number and advertising them
with a remaining subscription. Forget matching up the MAC address to the
system - they managed to screw that notion up. The PHYSICAL MAC is never
properly recorded (and at Jan of 2009 still was not). This is read from a
text file that can be set to anything you like. The only real restriction
comes from a simple geo lookup on your IP when you connect to Barracuda.
Domestic US units being used outside of the USA will fail with CODE -4
(you can always try an HTTP proxy or another serial number). Changing the
password involves changing a few files and a couple of database entries.
This is easy to script with this tested perl script that also backs up
the current settings:
<START OF SCRIPT>
#!/usr/bin/perl -w
use DBI;
my $newserial = "12";
my $newmodel = "120";
my $newmac = "GG:GG:GG:GG:GG:GG";
my $current_model = "";
my $keypress = "";
my @oldmachine =();
my @machinearray =();
my @result= ();
my $dsn = "";
my $dbn = "";
my $sth = "";
my $sql = "";
my $a1 = 0;
my $xx = 0;
my $shell_command ="";
my $count = 0;
my $database = "config";
my $hostname = "localhost";
my $port = "3306";
my $db_username = "root";
my $db_password = "none";
print "\n*************************************************\n";
print "* Barracuda Serial Number & Model Changer v1 *\n";
print "*************************************************\n";
while (1) {
print "\nenter new serial (or k to keep existing | x to exit): ";
$keypress = <STDIN>;
chomp ($keypress);
if ($keypress =~ /\D/){
if (($keypress eq "k") || ($keypress eq "K")) {
last;
}
if (($keypress eq "x") || ($keypress eq "X")) {
exit;
}
print "\n! Error ! - numeric input only
please\n";
next;
}
if ($keypress >99 && $keypress < 1000000) {
$newserial = $keypress;
last;
} else {
print "\n! Error ! - check serial number is
within correct range\n";
next;
}
}
while (1) {
print "\nenter new model (or k to keep existing | x to exit): ";
$keypress = <STDIN>;
chomp ($keypress);
if ($keypress =~ /\D/){
if (($keypress eq "k") || ($keypress eq "K")) {
last;
}
if (($keypress eq "x") || ($keypress eq "X")) {
exit;
}
print "\n! Error ! - model number is bad
try again\n";
next;
}
if ($keypress ==100 || $keypress ==200 ||
$keypress ==300 || $keypress ==400 || $keypress ==600 || $keypress
==800) {
$newmodel = $keypress;
last;
} else {
print "\n! Error ! - check model number is within
correct range\n";
next;
}
}
while (1) {
print "\nenter new mac (or k to keep existing | x to exit):";
$keypress = <STDIN>;
chomp ($keypress);
if ($keypress =~ /[0-9A-Fa-f][0-9A-Fa-f]\:
[0-9A-Fa-f][0-9A-Fa-f]\:[0-9A-Fa-f][0-9A-Fa-f]\:[0-9A-Fa-f][0-9A-Fa-f]\:
[0-9A-Fa-f][0-9A-Fa-f]\:[0-9A-Fa-f][0-9A-Fa-f]/){
$newmac = $keypress;
last;
} else {
if (($keypress eq "k") || ($keypress eq
"K")) {
last;
if (($keypress eq "x") || ($keypress eq
"X")) {
exit;
}
print "\n! Error ! - check mac address
and try again\n";
next;
}
}
}
print "\n*************************************************\n";
print "* Checking current config and updating....... *\n";
print "*************************************************\n";
$dsn = "DBI:mysql:database=$database;host=$hostname;port=$port";
$dbh = DBI->connect($dsn, $db_username ) or die("fatal error - could not
connect to backend database.");
$sql="SELECT * FROM config WHERE variable like 'system_serial';";
$sth = $dbh->prepare($sql);
$sth->execute or die "SQL Error: $DBI::errstr\n";
if ($sth->rows) {
@row = $sth->fetchrow_array;
if (@row) {
push(@oldmachine, $row[1]);
print "CURRENT DATABASE SERIAL:
" . $oldmachine[0] . "\n";
} else {
die("fatal error - unable to find
current serial number in databasee.")
}
};
$shell_command = `ifconfig -a`;
if(($shell_command =~ /eth\d.*HWaddr.*\d/)){
$shell_command =~ m/\b..\:..\:..\:..\:..\:..\b/;
$shell_command = uc($&);
} else {
$shell_command = "UNKNOWN";
}
push(@oldmachine, $shell_command);
print "CURRENT ACTUAL MAC: " . $oldmachine[1] . "\n";
if (-e "/home/remote/backup") {
unless (-d "/home/remote/backup") {
die "MCF File exists but is not directory";
}
}
else {
mkdir("/home/remote/backup", 0777) or die "Can't make directory: $!";
}
if (-e "/root/machine$oldmachine[0]") {
print "\nMachine File found - backing up;\n";
$shell_command = `cp /root/machine$oldmachine[0] /home/remote/
backup/`;
print "CONTENTS OF CURRENT MACHINE FILE:\n";
open (FILE, "/root/machine$oldmachine[0]");
while (<FILE>) {
chomp; #cut off /n newlines from the end of each line
next unless /\S/; # if the file line is blank move on - we don't
need blank lines
$member = $_;
print $member . "\n";
if (($member =~ /serial_number/) && ($newserial ne "12")){
push (@machinearray, "serial_number $newserial");
next;
}
if (($member =~ /mac_address/) && ($newmac ne
"GG:GG:GG:GG:GG:GG")){
push (@machinearray, "mac_address $newmac");
next;
}
if($member =~ /model \d\d\d/) {
$current_model = $member;
$current_model =~ /\d\d\d/;
$current_model = $&;
if($newmodel ne "120"){
push (@machinearray, "model $newmodel");
next;
}
}
push (@machinearray, $member);
}
close (FILE);
# now write the new machine file
print "\nPOPULATE NEW MACHINE FILE\n";
foreach $member(@machinearray)
{
$fileout .= "$member\n";
}
print $fileout;
open FILE, ">/root/machine$newserial";
print FILE "$fileout";
close (FILE);
}
if (-e "/etc/barracuda/serial") {
print "\nBarracuda Serial File found - backing up\n";
$shell_command = `cp /etc/barracuda/serial /home/remote/backup/`;
print "CONTENTS OF SERIAL FILE: ";
open (FILE, "/etc/barracuda/serial");
while (<FILE>) {
chomp;
next unless /\S/;
print $_ . "\n";
}
close (FILE);
if($newserial ne "12") {
print "\ndebug - newserial is NOT EQUAL to 12 :>$newserial<:\n";
open FILE, ">/etc/barracuda/serial";
print FILE "$newserial\n";
close (FILE);
print "Overwritten /etc/barracuda/serial with:\n";
open (FILE, "/etc/barracuda/serial");
while (<FILE>) {
chomp;
next unless /\S/;
print $_ . "\n";
}
close (FILE);
}
}
if (-e "/etc/barracuda/model") {
print "\nBarracuda model File found - backing up\n";
$shell_command = `cp /etc/barracuda/model /home/remote/backup/`;
print "CONTENTS OF MODEL FILE: ";
open (FILE, "/etc/barracuda/model");
while (<FILE>) {
chomp;
next unless /\S/;
print $_ . "\n";
}
close (FILE);
if($newmodel ne "120") {
open FILE, ">/etc/barracuda/model";
print FILE "$newmodel\n";
close (FILE);
print "Overwritten /etc/barracuda/model with:\n";
open (FILE, "/etc/barracuda/model");
while (<FILE>) {
chomp;
next unless /\S/;
print $_ . "\n";
}
close (FILE);
}
}
if (-e "/etc/cudamodel") {
print "\nBarracuda cudamodel found - backing up\n";
$shell_command = `cp /etc/cudamodel /home/remote/backup/`;
#read serial file
print "CONTENTS OF cudamodel: ";
open (FILE, "/etc/cudamodel");
while (<FILE>) {
chomp;
next unless /\S/;
print $_ . "\n";
}
close (FILE);
if($newmodel ne "120") {
open FILE, ">/etc/cudamodel";
print FILE "$newmodel\n";
close (FILE);
print "Overwritten /etc/cudamodel with:\n";
open (FILE, "/etc/cudamodel");
while (<FILE>) {
chomp;
next unless /\S/;
print $_ . "\n";
}
close (FILE);
}
}
$shell_command = `mysqldump --user root config >/home/remote/
backup/database.sql`;
if ($newserial ne "12") {
$sql="update config set value = ". $newserial . " where variable
like 'system_serial';";
$sth = $dbh->prepare($sql);
$sth->execute or die "SQL Error: $DBI::errstr\n";
print "\nUPDATE DATABASE with query: $sql:\n";
$sql="update config set value = ". $newserial . " where variable
like 'user_quarantine_server%' and value = " . $oldmachine[0] . ";";
$sth = $dbh->prepare($sql);
$sth->execute or die "SQL Error: $DBI::errstr\n";
print "\nUPDATE DATABASE with query: $sql:\n";
$sql="update last_notified set server = ". $newserial . " where
server like '" . $oldmachine[0] . "';";
$sth = $dbh->prepare($sql);
$sth->execute or die "SQL Error: $DBI::errstr\n";
print "\nUPDATE DATABASE with query: $sql:\n";
$sql="select value from config where variable like
'cluster_systems_serial';";
$sth = $dbh->prepare($sql);
$sth->execute or die "SQL Error: $DBI::errstr\n";
if ($sth->rows) {
@row = $sth->fetchrow_array;
if (@row) {
print "\nCurrent Clustered Serial Numbers\n";
@clustermembers = split(/\n/, $row[0]);
foreach $cluster(@clustermembers)
{
print "Cluster Member:|> " . $cluster . "
<|";
#print it
if ($cluster eq $oldmachine[0]){
print " OLD/CURRENT SERIAL FOUND &
MATCHED";
$oldmachine[2] = $newserial;
} else {
$oldmachine[2] .= "\n" . $cluster;
}
print "\n";
}
print "\nUPDATE CLUSTER DATABASE - run
following sql:\n";
$sql = "update config set value='" .
$oldmachine[2] . "' where variable like'cluster_systems_serial';";
print "$sql\n";
} else {
die("fatal error - unable to find
current cluster serial.")
}
}
$shell_command = `rm -f /root/machine$oldmachine[0]`;
}
$sth->finish;
$dbh-> disconnect;
exit();
<END OF SCRIPT>
---------------------------------------------------------------------------------------
What else can you do?
View the logs:
less /mail/log/info (mail log)
less /mail/log/gui (what has done on the gui)
run diagnose.sh and get a look at what is wrong
Read database values such as domain controller/ad login credentials with
config_read %ldap% and a plethora of other useful information
READ, REQUEUE & REDELIVER MESSAGES;
REQUEUE INBOUND/ALL MAIL
postsuper -r ALL
REQUEUE OUTBOUND MAIL
postsuper -c /home/emailswitch/code/firmware/current/etc_outbound -r ALL
postcat <path_to_message>
postcat -q <queue_id>
READ INBOUND
mailq
postqueue -c /home/emailswitch/code/firmware/current/etc/ -p
find /mail/email/deferred -type f -exec ls -l {} \; | wc -l
******** THIS WILL GIVE QUEUE ERRORS ************
find /mail/email/defer -type f -exec head {} \;
******** THIS WILL GIVE QUEUE ERRORS ************
READ OUTBOUND
postqueue -c /home/emailswitch/code/firmware/current/etc_outbound/ -p
find /mail/email_outbound/deferred -type f -exec ls -l {} \; | wc -l //
show how many
find /mail/email_outbound/defer -type f -exec head {} \;
REDELIVERY
In spam firewall v3.5.12.010 there is a new deliver_mstore that will find
messages even if they are further then the previous 250,000 message limit.
It does require full timestamps when specifying date ranges. yyyy-mm-
ddThh:mm:ss
For example:
"2007-04-10T04:00:00:00/2007-04-12T00:00:00" or "2007-05-16T10:40:53/
T17:03:00"
Start or end may be omitted: "2007-01-20T00:00:00/"
deliver_mstore.pl -d "2007-10-09T11:47/2007-10-09T11:48"
2007 - Year
10 - Month
09 – Day
T11:47 – Time from
T11:48 – Time To
Use the FILTER to narrow down the delivery
-d, --time=s
(Must specify) A date/time range, specified as start/end dates
and times of day in the ISO 8601 extended format (e.g.,
"2007-04-10T04:00/2007-04-12" or
"2007-05-16T10:40:53/T17:03:00".). Start or end may be omitted,
as "2007-01-20T00:00/".
-f, --from=s
The mail envelope sender.
-t, --to=s
The mail envelope recipient.
-c, --action=s
The action taken for the message. Either a number, or one of:
allowed, aborted, blocked, quarantined, tagged,
deferred, pu-quarantine, or whitelisted.
-r, --reason=i
The reason for the action taken for the message. A number.
-e, --extra=s
Additional details on the reason for the action taken for the
message. An exact string match.
-s, --subject=s
Substring search within subject.
-b, --body-text
A regular expression to match against the message content
(header & body). WARNING: use of this option will incur extra
overhead, as it requires that all mail content be decoded and
processed.
-o
OR the previous filter option with the following one
(otherwise, they are ANDed).
--regex
Use regexes for filters, instead of matches.
!
Negate the sense of the following filter option.
(, )
Used to group options together. Note that you will need to
escape these within the shell: \( \) or '(' ')'.
Example (per-user email address): this will redeliver from Date (-d),
Action (-c) and To Email (-t)
# deliver_mstore.pl -d "2008-03-13T01:00/2008-03-15T01:00" -c "allowed" -
t "test...@twonks.com"
Example (per domain): this will redeliver from Date (-d), Action (-c) and
To domain (-t) (note: --regex must be there)
#deliver_mstore.pl -d "2008-02-20/2008-03-18" --regex -c "0" -t
"*.@barracuda.com"