[주요정보통신기반시설 웹 애플리케이션 취약점 분석·평가 21일 완성 코스] 1강 — [Day 1] 코드 인젝션 (Code Injection)
[Day 1] 코드 인젝션 (Code Injection) - 서버의 권한을 뒤흔드는 치명적 위협
안녕하세요! Hackerstory 공부방의 IT/보안 튜터 정다은입니다. 👋
오늘부터 과학기술정보통신부 및 KISA의 **'주요정보통신기반시설 기술적 취약점 분석·평가 가이드'**를 바탕으로, 웹 애플리케이션 보안의 핵심 항목 21개를 21일 동안 하나씩 파헤쳐 보는 장정이 시작됩니다!
보안 입문자분들도 쉽게 이해할 수 있도록 원리부터 예시, 진단 방법, 그리고 실무적인 대응 방안까지 친절하게 설명해 드릴 테니 끝까지 잘 따라와 주세요.
첫 번째 시간인 Day 1에서 다룰 취약점은 바로 **'코드 인젝션 (Code Injection)'**입니다.
1. 개념 설명: 코드 인젝션이란?
💡 "데이터를 넣으라고 했더니, 코드를 실행해 버렸다?"
**코드 인젝션(Code Injection)**은 웹 애플리케이션이 사용자로부터 입력받은 값을 적절한 검증이나 필터링 없이 서버 측 스크립트 엔진(PHP, ASP, JSP, Python, Node.js 등)의 코드로 해석하고 실행할 때 발생하는 취약점입니다.
개발자는 단순한 '텍스트(데이터)'를 입력받기를 기대했지만, 공격자는 그 자리에 **'실행 가능한 프로그램 코드'**를 밀어 넣는(Inject) 것이죠.
[정상적인 흐름]
사용자 입력("1 + 1") ➔ 웹 애플리케이션 ➔ 단순 데이터로 처리 ➔ 결과 출력
[코드 인젝션 공격 흐름]
공격자 입력("1; system('id');") ➔ 웹 애플리케이션 ➔ 서버 스크립트 언어가 '명령어'로 해석 및 실행 ➔ 서버 권한 탈취!
🔥 왜 치명적인가요? (영향도)
코드 인젝션이 성립하면 공격자는 RCE(Remote Code Execution, 원격 코드 실행) 권한을 얻게 됩니다.
- 웹쉘(Webshell) 업로드 및 실행: 서버 내 악성 파일 생성
- 서버 제어권 탈취: 웹 서버 프로세스 권한으로 시스템 명령어 실행 (데이터베이스 접근, 파일 시스템 조회/수정/삭제)
- 내부망 침투: 공격 대상 서버를 거점으로 삼아 기업 내부 네트워크로 공격 확장
2. 동작 원리 및 예시
코드 인젝션은 보통 개발 편의성을 위해 동적으로 코드를 평가(Evaluation)하는 위험한 함수를 사용할 때 발생합니다.
⚠️ 각 언어별 대표 위험 함수
- PHP:
eval(),assert(),preg_replace()(/e옵션) - Python:
eval(),exec() - JavaScript (Node.js):
eval(),Function() - ASP/VBScript:
Execute(),ExecuteGlobal()
💻 [취약한 코드 예시] PHP 기반 계산기 기능
개발자가 수식을 입력받아 동적으로 계산 결과를 반환하는 기능을 구현했다고 가정해 봅시다.
<?php
// 취약한 코드 예시 (PHP)
if (isset($_GET['expr'])) {
$expression = $_GET['expr'];
// 사용자 입력을 검증 없이 eval() 함수에 전달 🚨
eval("\$result = " . $expression . ";");
echo "계산 결과: " . $result;
}
?>
🎯 공격 시나리오
공격자는 expr 파라미터에 단순 수식이 아닌, PHP 시스템 명령어를 포함시켜 요청을 보냅니다.
공격자 요청:
GET /calc.php?expr=1;system('id') HTTP/1.1
Host: vulnerable-website.com
서버 내부에서 실행되는 실제 코드:
eval("$result = 1;system('id');;");
결과:
PHP 엔진은 1; 처리 후, 이어서 작성된 system('id') 명령어를 정상적인 코드 문법으로 인식하여 실행합니다. 그 결과, 현재 웹 서버 프로세스의 유저 권한 정보(uid=33(www-data) gid=33(www-data)...)가 화면에 노출되거나 공격자에게 전달됩니다.
3. 실무 진단 및 대응 방안
웹 진단원으로서 이 취약점을 어떻게 찾고, 어떻게 막아야 할까요?
🔍 진단 방법 (Checklist)
- 소스코드 진단:
eval(),exec(),assert()등 위험 함수가 사용되었는지 전수 조사합니다.- 해당 함수의 인자값으로 사용자 입력값(GET/POST, Cookie, Header 등)이 유입되는지 추적(Taint Analysis)합니다.
- 동적 진단 (블랙박스 테스트):
- 서버 측 스크립트 구문을 입력창이나 파라미터에 주입해 봅니다.
- 예시 (PHP):
var_dump(123);,phpinfo();입력 시 동작 여부 확인 - 예시 (Node.js):
res.send(process.env)입력 시 환경변수 출력 여부 확인
🛡️ 안전한 보안 대책 (Solution)
1. 위험한 동적 코드 실행 함수 사용 금지 (최선책)
eval() 같은 함수는 보안상 매우 위험하므로 사용하지 않는 것이 가장 좋은 대책입니다. 대부분의 로직은 위험 함수 없이 일반적인 조건문이나 연산 로직으로 대체 가능합니다.
// ❌ 개선 전 (위험)
eval("\$result = " . $user_input . ";");
// ✅ 개선 후 (안전: 정해진 연산만 수행하도록 로직 분기)
switch ($operator) {
case 'add': $result = $val1 + $val2; break;
case 'sub': $result = $val1 - $val2; break;
}
2. 화이트리스트 기반의 엄격한 입력값 검증
어쩔 수 없이 동적 처리가 필요하다면, 입력값을 **허용된 문자(화이트리스트)**만 포함하도록 강력하게 필터링해야 합니다.
// 숫자 및 기본 연산자(+, -, *, /)만 허용하는 정규표현식 검증
if (!preg_match('/^[0-9\+\-\*\/\s]+$/', $expression)) {
die("잘못된 입력값입니다.");
}
3. 서버 권한 및 환경 설정 최소화
- 최소 권한 원칙: 웹 서버 프로세스(www-data, apache 등)의 권한을 최소화하여 인젝션이 발생하더라도 시스템 전체가 장악당하는 것을 방지합니다.
- PHP 환경 설정 (
php.ini): 위험한 함수들의 실행을 엔진 차원에서 차단합니다.disable_functions = exec, passthru, shell_exec, system, proc_open, popen, curl_exec, curl_multi_exec, parse_ini_file, show_source
4. 핵심 요약 (Cheat Sheet)
| 항목 | 주요 내용 |
|---|---|
| 취약점명 | 코드 인젝션 (Code Injection) |
| 주요 원인 | 사용자 입력값이 서버 스크립트 언어의 실행 코드(eval 등)로 직접 유입 |
| 위험성 | 원격 코드 실행(RCE), 서버 제어권 완전 탈취, 내부망 침투 |
| 핵심 방어 | ① eval() 등 위험 함수 사용 금지<br>② 입력값 화이트리스트 검증<br>③ disable_functions 등 서버 설정 강화 |
오늘 공부한 코드 인젝션은 발생 빈도가 아주 높지는 않지만, 일단 터지면 **'대형 사고(RCE)'**로 이어지는 매우 위험한 취약점입니다. 소스코드를 리뷰할 때 동적 평가 함수가 존재한다면 항상 눈에 불을 켜고 검증하셔야 합니다!
질문이 있으시다면 언제든 댓글로 남겨주시고요. 오늘 배운 내용을 복습해 보시길 권장합니다.
다음 챕터 예고:
내일 **[Day 2]**에서는 웹 보안에서 가장 유명하면서도 강력한 공격인 **SQL 인젝션 (SQL Injection)**을 다룹니다. 데이터베이스를 뒤흔드는 공격 원리와 방어 기법을 자세히 알아보겠습니다.
오늘도 고생 많으셨습니다. 내일 만나요! 👏
댓글 0
로그인하면 댓글을 작성할 수 있습니다.