422. 지속성·재침투 — systemd timer 지속성 탐지

changseop lee·2026년 10월 9일

시스템 보안 · 취약점

목록 보기
422/450

시스템 보안 · 취약점 › I. 지속성 · 재침투 징후 · 22/50편 (전체 422/450)
학습 단계: 스케줄·서비스·부팅 지속성 탐지
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.

선행 학습

1. 개념

systemd timer는 cron의 현대적 대체 수단입니다(T1053.006). .timer 유닛이 정한 주기에 맞춰 같은 이름의 .service를 실행합니다. cron만 점검하는 조직에서는 timer가 사각지대가 됩니다.

timer 지속성 구조
 update-check.timer   [Timer] OnBootSec=5min  OnUnitActiveSec=15min
        ↓ 주기마다 실행
 update-check.service [Service] ExecStart=/var/tmp/.u/run.sh
 활성화: systemctl enable --now update-check.timer
 사용자 timer: ~/.config/systemd/user/*.timer (root 불필요)

핵심: timer는 cron 로그에 남지 않는다 — list-timers와 journal로 본다

timer와 service는 쌍으로 동작하므로, 의심 timer를 발견하면 짝이 되는 service의 ExecStart까지 반드시 확인합니다.

2. 왜 중요한가

  • cron 중심 점검을 우회하는 주기 실행 수단입니다.
  • OnBootSec과 함께 쓰면 부팅 지속성과 주기 실행을 동시에 얻습니다.
  • 사용자 timer는 root 없이도 만들 수 있어 권한 상승 전 단계에서도 쓰입니다.

3. 핵심 명령어 / 설정

확인명령포인트
전체 timersystemctl list-timers --all신규 timer
사용자 timersystemctl --user -M <user>@ list-timers사용자 수준
쌍 확인systemctl cat <name>.timer <name>.serviceExecStart
실행 기록journalctl -u <name>.service주기 실행

4. 실습 (실습 예시)

# systemd timer 점검 (분석 방법)
systemctl list-timers --all --no-legend | awk '{print $(NF-1)}' | sort
for t in $(systemctl list-timers --all --no-legend | awk '{print $(NF-1)}'); do
  s=$(systemctl show -p Unit --value "$t")
  f=$(systemctl show -p FragmentPath --value "$s")
  rpm -qf "$f" >/dev/null 2>&1 || dpkg -S "$f" >/dev/null 2>&1 || echo "미소유: $t → $s ($f)"
done
sudo find /home /root -path '*systemd/user/*.timer' 2>/dev/null

5. 정상 상태

dnf-makecache.timer → dnf-makecache.service (dnf 소유)
logrotate.timer → logrotate.service (logrotate 소유)
미소유 timer: 없음

모든 timer와 짝 service가 패키지에 속하거나 승인된 배포이고, 사용자 timer가 없는 상태가 정상입니다.

6. 이상 상태

미소유: update-check.timer → update-check.service (/etc/systemd/system/update-check.service)
ExecStart=/var/tmp/.u/run.sh
journalctl: Started update-check.service (15분 간격 반복)
  • 패키지 미소유 timer + 숨김 경로 스크립트 → timer 지속성
  • 15분마다 반복 실행 → cron 로그 없이 주기 실행
  • 업데이트 확인처럼 보이는 이름 → 위장

7. 로그 분석 (분석 방법)

timer 지속성 분석 흐름입니다(가상의 예시).

[timer 목록] list-timers --all (시스템 + 사용자)
   ↓
[쌍 해석] timer → Unit= → service ExecStart
   ↓
[소유·경로] 패키지 소유 · 실행 파일 위치
   ↓
[실행 기록] journalctl -u (최초 실행 = 설치 시점 추정)
항목확인
OnBootSec부팅 후 실행
OnUnitActiveSec주기
Persistent놓친 실행 보충

Persistent=true가 있으면 서버가 꺼져 있던 동안 놓친 실행을 부팅 직후 보충하므로, 재부팅 직후 실행 기록도 확인해야 합니다.

8. SOC 관제 포인트

  • 지속성 점검 절차에서 cron과 timer를 항상 함께 봅니다.
  • 사용자 timer 디렉터리를 감시 대상에 포함합니다.
  • timer 실행 기록의 최초 시각을 설치 시점 추정에 씁니다.

9. 탐지 규칙

<!-- 실습 예시 룰: 적용 전 wazuh-logtest 및 테스트 환경 검증 필요 -->
<group name="local,syssec_i,persistence,">
  <rule id="108210" level="12">
    <if_sid>108000</if_sid>
    <field name="audit.key">persist_svc</field>
    <field name="audit.file.name" type="pcre2">systemd/(system|user)/.*\.timer$</field>
    <description>systemd timer 유닛 생성·수정(주기 실행 지속성 의심)</description>
    <mitre><id>T1053.006</id></mitre>
  </rule>
</group>

.timer 파일 생성은 패키지 설치 외에는 드물어 독립 룰로 경보합니다. 사용자 디렉터리(~/.config/systemd/user)도 감시 경로에 넣어야 탐지됩니다.

10. 대응 방법

  1. 초기 확인 — timer와 짝 service, 실행 파일을 확인합니다.
  2. 범위 확인 — 같은 실행 파일을 쓰는 다른 지속성(cron·서비스)을 확인합니다.
  3. 증거 확보 — 유닛 파일·스크립트·journal 실행 기록을 보존합니다.
  4. 차단/조치 — systemctl disable --now <timer> 후 timer·service·스크립트를 격리합니다.
  5. 재발 방지 — timer를 지속성 점검 표준 항목에 넣습니다.

11. 핵심 정리

항목확인
목록list-timers --all
쌍timer → service
사용자~/.config/systemd/user
기록journalctl -u
면접 포인트"timer는 cron 로그에 안 남는 cron — timer와 service를 쌍으로 본다"

12. 다음 편 예고

다음 편 423. 지속성·재침투 — systemd drop-in·generator 악용 탐지 에서는 정상 서비스에 drop-in override로 ExecStartPre를 끼워 넣거나 generator로 유닛을 동적 생성하는 은밀한 systemd 지속성을 탐지하는 방법을 다룹니다.


이전 편: 421. 지속성·재침투 — systemd 서비스 지속성 탐지
📚 시리즈 전체 보기: 시스템 보안 · 취약점

profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글