057. 계정 · 인증 보안 — sudo 사용 로그 분석 심화

changseop lee·6일 전

시스템 보안 · 취약점 › B. 계정 · 인증 보안 강화 · 7/50편 (전체 057/450)
학습 단계: 1단계 · 기본 개념
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.

선행 학습

1. 개념

056편이 "얼마나 많이" root를 쓰는지 봤다면, 이 편은 sudo 로그 한 줄을 "어떻게" 썼는지 읽는 방법입니다. sudo 로그는 네 개의 필드만으로 많은 맥락을 줍니다.

devops : TTY=pts/1 ; PWD=/home/devops ; USER=root ; COMMAND=/usr/bin/systemctl restart httpd
  │        │            │                 │            │
 실행자   터미널        작업 위치         대상 사용자   명령·인자
          pts/N = 대화형(SSH)          root 외면 -u 사용
          unknown = 터미널 없음 → 스크립트·웹 프로세스 경유 가능성
위험 등급명령 유형왜 위험한가
HIGH셸·인터프리터(bash, sh, python, perl)이후 명령이 sudo 로그에 안 남고 임의 코드 실행 가능
HIGH편집기·페이저(vi, less, more)프로그램 내부에서 셸 탈출 가능
MID권한 변경(chmod, chown) — /etc·/usr 대상권한 상승 준비(D영역)
MID계정·권한 조작(useradd, usermod, visudo)지속성·권한 확대
MID외부 통신(curl, wget) — 역할에 없을 때도구 반입 가능성
LOW서비스 조회·관리(systemctl status/restart)일반 운영

2. 왜 중요한가

  • 같은 "sudo 성공"이라도 systemctl status httpd와 인터프리터 실행은 위험도가 완전히 다릅니다. 명령을 분류하지 않으면 모든 sudo 로그가 같은 무게로 보입니다.
  • PWD가 /tmp·/dev/shm·웹 루트이면 정상 관리 작업보다 침해 후 작업일 가능성이 높습니다.
  • TTY=unknown은 사람이 직접 입력하지 않은 실행(스크립트·cron·웹 프로세스)이므로 실행 주체를 더 깊이 확인해야 합니다.

3. 핵심 명령어 / 설정

확인명령
사용자별 명령 빈도sudo grep ' devops : ' /var/log/secure | sed 's/.*COMMAND=//' | sort | uniq -c | sort -rn
고위험 명령 필터sudo grep -E 'COMMAND=\S*(bash|/sh|python|perl|vi|less|curl|wget|chmod|chown)( |$)' /var/log/secure
임시·웹 경로 작업sudo grep -E 'PWD=/(tmp|dev/shm|var/tmp|var/www)' /var/log/secure
터미널 없는 실행sudo grep 'TTY=unknown' /var/log/secure
다른 사용자로 실행sudo grep 'COMMAND=' /var/log/secure | grep -v 'USER=root'

4. 실습 (실습 예시)

LOG=/var/log/secure        # Ubuntu: /var/log/auth.log

# 1) sudo 성공 로그를 필드별로 분해해 표로 보기 (분석용, 실행 아님)
sudo grep 'COMMAND=' $LOG | \
  sed -E 's/.*sudo\[[0-9]+\]: +([^ ]+) : TTY=([^ ;]+) ; PWD=([^;]+) ; USER=([^ ;]+) ; COMMAND=(.*)/\1|\2|\3|\4|\5/' | \
  column -t -s'|' | tail -15

# 2) 명령 유형별 위험 등급 집계 (역할별로 기준 조정)
sudo grep 'COMMAND=' $LOG | awk -F'COMMAND=' '{c=$2; r="LOW";
  if (c ~ /(chmod|chown|useradd|usermod|visudo|passwd|curl|wget)/) r="MID";
  if (c ~ /(bash|\/sh|python|perl|vi |less |more )/) r="HIGH";
  print r}' | sort | uniq -c

분류 기준은 서버 역할에 따라 다릅니다. 배포 서버라면 curl이 정상 업무일 수 있으므로 역할별 허용 명령 목록을 함께 관리합니다.

5. 정상 상태

admin1 | pts/0 | /home/admin1 | root | /usr/bin/systemctl restart httpd
admin1 | pts/0 | /etc/httpd   | root | /usr/bin/vi /etc/httpd/conf.d/ssl.conf
admin1 | pts/0 | /home/admin1 | root | /usr/bin/dnf update -y
     72 LOW
     11 MID

관리자 계정이 대화형 터미널(pts)에서, 홈·설정 디렉터리 기준으로, 서비스 관리 명령 위주로 실행한 모습입니다. MID 항목(편집기·패치)은 변경관리 기록과 맞으면 정상입니다.

6. 이상 상태

