OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Neil K (neilkALLDAS.DE)
Date: Mon Feb 19 2001 - 06:04:44 CST

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    |---------------------------------------------------------------------------------|
    / Product: Adcycle Banner Rotation. /
    \ Vendor URL: www.adcycle.com \
    / Tested on: v0.77 - 0.78b [Freeware] Linux /
    \ Vendor Contact: Mailed on 15th January [i think] Twice with NO reply \
    / Other: Commericial version NOT tested /
    \ \
    |-- First Off, ---------------------------------------------------------------------|
                        those who frequent www.alldas.de will know the general outlay
    of the site (see credits), and possible the fact that we (don't)run this script. It
    was an extreme bout of bordom and quite frankly moreover essential to check
    this script since we (used to)run it. NEVER trust a script cos others use it anyway...

    |-- The Problem, -----------------------------------------------------------------|
                        over the last few months a few ppl have come forward with posts
    that demonstrate or exploit various vulnerabilities in Perl/PHP scripts use of SQL
    based queries. Early this year some time in January when i looked at adcycle i
    found many of these problems, but never really tried to exploit them probably
    because i couldn't be arsed until now.....

    -Overview,
                    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)

    -/Overview

    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 0wn 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. I myself have never
    logged out of a hotmail account let alone clicked the word 'logout' written in size 6-8
    miniature text at the bottom of a browser.

    --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?

    If anyone comes up with a more efficient way to subvert authentication on this script
    then mail me :),
    /--

    |-- Exploit, -----------------------------------------------------------------------|
                    to better demostrate this problem i have included a small perl script sploit
    that will alter banner images, some alteration maybe needed for it to werk but hey it
    worked for me?!?.

    |-- Solution, ----------------------------------------------------------------------|
                    well considering that i have yet to get a response from adcycle after 4
    weeks?, says quite alot if you ask me. Possible because this script is freeware it ain't
    supported?. Well to say the least that sux real hard in my mind...

    Anyways how to patch?? well you could parse out the following character from *all
    the user defined fields: '.

    Here are the alterations to the script:

    AdLibrary.pm:
    sub db_login {
    =>
        my $agent=$env->get_agent;

    + while($agent =~ s/'// !=0 ){}

        my $cookie=$env->get_cookie;
        my $datestamp=$env->get_datestamp;
        my $admin_user_name=$config->get_admin_user_name;

    =>
        if($verify==0){
        my($trash,$mycookname,$mycookpid)=split(/\!\!/,$cookie);

    + while($mycookpid =~ s/'// !=0 ){}

    =>
        $FOUND=0;
        $sth = $dbh->prepare("SELECT * FROM login WHERE pid='$mycookpid' && agent='$agent' ORDER BY stime DESC");
        $sth->execute;
            while(login = $sth->fetchrow_array){
                if(length($login[1])>1){
                    $verify=1;
                    $whoami=$login[1];
                    $pid=$mycookpid;
                }
            }
            $sth->finish();
        }
    <=
    }

    Pls note this is a Hotfix and your script should be updated when (if) adcycle update
    theirs.

    |-- Credits, -----------------------------------------------------------------------|

            domz - designed and created alldas.de has mad html+PHP+infinitum
                              skillz. In process of coding a *new* banner rotation script....
            mjm - gmc-online.de, long time no speak.
            Jochen Wiedmann - joeispsoft.de for not allowing multiple queries
                                               on a single line, the TRUE saviour of all PHP and
                                               Perl programmers who write scripts that use MySQL.
            m8's werk where i finally quit after 3.5 years :-).
            all alldas.de, there sooo many i can't list them here!

           Thanks to rfp for a most *interesting* article abt PHP-Nuke which prompted
           me to get off me arse and write this :-).
    ______________________________________________________________

    NeilK (neilalldas.de/neilkalldas.de)
    www.alldas.de

                 "I'm always Frank and Ernest with the ladies,
                        Frank in New York, Ernest in Boston"
                                    --quoted from some film i watched last night