/* Half-Life (not Steam) Linux server/client work-around 0.2 by Luigi Auriemma e-mail: aluigi@altervista.org web: http://aluigi.altervista.org Intro: This simple patch is a hooker that checks some values from the recvfrom() function. The relative advisory is available here: http://aluigi.altervista.org/adv/hlboom-adv.txt I (Tomas Janousek) added code to handle some other split issue Virtual Master told me about. Compilation: gcc -s -O3 -D_GNU_SOURCE -fPIC -shared -ldl -o hllinfix.so hllinfix.c Usage: launch the server with this env var: LD_PRELOAD=/path/to/hllinfix.so (where /path/to/ is the path in which is located the compiled fix) */ #include #include #include #include #include #include #include #include #include /* uncomment the following #define to know the possible IP address of the attacker (remember that the attacker can spoof it) */ #define SHOW_ATTACKER 1 static ssize_t (*old_recvfrom)(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) = 0; ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) { ssize_t ret; if(!old_recvfrom) { old_recvfrom = dlsym(RTLD_NEXT, "recvfrom"); if(!old_recvfrom) exit(-1); } ret = old_recvfrom(s, buf, len, flags, from, fromlen); if((ret == 8 && *(unsigned long *)buf == 0xfffffffe) || (ret > 9 && *(unsigned long *)buf == 0xfffffffe && ((((unsigned char*)buf)[8] & 0xf0) >> 4) * 1391 + ret - 9 > 0xfaa)) { #ifdef SHOW_ATTACKER printf("- Packet split attack from %s\n", inet_ntoa(((struct sockaddr_in *)from)->sin_addr)); #endif return(0); } return(ret); }