Ich möchte ein Protokoll aller Prozesse erhalten, die mit dem Zeitpunkt des Starts und den Argumenten gestartet wurden, mit denen sie gestartet wurden. Ist das unter Linux möglich?
Ich möchte ein Protokoll aller Prozesse erhalten, die mit dem Zeitpunkt des Starts und den Argumenten gestartet wurden, mit denen sie gestartet wurden. Ist das unter Linux möglich?
Antworten:
Ihr Ausgangspunkt sollte auditiert werden.
Versuchen Sie so etwas:
apt-get install auditd
auditctl -a task,always
ausearch -i -sc execve
chmod 0750 /sbin/audispd
Unable to set audit pid, exiting
aber ich denke , dass das eigentliche Problem , dass das System läuft in LXC Containern sein wird
Ich musste dies tun, außer (1) ich brauchte nicht die Zeit und (2) ich interessierte mich nur für Prozesse, die von einem bestimmten Prozess gestartet werden, und seine Kinder und nachfolgenden Nachkommen. Auch in der Umgebung, die ich benutzte, war es nicht möglich, auditd
oder zu bekommen accton
, aber es gab valgrind
.
Stellen Sie dem gewünschten Prozess in der Befehlszeile Folgendes voran:
valgrind --trace-children=yes
Die Informationen, die Sie benötigen, werden in der Protokollausgabe von STDERR angezeigt.
memcheck
Tool ausgeführt. Um das Werkzeug und den damit verbundenen Protokollierung zu deaktivieren, und drucken nur die Schaffung neuer Befehle (zusätzlich zu dem üblichen Ausgang Ihres Programms), verwenden Sie stattdessen den folgenden Befehl: valgrind --tool=none --trace-children=yes [command and args here]
. Immer wenn ein Unterprozess erzeugt wird, protokolliert Valgrind den vollständigen Befehl, einschließlich der Argumente, die an ihn übergeben wurden.
Sie könnten dafür snoopy verwenden .
Es ist sehr einfach zu installieren und kann seit 2.x beliebige Daten (Argumente, Umgebungsvariablen, cwd usw.) protokollieren.
Offenlegung: Snoopy Betreuer hier.
Sie können startmon ausführen und die Standardausgabe, Strg-C, befolgen, wenn Sie fertig sind. So kompilieren Sie startmon und führen es auf neueren von Red Hat abgeleiteten Distributionen (RHEL, Fedora, CentOS) aus:
sudo yum install git cmake gcc-c++
git clone https://github.com/pturmel/startmon
cd startmon
cmake .
make
sudo ./startmon -e
Unter Debian (und Ubuntu usw.) ändert sich die erste Zeile der obigen Änderungen in:
sudo apt-get install git cmake g++
Alternativ können Sie das execsnoop
Skript in perf-tools ausprobieren , siehe diese Antwort . Standardmäßig werden nur die ersten 8 Argumente angezeigt (9 einschließlich des Programmnamens). Sie können dies über erhöhen
sudo ./execsnoop -a 16
Wenn Sie keinen Root-Zugriff auf das System haben, können Sie am besten weiter abfragen /proc
und hoffen, dass es alles abfängt (was nicht der Vollständigkeit halber) Dies ist zwar nicht so gut wie das ordnungsgemäße Verfolgen mit einer der oben genannten Methoden, hat jedoch den leichten Vorteil, dass Trennzeichen zwischen den Befehlszeilenargumenten eindeutig angezeigt werden, falls Sie dies jemals mitteilen müssen Unterschied zwischen Leerzeichen innerhalb eines Arguments und Leerzeichen zwischen Argumenten. Dieses Skript ist ineffizient, da es die CPU (also einen seiner Kerne) zu 100% auslastet.
function pstail () { python -c 'import os
last=set(os.listdir("/proc")) ; o=x=""
while True:
pids=set(os.listdir("/proc"))
new=pids.difference(last);last=pids
for n in new:
try: o,x=x,[j for j in open("/proc/"+n+"/cmdline")
.read().split(chr(0)) if j]
except IOError: pass
if x and not o==x: print n,x' ; }
pstail
Sie können auch patchen execsnoop
, um genauer zu sagen, welches Argument welches ist:grep -v sub.*arg < execsnoop > n && chmod +x n && mv n execsnoop
CONFIG_FTRACE
und CONFIG_KPROBES
durchbrendangregg/perf-tools
git clone https://github.com/brendangregg/perf-tools.git
cd perf-tools
git checkout 98d42a2a1493d2d1c651a5c396e015d4f082eb20
sudo ./execsnoop
Auf einer anderen Shell:
while true; do sleep 1; date; done
Erste Shell zeigt Daten des Formats:
Tracing exec()s. Ctrl-C to end.
Instrumenting sys_execve
PID PPID ARGS
20109 4336 date
20110 4336 sleep 1
20111 4336 date
20112 4336 sleep 1
20113 4336 date
20114 4336 sleep 1
20115 4336 date
20116 4336 sleep 1
CONFIG_PROC_EVENTS
Beispielsitzung:
$ su
# ./proc_events &
# /proc_events.out &
set mcast listen ok
# sleep 2 & sleep 1 &
fork: parent tid=48 pid=48 -> child tid=56 pid=56
fork: parent tid=48 pid=48 -> child tid=57 pid=57
exec: tid=57 pid=57
exec: tid=56 pid=56
exit: tid=57 pid=57 exit_code=0
exit: tid=56 pid=56 exit_code=0
CONFIG_PROC_EVENTS
Legt die Ereignisse über einen Netlink-Socket für das Benutzerland offen .
proc_events.c angepasst von: https://bewareofgeek.livejournal.com/2945.html
#define _XOPEN_SOURCE 700
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/connector.h>
#include <linux/cn_proc.h>
#include <signal.h>
#include <errno.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
static volatile bool need_exit = false;
static int nl_connect()
{
int rc;
int nl_sock;
struct sockaddr_nl sa_nl;
nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
if (nl_sock == -1) {
perror("socket");
return -1;
}
sa_nl.nl_family = AF_NETLINK;
sa_nl.nl_groups = CN_IDX_PROC;
sa_nl.nl_pid = getpid();
rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
if (rc == -1) {
perror("bind");
close(nl_sock);
return -1;
}
return nl_sock;
}
static int set_proc_ev_listen(int nl_sock, bool enable)
{
int rc;
struct __attribute__ ((aligned(NLMSG_ALIGNTO))) {
struct nlmsghdr nl_hdr;
struct __attribute__ ((__packed__)) {
struct cn_msg cn_msg;
enum proc_cn_mcast_op cn_mcast;
};
} nlcn_msg;
memset(&nlcn_msg, 0, sizeof(nlcn_msg));
nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg);
nlcn_msg.nl_hdr.nlmsg_pid = getpid();
nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE;
nlcn_msg.cn_msg.id.idx = CN_IDX_PROC;
nlcn_msg.cn_msg.id.val = CN_VAL_PROC;
nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op);
nlcn_msg.cn_mcast = enable ? PROC_CN_MCAST_LISTEN : PROC_CN_MCAST_IGNORE;
rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
if (rc == -1) {
perror("netlink send");
return -1;
}
return 0;
}
static int handle_proc_ev(int nl_sock)
{
int rc;
struct __attribute__ ((aligned(NLMSG_ALIGNTO))) {
struct nlmsghdr nl_hdr;
struct __attribute__ ((__packed__)) {
struct cn_msg cn_msg;
struct proc_event proc_ev;
};
} nlcn_msg;
while (!need_exit) {
rc = recv(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
if (rc == 0) {
/* shutdown? */
return 0;
} else if (rc == -1) {
if (errno == EINTR) continue;
perror("netlink recv");
return -1;
}
switch (nlcn_msg.proc_ev.what) {
case PROC_EVENT_NONE:
printf("set mcast listen ok\n");
break;
case PROC_EVENT_FORK:
printf("fork: parent tid=%d pid=%d -> child tid=%d pid=%d\n",
nlcn_msg.proc_ev.event_data.fork.parent_pid,
nlcn_msg.proc_ev.event_data.fork.parent_tgid,
nlcn_msg.proc_ev.event_data.fork.child_pid,
nlcn_msg.proc_ev.event_data.fork.child_tgid);
break;
case PROC_EVENT_EXEC:
printf("exec: tid=%d pid=%d\n",
nlcn_msg.proc_ev.event_data.exec.process_pid,
nlcn_msg.proc_ev.event_data.exec.process_tgid);
break;
case PROC_EVENT_UID:
printf("uid change: tid=%d pid=%d from %d to %d\n",
nlcn_msg.proc_ev.event_data.id.process_pid,
nlcn_msg.proc_ev.event_data.id.process_tgid,
nlcn_msg.proc_ev.event_data.id.r.ruid,
nlcn_msg.proc_ev.event_data.id.e.euid);
break;
case PROC_EVENT_GID:
printf("gid change: tid=%d pid=%d from %d to %d\n",
nlcn_msg.proc_ev.event_data.id.process_pid,
nlcn_msg.proc_ev.event_data.id.process_tgid,
nlcn_msg.proc_ev.event_data.id.r.rgid,
nlcn_msg.proc_ev.event_data.id.e.egid);
break;
case PROC_EVENT_EXIT:
printf("exit: tid=%d pid=%d exit_code=%d\n",
nlcn_msg.proc_ev.event_data.exit.process_pid,
nlcn_msg.proc_ev.event_data.exit.process_tgid,
nlcn_msg.proc_ev.event_data.exit.exit_code);
break;
default:
printf("unhandled proc event\n");
break;
}
}
return 0;
}
static void on_sigint(__attribute__ ((unused)) int unused)
{
need_exit = true;
}
int main()
{
int nl_sock;
int rc = EXIT_SUCCESS;
signal(SIGINT, &on_sigint);
siginterrupt(SIGINT, true);
nl_sock = nl_connect();
if (nl_sock == -1)
exit(EXIT_FAILURE);
rc = set_proc_ev_listen(nl_sock, true);
if (rc == -1) {
rc = EXIT_FAILURE;
goto out;
}
rc = handle_proc_ev(nl_sock);
if (rc == -1) {
rc = EXIT_FAILURE;
goto out;
}
set_proc_ev_listen(nl_sock, false);
out:
close(nl_sock);
exit(rc);
}
Ich glaube jedoch nicht, dass Sie Prozessdaten wie UID und Prozessargumente abrufen können, da diese exec_proc_event
so wenig Daten enthalten: https://github.com/torvalds/linux/blob/v4.16/include/uapi/linux/cn_proc .h # L80 Wir könnten versuchen, es sofort zu lesen /proc
, aber es besteht die Gefahr, dass der Prozess beendet wird und ein anderer seine PID erhält, so dass es nicht zuverlässig ist.
Getestet in Ubuntu 17.10.
Sie können versuchen, cat ~/.bash_history
Es gibt system log viewer
, das kann Ihnen helfen.
~/.bash_history
enthält nur Befehle, die ich anscheinend in einem Terminal ausgeführt habe. Ich suche nach einem Protokoll aller ausgeführten Programme, z. B. wenn ich auf ein Symbol klicke, um meinen E-Mail-Client oder gedit zu öffnen, oder wenn ich meinen Browser öffne und mein Browser selbst einen anderen Prozess ausführt. Die Antwort von new123456 hat es geschafft.
history
die übliche Art ist, auf diese Informationen zuzugreifen.
The audit system is disabled
Wo kann ich sie aktivieren?