리눅스 시스템 기초 · 입문편 — 본문의 "N편"은 입문 과정 번호다. 번호별 글과 전체 250편 구성은 통합 로드맵에서 확인할 수 있다.
리눅스 시스템 기초 32 / 50 · Part 4. 프로세스·서비스·리소스
실습 환경: Rocky Linux 9 (10.0.0.200)
이전 글: 31. Linux 프로세스 이해
31편에서 프로세스의 정보(PID, PPID, 상태, 실행 계정)와 상태 전이를 정리했다. 이번 글은 그 정보를 뽑아내는 가장 기본적인 도구 ps를 다룬다.
ps는 옵션 체계가 독특해서 처음 배울 때 헷갈린다. ps aux와 ps -ef는 둘 다 "전체 프로세스 보기"인데 보여주는 컬럼이 다르다. 관제에서는 두 형식을 구분해서 읽을 줄 알아야 하고, 무엇보다 -o 옵션으로 헌팅에 필요한 컬럼만 골라 출력 할 줄 알아야 한다.
이번 글에서 답할 질문:
ps aux와 ps -ef는 무엇이 다른가?| 형식 | 예 | 특징 |
|---|---|---|
| BSD 형식 | ps aux | 옵션 앞에 -가 없다. %CPU, %MEM, RSS, STAT |
| UNIX(POSIX) 형식 | ps -ef | -로 시작. PPID 가 있고 --forest 트리 가능 |
| 맞춤 형식 | ps -eo pid,ppid,user,args | 원하는 컬럼만, 스크립트·헌팅용 |
ps -aux처럼 섞어 쓰면 경고가 나거나 다르게 해석될 수 있으므로, ps aux 또는 ps -ef로 명확히 쓴다.
| 컬럼 | 의미 | 관제 포인트 |
|---|---|---|
USER / UID | 실행 계정 (EUID) | 웹 계정(apache)이 쉘을 실행 중이면 의심 |
PID / PPID | 프로세스 / 부모 번호 | 부모-자식 관계 (35편) |
%CPU | CPU 사용률 | 지속적으로 높으면 채굴 가능성 |
%MEM | 메모리 사용률 | 메모리 고갈 |
VSZ | 가상 메모리 크기 (KB) | 예약한 주소 공간 전체 |
RSS | 실제 사용 중인 물리 메모리 (KB) | 커널 스레드는 0 (4편) |
TTY | 연결된 터미널 | ? = 터미널 없음(데몬), pts/N = 원격 세션 |
STAT | 상태 + 보조 문자 | 31편 |
START / STIME | 시작 시각 | 로그인 시각과 비교 |
TIME | 누적 CPU 사용 시간 | 오래 켜져 있지 않은데 TIME이 크면 CPU 집약 |
COMMAND / CMD / args | 실행 인자 | 위장 가능 (4·29편) |
comm | 실행 파일 이름 (최대 15자) | args와 다르면 위장 의심 |
| 키워드 | 의미 |
|---|---|
etime / etimes | 실행 경과 시간 (형식 / 초) |
lstart | 정확한 시작 시각 (날짜 포함) |
nlwp | 스레드 수 |
ruser / euser | 실제 / 유효 사용자 (SUID 확인, 16편) |
cgroup | 소속 cgroup (어떤 systemd 서비스인지, 36편) |
label | SELinux 컨텍스트 (47편) |