devops | pts/1   | /tmp/.x       | root     | HIGH (인터프리터 실행)
devops | pts/1   | /tmp/.x       | root     | MID  (임시 경로 파일 chmod)
apache | unknown | /var/www/html | root     | HIGH (웹 프로세스 경유 셸)

(명령 원문 대신 위험 등급과 유형만 표기)

관찰판단
PWD=/tmp/.x 숨김 디렉터리에서 인터프리터·권한 변경침해 후 작업 공간
apache + TTY=unknown + 웹 루트서비스 계정이 사람 입력 없이 sudo 사용 → 웹 침해 연계 가능성
같은 세션에서 HIGH 명령 연속A영역 006편의 서비스 계정 sudo 백도어와 연결

보고서에는 명령 원문 대신 유형·대상 경로·위험 등급으로 기록하고, 원문이 필요하면 접근이 제한된 증거 보관소에만 둡니다.

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

sudo 로그와 auditd execve를 함께 보면 셸 진입 이후의 행위까지 이어집니다(가상의 예시 로그).

Oct  2 02:35:02 rocky9-web01 sudo[11801]:  apache : TTY=unknown ; PWD=/var/www/html ; USER=root ; COMMAND=/bin/bash -c ...
Oct  2 02:35:02 rocky9-web01 sudo[11801]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=48)
type=USER_CMD msg=audit(1759340102.004:3601): pid=11801 uid=apache auid=unset ses=unset msg='op=PAM:... acct=root cmd=... terminal=? res=success'
필드분석
by (uid=48)sudo를 호출한 실제 UID(apache) — 로그인 사용자 없음
TTY=unknown + auid=unset대화형 세션이 아님 → 웹·스크립트 경유
COMMAND=/bin/bash이후 명령은 sudo 로그에 안 남음 → I/O 로그·execve로 보완(A영역 007편)

명령 인자 원문은 분석에 필요한 범위에서만 다루고, 공개 기록에는 남기지 않습니다.

8. SOC 관제 포인트

  • sudo 성공 로그를 명령 유형·PWD·TTY 세 기준으로 등급화해 HIGH만 우선 확인합니다.
  • 서비스 계정의 sudo, TTY=unknown sudo는 등급과 무관하게 즉시 확인 대상입니다.
  • 셸·인터프리터 진입 이후는 sudo 로그가 비므로 auditd execve(ses 기준)로 이어 봅니다.

9. 탐지 규칙

<group name="local,syssec_b,privilege,">
  <rule id="101060" level="11">
    <if_sid>5402</if_sid>
    <regex type="pcre2">COMMAND=\S*/(bash|sh|python[0-9.]*|perl)( |$)</regex>
    <description>sudo를 통한 셸/인터프리터 실행</description>
  </rule>
  <rule id="101061" level="12">
    <if_sid>5402</if_sid>
    <regex type="pcre2">PWD=/(tmp|dev/shm|var/tmp)/|TTY=unknown ;</regex>
    <description>임시 경로 또는 터미널 없는 sudo 실행</description>
  </rule>
</group>

5402는 Wazuh의 "Successful sudo to ROOT" 기본 룰입니다. 운영에서 인터프리터 sudo가 정상인 서버(자동화 등)는 해당 호스트·계정을 좁게 예외 처리합니다(A영역 048편).

10. 대응 방법

  1. 초기 확인 — HIGH 등급 sudo의 실행자·대상 경로·TTY·세션을 확인합니다.
  2. 범위 확인 — 같은 세션의 이후 execve, 같은 계정의 다른 서버 sudo를 확인합니다.
  3. 증거 확보 — sudo 로그·audit 로그를 보존하고, 명령 원문은 접근 제한 저장소에만 둡니다.
  4. 차단/조치 — 비인가 세션 종료·sudo 권한 회수·관련 계정 조치를 진행합니다.
  5. 재발 방지 — 명령 등급화 기준과 서비스 계정 sudo·임시 경로 sudo 룰을 운영합니다.

11. 핵심 정리

필드분석 포인트
TTYpts(대화형) vs unknown(스크립트·웹 경유)
PWD임시·웹 경로면 침해 후 작업 의심
USERroot 외 사용자면 -u 사용
COMMAND셸·인터프리터·편집기 = HIGH
면접 포인트"sudo 셸 진입 이후는 로그가 비므로 execve로 이어 본다"

12. 다음 편 예고

다음 편 058. 계정 · 인증 보안 — su 사용 로그와 권한 전환 추적 에서는 권한 전환의 또 다른 경로인 su 사용 로그와 권한 전환 추적을 다룹니다.


이전 편: 056. 계정 · 인증 보안 — root 계정 사용 패턴 분석
📚 시리즈 전체 보기: 시스템 보안 · 취약점

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

0개의 댓글