두 줄 코드는 프로세스가 top에 표시되는 것을 숨깁니다

9386 단어
오늘 상해에 비교적 일찍 도착해서 가태선 버스를 타서 몇 십 위안을 절약하고 택시비를 탔으니 기쁘다!
두 줄의 코드는 무엇을 할 수 있습니까?프로세스가 top에 표시되는 것을 숨길 수 있지만, 프로세스가 top에 표시되는 것도 숨길 수 있습니다.만약 굳이 말대꾸를 해야 한다면,perf는 폭로할 수 있고,trace는 폭로할 수 있다.... 그것은 분명히 내가 말하고자 하는 점에 get이 없다.
CPU를 순환적으로 소모하는 프로그램을 작성합니다.
int main()
{
	while (1) {}
}

그런 다음 그것을 실행하고 top:
top - 18:06:34 up 19:13,  4 users,  load average: 0.22, 0.06, 0.06
Tasks:  90 total,   3 running,  87 sleeping,   0 stopped,   0 zombie
%Cpu(s): 99.5 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.5 si,  0.0 st
KiB Mem :  1016860 total,    69464 free,   482116 used,   465280 buff/cache
KiB Swap:  2097148 total,  2055368 free,    41780 used.   317840 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
18351 root      20   0    4212    352    280 R 99.9  0.0   0:15.21 a.out
18345 root      20   0  161892   2160   1564 R  0.3  0.2   0:00.01 top
    1 root      20   0   51684   1928   1192 S  0.0  0.2   0:07.87 systemd
    2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd
    3 root      20   0       0      0      0 S  0.0  0.0   0:00.53 ksoftirqd/0

a.out의 CPU 활용도에 유의하십시오.
그렇다면 어떻게 가장 간단한 방법으로 그것을 숨길까요?간단합니다.
#!/usr/bin/stap -g

global pid;

probe kernel.function("account_process_tick")
{
	if (pid() == pid) {
		@cast($p, "struct task_struct")->signal->prev_cputime->utime = 0x3fffffffffffffff;
		@cast($p, "struct task_struct")->signal->prev_cputime->stime = 0x3fffffffffffffff;
		exit();
	}
}

probe begin
{
	pid = $1
}

a.out의pid18351을 매개 변수로 실행하고 다시 top:
top - 18:11:33 up 19:18,  4 users,  load average: 1.18, 0.76, 0.36
Tasks:  88 total,   3 running,  85 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1016860 total,   286132 free,   283276 used,   447452 buff/cache
KiB Swap:  2097148 total,  2055280 free,    41868 used.   515244 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
    1 root      20   0   51684   1924   1192 S  0.0  0.2   0:07.92 systemd
    2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd
    3 root      20   0       0      0      0 S  0.0  0.0   0:00.54 ksoftirqd/0
    7 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 migration/0

하하, 없어졌어!
그러나 토탈 usage는 아직 있지만 두 줄 코드가 할 수 있는 것도 그저 그렇다. 코드가 많으면 토탈 usage를 계속 숨길 수 있고 심지어perf 이벤트도 약탈할 수 있다.
내가 말하는 그 두 줄의 코드는 바로 다음과 같다.
@cast($p, "struct task_struct")->signal->prev_cputime->utime = 0x3fffffffffffffff;
@cast($p, "struct task_struct")->signal->prev_cputime->stime = 0x3fffffffffffffff;

왜 그랬을까?
모든 시계가 끊기면, 인터럽트 프로세서가 현재 프로세스의 상태를 판단하고, 이전 시계 주기를current의utime나stime에 기장합니다.
top 명령이 프로세스의 CPU 시간을 가져올 때 cputimeadjust:
static void cputime_adjust(struct task_cputime *curr,
               struct cputime *prev,
               cputime_t *ut, cputime_t *st)
{
    cputime_t rtime, stime, utime;

    /*
     * Tick based cputime accounting depend on random scheduling
     * timeslices of a task to be interrupted or not by the timer.
     * Depending on these circumstances, the number of these interrupts
     * may be over or under-optimistic, matching the real user and system
     * cputime with a variable precision.
     *
     * Fix this by scaling these tick based values against the total
     * runtime accounted by the CFS scheduler.
     */
    rtime = nsecs_to_cputime(curr->sum_exec_runtime);

    /*
     * Update userspace visible utime/stime values only if actual execution
     * time is bigger than already exported. Note that can happen, that we
     * provided bigger values due to scaling inaccuracy on big numbers.
     */
    if (prev->stime + prev->utime >= rtime)
        goto out;
    ...

그 goto out에 주의하세요. 저는 주석을 보고 알았어요. 그래서 이 Trick은 이 조건을 이용했어요.모든 타임은 u64의 유형이고 단위는 나초이다. 즉, 1초에 흐르는 타임 영화는 1000100010001000개이다. 그러나 u64가 표시할 수 있는 숫자는 18446744073709551615이고 대체적으로 10000000000초의 양급이다. 약 317년이다.
즉, 300여 년이 지나야 u64가 돌아갈 수 있기 때문에 저는 prev의 stime와utime의 합을 충분하게 설정하면 OK입니다. 바로 위의 두 줄 코드입니다.
이런 수법은 단번에 잡혀서 놀 수밖에 없어요. 제가 앞에 쓴 Rootkit 수법은 깊이 연구할 수 있어요.
닭똥도 남기지 않고 손으로 때려 정제육구!
절강성 온주는 구두가 젖어서 비가 오면 물에 들어가도 살이 찌지 않는다.

좋은 웹페이지 즐겨찾기