ps는 스스로 정보를 만들어 내지 않는다. /proc/<PID>/ 아래의 파일(stat, status, cmdline)을 읽어서 보기 좋게 정리할 뿐이다. 그래서:
ps의 COMMAND는 /proc/PID/cmdline에서 온다 → 프로세스가 스스로 바꿀 수 있다.ps가 조작되었거나(7편 명령어 교체), 프리로드 루트킷(9편)이 있으면 ps 결과를 믿을 수 없다. 이때는 /proc을 직접 읽거나 SIEM에 이미 수집된 정보를 본다.ps는 실행한 순간의 스냅샷 이다. 계속 변하는 상태는 top(33편)으로 본다.# 1) 두 형식 비교
ps aux | head -5
ps -ef | head -5
# 2) 부모-자식 트리
ps -ef --forest | less
ps -eo pid,ppid,user,args --forest | grep -A3 httpd
# 3) 헌팅용 맞춤 출력 — CPU 순
ps -eo pid,ppid,user,etimes,stat,%cpu,rss,tty,args --sort=-%cpu | head
# 4) 메모리 순
ps -eo pid,user,rss,%mem,comm --sort=-rss | head
# 5) 특정 조건
ps -u apache -o pid,ppid,etime,args # 계정
ps -C sshd -o pid,etime,args # 이름
ps --ppid "$(pgrep -o httpd)" -o pid,user,args # 특정 부모의 자식
# 6) comm과 args 비교 — 위장 탐지
ps -eo pid,comm,args | awk '{c=$2; a=$3; sub(".*/","",a); if (c!=a && a!~/^\[/) print}' | head
# 7) 터미널이 붙은(대화형) 프로세스
ps -eo pid,user,tty,args | awk '$3 ~ /pts/'
아래 출력은 형식 설명용 예시다.
① ps -eo pid,ppid,user,etimes,stat,%cpu,rss,tty,args --sort=-%cpu
PID PPID USER ETIMES STAT %CPU RSS TT COMMAND
7811 1 apache 512 Rl 98.7 24180 ? /tmp/.x/sysd -o pool.example:3333
945 1 root 86400 Ss 0.1 12040 ? /usr/sbin/httpd -DFOREGROUND
2310 2309 roror 1200 Ss 0.0 5120 pts/0 -bash
| 줄 | 판단 근거 |
|---|---|
| 7811 | apache 계정 · PPID 1(고아) · 512초 전 시작 · CPU 98.7% · /tmp 실행 · 채굴 풀 주소 형태 인자 → 채굴 악성코드 의심 |
| 945 | root가 시작한 httpd 부모 프로세스 · 하루째 실행 · 정상 |
| 2310 | 관리자의 SSH 세션(pts/0) · 정상 |
etimes=512초면 약 8분 30초 전에 시작 한 것이다. 이 시각을 로그인 로그·웹 로그와 대조하면 어떤 행위 직후 실행됐는지 알 수 있다.
② TTY 컬럼
| 값 | 의미 | 판단 |
|---|---|---|
? | 제어 터미널 없음 | 데몬·서비스는 정상 |
pts/0 | SSH·터미널 세션 | 누가 대화형으로 쓰고 있는지 |
웹 계정 + pts | 웹 계정이 터미널을 가짐 | 대화형 쉘 획득 의심 |
| 공격 흔적 | ps에서 보이는 모습 | 확인 컬럼 |
|---|---|---|
| 채굴 악성코드 | 높은 %CPU, 많은 nlwp, 풀 주소 인자 | %cpu,nlwp,args |
| 웹셸 명령 실행 | apache가 sh, bash, curl 실행 | user,ppid,args + --forest |
| 권한 상승 흔적 | ruser와 euser가 다름 (SUID 실행) | ruser,euser,args |
| 이름 위장 | comm과 args의 프로그램 이름이 다름 | comm,args |
| 백그라운드 잔류 | PPID 1, 사용자 계정 | ppid,user |
| 최근 실행 | 로그인 직후의 작은 etimes | etimes,lstart |
# 웹 계정이 실행한 쉘·다운로드 도구
ps -eo pid,ppid,user,args | awk '$3 ~ /^(apache|nginx|www-data)$/ && $4 ~ /(sh|bash|curl|wget|python|perl|nc)$/'
# SUID로 권한이 바뀐 채 실행 중인 프로세스
ps -eo pid,ruser,euser,args | awk 'NR==1 || $2!=$3'
# 최근 10분 이내 시작된 프로세스
ps -eo pid,user,etimes,args --sort=etimes | awk 'NR==1 || $3<600'
[Alert] 서버 CPU 사용률 95% 이상 지속 (모니터링)
↓
[ps] --sort=-%cpu → apache 계정, /tmp/.x/sysd, PPID 1, etimes 512
↓
[IOC] 실행 경로, 인자의 채굴 풀 주소, 해시(29편 /proc/PID/exe 복사)
↓
[역추적] 512초 전 = 02:31 → access_log 의 같은 시각 요청 (25편)
↓
[판단] 웹 취약점 → apache 권한 코드 실행 → 채굴기 설치
↓
[Response] kill -STOP → 증적 → 풀 주소 차단 → 웹 취약점 조치 → kill (34편)
ps aux(BSD)는 자원 사용률, ps -ef(UNIX)는 PPID와 트리를 보기 좋다.ps -eo pid,ppid,user,etimes,stat,%cpu,rss,tty,args 처럼 필요한 컬럼만 고른다.RSS는 실제 메모리, TTY ?는 데몬, pts/N은 원격 세션이다.etimes로 시작 시각을 계산해 로그와 대조한다.ps는 /proc을 읽는 스냅샷 도구다. COMMAND는 위장 가능하고, ps 자체가 변조될 수도 있다.ruser≠euser는 SUID 실행, comm≠args는 이름 위장 신호다.다음 글 「33. top으로 시스템 리소스 확인」 에서는 스냅샷인 ps와 달리 실시간으로 변하는 상태 를 보는 top을 다룬다. 상단 요약 영역(load average, CPU 항목 us·sy·wa·st, 메모리)의 의미와, 채굴 악성코드처럼 자원을 잠식하는 프로세스를 찾는 방법을 정리한다.