225 lines
3.9 KiB
C
225 lines
3.9 KiB
C
|
/*
|
||
|
* Copyright (c) 2007 H D Moore <hdm [at] metasploit.com>
|
||
|
* This file is part of the Metasploit Framework.
|
||
|
* $Revision: 2053 $
|
||
|
*/
|
||
|
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/param.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <limits.h>
|
||
|
#include <unistd.h>
|
||
|
#include <string.h>
|
||
|
#include <errno.h>
|
||
|
#include <stdio.h>
|
||
|
#include <dirent.h>
|
||
|
#include <pwd.h>
|
||
|
#include <grp.h>
|
||
|
#include <sys/fcntl.h>
|
||
|
#include <sys/socket.h>
|
||
|
#include <arpa/inet.h>
|
||
|
#include <netdb.h>
|
||
|
\
|
||
|
#include "cmd.h"
|
||
|
|
||
|
void cmd_download(int argc, char * argv[])
|
||
|
{
|
||
|
int src, dst, len, i;
|
||
|
char buff[4096];
|
||
|
char *path, *p, *t;
|
||
|
char *uri;
|
||
|
char *host;
|
||
|
struct sockaddr_in server;
|
||
|
struct hostent *haddr;
|
||
|
int port = 80;
|
||
|
int dmode = 0;
|
||
|
int off = 0;
|
||
|
int clen = 0;
|
||
|
int tot = 0;
|
||
|
|
||
|
// src == socket
|
||
|
p = strstr(argv[1], "http://");
|
||
|
if( p == NULL) {
|
||
|
printf("The url must start with http://\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
p+=7;
|
||
|
|
||
|
t = strstr(p, "/");
|
||
|
if (t == NULL) {
|
||
|
printf("The url must contain a path\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
uri = strdup(t);
|
||
|
*t = '\0';
|
||
|
|
||
|
t = strstr(p, ":");
|
||
|
if (t != NULL) {
|
||
|
*t = '\0';
|
||
|
t++;
|
||
|
port = atoi(t);
|
||
|
}
|
||
|
|
||
|
host = strdup(p);
|
||
|
|
||
|
sprintf(buff, "GET %s HTTP/1.0\r\nHost: %s:%d\r\nConnection: Close\r\nUser-Agent: iPwn\r\n\r\n", uri, host, port);
|
||
|
|
||
|
if( ( haddr = gethostbyname(host) ) == NULL ) {
|
||
|
free(host);
|
||
|
perror("gethostbyname");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
free(host);
|
||
|
|
||
|
if (port < 1 || port > 65535) {
|
||
|
free(uri);
|
||
|
perror("invalid port");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if( ( src = socket ( PF_INET, SOCK_STREAM, IPPROTO_TCP ) ) < 0 ) {
|
||
|
free(uri);
|
||
|
perror("socket");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
memset ( &server, 0, sizeof( server ) );
|
||
|
server.sin_family = AF_INET;
|
||
|
server.sin_addr.s_addr = *( ( unsigned long * ) haddr->h_addr );
|
||
|
server.sin_port = htons ( port );
|
||
|
|
||
|
if( connect ( src, ( struct sockaddr * )&server, sizeof( server ) ) < 0 ) {
|
||
|
free(uri);
|
||
|
close(src);
|
||
|
perror("connect");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if( send( src, buff, strlen(buff), 0 ) != strlen(buff) ) {
|
||
|
free(uri);
|
||
|
close(src);
|
||
|
perror("send");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
path = strdup(argv[2]);
|
||
|
dst = open(path, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
|
||
|
if (dst == -1) {
|
||
|
|
||
|
if(errno == EISDIR) {
|
||
|
t = strrchr(uri, '/');
|
||
|
if (t != NULL) {
|
||
|
t++;
|
||
|
if(strlen(t) == 0) {
|
||
|
free(uri);
|
||
|
t = "download.out";
|
||
|
}
|
||
|
} else {
|
||
|
t = uri;
|
||
|
}
|
||
|
|
||
|
p = malloc(strlen(path) + strlen(t) + 2);
|
||
|
sprintf(p, "%s/%s", path, t);
|
||
|
free(path);
|
||
|
path = p;
|
||
|
|
||
|
dst = open(path, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
|
||
|
if ( dst == -1 ) {
|
||
|
close(src);
|
||
|
free(path);
|
||
|
free(uri);
|
||
|
perror("open(dst)");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
close(src);
|
||
|
free(path);
|
||
|
free(uri);
|
||
|
perror("open(dst)");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
free(uri);
|
||
|
|
||
|
memset(buff, 0, sizeof(buff));
|
||
|
off = 0;
|
||
|
tot = 0;
|
||
|
while (dmode == 0) {
|
||
|
|
||
|
if (sizeof(buff)-1-off <= 0)
|
||
|
break;
|
||
|
|
||
|
len = read(src, buff+off, sizeof(buff)-1-off);
|
||
|
|
||
|
if (len == -1) break;
|
||
|
if (len == 0) break;
|
||
|
off += len;
|
||
|
|
||
|
p = strstr(buff, "Content-Length:");
|
||
|
|
||
|
if (p) {
|
||
|
p += 15;
|
||
|
clen = atoi(p);
|
||
|
}
|
||
|
|
||
|
t = strstr(buff, "\r\n\r\n");
|
||
|
if (t) {
|
||
|
dmode = 1;
|
||
|
*t = '\0';
|
||
|
t += 4;
|
||
|
|
||
|
i = (int) ((buff + off) - t);
|
||
|
write(dst, t, i);
|
||
|
tot += i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printf("\n====================\n");
|
||
|
printf("HTTP Server Response\n");
|
||
|
printf("====================\n\n%s\n\n",buff);
|
||
|
|
||
|
if(! dmode || clen < 0) {
|
||
|
printf("could not parse the server response\n");
|
||
|
close(src);
|
||
|
close(dst);
|
||
|
unlink(path);
|
||
|
free(path);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(clen > 0) {
|
||
|
printf("Receiving %d bytes...\n", clen);
|
||
|
while(clen > 0 && len > 0) {
|
||
|
len = read(src, buff, sizeof(buff));
|
||
|
if (len > 0) {
|
||
|
write(dst, buff, len);
|
||
|
tot += len;
|
||
|
}
|
||
|
clen -= len;
|
||
|
}
|
||
|
} else {
|
||
|
printf("Receiving data...\n");
|
||
|
while(len > 0) {
|
||
|
len = read(src, buff, sizeof(buff));
|
||
|
if (len > 0) {
|
||
|
write(dst, buff, len);
|
||
|
tot += len;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printf("Received %d bytes\n", tot);
|
||
|
|
||
|
close(src);
|
||
|
close(dst);
|
||
|
|
||
|
chmod(path, 0755);
|
||
|
free(path);
|
||
|
}
|