상세 컨텐츠

본문 제목

DVWA : Command Injection - Low level

Vulnerability Assessment/Web Application

by DarkSoul.Story 2024. 12. 29. 17:31

본문

반응형
이 문서에 포함된 어떠한 내용도 불법적이거나 비윤리적인 목적으로 보안 도구나 방법론을 사용하도록 가르치거나 장려하지 않습니다. 항상 책임감 있는 태도로 행동하세요. 여기에 설명된 도구나 기법을 사용하기 전에 개인 테스트 환경 또는 허가를 받았는지 확인하세요.

 

[ 환경 ]

DVWA v1.9
Burp Suite Community Edition v2024.11.2

1. Overview

명령어 삽입 (Command Injection)은 사용자 입력값을 시스템 명령어로 전달하는 과정에서 발생하는 보안 취약점으로, 공격자가 시스템에 임의의 명령을 실행할 수 있게 한다. 이로 인해 데이터 유출, 시스템 장악, 서비스 중단 등 심각한 피해를 초래할 수 있다.

 

명령어 삽입은 애플리케이션이 사용자 입력값을 시스템 명령어에 직접 포함하여 실행할 때 발생한다. 개발자가 입력값 검증을 충분히 하지 않거나, 시스템 명령어와 사용자 입력값의 경계를 분리하지 못할 때 공격자가 이를 악용할 수 있다. 

 

명령어 삽입 취약점이 발생하는 어떻게 발생하는지 이해하기 전에 운영 체제 셸에서 명령어가 실행되는 기본 원리를 이해해 보겠다. [그림 1]을 보면 두 개 이상의 두 개 이상의 명령을 동시에 실행할 때마다 &&, ||, ;, 등을 사용한다는 것을 알 수 있다. 따라서 두 개 이상의 OS 명령이 있는 경우 왼쪽에서 오른쪽으로 순서대로 실행된다. 또한 시퀀스의 명령이 실패해도 다른 명령의 실행이 중단되지 않다. 이 명령어의 연결 기능은 웹 애플리케이션에서 제대로 구현되지 않은 경우 주로 OS 명령 인젝션의 원인이 된다.

[그림 1] 명령어 실행

 

명령어 삽입 (Command Injection) 예제

ㅁ 기본 예제 : 쉘 명령어 호출

# 취약한 코드
import os
user_input = input("파일명을 입력하세요: ")  # 사용자 입력
os.system(f"cat {user_input}")  # 입력값을 시스템 명령에 삽입
  • 사용자가 file.txt 대신 file.txt; rm -rf /를 입력하면, 명령어 cat file.txt와 함께 rm -rf /이 실행된다. 결과적으로 시스템이 손상될 수 있다.

ㅁ 웹 애플리케이션에서의 예제

// PHP 취약 코드
$ip = $_GET['ip'];  // 사용자 입력
exec("ping $ip");   // 입력값을 시스템 명령에 포함
  • 공격자가 URL에 http://example.com?ip=127.0.0.1; ls를 입력하면, ping 명령과 함께 ls 명령이 실행된다. 이는 서버에 저장된 민감한 파일 리스트가 노출될 수 있음을 의미한다.

ㅁ 명령어 삽입 (Command Injection) 취약점 발생 원인

입력값 검증 부족

  • 사용자 입력값이 명령어의 인자로 사용되면서, 입력값에 포함된 악성 명령어가 그대로 실행된다.

취약한 명령어 실행 로직

  • 애플리케이션에서 운영 체제 명령어를 실행할 때, 사용자 입력값을 동적으로 구성하여 실행하는 경우

보안 경계 분리 실패

  • 애플리케이션과 운영 체제 간의 신뢰 경계를 적절히 분리하지 못하여 입력값이 명령어 실행에 영향을 미친다.

외부 입력값 사용

  • 파일 이름, URL, HTTP 요청 파라미터 등 외부로 부터 입력받은 데이터를 검증 없이 시스템 명령어로 전달

ㅁ 명령어 삽입 (Command Injection) 공격 시나리오

기본 명령어 확장

  • 명령어에 추가적인 명령을 연결하여 악성 코드를 실행
  • 예: ping 127.0.0.1; cat /etc/passwd → ping 명령 이후 /etc/passwd 파일의 내용 노출

