Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#91 packet_cap_apps : false positive

closed-fixed
John Horne
Detection (54)
5
2012-12-06
2012-08-20
Philippe Naudin
No

The test packet_cap_apps looks for an inode in /proc/net/packet, and then grep this inode in the output of
lsof -lMnPw -d 1-20
This can lead to false positive, for example when there is a match with the size of a file. Study case :
$ cat /proc/net/packet
sk RefCnt Type Proto Iface R Rmem User Inode
f5d18800 3 3 0003 2 1 0 0 5946
## this one is probably dhclient
$ dd if=/dev/zero of=toto bs=1 count=5946
$ tail -f toto
## and on an other xterm :
$ rkhunter --enable packet_cap_apps --report-warnings-only
Warning: Process '/usr/bin/tail' (PID 18996) is listening on the network.

(tested with rkhunter-1.4.0-1.el5)

Discussion

  • John Horne
    John Horne
    2012-08-21

    The code actually says not to use any '/proc/net/packet' entry which begins with 'sk' (so that the header line), and anything with '888e'. I cannot reproduce your problem because on my Fedora 17 system the tail process ends up in /proc/net/packet with an 'proto' of 888e. In your case the proto is '0003', so RKH reports it as a warning.

    However, I agree that this test needs a bit more work perhaps. The 'greps' are a bit generic in that they will match on anything, and we should perhaps tie the output of /proc/net/packet more closely to the output from lsof (i.e. make sure we are matching what we want to match and not just matching anything).

     
  • Sorry, I was not clear : the entry in /proc/net/packet is unrelated to tail (it probably comes from dhclient).

    I just search /proc/net/packet for an entry with proto != 888e, take note of the inode, and create a file with the *size* equal to the inode already in /proc/net/packet. Then I open this file and start rkhunter : there is a match.

    A possible fix for Linux, but I don't know how is the output of lsof on other platforms, is to replace line 14103 (in rkhunter-1.4.0) by :
    for PID in `${LSOF_CMD} -lMnPw -d 1-20 | awk "\\$7 ~ /^(${INODE_LIST})$/ { print \\$2 }"`; do

    It works since lsof cuts the name of a process if there is a space in the name (and completely ignore the process when there is a carriage return in the name, which is an other story and quite a problem imho).

    Best regards,

    --
    Philippe

     
  • Arrgh...
    awk "\\$8 ~ /^(${INODE_LIST})$/ { print \\$2 }"
    \\$8, of course.

    Sorry !

     
  • John Horne
    John Horne
    2012-09-10

    I have put a small fix into the CVS version. This should work for the example you state above because it looks for socket type connections, and your file above (toto) would be a regular file not a socket.

    If you want to try this out please download the CVS verson, or I can send you a drop-in 'rkhunter' replacement.

     
  • John Horne
    John Horne
    2012-09-10

    • assigned_to: nobody --> jhorne
     
  • Sorry for the late reply...

    I have checked the CVS, with the line :
    for PID in `${LSOF_CMD} -lMnPw -d 1-20 | egrep "[ ](pack|sock)[ ]+(${INODE_LIST})[ ]" | awk '{ print $2 }'`; do

    Yes, this prevents a regular file to appear as a listening socket.
    But I'm afraid it has also an effect on real sockets. See this example :

    $ cat /proc/net/packet
    sk RefCnt Type Proto Iface R Rmem User Inode
    ffff8100bd4ac000 3 3 0003 2 1 0 0 8394
    # inode 8394 is listening, and will appear in ${INODE_LIST}

    $ sudo lsof -lMnPw -d 1-20 | egrep "[[:space:]]+(8394)[[:space:]]"
    dhclient 2327 0 5u sock 0,5 0t0 8394 can't identify protocol
    # inode 8394 is dhclient, with TYPE=sock

    $ sudo lsof -lMnPw -d 1-20 | egrep "[[:space:]](pack|sock)[[:space:]]+(8394)[[:space:]]"
    <nothing>
    # there are two fields between "sock" and the inode number : the regexp don't match.

    This version of lsof is :
    lsof version information:
    revision: 4.78
    constructed by and on: mockbuild@builder10.centos.org
    compiler: cc
    compiler version: 4.1.2 20080704 (Red Hat 4.1.2-52)
    compiler flags: -DLINUXV=26016 -DGLIBCV=205 -DHASIPv6 -DHASSELINUX -D_FILE_OFFSET_BITS=64 -DLSOF_VSTR="2.6.16" -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic
    loader flags: -L./lib -llsof -lselinux
    system info: Linux builder10.centos.org 2.6.18-53.el5 #1 SMP Mon Nov 12 02:14:55 EST 2007 x86_64 x86_64 x86_64 GNU/Linux
    Anyone can list all files.
    /dev warnings are disabled.
    Kernel ID check is disabled.

    Best regards,

    --
    Philippe

     
  • John Horne
    John Horne
    2012-09-12

    Okay, updated CVS again.
    This basically looks in the lsof output for ' pack <inode> ' or ' sock <something> <something> <inode> '.
    Although this looks like something awk should handle, we cannot guarantee the field order, so we are, largely, just looking for the inode as an individual (separate) field.

     
  • Thanks : it works fine !

    The regexp on line 14103 can be shortened to
    egrep "[[:space:]](pack|sock[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+)[[:space:]]+(${INODE_LIST})[[:space:]]" | awk '{ print $2 }'
    or, using awk only, to
    awk "/[[:space:]](pack|sock[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+)[[:space:]]+(${INODE_LIST})[[:space:]]/ {print \$2}"
    but this is a detail.

    I definitely agree that parsing the output of lsof is a pain. I've tried
    lsof -F0 only to end with a good headache...

    Thanks again for all your time on rkhunter,

    --
    Philippe

     
  • John Horne
    John Horne
    2012-12-06

    • status: open --> closed-fixed