cpu占用100%,top和ps无法查看进程

/etc/ld.so.preload 设置了隐藏进程

[root@ecs-5611 ~]# lsattr /etc/ld.so.preload
----ia--------e----- /etc/ld.so.preload

[root@ecs-5611 ~]# chattr -i -a /etc/ld.so.preload
-bash: /usr/bin/chattr: 权限不够

[root@ecs-5611 ~]# cat /etc/ld.so.preload
/usr/local/lib/uncompress.so

[root@ecs-5611 ~]# lsattr /usr/local/lib/uncompress.so
----ia--------e----- /usr/local/lib/uncompress.so

cp /usr/bin/chmod /usr/bin/chmod2
chmod2 755 /usr/bin/chmod

cp /usr/bin/ /usr/bin/chattr2
chmod 777 /usr/bin/chattr2
chattr2 -i -a /usr/bin/chattr
chmod 755 /usr/bin/chattr
ls -la /usr/bin/chattr
lsattr /usr/bin/chattr

发现chattr2 不能修改,原来的chattr被破坏了
需要重新编译charrt
1. 下载源码:https://github.com/posborne/linux-programming-interface-exercises/blob/master/15-file-attributes/chattr.c
2. 编译,cc chattr,得到文件a.out,把名字改成chattr

[root@ecs-5611 ~]# vi chattr.c
[root@ecs-5611 ~]# cc chattr.c

[root@ecs-5611 ~]# mv a.out chattr

[root@ecs-5611 ~]# ./chattr -i /usr/bin/chattr
cur attrs: 0x00080030, mask: 0x00000010
new attrs: 0x00080020
[root@ecs-5611 ~]# ./chattr -a /usr/bin/chattr
cur attrs: 0x00080020, mask: 0x00000020
new attrs: 0x00080000

[root@ecs-5611 ~]# rm /usr/bin/chattr -rf
[root@ecs-5611 ~]# cp ./chattr /usr/bin/
[root@ecs-5611 ~]#

[root@ecs-5611 ~]#
[root@ecs-5611 ~]# chattr -i /etc/ld.so.preload
cur attrs: 0x00080030, mask: 0x00000010
new attrs: 0x00080020
[root@ecs-5611 ~]# chattr -a /etc/ld.so.preload
cur attrs: 0x00080020, mask: 0x00000020
new attrs: 0x00080000

# 清空文件内容
[root@ecs-5611 ~]# vi /etc/ld.so.preload

# 隐藏进程出现了
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3593504 root 20 0 1258816 270976 3968 S 386.1 1.7 956:16.68 daemon
3593904 root 20 0 1258752 8704 3456 S 194.4 0.1 508:00.48 daemon
3593764 root 20 0 1258752 8960 3712 S 192.7 0.1 508:00.52 daemon


[root@ecs-5611 ~]# find / -name daemon
/var/lib/docker/containerd/daemon
find: ‘/proc/3575193’: 没有那个文件或目录
find: ‘/proc/3819946’: 没有那个文件或目录
find: ‘/proc/3839127’: 没有那个文件或目录
find: ‘/proc/3839173’: 没有那个文件或目录
find: ‘/proc/3839174’: 没有那个文件或目录
find: ‘/proc/3839176’: 没有那个文件或目录
find: ‘/proc/3839213’: 没有那个文件或目录
find: ‘/proc/3839214’: 没有那个文件或目录
find: ‘/proc/3839215’: 没有那个文件或目录
find: ‘/proc/3839216’: 没有那个文件或目录
/usr/bin/daemon
/usr/lib/python3.7/site-packages/tuned/daemon
/run/docker/containerd/daemon
/home/docker-data/containerd/daemon
/data/docker-data/docker/containerd/daemon
[root@ecs-5611 ~]#

# 查看属性
[root@ecs-5611 ~]# lsattr /usr/bin/daemon
----ia--------e----- /usr/bin/daemon

# 去掉属性
# 不能两个一起减
[root@ecs-5611 ~]# chattr -i -a /usr/bin/daemon
ERROR: Unable to get flags on -a, skipping
cur attrs: 0x00080030, mask: 0x00000010
new attrs: 0x00080020
[root@ecs-5611 ~]# chattr -a /usr/bin/daemon
cur attrs: 0x00080020, mask: 0x00000020
new attrs: 0x00080000
[root@ecs-5611 ~]# lsattr /usr/bin/daemon
--------------e----- /usr/bin/daemon
[root@ecs-5611 ~]#

# 删除文件
[root@ecs-5611 ~]# rm -rf /usr/bin/daemon

# 删除进程
[root@ecs-5611 ~]# kill -9 3593504 3593904 3593764

# 这个不知道是什么
[root@ecs-5611 ~]# rm -rf /usr/local/lib/uncompress.so


chattr源码

#include <fcntl.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/fs.h>

#define ACTION_ADD '+'
#define ACTION_REMOVE '-'
#define ACTION_ONLY '='

#define ATTRS_LIST "acdeijstuADT"
#define ATTR_APPEND_ONLY 'a'
#define ATTR_COMPRESSED 'c'
#define ATTR_NO_DUMP 'd'
#define ATTR_EXTENT_FORMAT 'e'
#define ATTR_IMMUTABLE 'i'
#define ATTR_JOURNALLING 'j'
#define ATTR_SECURE_DELETE 's'
#define ATTR_NO_TAIL_MERGE 't'
#define ATTR_UNDELETABLE 'u'
#define ATTR_NO_ATIME_UPDATES 'A'
#define ATTR_SYNCHRONOUS_DIR_UPDATES 'D'
#define ATTR_TOP_OF_DIRECTORY_HIERARCHY 'T'

