[Playbook] OS Command Injection 진단 Cheat Sheet

목차


이 문서는 OS Command Injection 진단 중 사용자 입력이 명령에 전달되는 위치를 찾고, 실행 흔적이 남는 통로에 따라 다음 확인을 고르기 위한 빠른 참고서다. 유형별 원리와 대응 방안은 OS Command Injection Lab에 정리했다.

30초 진단 흐름

  1. 외부 프로그램을 호출할 가능성이 있는 기능의 정상 요청을 확보한다.
  2. 입력값을 하나씩 바꾸며 본문·오류·처리 시간의 차이를 기록한다.
  3. 명령 출력이 응답에 포함되면 변경 전후의 본문을 비교한다.
  4. 출력이 없다면 시간 지연, 파일 조회, OOB 통신 중 사용 가능한 통로를 확인한다.
  5. 관찰한 결과를 해당 요청과 연결하고 실행 프로세스의 권한 범위로 영향을 정리한다.
관찰 결과판단다음 확인
입력에 따라 명령 출력이 응답에 추가됨출력이 직접 반환되는 실행 경로정상 응답과 추가 출력의 대응
본문은 같고 처리 시간이 달라짐시간 기반 확인 가능성정상 요청 대비 반복성과 지연 크기
HTTP 응답 이후 별도 처리가 진행됨비동기 실행 가능성파일·OOB 통로
웹에서 읽을 수 있는 위치에 쓰기 가능출력 파일을 통한 확인 가능성파일시스템 경로와 조회 URL 매핑
Collaborator에 DNS 조회가 도착함입력한 조회 명령의 실행 흔적발급한 주소·시각·요청 대응
DNS 이름에 명령 결과가 포함됨외부 통신으로 출력값 전달조회 이름과 예상 출력 형식 비교

1. 입력과 기준 응답 확보

확인 대상기록할 내용
정상 기능재고 조회, 피드백, 파일 처리 등 요청의 목적
입력 위치쿼리·폼·JSON·헤더 중 실제 사용되는 값
정상 값값의 타입, 길이, 허용 범위
응답상태 코드·본문·오류·처리 시간
처리 방식결과를 즉시 반환하는지, 접수 후 별도 처리하는지
  • 한 번에 하나의 입력만 변경한다.
  • 오류가 생기면 입력 검증 오류와 외부 프로그램의 오류를 구분한다.
  • 입력에 구분자를 넣었을 때 요청 형식이 먼저 달라지지 않았는지 확인한다. 예를 들어 폼 본문의 &는 파라미터 구분자이므로 전달할 값의 인코딩을 확인해야 한다.

2. 출력이 응답에 보이는 경우

재고 조회 랩에서는 다음과 같이 응답을 비교했다.

요청의 storeId관찰한 응답판단
1재고 수량 62정상 처리 기준
1;whoami실행 사용자 이름 peter-IBpHNv추가 명령 실행 확인
  • 출력이 요청 문자열을 그대로 반사한 것인지, 명령이 생성한 값인지 확인한다.
  • 원래 명령의 출력과 추가 명령의 출력을 나누어 기록한다.
  • 실행 사용자 이름은 이후 파일 접근 권한을 이해하는 단서가 된다.

요청과 응답은 OS command injection, simple case에서 확인할 수 있다.

3. 응답 시간으로 확인

명령의 완료를 기다리는 요청이라면 처리 시간이 관찰 통로가 된다.

  1. 정상 요청의 처리 시간을 확인한다.
  2. 같은 입력 위치에서 지연 명령을 포함한 요청과 비교한다.
  3. 동일한 조건에서 지연이 반복되는지 확인한다.
  4. 입력한 지연과 실제 차이의 관계를 기록한다.
관찰다음 판단
변경한 요청에서 일정한 지연이 반복됨입력과 지연의 관계 확인
정상 요청도 비슷하게 느림서버 부하·네트워크 영향 재확인
한 번만 느리고 재현되지 않음추가 근거 확보
비동기 접수 응답만 즉시 반환됨파일·OOB 통로 검토

email에 sleep 10을 넣어 지연을 확인한 기록은 time delays에 정리했다.

4. 파일로 출력 확인

출력을 파일에 저장하는 방식에는 쓰기 경로와 조회 경로가 함께 필요하다.

