【安全】Linux利用chkrootkit檢測RootKit木馬、后門等

  • 內容
  • 相關
Rootkit是一種特殊的惡意軟件,它的功能是在安裝目標上隱藏自身及指定的文件、進程和網絡鏈接等信息,比較多見到的是Rootkit一般都和木馬、后門等其他惡意程序結合使用。Rootkit一詞更多地是指被作為驅動程序,加載到操作系統內核中的惡意軟件。
chkrootkit簡介
chkrootkit是一個linux下檢RootKit的腳本,在某些檢測中會調用當前目錄的檢測程序
官網:http://www.chkrootkit.org/
下載源碼:ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz
解壓后執行 make 命令,就可以使用了
一般直接運行,一旦有INFECTED,說明可能被植入了RootKit
./chkrootkit | grep INFECTED
總體流程
首先刪除別名,確保接下來的一些操作不會用了被RootKit改變了的別名
### workaround for some Bourne shell implementations
unalias login > /dev/null 2>&1
unalias ls > /dev/null 2>&1
unalias netstat > /dev/null 2>&1
unalias ps > /dev/null 2>&1
unalias dirname > /dev/null 2>&1
一開始會檢測一些必要的命令是否可用,可執行,因為檢測基于這些命令
cmdlist="
awk
cut
echo
egrep
find
head
id
ls
netstat
ps
sed
ssh
strings
uname
"
接下來就是檢測ps的參數ax好不好使,好使就使用ax,不好使就用-fe
# Check if ps command is ok
if ${ps} ax >/dev/null 2>&1 ; then
ps_cmd="ax"
else
ps_cmd="-fe"
fi
當然還需檢測你是否是root,就根據你的id號是否為0
if [ `${id} | ${cut} -d= -f2 | ${cut} -d\( -f1` -ne 0 ]; then
echo "$0 need root privileges"
exit 1
fi
接下來就是默認執行所有測試,當然你也可以指定測試的命令
if [ $# -gt 0 ]
then
### perform only tests supplied as arguments
for arg in $*
do
### check if is a valid test name
if echo "${TROJAN} ${TOOLS}"| \
${egrep} -v "${L_REGEXP}$arg${R_REGEXP}" > /dev/null 2>&1
then
echo >&2 "$0: \`$arg': not a known test"
exit 1
fi
done
LIST=$*
else
### this is the default: perform all tests
LIST="${TROJAN} ${TOOLS}"
fi
接下來只是對是否開啟調試模式,用戶是否指定了要檢測的根目錄進行處理
if [ "${DEBUG}" = "t" ]; then
set -x
fi
if [ "${ROOTDIR}" != "/" ]; then
### remove trailing `/'
ROOTDIR=`echo ${ROOTDIR} | ${sed} -e 's/\/*$//g'`
for dir in ${pth}
do
if echo ${dir} | ${egrep} '^/' > /dev/null 2>&1
then
newpth="${newpth} ${ROOTDIR}${dir}"
else
newpth="${newpth} ${ROOTDIR}/${dir}"
fi
done
pth=${newpth}
ROOTDIR="${ROOTDIR}/"
fi
最后便是循環調用各個check函數進行處理了
for cmd in ${LIST}
do
if echo "${TROJAN}" | \
${egrep} "${L_REGEXP}$cmd${R_REGEXP}" > /dev/null 2>&1
then
if [ "${EXPERT}" != "t" -a "${QUIET}" != "t" ]; then
printn "Checking \`${cmd}'... "
fi
chk_${cmd}
STATUS=$?
### quiet mode
if [ "${QUIET}" = "t" ]; then
### show only INFECTED status
if [ ${STATUS} -eq 0 ]; then
echo "Checking \`${cmd}'... INFECTED"
fi
continue
fi
case $STATUS in
0) echo "INFECTED";;
1) echo "not infected";;
2) echo "not tested";;
3) echo "not found";;
4) echo "infected but disabled";;
5) ;; ### expert mode
esac
else
### external tool
if [ "${EXPERT}" != "t" -a "${QUIET}" != "t" ]; then
printn "Checking \`$cmd'... "
fi
${cmd}
fi
done
那么接下來每個check方法到底是怎么檢測的呢?接下來
檢測方法
通過分析腳本,總結出檢測方法如下:
搜索通用的ROOTKIT特征的字符串
對某種特定的rootkits,或者命令的特殊的感染特征進行檢測
對某種特定的rootkits的生成的特定文件的檢測
對程序的SUID位的設置進行檢測
對ldsopreload的檢測
查找可疑的log文件
查找可疑的php文件
檢測.history文件
檢測有無程序監聽了一些可疑的端口
檢測Linux可加載內核模塊
檢測有無隱藏進程
檢測目錄的軟鏈接異常
檢測網絡接口的異常
檢測用戶的登錄日志
檢測上一次登錄
檢測可疑的沒有tty記錄的進程
下面對上面這些方法結合腳本代碼進行簡單說明
搜索通用的ROOTKIT特征的字符串
搜索的是下面的比較通用的ROOTKIT字符串
# Many trojaned commands have this label
GENERIC_ROOTKIT_LABEL="^/bin/.*sh$|bash|elite$|vejeta|\.ark|iroffer"
可以看到前兩個都是shell相關的,相關的示例代碼如下:
chk_chfn () {
STATUS=${NOT_INFECTED}
CMD=`loc chfn chfn $pth`
[ ${?} -ne 0 ] && return ${NOT_FOUND}
if [ "${EXPERT}" = "t" ]; then
expertmode_output "${strings} -a ${CMD}"
return 5
fi
case "${SYSTEM}" in
Linux)
if ${strings} -a ${CMD} | ${egrep} "${GENERIC_ROOTKIT_LABEL}" \
>/dev/null 2>&1
then
STATUS=${INFECTED}
fi;;
FreeBSD)
[ `echo $V | ${awk} '{ if ( $1 >= 5.0) print 1; else print 0 }'` -eq 1 ] && n=1 || n=2
if [ `${strings} -a ${CMD} | \
${egrep} -c "${GENERIC_ROOTKIT_LABEL}"` -ne $n ]
then
STATUS=${INFECTED}
fi;;
esac
return ${STATUS}
}
程序針對Linux和FreeBSD系統分開處理,都是通過strings獲取二進制程序中的字符串,再使用egrep命令去正則匹配,匹配成功就將返回值STATUS設置為INFECTED這個常量(這個在文件開頭處定義了)
對某種特定的rootkits,或者命令的特殊的感染特征進行檢測
比如這個amd命令的某個感染特征
chk_amd () {
STATUS=${NOT_INFECTED}
AMD_INFECTED_LABEL="blah"
CMD=`loc amd amd $pth`
if [ ! -x "${CMD}" ]; then
return ${NOT_FOUND}
fi
if [ "${EXPERT}" = "t" ]; then
expertmode_output "${strings} -a ${CMD}"
return 5
fi
if ${strings} -a ${CMD} | ${egrep} "${AMD_INFECTED_LABEL}" >/dev/null 2>&1
then
STATUS=${INFECTED}
fi
return ${STATUS}
}
下面這個檢測crontab的nobody用戶,并且定時任務中有數字的, 可能是Lupper.Worm
當然還是有CRONTAB_I_L這個特殊的檢測
chk_crontab () {
STATUS=${NOT_INFECTED}
CRONTAB_I_L="crontab.*666"
CMD=`loc crontab crontab $pth`
if [ ! -r ${CMD} ]
then
return ${NOT_FOUND}
fi
if [ "${EXPERT}" = "t" ]; then
expertmode_output "${CMD} -l -u nobody"
return 5
fi
# slackware's crontab have a bug
if ( ${CMD} -l -u nobody | $egrep [0-9] ) >/dev/null 2>&1 ; then
${echo} "Warning: crontab for nobody found, possible Lupper.Worm... "
if ${CMD} -l -u nobody 2>/dev/null | ${egrep} $CRONTAB_I_L >/dev/null 2>&1
then
STATUS=${INFECTED}
fi
fi
return ${STATUS}
}
對Ramen Worm進行特征匹配
if ${egrep} "^asp" ${ROOTDIR}etc/inetd.conf >/dev/null 2>&1; then
echo "Warning: Possible Ramen Worm installed in inetd.conf"
STATUS=${INFECTED}
fi
對某種特定的rootkits生成的特定文件的檢測
如下面的HiDrootkit和t0rn
### HiDrootkit
if [ "${QUIET}" != "t" ]; then printn \
"Searching for HiDrootkit's default dir... "; fi
if [ -d ${ROOTDIR}var/lib/games/.k ]
then
echo "Possible HiDrootkit installed"
else
if [ "${QUIET}" != "t" ]; then echo "nothing found"; fi
fi
### t0rn
if [ "${QUIET}" != "t" ]; then printn\
"Searching for t0rn's default files and dirs... "; fi
if [ -f ${ROOTDIR}etc/ttyhash -o -f ${ROOTDIR}sbin/xlogin -o \
-d ${ROOTDIR}usr/src/.puta -o -r ${ROOTDIR}lib/ldlib.tk -o \
-d ${ROOTDIR}usr/info/.t0rn ]
then
echo "Possible t0rn rootkit installed"
else
if [ "${QUIET}" != "t" ]; then echo "nothing found"; fi
fi
對程序的SUID位的設置進行檢測
chk_basename () {
STATUS=${NOT_INFECTED}
CMD=`loc basename basename $pth`
if [ "${EXPERT}" = "t" ]; then
expertmode_output "${strings} -a ${CMD}"
expertmode_output "${ls} -l ${CMD}"
return 5
fi
if ${strings} -a ${CMD} | ${egrep} "${GENERIC_ROOTKIT_LABEL}" > /dev/null 2>&1
then
STATUS=${INFECTED}
fi
[ "$SYSTEM" != "OSF1" ] &&
{
if ${ls} -l ${CMD} | ${egrep} "^...s" > /dev/null 2>&1
then
STATUS=${INFECTED}
fi
}
return ${STATUS}
}
這個除了檢測有無關鍵字,還檢測SUID位有無設置
對ldsopreload的檢測
chk_ldsopreload() {
STATUS=${NOT_INFECTED}
CMD="${ROOTDIR}lib/libshow.so ${ROOTDIR}lib/libproc.a"
if [ "${SYSTEM}" = "Linux" ]
then
if [ ! -x ./strings-static ]; then
printn "can't exec ./strings-static, "
return ${NOT_TESTED}
fi
if [ "${EXPERT}" = "t" ]; then
expertmode_output "./strings-static -a ${CMD}"
return 5
fi
### strings must be a statically linked binary.
if ./strings-static -a ${CMD} > /dev/null 2>&1
then
STATUS=${INFECTED}
fi
else
STATUS=${NOT_TESTED}
fi
return ${STATUS}
}
檢測是否有libshow.so,libproc.a,有就說明感染了惡意so文件
可以看到為了保險起見,作者使用的是自己目錄下靜態編譯的strings進行檢測
查找可疑的log文件
例子如下:
files=`${find} ${ROOTDIR}dev ${ROOTDIR}tmp ${ROOTDIR}lib ${ROOTDIR}etc ${ROOTDIR}var \
${findargs} \( -name "tcp.log" -o -name ".linux-sniff" -o -name "sniff-l0g" -o -name "core_" \) \
2>/dev/null`
if [ "${files}" = "" ]
then
if [ "${QUIET}" != "t" ]; then echo "nothing found"; fi
else
echo
echo ${files}
fi
查找可疑的php文件
查找一些可疑的php文件
###
### Suspect PHP files
###
if [ "${QUIET}" != "t" ]; then
printn "Searching for suspect PHP files... "; fi
files="`${find} ${ROOTDIR}tmp ${ROOTDIR}var/tmp ${findargs} -name '*.php' 2> /dev/null`"
if [ `echo abc | head -n 1` = "abc" ]; then
fileshead="`${find} ${ROOTDIR}tmp ${ROOTDIR}var/tmp ${findargs} -type f -exec head -n 1 {} \; | $egrep '#!.*php' 2> /dev/null`"
else
fileshead="`${find} ${ROOTDIR}tmp ${ROOTDIR}var/tmp ${findargs} -type f -exec head -1 {} \; | grep '#!.*php' 2> /dev/null`"
fi
if [ "${files}" = "" -a "${fileshead}" = "" ]; then
if [ "${QUIET}" != "t" ]; then echo "nothing found"; fi
else
echo
echo "${files}"
echo "${fileshead}"
fi
檢測.history文件
看看history有沒有被清空了,或者軟連接到其他地方了
if [ "${QUIET}" != "t" ]; then \
printn "Searching for anomalies in shell history files... "; fi
files=""
if [ ! -z "${SHELL}" -a ! -z "${HOME}" ]; then
files=`${find} ${ROOTDIR}${HOME} ${findargs} -name '.*history' -size 0`
[ ! -z "${files}" ] && \
echo "Warning: \`${files}' file size is zero"
files1=`${find} ${ROOTDIR}${HOME} ${findargs} -name '.*history' \( -links 2 -o -type l \)`
[ ! -z "${files1}" ] && \
echo "Warning: \`${files1}' is linked to another file"
fi
if [ -z "${files}" -a -z "${files1}" ]; then
if [ "${QUIET}" != "t" ]; then echo "nothing found"; fi
fi
檢測有無程序監聽了一些可疑的端口
檢測代碼如下:
bindshell () {
PORT="114|145|465|511|600|1008|1524|1999|1978|2881|3049|3133|3879|4000|4369|5190|5665|6667|10008|12321|23132|27374|29364|30999|31336|31337|37998|45454|47017|47889|60001|7222"
OPT="-an"
PI=""
if [ "${ROOTDIR}" != "/" ]; then
echo "not tested"
return ${NOT_TESTED}
fi
if [ "${EXPERT}" = "t" ]; then
expertmode_output "${netstat} ${OPT}"
return 5
fi
for P in `echo $PORT | ${sed} 's/|/ /g'`; do
if ${netstat} "${OPT}" | ${egrep} "^tcp.*LIST|^udp" | ${egrep} \
"[.:]${P}[^0-9.:]" >/dev/null 2>&1
then
PI="${PI} ${P}"
fi
done
if [ "${PI}" != "" ]
then
echo "INFECTED PORTS: ($PI)"
else
if [ "${QUIET}" != "t" ]; then echo "not infected"; fi
fi
}
檢測Linux可加載內核模塊
lkm ()
{
prog=""
if [ \( "${SYSTEM}" = "Linux" -o \( "${SYSTEM}" = "FreeBSD" -a \
`echo ${V} | ${awk} '{ if ($1 > 4.3 || $1 < 6.0) print 1; else print 0 }'` -eq 1 \) \) -a "${ROOTDIR}" = "/" ]; then
[ -x ./chkproc -a "`find /proc | wc -l`" -gt 1 ] && prog="./chkproc"
[ -x ./chkdirs ] && prog="$prog ./chkdirs"
if [ "$prog" = "" ]; then
echo "not tested: can't exec $prog"
return ${NOT_TESTED}
fi
if [ "${EXPERT}" = "t" ]; then
[ -r /proc/$KALLSYMS ] && ${egrep} -i "adore|sebek" < /proc/$KALLSYMS 2>/dev/null
[ -d /proc/knark ] && ${ls} -la /proc/knark 2> /dev/null
PV=`$ps -V 2>/dev/null| $cut -d " " -f 3 |${awk} -F . '{ print $1 "." $2 $3 }' | ${awk} '{ if ($0 > 3.19) print 3; else if ($0 < 2.015) print 1; else print 2 }'`
[ "$PV" = "" ] && PV=2
[ "${SYSTEM}" = "SunOS" ] && PV=0
expertmode_output "./chkproc -v -v -p $PV"
return 5
fi
### adore LKM
[ -r /proc/$KALLSYMS ] && \
if `${egrep} -i adore < /proc/$KALLSYMS >/dev/null 2>&1`; then
echo "Warning: Adore LKM installed"
fi
### sebek LKM (Adore based)
[ -r /proc/$KALLSYMS ] && \
if `${egrep} -i sebek < /proc/$KALLSYMS >/dev/null 2>&1`; then
echo "Warning: Sebek LKM installed"
fi
### knark LKM
if [ -d /proc/knark ]; then
echo "Warning: Knark LKM installed"
fi
PV=`$ps -V 2>/dev/null| $cut -d " " -f 3 |${awk} -F . '{ print $1 "." $2 $3 }' | ${awk} '{ if ($0 > 3.19) print 3; else if ($0 < 2.11) print 1; else print 2 }'`
[ "$PV" = "" ] && PV=2
[ "${SYSTEM}" = "SunOS" ] && PV=0
if [ "${DEBUG}" = "t" ]; then
${echo} "*** PV=$PV ***"
fi
if ./chkproc -p ${PV}; then
if [ "${QUIET}" != "t" ]; then echo "chkproc: nothing detected"; fi
else
echo "chkproc: Warning: Possible LKM Trojan installed"
fi
dirs="/tmp"
for i in /usr/share /usr/bin /usr/sbin /lib; do
[ -d $i ] && dirs="$dirs $i"
done
if ./chkdirs $dirs; then
if [ "${QUIET}" != "t" ]; then echo "chkdirs: nothing detected"; fi
else
echo "chkdirs: Warning: Possible LKM Trojan installed"
fi
else
if [ "${QUIET}" != "t" ]; then echo "chkproc: not tested"; fi
fi
}
loadable kernel module (LKM),這個是檢測內核模塊的 ,看看有無adore,sebek這些內核模塊
之后調用chkproc,chkdirs進行檢測,這兩個下面檢測有無隱藏進程,會說到
檢測有無隱藏進程
這個代碼在chkproc.c中,它通過暴力遞歸,看看有沒有/proc目錄存在,而ps查不出來的進程,那么就說明有進程隱藏了
/* Brute force */
strcpy(buf, "/proc/");
retps = retdir = 0;
for (i = FIRST_PROCESS; i <= MAX_PROCESSES; i++)
{
// snprintf(&buf[6], 6, "%d", i);
snprintf(&buf[6], 8, "%d", i);
if (!chdir(buf))
{
if (!dirproc[i] && !psproc[i])
{
#if defined(__linux__)
if (!isathread[i]) {
#endif
retdir++;
if (verbose)
printf ("PID %5d(%s): not in readdir output\n", i, buf);
#if defined(__linux__)
}
#endif
}
if (!psproc[i] ) /* && !kill(i, 0)) */
{
#if defined(__linux__)
if(!isathread[i]) {
#endif
retps++;
if (verbose)
printf ("PID %5d: not in ps output\n", i);
#if defined(__linux__)
}
#endif
}
檢測目錄的軟鏈接異常
chkdirs比較的是父目錄的軟鏈接數和子目錄的個數
正常情況下,父目錄的軟鏈接數 = 子目錄的個數 + 2
if (!linkcount) {
if (lstat(".", &statinfo)) {
fprintf(stderr, "lstat(%s): %s\n", fullpath, strerror(errno));
goto abort;
}
linkcount = statinfo.st_nlink; //獲取符號鏈接數
}
if (!(dirhandle = opendir("."))) {
fprintf(stderr, "opendir(%s): %s\n", fullpath, strerror(errno));
goto abort;
}
numdirs = 0;
dl = (struct dirinfolist *)NULL;
while ((finfo = readdir(dirhandle))) {
if (!strcmp(finfo->d_name, ".") || !strcmp(finfo->d_name, ".."))
continue;
if (lstat(finfo->d_name, &statinfo)) {
fprintf(stderr, "lstat(%s/%s): %s\n",
fullpath, finfo->d_name, strerror(errno));
closedir(dirhandle);
goto abort;
}
if (S_ISDIR(statinfo.st_mode)) { //判斷是否是目錄
numdirs++;
if (norecurse) continue; /* just count subdirs if "-n" */
/* Otherwise, keep a list of all directories found that have link
count > 2 (indicating directory contains subdirectories). We'll
call check_dir() on each of these subdirectories in a moment...
*/
if (statinfo.st_nlink > 2) {
dptr = dl;
if (!(dl = (struct dirinfolist *)malloc(sizeof(struct dirinfolist)))) {
fprintf(stderr, "malloc() failed: %s\n", strerror(errno));
norecurse = 1;
while (dptr) {
dl = dptr->dil_next;
free((void *)dptr);
dptr = dl;
}
continue;
}
strncpy(dl->dil_name, finfo->d_name, sizeof(dl->dil_name));
dl->dil_lc = statinfo.st_nlink;
dl->dil_next = dptr;
}
}
}
closedir(dirhandle);
/* Parent directory link count had better equal #subdirs+2... */
diff = linkcount - numdirs - 2; //
if (diff) printf("%d\t%s\n", diff, fullpath);
檢測網絡接口的異常
sniffer () {
if [ "${ROOTDIR}" != "/" ]; then
echo "not tested"
return ${NOT_TESTED}
fi
if [ "$SYSTEM" = "SunOS" ]; then
return ${NOT_TESTED}
fi
if [ "${EXPERT}" = "t" ]; then
expertmode_output "./ifpromisc" -v
return 5
fi
if [ ! -x ./ifpromisc ]; then
echo "not tested: can't exec ./ifpromisc"
return ${NOT_TESTED}
else
[ "${QUIET}" != "t" ] && ./ifpromisc -v || ./ifpromisc -q
fi
}
這個是對網絡接口的檢測,看看有無開啟網卡混雜模式(英語:promiscuous mode)
而PF_PACKET可以操作鏈路層的數據,可以讀取和發送鏈路層的數據包
./ifpromisc -v
ens3: PF_PACKET(/sbin/dhclient)
virbr0: not promisc and no PF_PACKET sockets
docker0: not promisc and no PF_PACKET sockets
br-47a3d838588a: not promisc and no PF_PACKET sockets
檢測用戶的登錄日志
檢測用戶的登錄相關的log文件
SunOS使用的是check_wtmpx,比較的文件是/var/adm/wtmp,/var/adm/wtmpx,check_wtmpx部分代碼,比較這兩個文件的一些差異,比如下面的比較uid
if ( memcmp( utmp_entry.ut_id, utmpx_entry.ut_id, 4 ) != 0 )
{
fprintf( stderr, "[ %u ] utmp_entry.ut_id != utmpx_entry.ut_id\n", wtmp_read_counter );
break;
}
其他linux檢測的是var/log/wtmp或者var/adm/wtmp
chkwtmp部分代碼,查看有無刪除了登錄時間
gettimeofday(&mytime, &dummy);
act_time=mytime.tv_sec;
wtmpfile[127]='\0';
memcpy(wtmpfile, WTMP_FILENAME, 127);
if ( argc == 3 && !memcmp("-f", argv[1], 2) && *argv[2])
memcpy(wtmpfile, argv[2], 127);
if ((filehandle=open(wtmpfile,O_RDONLY)) < 0) {
fprintf(stderr, "unable to open wtmp-file %s\n", wtmpfile);
return(2);
}
while (read (filehandle, (char *) &utmp_ent, sizeof (struct utmp)) > 0) {
if (utmp_ent.ut_time == 0)
del_counter++;
else {
if (del_counter) {
printit(del_counter, start_time,
utmp_ent.ut_time);
t_del++;
del_counter=0;
}
start_time=utmp_ent.ut_time;
}
}
close(filehandle);
if (del_counter)
printit(del_counter, start_time, act_time);
exit((int) t_del+del_counter);
檢測上一次登錄
使用chklastlog程序檢測,下面是部分代碼,用戶的數據通過getpwent函數獲取,其實就是通過/etc/passwd獲取,檢測基于兩點
1、通過比較MAX_ID,與當前的遍歷的用戶的id,看看id是否大于環境變量MAX_ID
2、看看是否有這樣的情況:用戶名出現在lastlog,wtmp文件中,而在/etc/passwd中沒有的
if ( !nonuser(utmp_ent) && strncmp(utmp_ent.ut_line, "ftp", 3) &&
(uid=localgetpwnam(localpwd,utmp_ent.ut_name)) != NULL )
{
if (*uid > MAX_ID)
{
fprintf(stderr, "MAX_ID is %ld and current uid is %ld, please check\n\r", MAX_ID, *uid );
exit (1);
}
if (!userid[*uid])
{
lseek(fh_lastlog, (long)*uid * sizeof (struct lastlog), 0);
if ((wtmp_bytes_read = read(fh_lastlog, &lastlog_ent, sizeof (struct lastlog))) > 0)
{
if (wtmp_bytes_read < sizeof(struct lastlog))
{
fprintf(stderr, "lastlog entry may be corrupted");
break;
}
if (lastlog_ent.ll_time == 0)
{
if (-1 != (slot = getslot(localpwd, *uid)))
printf("user %s deleted or never logged from lastlog!\n",
NULL != localpwd->uname[slot] ?
(char*)localpwd->uname[slot] : "(null)");
else
printf("deleted user uid(%d) not in passwd\n", *uid);
++status;
}
userid[*uid]=TRUE;
}
}
}
}
檢測可疑的沒有tty記錄的進程
檢測的是/var/run/utmp或者/var/adm/utmpx,方法是比較的是ps命令與/var/run/utmp文件之間的差別
y = fetchps(ps_l);
z = fetchutmp(ut_l);
hdr_prntd = 0;
for (h = 0; h < y; h++) { /* loop through 'ps' data */
mtch_fnd = 0;
for (i = 0; i < z; i++) { /* try and match the tty from 'ps' to one in utmp */
if (ut_l[i].ut_type == LOGIN_PROCESS /* ignore getty processes with matching pid from 'ps' */
&& ut_l[i].ut_pid == ps_l[h].ps_pid)
{
mtch_fnd = 1;
break;
}
else if (strncmp(ps_l[h].ps_tty, ut_l[i].ut_tty, /* compare the tty's */
strlen(ps_l[h].ps_tty)) == 0)
{
mtch_fnd = 1;
break;
}
}
if (!mtch_fnd) {
if (!hdr_prntd) {
printf
(" The tty of the following user process(es) were not found\n");
printf(" in %s !\n", UTMP);
printf("! %-9s %7s %-6s %s\n", "RUID", "PID", "TTY",
"CMD");
hdr_prntd = 1;
}
printf("! %-9s %7d %-6s %s", ps_l[h].ps_user,
ps_l[h].ps_pid, ps_l[h].ps_tty, ps_l[h].ps_args);
}
比如下面的檢測結果,而我的/var/run/utmp中是沒有tty7這個tty的記錄的
Checking `chkutmp'... The tty of the following user process(es) were not found
in /var/run/utmp !
! RUID PID TTY CMD
! root 1076 tty7 /usr/lib/xorg/Xorg -core :0 -seat seat0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch

本文標簽:

版權聲明:若無特殊注明,本文皆為《Jerome》原創,轉載請保留文章出處。

本文鏈接:【安全】Linux利用chkrootkit檢測RootKit木馬、后門等 - http://www.vnshangna.cn/post-406.html

發表評論

電子郵箱不會被公開。昵稱為必填。

未顯示?請點擊刷新

允許郵件通知
广东11选5合买