i incidentally found a bug in gtetrinet 0.7.9 which allows mallicius
tetrinet servers to inject code into a client. the problem lies in the
function tetrinet_inmessage (tetrinet.c line 174++):
733 case IN_LVL:
734 {
735 char *token;
736 int pnum; << signed int
737 token = strtok (data, " "); << data from server
738 if (token == NULL) break;
739 pnum = atoi (token);
740 if (pnum >= MAX_PLAYERS) << only check upper bound
741 break;
742 token = strtok (NULL, "");
743 if (token == NULL) break;
744 playerlevels[pnum] = atoi (token); << use pnum as index
so if the server sends negative pnum arbitary memory regions can be
overwritten (e.g. inject shellcode/overwrite GOT entry). this issue can
easily fixed by checkig the pnum for a negative value.
within this function there are several other instances where the pnum
isnt checked for negative values (IN_PLAYERJOIN, IN_PLAYERLEAVE, ...)
and is later used as an array index, and thus can be abused for
arbitrary memory overwrites.
the attached code is (quick/rough) simple demonstration of this problem.
it behaves as tetrinet server, waits for incomming connections and
injects a simple write(1, "badcode")-shellcode to the client (there are
some hardocded offsets in the code so it will only work on the ubunbtu
6.06 package tough). however as it seems some tetrinet server dont do
any sanity checking on incomming messages, and just broadcast the to the
other clients, an client to client attack might also be possible.
greets
Michael Gehring