[TOOL] PSReal, Hidden Process Revealer

From: support@securiteam.com
Date: 06/28/02


From: support@securiteam.com
To: list@securiteam.com
Date: Fri, 28 Jun 2002 12:59:08 +0200 (CEST)

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -

  PSReal, Hidden Process Revealer
------------------------------------------------------------------------

DETAILS

The following tool will try to show hidden processes (even if there were
hidden by by kernel modules).

Tool code:
/*
 * ghQst - ElectronicSouls
 * tool to find hidden processes
 * works on 2.4.x kernels
 *
 * compile like this:
 * gcc -o psreal psreal.c -I/usr/src/linux/include/linux
 */

#define __KERNEL__
#include <linux/sched.h>
#undef __KERNEL__
#include <stdio.h>
#include <errno.h>

#define TASKSYMBOL "init_task_union"
#define MAXPIDS 1024

unsigned long findtasksymbol(char *tasksymbol);
int checkproc(int pid);
int createpidlist(int *pidlist, int len);
int checkpidlist(int pid, int *pidlist, int len);

int main(int argc, char *argv[])
{
  int pidlist[MAXPIDS];
  struct task_struct task;
  char *tasksymb = TASKSYMBOL;
  unsigned long inittask, nexttask;
  int fd, rt, lstpid;

  if (argc > 2) {
    fprintf(stderr, "usage:\t%s <tasksymbol>\n", argv[0]); exit(1);
  }
  if (argc > 1) tasksymb = argv[1];

  lstpid = createpidlist(pidlist, MAXPIDS);
  if (lstpid == -1) return -1;
  if (lstpid >= MAXPIDS) {
    fprintf(stderr, "%s:\tpid buffer to small\n", argv[0]); exit(1);
  }

  inittask = findtasksymbol(tasksymb);
  if (inittask == -1) {
    fprintf(stderr, "%s:\tcouldnt find task symbol\n", argv[0]); exit(1);
  }
  printf("symbol %s found: 0x%.8x\n", tasksymb, inittask);

  fd = open("/dev/kmem", O_RDONLY);
  if (fd == -1) {
    perror("open"); exit(1);
  }

  nexttask = inittask;
  while (nexttask) {
    rt = lseek(fd, nexttask, SEEK_SET);
    if (rt != nexttask) {
      perror("lseek"); exit(1);
    }
    rt = read(fd, &task, sizeof(task));
    if (rt < 0) {
      perror("read"); exit(1);
    }
    if (checkproc(task.pid)) {
      printf("- process %u (%s) hidden by the kernel\n", task.pid,
task.comm);
    } else if (checkpidlist(task.pid, pidlist, lstpid)) {
      printf("- process %u (%s) hidden by ps\n", task.pid, task.comm);
    }
    nexttask = (unsigned long)task.next_task;
    if (nexttask == inittask) break;
  }

  close(fd);
  return 0;
}

unsigned long findtasksymbol(char *tasksymbol)
{
  unsigned long addr;
  char buffer[1024];
  FILE *ksyms;
  char *p;

  ksyms = fopen("/proc/ksyms", "r");
  if (ksyms == NULL) {
    perror("findtasksymbol - fopen"); return -1;
  }

  bzero(buffer, sizeof(buffer));
  while (fgets(buffer, sizeof(buffer) - 1, ksyms)) {
    if (!(p = (char *)strchr(buffer, ' '))) continue;
    if (strstr(p+1, tasksymbol)) {
      *p = 0; addr = strtoul(buffer, NULL, 16);
      fclose(ksyms); return addr;
    }
  }

  fclose(ksyms);
  return -1;
}

int createpidlist(int *pidlist, int len)
{
  char buffer[1024];
  int rt, fd[2], lst;
  char *arg[3];
  FILE *ps;

  rt = pipe(fd);
  if (rt == -1) {
    perror("fork"); return -1;
  }

  rt = fork();
  switch (rt) {
  case -1:
    perror("fork"); return -1;
  case 0:
    close(fd[0]); dup2(fd[1], 1);
    arg[0] = "ps"; arg[1] = "-A"; arg[2] = NULL;
    execvp("/bin/ps", arg); exit(1);
  }

  close(fd[1]); lst = 0;
  if ((ps = fdopen(fd[0], "r")) == NULL) return -1;
  while (fgets(buffer, sizeof(buffer) - 1, ps) && lst < len) {
    buffer[6] = 0; pidlist[lst++] = atoi(buffer);
  }

  wait(NULL);
  return lst;
}

int checkproc(int pid)
{
  char buffer[1024];
  int fd;

  sprintf(buffer, "/proc/%d", pid);
  fd = open(buffer, O_RDONLY);
  if (fd == -1 && errno == ENOENT) return 1;
  close(fd);

  return 0;
}

int checkpidlist(int pid, int *pidlist, int len)
{
  int i;

  for (i=0; i<len; i++) {
    if (pidlist[i] == pid) return 0;
  }

  return 1;
}

ADDITIONAL INFORMATION

The information has been provided by ghQst.

========================================

This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

====================
====================

DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.



Relevant Pages