파이프(|) 및 리다렉션(>) 사용

  • 명령어 파이프라인을 추가하거나, 결과를 특정 파일에 저장
  • 예: ls > /tmp/malicious_file

백도어 설치

ㅁ 명령어 삽입 (Command Injection) 대응 방안

사용자 입력 검증

  • 사용자 입력값을 철저히 검증하고, 허용된 값(화이트리스트)만 처리.
  • 입력값에 특수문자(;, |, &, >)가 포함되지 않도록 필터링

명령어 실행 제한

  • 시스템 명령어를 실행하지 않도록 설계하고, 필요한 경우 안전한 API를 사용

입력값 이스케이프 처리

  • 사용자 입력값을 명령어의 인자로 전달할 때, 안전하게 이스케이프 처리하여 명령어 실행에 영향을 미치지 않도록 보장

최소 권한 원칙 적용

  • 명령어 실행에 필요한 계정에 최소 권한만 부여하여, 공격 성공 시 피해를 최소화
  • 중요 파일과 디렉토리에 대한 접근 권한 제한

애플리케이션 설계 개선

  • 운영 체제 명령어 호출을 완전히 배제하고, 애플리케이션 내에서 해당 기능을 구현
  • 예: 파일 조작은 시스템 명령어 대신 언어별 라이브러리로 처리.

로그 및 모니터링

  • 명령어 실행 이벤트를 기록하여 의심스러운 명령 실행을 탐지하고, 이상 징후를 관리자에게 알림

Command Injection은 잘못된 사용자 입력 처리로 발생하는 심각한 보안 취약점으로, 공격자는 이를 통해 서버의 제어권을 얻거나 데이터를 유출할 수 있다. 입력값 검증, 명령어 실행 제한, 최소 권한 적용 등 다층적인 보안 방식을 적용해 이러한 취약점을 방지해야한다. 안전한 코드 작성 습관과 정기적인 보안 점검은 Command Injection의 위험을 최소화하는 데 필수적이다.

 

2.  Source code analysis

[그림 2] Low level Source code

사용자 입력 처리

$target = $_REQUEST[ 'ip' ];
  • 사용자 입력을 $_REQUEST로 받아오며, $target $_REQUEST는 $_GET, $_POST, $_COOKIE 데이터를 모두 포함한다.
  • 여기서는 사용자는 IP 매개변수로 값을 전달 할 수 있으며, 입력값은 그대로 변수 $target에 저장하므로 입력값 검증이 없다.

시스템 명령어 실행

if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
     $cmd = shell_exec( 'ping  ' . $target );
} else {

     $cmd = shell_exec( 'ping  -c 4 ' . $target );
}
  • OS에 따라 다른 ping 명령어를 실행한다. Windows 환경인 경우 ping {입력값},  Unix/Linux 환경의 경우 ping -c {입력값} 명령어가 실행된다.
  • shell_exec는 PHP에서 시스템 명령어를 실행하는 함수로 $target에 공격자가 악의적인 명령 (예: 127.0.0.1; rm -rf /)을 삽입하면, 원래 명령 뒤에 추가 명령이 실행된다.
  • 이는 명령어 삽입(Command Injection) 취약점의 주요 원인이 된다.

사용자 출력

echo "<pre>{$cmd}</pre>";
  • shell_exec로 실행한 명령의 결과를 사용자에게 그대로 출력하며, 공격자가 실행한 명령의 출력 결과(예: 파일 내용, 시스템 정보)가 사용자에게 노출될 수 있다.

 

3. Practical exercises

소스코드에서 확인하였듯이  $target $_REQUEST'ip' ]; 로 target 변수에 입력한 IP를 대입하며,  shell_exec( ) 함수는 $target 에서 입력한 IP를 이용해서 Ping 실행한다는 것을 확인하였다. 애플리케이션이 명령어 삽입 취약점에 취약한 경우, Injection된 OS 명령어가 실행된다.  입력 필드에  127.0.0.1; cat /etc/passwd를 삽입하는 경우 명령어가 잘 실행되어, /etc/passwd 파일의 내용을 확인할 수 있다.

[그림 3] Command Injection 결과

반응형

관련글 더보기