<<< Date Index >>>     <<< Thread Index >>>

Eggrop bug



http://mogan.nonsoloirc.com/egg_advisory.txt

==========================
Topic: eggdrop share.mod problem
Issue date: 07/02/2004
Severity: remote exploit
Affected versions: 1.6.x <= 1.6.15, others?
======================

Eggdrop is a bot written in C. It is highly configurable
and can be easily expandeded with TCL scripts. It is widely used in almost every
IRC Network.
Eggdrop can be downloaded from:
     http://www.eggheads.org

Description:
==============
A vulnerability has been discovered in share.mod module provided with eggdrop
sources.
A tricky attacker can gain the control over (almost) any eggdrop botnet.
the bug rely in the fact that every legitimate bot can gain share status even 
if it
is not marked to share with someone.


Issue Details:
==============
share.mod use tandem buffers to handle userfile resync transfers. tandem buffers
are checked
minutely by check_expired_tbufs() in order to flush tandem buffers older than 15
minutes
(resync_time). check_expired_tbufs() accomplish also to handle userfile requests
in limbo
(that haven't received yet any response from tandem bot). While doing those
checks the
programmer has left out some parentheses and the worst has happened:
Here the incriminated snip:

  for (i = 0; i < dcc_total; i++)
    if (dcc[i].type->flags & DCT_BOT) {
      if (dcc[i].status & STAT_OFFERED) {
        if (now - dcc[i].timeval > 120) {
          if (dcc[i].user && (bot_flags(dcc[i].user) & BOT_AGGRESSIVE))
            dprintf(i, "s u?\n");
          /* ^ send it again in case they missed it */
        }
        /* If it's a share bot that hasnt been sharing, ask again */
      } else if (!(dcc[i].status & STAT_SHARE)) {

------- /* Bug now every bot gain the STAT_OFFERED status. */
        if (dcc[i].user && (bot_flags(dcc[i].user) & BOT_AGGRESSIVE))
          dprintf(i, "s u?\n");
        dcc[i].status |= STAT_OFFERED;
------- /* eof Bug */

      }
    }

As we can see, every non sharebot gain STAT_OFFERED status, minutely.

the next step is to gain STAT_SHARE.. we use share_ufyes().
That function doesn't STAT_SHARE check, just STAT_OFFERED.

static void share_ufyes(int idx, char *par)
{
  if (dcc[idx].status & STAT_OFFERED) {
    dcc[idx].status &= ~STAT_OFFERED;
    dcc[idx].status |= STAT_SHARE;
    dcc[idx].status |= STAT_SENDING;
    uf_features_parse(idx, par);
    start_sending_users(idx);
    putlog(LOG_BOTS, "*", "Sending user file send request to %s",
           dcc[idx].nick);
  }
}


bingo!
the bot is now completely recognized as a sharebot and we can adduser..
deluser.. chattr..


Notes:
=============
Two bots directly linked, at the moment of link, share a password (handshake)
but probably two bots not directly linked will not. So can be possible to fake a
real bot simply telnetting the bot port and pressing enter :).




Patch:
=============
Trivial,

-------- Cut Here ---------

--- eggdrop1.6.15/src/mod/share.mod/share.c     Sat Feb  7 05:13:32 2004
+++ eggdrop1.6.15-sp/src/mod/share.mod/share.c  Sat Feb  7 05:43:33 2004
@@ -1457,9 +1457,11 @@
           /* ^ send it again in case they missed it */
         /* If it's a share bot that hasnt been sharing, ask again */
       } else if (!(dcc[i].status & STAT_SHARE)) {
-        if (dcc[i].user && (bot_flags(dcc[i].user) & BOT_AGGRESSIVE))
+       /* Patched from original source by giusc@xxxxxxx <20040207> */
+        if (dcc[i].user && (bot_flags(dcc[i].user) & BOT_AGGRESSIVE))  {
           dprintf(i, "s u?\n");
-        dcc[i].status |= STAT_OFFERED;
+          dcc[i].status |= STAT_OFFERED;
+        }
       }
     }
 }


-------- Cut Here ---------



Exploit:
=============
trivial,
not yet available for kiddies.



Acknowledgment:
===============
Luca De Roberto <luca_adsl (at) tin (dot) it>
Dania Stolfi <cyborgirl (at) libero (dot) it>
Giuseppe Caulo <giusc (at) gbss (dot) it>



Vendor status:
===============
Notified on 07 February 2004