"Fossies" - the Fresh Open Source Software Archive

Member "chkrootkit-0.55/chkutmp.c" (8 Mar 2021, 5965 Bytes) of package /linux/misc/chkrootkit-0.55.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "chkutmp.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.51_vs_0.52.

    1 /*
    2  * 2004/09/23 - Jeremy Miller <jmtgzd@gmail.com>
    3  *
    4  * This utility compares the output from the ps command and tries to find
    5  * a matching entry bound to the same tty in the utmp login records. The
    6  * idea is to display users that may have wiped themselves from the utmp
    7  * log.  When analyzing a compromised box, it is assumed you have the
    8  * path to a known good 'ps' binary in your PATH.
    9  *
   10  * LICENSE: This program is free software; you can redistribute it and/or
   11  * modify it under the terms of the GNU General Public License as
   12  * published by the Free Software Foundation; either version 2 of the
   13  * License, or (at your option) any later version.
   14  *
   15  * This program is distributed in the hope that it will be useful, but
   16  * WITHOUT ANY WARRANTY; without even the implied warranty of
   17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18  * General Public License for more details.
   19  *
   20  * You should have received a copy of the GNU General Public License along
   21  * with this program; if not, write to the Free Software Foundation, Inc.,
   22  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   23  *
   24  *  Changelog:
   25  *   Ighighi X - Improved speed via break command - 2005/03/27
   26  *   Some overflow fixes by Michael Schwendt - 2009/07/21
   27  *   Fixed false warning  - 2017/02/18 - George Ogata
   28  *
   29  */
   30 
   31 #if !defined(__sun) && !defined(__linux__)
   32 int main () { return 0; }
   33 #else
   34 #include <unistd.h>
   35 #include <stdlib.h>
   36 #include <stdio.h>
   37 #include <string.h>
   38 #include <utmp.h>
   39 #include <fcntl.h>
   40 #if defined(__sun)
   41 #include <utmpx.h>
   42 #else
   43 #include <utmp.h>
   44 #endif
   45 #include <ctype.h>
   46 
   47 #define MAXREAD 1024
   48 #define MAXBUF 4096
   49 #define MAXLENGTH 256
   50 #define UT_PIDSIZE 12
   51 #if defined(__sun)
   52 #define UTMP "/var/adm/utmpx"
   53 #define UT_LINESIZE 12
   54 #define UT_NAMESIZE 8
   55 #define PS_CMD 0
   56 #else
   57 #define PS_CMD 1
   58 #define UTMP "/var/run/utmp"
   59 #endif
   60 
   61 struct ps_line {
   62     char ps_tty[UT_LINESIZE];
   63     char ps_user[UT_NAMESIZE];
   64     char ps_args[MAXLENGTH];
   65     int ps_pid;
   66 };
   67 struct utmp_line {
   68     char ut_tty[UT_LINESIZE];
   69     int ut_pid;
   70     int ut_type;
   71 };
   72 static char *cmd[] = {
   73     "ps -ef -o \"tty,pid,ruser,args\"", /* solaris */
   74     "ps ax -o \"tty,pid,ruser,args\""   /* linux */
   75 };
   76 int fetchps(struct ps_line *);
   77 int fetchutmp(struct utmp_line *);
   78 
   79 int fetchps(struct ps_line *psl_p)
   80 {
   81     FILE *ps_fp;
   82     char line[MAXREAD + 1], pid[UT_PIDSIZE];
   83     char *s, *d;
   84     struct ps_line *curp = &psl_p[0];
   85     struct ps_line *endp = &psl_p[MAXBUF-1];
   86     int i, x, line_length;
   87 
   88     i = 0;
   89     if ((ps_fp = (popen(cmd[PS_CMD], "r"))) != NULL) {
   90     fgets(line, MAXREAD, ps_fp);    /* skip header */
   91     while (fgets(line, MAXREAD, ps_fp)) {
   92         s = line;
   93         if (*s != '\?' && curp <= endp) {   /* only interested in lines that
   94                          * have a tty */
   95         d = curp->ps_tty;
   96         for (x = 0; (!isspace(*s)) && (*d++ = *s++) && x <= UT_LINESIZE; x++)   /* grab tty */
   97             ;
   98         *d = '\0';
   99         while (isspace(*s)) /* skip spaces */
  100             s++;
  101         d = pid;
  102         for (x = 0; (!isspace(*s)) && (*d++ = *s++) && x <= UT_LINESIZE; x++)   /* grab pid */
  103             ;
  104         *d = '\0';
  105         curp->ps_pid = atoi(pid);
  106         while (isspace(*s)) /* skip spaces */
  107             s++;
  108         d = curp->ps_user;
  109         for (x = 0; (!isspace(*s)) && (*d++ = *s++) && x <= UT_NAMESIZE; x++)   /* grab user */
  110             ;
  111         *d = '\0';
  112         d = curp->ps_args;
  113         while (isspace(*s)) /* skip spaces */
  114             s++;
  115         for (x = 0; (*d++ = *s++) && x <= MAXLENGTH; x++)   /* cmd + args */
  116             ;
  117         i++;
  118         curp++;
  119                 /* if we didn't read the line, skip the rest */ 
  120                 line_length = strlen(line); 
  121                 while (!(line_length == 0 || line[line_length -1] == '\n')) { 
  122                    fgets(line, MAXREAD, ps_fp);
  123                    line_length = strlen(line); 
  124                 } 
  125         }
  126     }
  127     pclose(ps_fp);
  128     } else {
  129     fprintf(stderr, "\nfailed running 'ps' !\n");
  130     exit(EXIT_FAILURE);
  131     }
  132     return i;
  133 }
  134 
  135 int fetchutmp(struct utmp_line *utl_p)
  136 {
  137 #if defined(__sun)
  138     struct utmpx ut;
  139 #else
  140     struct utmp ut;
  141 #endif
  142     struct utmp_line *curp = &utl_p[0];
  143     struct utmp_line *endp = &utl_p[MAXBUF-1];
  144     int i, f, del_cnt, sz_ut;
  145 
  146     i = del_cnt = 0;
  147     if ((f = open(UTMP, O_RDONLY)) > 0) {
  148 #if defined(__sun)
  149     sz_ut = sizeof(struct utmpx);
  150 #else
  151     sz_ut = sizeof(struct utmp);
  152 #endif
  153 
  154     while (read(f, &ut, sz_ut) > 0 && curp <= endp) {
  155 #if !defined(__sun)
  156         if (ut.ut_time == 0)
  157         del_cnt++;  /* ut_time shouldn't be zero */
  158 #endif
  159         if (strlen(ut.ut_user) > 0) {
  160         strncpy(curp->ut_tty, ut.ut_line, UT_LINESIZE);
  161         curp->ut_pid = ut.ut_pid;
  162         curp->ut_type = ut.ut_type;
  163         i++;
  164         curp++;
  165         }
  166     }
  167     close(f);
  168     if (del_cnt > 0)
  169         printf("=> possibly %d deletion(s) detected in %s !\n",
  170            del_cnt, UTMP);
  171     } else {
  172     fprintf(stderr, "\nfailed opening utmp !\n");
  173     exit(EXIT_FAILURE);
  174     }
  175     return i;
  176 }
  177 
  178 int main(int argc, char *argv[])
  179 {
  180     struct ps_line ps_l[MAXBUF];    /* array of data from 'ps' */
  181     struct utmp_line ut_l[MAXBUF];  /* array of data from utmp log */
  182     int h, i, y, z, mtch_fnd, hdr_prntd;
  183 
  184     y = fetchps(ps_l);
  185     z = fetchutmp(ut_l);
  186     hdr_prntd = 0;
  187     for (h = 0; h < y; h++) {   /* loop through 'ps' data */
  188     mtch_fnd = 0;
  189     for (i = 0; i < z; i++) {   /* try and match the tty from 'ps' to one in utmp */
  190         if (ut_l[i].ut_type == LOGIN_PROCESS    /* ignore getty processes with matching pid from 'ps' */
  191         && ut_l[i].ut_pid == ps_l[h].ps_pid)
  192        {
  193         mtch_fnd = 1;
  194             break;
  195            }
  196         else if (strncmp(ps_l[h].ps_tty, ut_l[i].ut_tty,    /* compare the tty's */
  197                  strlen(ps_l[h].ps_tty)) == 0)
  198         {
  199         mtch_fnd = 1;
  200             break;
  201         }
  202     }
  203     if (!mtch_fnd) {
  204         if (!hdr_prntd) {
  205         printf
  206             (" The tty of the following user process(es) were not found\n");
  207         printf(" in %s !\n", UTMP);
  208         printf("! %-9s %7s %-6s %s\n", "RUID", "PID", "TTY",
  209                "CMD");
  210         hdr_prntd = 1;
  211         }
  212         printf("! %-9s %7d %-6s %s", ps_l[h].ps_user,
  213            ps_l[h].ps_pid, ps_l[h].ps_tty, ps_l[h].ps_args);
  214     }
  215     }
  216     exit(EXIT_SUCCESS);
  217 }
  218 #endif