Post

[Security] Secure Coding(6-3) - Command Injection

[Security] Secure Coding(6-3) - Command Injection

πŸ”’ μ‹œνμ–΄ μ½”λ”© μˆ˜μ—… 정리

Command Injection

πŸ“šCommand Injection: μ‚¬μš©μž μž…λ ₯값이 μ μ ˆν•œ 검증 없이 μ‹œμŠ€ν…œ λͺ…λ Ήμ–΄μ˜ μΌλΆ€λ‘œ μ‚¬μš©λ  λ•Œ λ°œμƒν•˜λŠ” λ³΄μ•ˆ 취약점

πŸ’‘λ°œμƒ 원인

  • 운영체제 λͺ…령을 μ‹€ν–‰ν•˜λŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 경우
  • κ²€μ¦λ˜μ§€ μ•Šμ€ μ‚¬μš©μž μž…λ ₯ 값이 λͺ…λ Ήμ΄λ‚˜ λͺ…λ Ήμ˜ νŒŒλΌλ―Έν„°λ‘œ μ‚¬μš©λ˜λŠ” 경우

alt text

μš΄μ˜μ²΄μ œλ³„ λͺ…λ Ήμ–΄ μ‹€ν–‰ 방식 이해

Windows

  • κΈ°λ³Έ λͺ…λ Ήμ–΄ 인터프리터
    • 주둜 cmd.exe와 μ΅œκ·Όμ—λŠ” PowerShell μ‚¬μš©
    • λ‚΄λΆ€ λͺ…령어와 μ™ΈλΆ€ ν”„λ‘œκ·Έλž¨ 호좜 방식 ꡬ뢄
  • λͺ…λ Ήμ–΄ νŒŒμ‹± 및 μ‹€ν–‰ κ³Όμ •
    • 특수문자(예: &, |, >)λ₯Ό μ΄μš©ν•œ λͺ…λ Ήμ–΄ μ—°κ²° 및 λ¦¬λ‹€μ΄λ ‰μ…˜
  • λ³΄μ•ˆ 고렀사항
    • Command Injection μ‹œ, cmd.exe의 특수문자 해석을 μ•…μš© κ°€λŠ₯
    • PowerShell의 슀크립트 μ‹€ν–‰ μ •μ±… 및 λͺ…λ Ήμ–΄ ν™•μž₯ 취약점 쑴재

