입력 검증 및 코드 무결성 시연

CompTIABeginner
지금 연습하기

소개

이 실습에서는 두 가지 기본적인 보안 개념인 입력 유효성 검사 (input validation) 와 코드 무결성 (code integrity) 을 탐구합니다. 입력 유효성 검사는 프로그램이 처리하기 전에 프로그램이 받는 모든 입력이 안전하고 올바르게 형식화되었는지 확인하는 관행입니다. 이는 명령 주입 (command injection) 을 포함한 광범위한 공격에 대한 중요한 방어 수단입니다. 코드 무결성은 애플리케이션 코드가 승인되지 않은 당사자에 의해 변경되거나 손상되지 않았는지 확인하는 것을 포함합니다.

실습을 통해 이러한 개념을 배우게 됩니다. 먼저, 의도적으로 명령 주입에 취약한 간단한 쉘 스크립트 (shell script) 를 생성합니다. 다음으로, 이 취약점을 악용하여 위험을 이해합니다. 그런 다음, 적절한 입력 정제 (input sanitization) 를 구현하여 스크립트를 안전하게 만듭니다. 마지막으로, 스크립트의 무결성을 확인하기 위해 암호화 해시 (cryptographic hashes) 를 사용하는 방법을 배워 스크립트가 변조되지 않았는지 확인합니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 98%입니다.학습자들로부터 97%의 긍정적인 리뷰율을 받았습니다.

사용자 입력을 포함한 간단한 스크립트 생성

이 단계에서는 사용자에게 파일 이름을 묻고 ls -l 명령을 사용하여 해당 파일에 대한 자세한 정보를 표시하는 간단한 Bash 스크립트를 생성합니다. 이 초기 버전의 스크립트에는 보안 검사가 없습니다.

먼저 nano 편집기를 사용하여 ~/project 디렉토리에 check_file.sh라는 새 파일을 생성합니다.

nano ~/project/check_file.sh

이제 파일에 다음 코드를 추가합니다. 이 스크립트는 파일 이름을 묻고, 입력을 filename이라는 변수로 읽어온 다음, eval 명령을 사용하여 해당 파일 이름에 대해 ls -l을 실행합니다. 사용자 입력과 함께 eval을 사용하는 것은 심각한 보안 취약점임을 유의하십시오.

#!/bin/bash

echo "Please enter a filename to check:"
read filename
echo "Checking details for: $filename"
eval "ls -l $filename"

Ctrl+X, Y, Enter를 눌러 파일을 저장하고 nano를 종료합니다.

다음으로, 스크립트를 실행할 수 있도록 실행 가능하게 만들어야 합니다. chmod 명령을 사용하여 실행 권한을 추가합니다.

chmod +x ~/project/check_file.sh

이제 스크립트를 실행하여 작동 방식을 살펴보겠습니다. 실습 환경에서 미리 생성된 testfile.txt를 사용합니다.

./check_file.sh

스크립트가 입력을 요청합니다. testfile.txt를 입력하고 Enter를 누릅니다.

Please enter a filename to check:
testfile.txt
Checking details for: testfile.txt
-rw-rw-r-- 1 labex labex 0 Aug  4 15:19 testfile.txt

사용자 입력을 받는 간단한 스크립트를 성공적으로 생성하고 실행했습니다. 다음 단계에서는 이 스크립트가 어떻게 악용될 수 있는지 살펴보겠습니다.

기본 명령 주입 공격 시뮬레이션

이 단계에서는 이전 단계에서 생성한 스크립트가 명령 주입 공격에 어떻게 취약한지 살펴보겠습니다. 명령 주입은 공격자가 취약한 애플리케이션을 통해 호스트 운영 체제에서 임의의 명령을 실행할 수 있을 때 발생합니다.

우리 스크립트는 eval을 사용하여 사용자 입력 ($filename) 을 포함하는 명령을 먼저 입력이 안전한지 확인하지 않고 실행하기 때문에 취약합니다. eval 명령은 전체 문자열을 실행할 명령으로 취급하므로 특히 위험합니다. 공격자는 추가 쉘 명령을 포함하는 입력을 제공하여 이를 악용할 수 있습니다.

스크립트를 다시 실행해 보겠습니다.

./check_file.sh

이번에는 파일 이름을 묻는 메시지가 표시될 때 다음 문자열을 입력합니다. 세미콜론 (;) 은 쉘에서 명령을 구분하는 특수 문자입니다.

testfile.txt; whoami

Enter를 누르면 다음과 같은 출력이 표시됩니다.

Please enter a filename to check:
testfile.txt; whoami
Checking details for: testfile.txt; whoami
-rw-rw-r-- 1 labex labex 0 Aug  4 15:19 testfile.txt
labex

어떤 일이 발생했는지 주목하십시오. 스크립트는 예상대로 먼저 ls -l testfile.txt를 실행했습니다. 그러나 세미콜론과 eval의 사용으로 인해 쉘은 두 번째 명령인 whoami를 실행했고, 이는 현재 사용자 이름 (labex) 을 출력했습니다. 이는 성공적인 명령 주입을 보여줍니다. eval 명령은 전체 입력을 실행 가능한 코드로 취급하여 이를 가능하게 했습니다. 공격자는 이 취약점을 사용하여 훨씬 더 위험한 명령을 실행할 수 있습니다.

참고: eval 없이 ls -l $filename을 사용한 경우 (원래 버전과 같이), 쉘은 testfile.txt; whoamils의 별도 인수로 취급하여 "'testfile.txt;'" 및 "'whoami'"에 액세스할 수 없음"과 같은 오류 메시지를 생성하므로 공격이 작동하지 않습니다. 이 예에서 명령 주입을 가능하게 하는 것은 eval 명령입니다.