확인 항목랩의 조건
쓰기 가능한 디렉터리/var/www/images/
출력 파일o.jpg
조회 요청/image?filename=o.jpg
확인할 본문파일에 저장된 whoami 출력
  • 서버의 파일 경로와 요청 URL이 어떻게 연결되는지 확인한다.
  • 확장자나 응답의 MIME 타입과 함께 실제 본문을 읽는다.
  • 파일 쓰기 실패, 조회 경로 오류, 캐시 때문에 같은 응답이 나온 경우를 나누어 본다.
  • 여러 번 확인한다면 이번 요청이 만든 파일인지 식별할 수 있도록 기록한다.

상세 과정은 output redirection에서 다룬다.

5. OOB 통신으로 확인

비동기 처리라면 원래 HTTP 응답 밖에서 발생하는 동작을 살펴본다.

관찰확인된 내용다음 확인
발급한 주소에 DNS 조회 발생해당 이름을 조회한 동작요청 시각과 조회 시각 대조
조회 이름에 실행 사용자 값 포함명령 출력의 외부 전달랩 목표 값과 비교
기록된 상호작용 없음이번 시도에서 외부 통신 미관찰주소, 명령 전달, DNS·네트워크 조건
  • 요청별로 구분되는 Collaborator 주소를 사용하면 결과를 대응시키기 쉽다.
  • DNS 조회는 리졸버를 거칠 수 있으므로 수신 측 IP만으로 애플리케이션 서버의 주소를 단정하지 않는다.
  • 조회 발생 여부를 확인하는 단계와 출력값을 읽는 단계를 구분해 기록한다.

DNS 조회 확인은 out-of-band interaction, 조회 이름에 결과를 포함한 과정은 out-of-band data exfiltration에 정리했다.

6. 예상과 다른 결과가 나올 때

점검할 조건살펴볼 영향
요청 인코딩셸에 도달하기 전에 파라미터가 분리되거나 문자가 바뀌는지
따옴표 위치입력이 문자열 내부에 들어가 구분자가 문자로 처리되는지
구분자의 의미순차 실행·조건부 실행·파이프·백그라운드 중 어떤 동작인지
원래 명령의 종료 상태&&·|| 조건이 달라지는지
표준 출력과 표준 오류애플리케이션이 어느 스트림을 반환하는지
실행 시점HTTP 응답이 작업 완료를 기다리는지
프로세스 권한파일 쓰기나 외부 통신이 가능한지

환경별 차이는 Lab의 구분자와 명령 치환 설명에서 정리했다.

7. 결과와 대응 정리

보고에는 입력 위치 → 변경한 값 → 관찰 통로 → 확인한 결과 → 필요한 수정을 연결한다.

확인된 원인대응 방향
사용자 입력을 셸 명령에 문자열로 결합내부 API로 대체하거나 셸 없이 인자 분리
실행 파일·옵션에 사용자 입력이 광범위하게 반영실행 파일 고정, 허용 값·타입·범위 검증
불필요한 파일 접근·쓰기 권한실행 계정과 디렉터리 권한 최소화
불필요한 외부 통신서비스에 필요한 목적지만 허용

전체 풀이는 OS Command Injection Write-up 아카이브에서 확인할 수 있다.

Quick Checklist

  • 정상 요청의 값·응답·처리 시간을 확보했는가?
  • 한 번에 하나의 입력을 변경했는가?
  • 폼·URL 인코딩 후 서버에 전달되는 값을 확인했는가?
  • 반사된 입력과 명령이 생성한 출력을 구분했는가?
  • 응답 지연을 정상 요청과 비교하고 반복성을 확인했는가?
  • 비동기 처리 여부를 고려했는가?
  • 파일 쓰기 경로와 조회 URL의 관계를 확인했는가?
  • Collaborator 주소와 요청 시각을 대응시켰는가?
  • 명령 실행 여부와 출력값 확인 범위를 구분해 기록했는가?
  • 실행 프로세스의 권한으로 영향을 설명했는가?
  • 대응에서 셸 호출 제거·인자 분리·입력 검증을 검토했는가?

참고자료
https://portswigger.net/web-security/os-command-injection/
https://docs.python.org/3.14/library/subprocess.html#security-considerations