Linux

  • κΈ°λ³Έ λͺ…λ Ήμ–΄ 인터프리터
    • 기본적으둜 /bin/sh(λŒ€λΆ€λΆ„ Bash 기반) μ‚¬μš©
    • μ‰˜μ˜ ν™•μž₯ κΈ°λŠ₯(νŒŒμ΄ν”„, λ¦¬λ‹€μ΄λ ‰μ…˜, μ™€μΌλ“œμΉ΄λ“œ λ“±) ν™œμš©
  • λͺ…λ Ήμ–΄ νŒŒμ‹± 및 μ‹€ν–‰ κ³Όμ •
    • 곡백, λ”°μ˜΄ν‘œ, μ΄μŠ€μΌ€μ΄ν”„ 문자() 처리 방식
    • ν™˜κ²½ λ³€μˆ˜, λͺ…λ Ήμ–΄ μΉ˜ν™˜(`, $() λ“±)의 해석 κ³Όμ • 포함
  • λ³΄μ•ˆ 고렀사항
    • μ‰˜ λ©”νƒ€λ¬Έμž 및 νŒŒμ΄ν”„, λͺ…λ Ήμ–΄ μΉ˜ν™˜μ˜ 잘λͺ»λœ 처리둜 μΈμ μ…˜ μœ„ν—˜ 증가
    • ν™˜κ²½ λ³€μˆ˜ μ‘°μž‘ 및 경둜 λ³€μ‘° 곡격 κ°€λŠ₯μ„±

Command Injection 진단

μˆ˜λ™ 진단

  • λͺ©ν‘œ
    • μ‚¬μš©μž μž…λ ₯이 μ‹œμŠ€ν…œ λͺ…령어와 κ²°ν•©λ˜μ–΄ μ‹€ν–‰λ˜λŠ” 경우, μ•…μ˜μ μΈ μ‘°μž‘μ΄ κ°€λŠ₯ν•œμ§€ 확인
    • μ˜λ„μΉ˜ μ•Šμ€ λͺ…λ Ή μ‹€ν–‰μ΄λ‚˜ 좜λ ₯ μ‘°μž‘μ„ 톡해 취약점을 탐지

πŸ’‘κΈ°λ³Έ μ ‘κ·Ό 방법

  • ν…ŒμŠ€νŠΈ μž…λ ₯ 값에 특수문자 및 μ œμ–΄ 문자λ₯Ό μ‚½μž…ν•˜μ—¬ λͺ…λ Ήμ–΄μ˜ μ‹€ν–‰ 흐름 λ³€ν™”λ₯Ό κ΄€μ°°
  • λ‹€μ–‘ν•œ OS(Windows, Linux)와 μ‰˜μ˜ νŒŒμ‹± κ·œμΉ™μ„ κ³ λ €ν•˜μ—¬ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ 섀계

λͺ…λ Ήμ–΄ μ—°κ²°μž ν…ŒμŠ€νŠΈ

  • &, &&, ||, ; λ“±μœΌλ‘œ μΆ”κ°€ λͺ…λ Ήμ–΄ μ‹€ν–‰ ν…ŒμŠ€νŠΈ
    • 예) "test && cat /etc/passwd" λ˜λŠ” "test; ls"

νŒŒμ΄ν”„ 및 λ¦¬λ‹€μ΄λ ‰μ…˜ ν…ŒμŠ€νŠΈ

  • |, >, < 등을 ν™œμš©ν•΄ λͺ…λ Ήμ–΄ μ‘°μž‘ ν…ŒμŠ€νŠΈ
    • 예) "test | ls", "test > output.txt"

ν™˜κ²½ λ³€μˆ˜ ν™œμš© ν…ŒμŠ€νŠΈ

  • $PATH, $IFS 등을 μ΄μš©ν•˜μ—¬ λͺ…λ Ήμ–΄ μ‹€ν–‰ ν™˜κ²½ λ³€κ²½ν•˜κ±°λ‚˜, 검증 우회 μ‹œλ„
    • 예) "test $PATH" λ˜λŠ” "test$IFSls" 처럼 ν™˜κ²½λ³€μˆ˜ ν™œμš© κ°€λŠ₯ν•œμ§€ ν…ŒμŠ€νŠΈ

μ„œλΈŒ λͺ…λ Ή μ‹€ν–‰ ν…ŒμŠ€νŠΈ

  • λ°±ν‹± (`) λ˜λŠ” $()`λ₯Ό μ‚¬μš©ν•΄ μ„œλΈŒ λͺ…λ Ήμ–΄ μ‹€ν–‰λ˜λŠ”μ§€ ν…ŒμŠ€νŠΈ
    • 예) β€œtest `ls`” λ˜λŠ” β€œtest $(ls)”

μžλ™ν™”λ„κ΅¬ ZAP

  • ZAP 곡식 μ‚¬μ΄νŠΈ(https://www.zaproxy.org/)μ—μ„œ μ΅œμ‹  버전 λ‹€μš΄λ‘œλ“œ 및 μ„€μΉ˜
  • ZAP μ‹€ν–‰ ν›„, ν”„λ‘μ‹œ 포트(κΈ°λ³Έ 8080) 확인

  • 진단 λŒ€μƒ μ›Ή μ„œλΉ„μŠ€ μ€€λΉ„
  • λΈŒλΌμš°μ € ν”„λ‘μ‹œ μ„€μ •
    • λΈŒλΌμš°μ €μ˜ ν”„λ‘μ‹œ 섀정을 ZAP의 ν”„λ‘μ‹œ(예: localhost:8080)둜 λ³€κ²½ν•˜μ—¬ λͺ¨λ“  νŠΈλž˜ν”½μ΄ ZAP을 톡해 흐λ₯΄λ„둝 μ„€μ •
  • ZAP의 μžλ™ 검사 Active Scan μˆ˜ν–‰ 방법
    • ZAP 쒌츑 νŠΈλ¦¬μ—μ„œ ν…ŒμŠ€νŠΈ λŒ€μƒ URL 선택 ν›„, 우 클릭 β†’ "Attack" β†’ "Active Scan" μ‹€ν–‰
  • μŠ€μΊ” κ²°κ³Ό 확인
    • μŠ€μΊ” κ²°κ³Ό μ°½μ—μ„œ β€œCommand Injection” κ΄€λ ¨ μ•Œλ¦Ό (예: μ—λŸ¬ λ©”μ‹œμ§€, 비정상 응닡 μ½”λ“œ λ“±) 확인
    • μ•Œλ¦Ό 상세 정보λ₯Ό 톡해 μ˜μ‹¬λ˜λŠ” μž…λ ₯ ν•„λ“œ 및 μ‹€ν–‰ κ²°κ³Ό 뢄석

alt text


Command Injection λŒ€μ‘

μ‹œνμ–΄ μ½”λ”© 적용

  • Command Injection이 λ°œμƒν•˜λŠ” 경우
1
2
3
4
// βŒμ•ˆμ „ν•˜μ§€ μ•Šμ€ μ½”λ“œ
String version = request.getParameter("version"); // version이 검증 없이 λͺ…령어에 직접 κ²°ν•©
String cmd = new String("cmd.exe /K \"run.bat \""); // 전체 λͺ…λ Ήμ–΄κ°€ ν•˜λ‚˜μ˜ λ¬Έμžμ—΄λ‘œ κ΅¬μ„±λ˜μ–΄ μ‰˜μ—μ„œ 해석
Runtime.getRuntime().exec(cmd + " c:\\prog_cmd\\" + version);
1
2
3
4
5
6
String version = request.getParameter("version");
if(version.matches("[0-9.]+")) { // μ •κ·œμ‹ [0-9.]+둜 μˆ«μžμ™€ 점만 ν—ˆμš©
    Runtime.getRuntime().exec(new String[]{"cmd.exe","/c", "run.bat", version}); //String[] λ°°μ—΄λ‘œ 각 인수λ₯Ό λΆ„λ¦¬ν•˜μ—¬ μ‰˜ 해석 λ°©μ§€
} else {
    λΆ€μ ν•©ν•œ κ°’μœΌλ‘œ 처리
}
  1. μ•ˆμ „ν•œ API μ‚¬μš©
    • 직접 OS λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•˜μ§€ μ•Šκ³ , μ•ˆμ „ν•˜κ²Œ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹€ν–‰ν•˜λŠ” API (예: 인자 λ°°μ—΄ λ°©μ‹μ˜ ProcessBuilder, execvp() λ“±) μ‚¬μš©
      β†’ Command μΈμ μ…˜ μœ„ν—˜μ„ 쀄이기 μœ„ν•΄ νŒŒλΌλ―Έν„°μ™€ λͺ…λ Ήμ–΄λ₯Ό λͺ…ν™•ν•˜κ²Œ 뢄리
  2. μ‚¬μš©μž μž…λ ₯ κ°’ 검증
    • ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ 기반 검증: ν—ˆμš©λœ κ°’λ§Œ 받아듀이고, μ˜ˆμƒμΉ˜ λͺ»ν•œ μž…λ ₯은 λͺ¨λ‘ κ±°λΆ€
      β†’ μ •κ·œ ν‘œν˜„μ‹, νƒ€μž… 체크 등을 ν™œμš©ν•˜μ—¬ μ˜¬λ°”λ₯Έ 포맷만 톡과
  3. 메타 문자 필터링
    • μ‚¬μš©μž μž…λ ₯μ—μ„œ 특수문자 (&, ;, |, >, <, $(), `` λ“±)λ₯Ό μ œκ±°ν•˜κ±°λ‚˜ μ΄μŠ€μΌ€μ΄ν”„ 처리
      β†’ μž…λ ₯ 값에 ν¬ν•¨λœ λ©”νƒ€λ¬Έμžλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μΉ˜ν™˜ν•˜κ±°λ‚˜ μ œκ±°ν•˜μ—¬, λͺ…λ Ήμ–΄ κ²°ν•© 우회 λ°©μ§€
  4. μ—λŸ¬ 핸듀링 및 λ‘œκΉ…
    • μž…λ ₯ κ°’ 검증 μ‹€νŒ¨ 및 λͺ…λ Ήμ–΄ μ‹€ν–‰ 였λ₯˜ μ‹œ, 민감 정보가 λ…ΈμΆœλ˜μ§€ μ•Šλ„λ‘ μ•ˆμ „ν•˜κ²Œ 처리
      β†’ 였λ₯˜ λ°œμƒ μ‹œ λ‚΄λΆ€ λ‘œκ·Έμ—λ§Œ κΈ°λ‘ν•˜κ³ , μ‚¬μš©μžμ—κ²ŒλŠ” μ΅œμ†Œν•œμ˜ μ •λ³΄λ§Œ 제곡
  5. μ½”λ“œ 리뷰 및 정적 뢄석
    • 정기적인 μ½”λ“œ 리뷰와 정적 뢄석 도ꡬλ₯Ό ν™œμš©ν•˜μ—¬ Command μΈμ μ…˜ 취약점 사전 탐지
    • λ³΄μ•ˆ κ΄€λ ¨ 라이브러리 및 ν”„λ ˆμž„μ›Œν¬μ˜ μ΅œμ‹  μ—…λ°μ΄νŠΈ 적용
  6. ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ 마련
    • λ‹€μ–‘ν•œ μ•…μ˜μ  μž…λ ₯(우회 νŽ˜μ΄λ‘œλ“œ, 인코딩 λ³€ν˜• λ“±)을 ν¬ν•¨ν•œ λ‹¨μœ„ ν…ŒμŠ€νŠΈ, 톡합 ν…ŒμŠ€νŠΈλ₯Ό μˆ˜ν–‰

μ‹œμŠ€ν…œ 보호 μ „λž΅

  1. μ΅œμ†Œ κΆŒν•œ 원칙 적용
    • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ˜λŠ” λͺ…λ Ήμ–΄ μ‹€ν–‰ μ‹œ λΉ„κΆŒν•œ μ‚¬μš©μž 계정을 ν™œμš©
    • μ‹œμŠ€ν…œ μ„œλΉ„μŠ€λ‚˜ μ›Ή μ„œλ²„μ˜ μ‹€ν–‰ κΆŒν•œ μ œν•œμ„ 톡해 곡격 성곡 μ‹œ ν”Όν•΄ λ²”μœ„ μ΅œμ†Œν™”
  2. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μƒŒλ“œλ°•μ‹± 및 μ»¨ν…Œμ΄λ„ˆν™”
    • μƒŒλ“œλ°•μŠ€ ν™˜κ²½ λ˜λŠ” μ»¨ν…Œμ΄λ„ˆ(예: Docker)λ₯Ό μ΄μš©ν•΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 격리
    • μ™ΈλΆ€ λͺ…λ Ή μ‹€ν–‰ μ‹œ 격리된 ν™˜κ²½ λ‚΄μ—μ„œ μ‹€ν–‰ν•˜μ—¬ μ‹œμŠ€ν…œ 전체에 영ν–₯을 μ£Όμ§€ μ•Šλ„λ‘ ꡬ성
  3. λ‘œκΉ… 및 λͺ¨λ‹ˆν„°λ§ ν™œμ„±ν™”
    • λͺ…λ Ήμ–΄ μ‹€ν–‰ 둜그, μ—λŸ¬ 둜그, μ ‘κ·Ό 둜그λ₯Ό μ²΄κ³„μ μœΌλ‘œ 기둝
    • 이상 행동 감지 μ‹œ 즉각 μ•Œλ¦Ό 및 λŒ€μ‘ν•  수 μžˆλŠ” λͺ¨λ‹ˆν„°λ§ μ‹œμŠ€ν…œ ꡬ좕
This post is licensed under CC BY 4.0 by the author.