- 문제점
- 보안 이슈
위 글의 마지막 실습에 대한 문제에 대해 언급하려고 한다.
1. 문제점
read 명령어를 통해 사용자 입력을 전달할 때 디렉토리 경로에 대한 입력 중 '~' 이라는 문자는 허용되지 않는다.
input-exam3.sh
#!/bin/bash
#: Usage : input-exam.sh
#: Description : Save the file list of the entered directory to /tmp.
echo -n "Directory Name or Path : "
read -r dirName
# 디렉토리가 존재하는지 확인
if [ -d "$dirName" ]; then
ls -al "$dirName" > "/tmp/$(date +%Y%m%d).txt"
else
echo "Directory does not exist."
fi
이 문제를 해결하기 위해서 eval 명령어를 통해 틸드('~') 허용을 포함한 스크립트로 수정하면 위 문제가 해결된다.
input-exam4.sh
#!/bin/bash
#: Usage : input-exam.sh
#: Description : Save the file list of the entered directory to /tmp.
echo -n "Directory Name or Path : "
read -r dirName
# 틸드 확장을 수행
realDirName=$(eval echo "$dirName")
# 디렉토리가 존재하는지 확인
if [ -d "$realDirName" ]; then
ls -al "$realDirName" > "/tmp/$(date +%Y%m%d).txt"
echo "Complete!"
else
echo "Directory does not exist."
fi
2. 보안 이슈
성공적으로 실행했지만 여기서 끝난다면 내가 이 글을 쓴 이유가 없다.
여기서 진짜 문제점은 eval명령어의 보안 문제이다.
eval 명령어는 문자열의 특수한 기호의 원래의 의미로 해석하여 주는 명령이다.
eval 의 그러한 특성으로 인해 사용자의 입력을 받을 때 악의적인 입력에 대한 내용까지 해석을 해버리는 문제가 생긴다.
예시로 한번 알아보자.
# 스크립트 실행
input-exam4.sh
Directory Name or Path : ~/bin ; mkdir virus
Complete!
스크립트 작성자는 단순히 디렉토리의 경로만 입력하길 희망하여 eval 명령어를 사용했는데 도리어 입력이 악용되는 무시무시한 사례가 벌어졌다.
~/bin ; mkdir virus
위 입력에 ; mkdir virus가 추가되었는데 리눅스에서는 명령어 여러 개를 한 줄로 처리하고 싶을 때 ';' 사용한다.
eval명령어로 인해 세미콜론(;)까지 특별한 의미로 해석이 되어 다음 명령어까지 실행이 되는 것이다.
이를 코드 인젝션 공격이라고 한다.
이 취약점은 어마어마한 파장을 일으키게 된다.
만약 뒤에 명령어가 mkdir virus 가 아니라 rm -rf / 이라면?
한순간에 시스템은 작살이 날 것이다.
이러한 이유로 eval이라는 명령어는 사용에 주의를 요하며 권장되지 않는다고 한다.
eval is evil 이라는 말이 나올 정도로 프로그래밍이나 쉘 스크립트에서 보안에 취약한 명령어라고 할 수 있다.
Shell Script에서 이를 보완할 수 있는 방법이 없나 Chat GPT와 대화도 나눠봤지만 아직 해결 방법은 없는 것 같다.
Chat GPT가 2022년 1월 까지의 지식만 갖고 있어서 이후에 나온 신기술을 모르기 때문에 지금쯤이면 있을지도 모르겠다.
나도 Shell Script 를 처음 배우는 입장에서 명령어에 대한 문제점을 알지 못하는 상황이라 예전부터 있었던 보안 이슈라고 할지라도 이러한 부분을 간과하고 넘어가는 경우가 많으니 주의해야겠다는 생각이 든다.
에필로그 : 시도한 실험
#!/bin/bash
#: Usage : input-exam.sh
#: Description : Save the file list of the entered directory to /tmp.
echo -n "Directory Name or Path : "
read -r dirName
# 틸드 확장을 수행하고 절대 경로를 얻기 위해 readlink 사용
realDirName=$(readlink -m "$dirName")
echo "$realDirName"
# 디렉토리가 존재하는지 확인
if [ -d "$realDirName" ]; then
ls -al "$realDirName" > "/tmp/$(date +%Y%m%d).txt"
else
echo "Directory does not exist."
fi
성공조차 안됨.
#!/bin/bash
#: Usage : input-exam.sh
#: Description : Save the file list of the entered directory to /tmp.
read -p "Directory Name or Path (~ is allowed): " userInput
# 틸드 확장 수행
eval userInput="$userInput"
# 디렉토리가 존재하는지 확인하여 작업
if [ -d "$userInput" ]; then
ls -al "$userInput" > "/tmp/$(date +%Y%m%d).txt"
echo "File list saved to /tmp/$(date +%Y%m%d).txt"
else
echo "Error: Directory not found."
fi
코드 인젝션 매우 잘 됨.
'Shell Script' 카테고리의 다른 글
Shell Script 기초(7) (0) | 2023.11.28 |
---|---|
Shell Script 기초(6) (0) | 2023.11.27 |
Shell Script 기초(5) (0) | 2023.11.24 |
Shell Script 기초(4) (0) | 2023.11.24 |
Shell Script 기초(3) (0) | 2023.11.23 |