파일 업로드 우회 기법

파일 업로드 시 보안 제한을 우회하는 다양한 방법들을 소개합니다. 여기서는 PHP 웹셸을 예시로 사용하겠습니다.

1. 프론트엔드 JS 파일 확장자 제한

웹 페이지에서 JavaScript를 통해 특정 확장자만 업로드할 수 있도록 제한하는 경우:

  • JS 코드의 파일 확장자 검사를 비활성화합니다.
  • 허용된 형식으로 파일을 업로드한 후, 패킷을 잡아 filename을 스크립트 형식으로 변경합니다.

2. Content-Type 제한

백엔드에서 업로드된 파일의 Content-Type이 지정된 값인지 확인하는 경우:

  • 업로드 시 패킷을 잡아 Content-Type을 수정합니다.
  • 허용된 형식의 파일을 업로드한 후, 패킷에서 filename을 스크립트 형식으로 변경합니다.

3. 파일 확장자 블랙리스트 제한

블랙리스트에 포함된 확장자는 차단하는 경우:

  • 대소문자를 활용하여 우회 (예: .php → .PHP 또는 .Php).
  • Windows 환경에서는 마지막 '.' 또는 '_'와 공백이 자동으로 제거되므로 이를 활용합니다 (예: .php. → .php).
  • '::$DATA' 추가로 우회 (Windows 전용): 파일명 뒤에 '::$DATA'를 붙이면 파일 스트림으로 처리됩니다.
  • 중복 문자열 우회: 일부 함수는 민감한 문자열을 대체하지만 재귀적으로 삭제하지 않으므로 중복 문자를 사용합니다 (예: a.phphpp → a.php).
  • Null 바이트 ('%00') 삽입으로 우회: 파일명에 Null 바이트를 추가하면 파싱 도중 문자열이 잘려집니다.

4. 해석 가능한 확장자 이용

특정 확장자가 해석될 수 있는 경우 이를 활용합니다:

  • ASP/ASPX: asp, aspx, asa, cer 등.
  • PHP: php, php5, phtml, html 등.
  • JSP: jsp, jspa, jspx 등.

Burp Suite 등의 도구를 사용해 테스트할 수 있습니다.

5. .htaccess 및 .user.ini 활용

.htaccess와 .user.ini 파일을 통해 제한을 우회할 수 있습니다:

  • .htaccess: Apache 환경에서 MIME 타입을 설정하여 이미지 파일을 PHP로 해석하게 합니다.
  • .user.ini: CGI/FastCGI 모드에서 auto_prepend_file 등을 통해 PHP 코드를 실행합니다.

6. 파일 헤더 제한 우회

파일 헤더를 검사하는 경우:

  • 이미지 파일에 스크립트 언어로 변환 가능한 확장자를 추가합니다.
  • 웹셸 파일의 첫 부분에 정상적인 파일 헤더 (예: GIF89a)를 추가합니다.

7. 위험한 함수 검출 우회

WAF가 업로드된 파일 내용을 검사하는 경우:

<?php $_GET['cmd']($_GET['param']); ?>

또는 인코딩된 웹셸을 업로드하고 별도의 스크립트를 통해 디코딩하여 새로운 파일로 작성합니다.

<?php
$encoded = "PD9waHAgZXZhbCgkX1BPU1RbJ2EnXSk7Pz4=";
$decoded = base64_decode($encoded);
file_put_contents('shell.php', $decoded);
?>

8. WAF 우회

다양한 WAF 우회 기법들이 있으며, 주로 서버가 파일을 수신 및 해석하는 방식과 WAF의 검출 로직 차이를 이용합니다:

  • 개행 문자 삽입: 파일명에 개행 문자를 추가하여 우회합니다.
  • 여러 '=' 추가: Content-Disposition 필드에 여러 '='을 넣습니다.
  • 큰 파일 크기: SQL Injection에서 사용하듯 무작위 문자열을 추가하여 WAF를 우회합니다.
  • 따옴표 제거 혹은 대체: 따옴표를 없애거나 다른 구분자로 대체합니다.
  • 추가적인 HTTP 헤더 삽입: Content-Type이나 Content-Disposition 순서를 바꾸거나 추가적인 헤더를 삽입합니다.

9. 경쟁 조건 활용

일부 시스템은 파일을 임시 폴더에 저장한 후 검증을 수행합니다. 이 과정에서 경쟁 조건을 이용하여 우회할 수 있습니다:

fputs(fopen('webshell.php', 'w'), '<?php @eval($_POST[\'cmd\']); ?>');

업로드 중 해당 파일에 대한 반복 요청을 보내면 검증 전에 웹셸이 생성될 가능성이 있습니다.

태그: PHP web-security file-upload

7월 4일 21:29에 게시됨