입력값 검증 (Sanitization) 을 통한 주입 방지 구현

이 단계에서는 사용자 입력을 검증하고 위험한 eval 명령을 제거하여 명령 주입 공격을 방지하도록 스크립트를 수정합니다. 입력 검증은 잠재적으로 악의적인 문자를 제거하거나 중화하기 위해 입력을 정리하거나 필터링하는 프로세스입니다.

우리의 전략은 다음과 같습니다.

  1. 위험한 eval 명령을 제거하고 적절한 따옴표를 사용하여 직접 명령 실행 사용
  2. 입력 파일 이름에 허용된 문자만 포함되어 있는지 확인합니다. 일반적인 파일 이름의 경우 문자, 숫자, 밑줄, 하이픈 및 점과 같은 문자의 화이트리스트를 만들 수 있습니다. 세미콜론과 같은 다른 문자를 포함하는 모든 입력을 거부합니다.

nanocheck_file.sh 스크립트를 다시 엽니다.

nano ~/project/check_file.sh

정규 표현식을 사용하여 유효성 검사 검사를 포함하도록 스크립트를 수정합니다. 기존 내용을 다음 코드로 바꿉니다.

#!/bin/bash

echo "Please enter a filename to check:"
read filename

## Input sanitization: only allow alphanumeric characters, underscores, hyphens, and dots.
if [[ "$filename" =~ ^[a-zA-Z0-9_.-]+$ ]]; then
  echo "Checking details for: $filename"
  ls -l "$filename"
else
  echo "Error: Invalid filename. Malicious input detected."
fi

주요 변경 사항은 다음과 같습니다.

  1. 위험한 eval 명령 제거
  2. ls 명령에서 "$filename" 주위에 적절한 따옴표 추가
  3. 입력 유효성 검사가 포함된 if 문. [[ "$filename" =~ ^[a-zA-Z0-9_.-]+$ ]] 표현식은 filename 변수가 시작 (^) 부터 끝 ($) 까지 지정된 세트의 문자만 포함하는지 확인합니다.

Ctrl+X, Y, Enter를 눌러 변경 사항을 저장합니다.

이제 동일한 공격을 다시 시도해 보겠습니다. 스크립트를 실행합니다.

./check_file.sh

악의적인 입력 testfile.txt; whoami를 입력하고 Enter를 누릅니다.

Please enter a filename to check:
testfile.txt; whoami
Error: Invalid filename. Malicious input detected.

보시다시피 스크립트는 이제 잘못된 문자를 감지하고 악의적인 whoami 명령을 실행하는 대신 오류 메시지를 출력합니다. 공격이 성공적으로 방지되었습니다.

해싱 (Hashing) 을 통한 스크립트 무결성 검증

이 단계에서는 암호화 해시를 사용하여 스크립트의 무결성을 검증하는 방법을 배웁니다. 이를 통해 스크립트를 안전하게 보호한 후 공격자가 수정하거나 변조하지 않았음을 보장할 수 있습니다. SHA-256 해시를 계산하는 sha256sum 유틸리티를 사용할 것입니다.

먼저, 보안이 적용된 check_file.sh 스크립트의 해시를 생성하고 파일에 저장합니다. 이 파일은 "알려진 양호한" 서명 역할을 합니다.

sha256sum ~/project/check_file.sh > ~/project/check_file.sha256

이 명령은 check_file.sh의 SHA-256 해시를 계산하고 출력을 check_file.sha256이라는 새 파일로 리디렉션합니다. 이 파일의 내용을 살펴보겠습니다.

cat ~/project/check_file.sha256

파일 이름 뒤에 긴 문자열이 표시됩니다. 이 문자열은 스크립트의 고유한 해시입니다.

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  /home/labex/project/check_file.sh

(참고: 해시 값은 다를 수 있습니다.)

이제 무단 수정을 시뮬레이션해 보겠습니다. 스크립트 끝에 간단한 주석을 추가합니다. 이와 같은 작은 변경으로도 해시가 완전히 변경되어야 합니다.

echo "## A harmless comment" >> ~/project/check_file.sh

스크립트가 수정되었습니다. 무결성을 확인하기 위해 -c(check) 옵션과 함께 sha256sum을 사용할 수 있습니다. 이 옵션은 서명 파일에서 해시를 읽고 스크립트의 현재 해시와 비교합니다.

sha256sum -c ~/project/check_file.sha256

파일이 변경되었기 때문에 명령이 실패를 보고합니다.

/home/labex/project/check_file.sh: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match

이는 스크립트의 무결성이 손상되었음을 확인합니다. 이 기술은 실행 중인 코드가 신뢰하는 코드인지 확인하는 데 필수적입니다.

요약

이 실습을 완료하신 것을 축하드립니다! 두 가지 중요한 보안 원칙에 대한 실질적인 경험을 쌓으셨습니다.

입력 검증을 구현하여 명령 주입 취약점을 식별하고 방지하는 방법을 배웠습니다. 허용된 문자 화이트리스트에 대해 사용자 입력을 검증함으로써 취약한 쉘 스크립트를 성공적으로 보호했습니다.

또한 암호화 해시를 사용하여 코드 무결성을 보장하는 방법을 배웠습니다. 스크립트에 대한 SHA-256 체크섬을 생성하여 무단 수정을 감지할 수 있는 검증 가능한 서명을 만들 수 있었습니다.

이러한 기술은 안전한 코드를 작성하고 시스템 보안을 유지하는 데 필수적입니다.