#define LIST_LENGTH(x) ((sizeof(x) / sizeof(x[0])))

struct attr_table_entry {
char code;
int fs_flag;
};

static struct attr_table_entry fs_attrs[] = {
{ATTR_APPEND_ONLY, FS_APPEND_FL},
{ATTR_COMPRESSED, FS_COMPR_FL},
{ATTR_NO_DUMP, FS_NODUMP_FL},
{ATTR_EXTENT_FORMAT, FS_EXTENT_FL},
{ATTR_IMMUTABLE, FS_IMMUTABLE_FL},
{ATTR_JOURNALLING, FS_JOURNAL_DATA_FL},
{ATTR_SECURE_DELETE, FS_SECRM_FL},
{ATTR_NO_TAIL_MERGE, FS_NOTAIL_FL},
{ATTR_UNDELETABLE, FS_UNRM_FL},
{ATTR_NO_ATIME_UPDATES, FS_NOATIME_FL},
{ATTR_SYNCHRONOUS_DIR_UPDATES, FS_DIRSYNC_FL},
{ATTR_TOP_OF_DIRECTORY_HIERARCHY, FS_TOPDIR_FL},
};


static void
print_usage()
{
fprintf(stderr, "Usage: ./prog_chattr [mode] files\n");
exit(EXIT_FAILURE);
}


static struct attr_table_entry*
lookup_attr_table_entry(char attr)
{
struct attr_table_entry *entry;
unsigned long i;
for (i = 0; i < LIST_LENGTH(fs_attrs); i++) {
entry = &fs_attrs[i];
if (entry->code == attr) {
return entry;
}
}
return NULL;
}


static bool
is_valid_attr(char attr)
{
char c;
int i = 0;
while ((c = ATTRS_LIST[i++]) != '\0') {
if (c == attr) {
return true;
}
}
return false;
}


static void
validate_mode_string(char *mode_string) {
int len;
char attr;
int i;
len = strlen(mode_string);
if (len < 2) {
fprintf(stderr, "ERROR: Invalid mode string specified (too short)\n");
print_usage();
}
i = 1;
while ((attr = mode_string[i++]) != '\0') {
if (!is_valid_attr(attr)) {
fprintf(stderr, "ERROR: Attribute '%c' is invalid\n", attr);
print_usage();
}
}
}


static int
get_mask_for_attrs(char *attrs)
{
int mask;
int i;
char attr;
struct attr_table_entry *entry;

i = 0;
mask = 0;
while ((attr = attrs[i++]) != '\0') {
entry = lookup_attr_table_entry(attr);
if (entry == NULL) {
/* we should have already validated */
fprintf(stderr, "ERROR: Invalid Attr '%c'\n", attr);
exit(EXIT_FAILURE);
}
mask |= (entry->fs_flag);
}
return mask;
}


static int
transform_attrs_add(int attrs, int mask)
{
return (attrs | mask);
}


static int
transform_attrs_remove(int attrs, int mask)
{
/*
* To ensure that the new attrs does not have any of the bits
* from mask set, we take the inverse of the mask and and it
* with the current attrs
*/
int reversed_mask;
int new_attrs;
reversed_mask = ~mask;
new_attrs = (attrs & reversed_mask);
return new_attrs;
}


static int
transform_attrs_only(int attrs, int mask)
{
return mask; /* In this case, just use the mask */
}


static int
do_action(char *attrs, int file_count, char **files, int(*transform_attrs)(int, int))
{
int mask;
int i;
size_t fd;
char *filename;
int current_attrs;
int new_attrs;

/* get mask for our attributes */
mask = get_mask_for_attrs(attrs);

/* Do the update on each file */
for (i = 0; i < file_count; i++) {
filename = files[i];
fd = open(filename, 0);
if (fd < 0) {
fprintf(stderr, "ERROR: Unable to open %s, skipping\n", filename);
continue;
}

/* Get the current flags */
if (ioctl(fd, FS_IOC_GETFLAGS, &current_attrs) == -1) {
fprintf(stderr, "ERROR: Unable to get flags on %s, skipping\n", filename);
goto cleanup;
}
printf("cur attrs: 0x%08x, mask: 0x%08X\n", current_attrs, mask);
new_attrs = transform_attrs(current_attrs, mask); /* enable all flags in mask */
printf("new attrs: 0x%08X\n", new_attrs);
if (ioctl(fd, FS_IOC_SETFLAGS, &new_attrs) == -1) {
fprintf(stderr, "ERROR: Unable to set flags on %s, skipping\n", filename);
}
cleanup:
close(fd);
}
return 0;
}


int main(int argc, char **argv)
{
int file_count = 0;
char *mode_string;
char *attrs;
char action;
if (argc < 3) {
print_usage();
}
mode_string = argv[1];
file_count = argc - 2;
validate_mode_string(mode_string);
action = mode_string[0];
attrs = &mode_string[1];
switch (action) {
case ACTION_ADD:
return do_action(attrs, file_count, &argv[2], transform_attrs_add);
break;
case ACTION_REMOVE:
return do_action(attrs, file_count, &argv[2], transform_attrs_remove);
break;
case ACTION_ONLY:
return do_action(attrs, file_count, &argv[2], transform_attrs_only);
break;
}
return 0;
}


1