[Dreamhack] Command Injection: 1 - Command Injection

securitykss·2023년 2월 9일
0

Pwnable 강의(dreamhack)

목록 보기
37/58

https://dreamhack.io/lecture/courses/108 을 토대로 작성한 글입니다.

1. Introduction

C/C++으로 프로그래밍을 할 때 종종 system함수를 사용하는 경우가 있다.

system 함수는 함수에 전달된 인자를 셸 프로그램에 전달해 명령어를 실행시킨다.

system("cat /etc/passwd")를 호출하면, 셸 프로그램으로 cat /etc/passwd를 실행한 것과 같다.

system함수를 사용하면 이미 설치된 소프트웨어들을 쉽게 이용할 수 있다는 것이 장점이다.

하지만 함수의 인자를 셸의 명령어로 전달한다는 점에서 치명적인 취약점으로 이어진다.

이처럼 명령어를 실행해주는 함수를 잘못 사용하여 발생하는 Command Injection 취약점에 대해 알아보자.


system 함수가 명령어를 실행하는 과정

system 함수는 라이브러리 내부에서 do_system 함수를 호출한다. do_system은 "sh -c"와 system 함수의 인자를 결합하여 execve 시스템 콜을 호출한다.


2. Command Injection

2.1 설명

Injection(인젝션)의 악의적인 데이터를 프로그램에 입력하여 이를 시스템 명령어, 코드, 데이터베이스 쿼리 등으로 실행되게 하는 기법이다.

이 중, 사용자의 입력을 시스템 명령어로 실행하게 하는 것을 Command Injection이라고 부른다.

Command Injection은 명령어를 실행하는 함수에 사용자가 임의의 인자를 전달할 수 있을 때 발생한다.

system 함수를 사용하면 사용자의 입력을 소프트웨어의 인자로 전달할 수 있다.

사용자가 입력한 임의 IP에 ping을 전송하고 싶다면 system("ping [사용자 입력]")을, 임의 파일을 읽고 싶다면 system("cat [사용자 입력]") 등의 형태로 system 함수를 사용할 수 있다.

이렇게 되면, 이러한 호출 과정에서 사용자의 입력을 제대로 검사하지 않으면 임의 명령어가 실행될 수 도 있다.

이는 리눅스 프로그램이 지원하는 여러 메타 문자 때문이다.

system 함수는 셸 프로그램에 명령어를 전달하여 실행하는데, 셸 프로그램은 다양한 메타 문자를 지원한다.

주목해야 할 것은, &&, ;, | 등을 사용하면 여러 개의 명령어를 연속으로 실행시킬 수 있다는 것이다.

따라서 ping [사용자 입력]을 실행할 때,

악의적인 사용자가 a; /bin/sh를 전달하면 ping a; /bin/sh가 명령어로 전달되면서,

ping을 실행하고, sh를 실행하게 됩니다. 이를 이용하여 공격자는 셸을 획득할 수 있다.

2.2 예제

2.2.1 코드

// Name: cmdi.c
// Compile: gcc -o cmdi cmdi.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const int kMaxIpLen = 36;
const int kMaxCmdLen = 256;

int main() {
  char ip[kMaxIpLen];
  char cmd[kMaxCmdLen];

  // Initialize local vars
  memset(ip, '\0', kMaxIpLen);
  memset(cmd, '\0', kMaxCmdLen);
  strcpy(cmd, "ping -c 2 ");
  
  // Input IP
  printf("Health Check\n");
  printf("IP: ");
  fgets(ip, kMaxIpLen, stdin);

  // Construct command
  strncat(cmd, ip, kMaxCmdLen);
  printf("Execute: %s\n",cmd);

  // Do health-check
  system(cmd);

  return 0;
}

2.2.2 정상적인 실행

2.2.3 비정상적인 실행

메타 문자 ;를 넣어 다음 명령어도 실행할 수 있게 끔 한뒤, /bin/sh을 넣어주니,

shell을 획득했다.

마치며

인젝션(Injection):

악의적인 데이터를 프로그램에 입력하여 이를 시스템 명령어, 코드, 데이터베이스 쿼리 등으로 실행되게 하는 기법

커맨드 인젝션(Command Injection):

인젝션의 종류 중 하나. 시스템 명령어에 대한 인젝션을 의미함.

취약점이 발생하는 원인은 단순하지만, 매우 치명적인 공격으로 이어질 수 있음.

개발자는 사용자의 입력을 반드시 검사해야 하며, 되도록e system 함수의 사용을 자제해 야함.

메타 문자(Meta Character):

셸 프로그램에서 특수하게 처리하는 문자. ;를 사용하면 여러 개의 명령어를 순서대로 실행시킬 수 있음.

Reference

https://dreamhack.io/lecture/courses/108

profile
보안 공부를 하는 학생입니다.

0개의 댓글