Sebek/Bugs

De Wikidroids

This page describes Sebek BSD bugs. You are welcome to add bugs you have found, and/or update this page. In this case, please also send an e-mail to the development team.

Sommaire

3.0 branch

The 3.0 branch is only available as highly beta.

Sebek OpenBSD / i386

From the fourth comment in the Honeynet Project bug #311 : unexpected (and non reproducible) crashes.

Stefan Kelm reports that he has "had [his] OpenBSD 3.7 machine crash twice over the last couple of weeks". He says that when the second crash has occured, he had the following kernel message :

uvm_fault(0xea7ed1b4, 0x0, 0, 1) -> e
kernel: page fault trap, code=0
Stopped at      send_sebek_s_packet+0xea:       movl    0x28(%eax),%eax 

He remembers neither wether the message of the first crash was the same, nor what was the system doing just before the crashs.

According to the message, we know that (at least) the second bug has occured in send_sebek_s_packet() (in sebek/sebek.c) in the block :

packet->socket.dip = ((struct inpcb *) s->so_pcb)->inp_faddr.s_addr;
packet->socket.dport = ((struct inpcb *) s->so_pcb)->inp_fport;
packet->socket.sip = ((struct inpcb *) s->so_pcb)->inp_laddr.s_addr;
packet->socket.sport = ((struct inpcb *) s->so_pcb)->inp_lport;

We do not know wether in some cases, s->so_pcb contains something else than a (properly allocated) struct inpcb *. It's important to say that before that code, we check :

if(s->so_proto->pr_domain->dom_family != AF_INET)
        return -1;

Note : since this part of the code is shared with Sebek NetBSD and FreeBSD, it is possible that the same bug exists in these version.

Sebek NetBSD / sparc64

The kernel crashes when booting up. To investigate, we have only kept the dofileread() hook. We have the following crash message :

data fault : pci=100aabr
             addr=ffffffffffffa000

addr seems to be the page address where is located the buffer variable (this is where the kernel stores the data it has just read, its address is 0xffffffffffffa49f). The crash occurs at the instruction :

memcpy(mtod(m2, char*), buffer, nbyte);

It seems that the kernel has no right to read in the page where the buffer variable is (the original sys_read() does not actually need to have this right, it only needs to be allowed to write in this page ; but the hooked function needs to be allowed to read it, since it sends the buffer to the Sebek server).

The buffer (which points to a userland-mapped location) can't be read because it is not accessible in kernelspace on some architectures like sparc64. The kernel uses the uiomove() function to copy data from/to userspace.

I (Zer0) tested a patch that corrects the problem : so now it works on sparc64 all syscall log the kernel no longer crashes, and packets contain the appropriate data. Here is another patch (not yet tested), which could correct the problem for netbsd correctly :

diff -c /home/zer0/sebek/sebek-bsd/sebek/sebek/sebek.c /var/partage/netbsd_src/src/sys/sebek/sebek.c
*** /home/zer0/sebek/sebek-bsd/sebek/sebek/sebek.c	2005-05-23 16:49:09.000000000 +0200
--- /var/partage/netbsd_src/src/sys/sebek/sebek.c	2005-07-28 00:19:48.070175096 +0200
***************
*** 49,54 ****
--- 49,56 ----
  #include <net/route.h> /* needed by in_pcb.h */
  #include <netinet/in_pcb.h> /* struct inpcb */
  
+ #include <sys/uio.h> /* for struct uio, TESTED only on NETBSD */
+ 
  #include <sys/time.h> /* microtime */
  #include <sys/protosw.h> /* struct protosw */
  #include <sys/domain.h> /* struct domain */
***************
*** 407,412 ****
--- 409,434 ----
    struct mbuf *m;
    struct mbuf *m2; // will receive external data 
    struct whole_rw_header *packet;
+   struct uio	auio;
+   struct iovec	aiov;
+ 
+   /* Fill uio structure with infos from buffer */
+   aiov.iov_base = (caddr_t)buf;
+   aiov.iov_len = nbyte;
+   auio.uio_iov = &aiov;
+   auio.uio_iovcnt = 1;
+   auio.uio_resid = nbyte;
+   auio.uio_rw = UIO_WRITE;
+   auio.uio_procp = p;
+ 
+   /* if buffer comes from a sys_read or sys_write call, it comes from
+      userspace, else it comes from a kernelspace buffer (sys_open) */
+   if(type == SEBEK_OPEN) {
+     auio.uio_segflg = UIO_SYSSPACE;
+   }
+   else {
+     auio.uio_segflg = UIO_USERSPACE;
+   }
  
    /* 
     * Allocating mbuf for creating the packet. This mbuf will only be filled
***************
*** 446,452 ****
    }
  
    if ( nbyte <= MLEN ){ /* mbuf is long enough, we copy our data into */
!     memcpy(mtod(m2, char *), buffer, nbyte);
    }
    else{               /* we must get external storage, too much data */
      MCLGET(m2, M_DONTWAIT);
--- 468,474 ----
    }
  
    if ( nbyte <= MLEN ){ /* mbuf is long enough, we copy our data into */
!     uiomove(mtod(m2, char *), nbyte, &auio);
    }
    else{               /* we must get external storage, too much data */
      MCLGET(m2, M_DONTWAIT);
***************
*** 455,461 ****
        m_freem(m2);
        return -1;
      }
!     memcpy(mtod(m2, caddr_t), buffer, (size_t)nbyte); // we copy our data into it
    }
  
    m->m_next = m2 ; /* mbuf of data m2 is linked to packet header mbuf m */     
--- 477,483 ----
        m_freem(m2);
        return -1;
      }
!     uiomove(mtod(m2, char *), nbyte, &auio); /* we copy our data into it */
    }
  
    m->m_next = m2 ; /* mbuf of data m2 is linked to packet header mbuf m */

I (Zer0) am going to test this patch for netbsd/sparc, then try to verify that it does not break anything for the i386/*bsd.

1.2 branch

Nothing known for now. However, you should avoid using the 1.2 branch, since Sebek can be circumvented. See the sebekill and sebekill2 libraries ; it has been designed for Sebek Linux, but can easily be adapted to kill Sebek BSD.

Boîte à outils
LANGUAGES