PDA

Bekijk Volledige Versie : Eggrop bug



cyborgirl@libero.it
09/02/04, 23:55
http://mogan.nonsoloirc.com/egg_advisory.txt

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

Eggdrop is a bot written in C. It is hi=
ghly configurable
and can be easily expandeded with TCL scripts. It is w=
idely used in almost every
IRC Network.
Eggdrop can be downloaded from:=

http://www.eggheads.org

Description:
=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D
A vulnerability has been discovered in share.mod modu=
le provided with eggdrop
sources.
A tricky attacker can gain the contro=
l 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 w=
ith someone.


Issue Details:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
share.mod use tandem buffers to handle userfile resync transfers. ta=
ndem 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 ha=
ven't received yet any response from tandem bot). While doing those
chec=
ks the
programmer has left out some parentheses and the worst has happen=
ed:
Here the incriminated snip:

for (i =3D 0; i < dcc_total; i++)=0D
=
if (dcc[i].type->flags & DCT_BOT) {
if (dcc[i].status & STAT_O=
FFERED) {
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 t=
hat hasnt been sharing, ask again */
} else if (!(dcc[i].status & =
STAT_SHARE)) {

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

}
}

As we can see, every non sharebot gain STA=
T_OFFERED status, minutely.

the next step is to gain STAT_SHARE.. we u=
se share_ufyes().
That function doesn't STAT_SHARE check, just STAT_OFFE=
RED.

static void share_ufyes(int idx, char *par)
{
if (dcc[idx].st=
atus & STAT_OFFERED) {
dcc[idx].status &=3D ~STAT_OFFERED;
dcc[=
idx].status |=3D STAT_SHARE;
dcc[idx].status |=3D 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 sharebo=
t and we can adduser..
deluser.. chattr..


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




Patch:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
Trivial,

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

--- eggdrop1.6.1=
5/src/mod/share.mod/share.c Sat Feb 7 05:13:32 2004
+++ eggdrop1.6.15-s=
p/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_f=
lags(dcc[i].user) & BOT_AGGRESSIVE))
+ /* Patched from original source b=
y giusc@gbss.it <20040207> */
+ if (dcc[i].user && (bot_flags(dcc=
[i].user) & BOT_AGGRESSIVE)) {
dprintf(i, "s u?\n");
- =
dcc[i].status |=3D STAT_OFFERED;
+ dcc[i].status |=3D STAT_O=
FFERED;
+ }
}
}
}


-------- Cut Here --------=
-



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



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



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

Jeff Fisher
10/02/04, 18:25
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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

Thankfully resync sharing is considered broken and most people do not
use it. Indeed though, this is a bug and thank you for finding it.

| --- 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@gbss.it <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;
| + }
| }
| }
| }
|

This patch has been applied to the latest CVS copy with the correct credits.

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

Where did you notify eggheads? I seem to be blind while looking for it.

Jeff

- --
Jeff Fisher <guppy@eggheads.org>
Eggdrop Development Team
Eggheads.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFAKFwHGi4Ni4h3f1YRAkoGAJ9FUHyPMhXW2z9/EU/+3gm9ac4O8gCgh0Ld
pghogz/K0O2at7ODk8JVOnM=
=yyRM
-----END PGP SIGNATURE-----

Giuseppe
10/02/04, 20:25
>Thankfully resync sharing is considered broken and most people do not
>use it. Indeed though, this is a bug and thank you for finding it.

that's not exactly true; yes, many people don't use resync, but..

char *share_start(Function *global_funcs)
{
.....................
add_hook(HOOK_SHAREIN, (Function) sharein_mod);
add_hook(HOOK_MINUTELY, (Function) check_expired_tbufs);
^^^^^^^^^
add_hook(HOOK_READ_USERFILE, (Function) hook_read_userfile);
.....................
}

the function, however, is called minutely, so the bug exists also if resync
is disabled.
As in previous mail has been already said, check_expired_tbufs() first
check for timed out resync buffers, then, "accomplish to handle userfile
requests in limbo (that haven't received yet any response from tandem bot)".

>Where did you notify eggheads? I seem to be blind while looking for it.

We've notified you at bugs@eggheads.org; in a private e-mail i''ve sent to
you the response we received.


With respect,
giuseppe