파일 업로드 취약점 시나리오 모의해킹

심야·2023년 7월 13일
0

공격 목표

직접 개발한 게시판 웹 애플리케이션 서비스를 공격자 관점에서 분석해 파일 업로드 취약점을 익스플로잇 하고 취약점 발생 원인과 대응 방안을 파악한다.

파일 업로드 취약점

취약점 설명

파일 업로드 취약점은 웹 애플리케이션에 악의적인 파일을 업로드할 수 있는 취약점이다. 공격자는 업로드 된 악성 파일을 활용해 웹 서버를 제어하거나, 사용자의 컴퓨터에 악성 코드를 감염시킬 수 있다.

개념 증명

공격자가 악의적인 파일을 업로드 하고 해당 파일을 활용해 웹 서버를 제어할 수 있는지 침투 테스트를 진행한다.

공격 시나리오

  1. 파일 업로드 취약점이 있는지 파악한다.
  2. 리버스 쉘을 업로드 해 침투 대상 서버의 쉘을 획득한다.
  3. 애플리케이션 경로를 파악해 index page를 변조한다.
  4. 파일 업로드 소스 코드를 파악해 어떻게 익스플로잇이 가능한지 파악한다.

취약점 확인

글쓰기 페이지에서 jsp 파일이 업로드 되는지 확인하겠다.

업로드 결과

jsp 파일 업로드 결과, 그림과 같이 업로드 할 수 없는 확장자라고 알림이 발생한다.

확장자 우회

대문자와 소문자를 섞어 확장자 우회를 시도하겠다. 업로드 파일 명은 msf_reverse_shell.Jsp 이다.

업로드 결과

확장자를 변경해 업로드에 성공하였다. 추측하건대 블랙 리스트 방식으로 파일을 검증하는 것 같다.

업로드 경로 찾기

리버스 쉘을 업로드 했으니 업로드 디렉터리에서 리버스 쉘 파일을 실행해야 한다. 파일을 실행하기 위해서는 파일이 저장되어 있는 디렉터리 경로를 알아야 한다. 우선 파일을 다운로드 해 업로드 경로가 노출되는지 찾아보겠다. download?file 파라미터로 파일을 다운로드 하고 있어 업로드 경로가 노출되지 않는다.

버프 스위트 Target 탭의 Site map 으로 컨텍스트 루트(context root)를 확인하겠다. 컨텍스트 루트는 웹 애플리케이션의 루트 디렉토리를 나타내는 문자열이다. 웹 애플리케이션의 URL에 포함되어 웹 애플리케이션의 리소스를 식별하는 데 사용하므로 하위 디렉터리 구조를 파악할 수 있다.

확인 결과, hackthebox 는 컨텍스트 루트이며 js, api, community 디렉터리를 하위 디렉터리로 두고 있다. 업로드 디렉터리도 컨텍스트 루트의 하위 디렉터리로 존재하거나 js, api, community 디렉터리의 하위 디렉터리로 존재할 수도 있다.

다운로드 경로가 /hackthebox/community/download?file= 이니 커뮤니티 아래에 업로드 디렉터리가 있을 수도 있다. /hackthebox/community/upload 또는 /hackthebox/community/uploads 경로를 요청하겠다.

커뮤니티 디렉터리 아래에는 없으니 컨텍스트 루트 아래에 있는지 확인하겠다.

/hackthebox/upload 경로는 404 코드를 응답하지만 /hackthebox/uploads 경로는 302 코드를 응답한다. 302 코드는 요청한 리소스가 일시적으로 이동 되었음을 나타내는 HTTP 상태 코드로 클라이언트는 요청한 경로로 이동한다. 더 정확한 확인을 위해 실제 경로인 /hackthebox/js 경로를 요청하겠다. /hackthebox/uploads 경로처럼 302 코드를 응답한다.

익스플로잇 실패

업로드 경로에 접근했으나 파일을 실행할 수 없고 읽을 수만 있다. 추측하건대 업로드 디렉터리에 실행 권한이 없거나 톰캣 서버에서 지원하지 않는 확장자일 수도 있다. 리버스 쉘 파일을 업로드 디렉터리가 아닌 상위 디렉터리에 업로드 해 다시 실행하겠다. 만약 상위 디렉터리에서도 실행되지 않는다면 지원하지 않는 확장자일 확률이 높다. 이 때는 톰캣에서 실행 가능한 다른 확장자 파일을 업로드 해야 한다.

상위 디렉터리 업로드 시도

/hackthebox/uploads 경로에 파일이 업로드 된다. 따라서 컨텍스트 루트로 이동해 하위 디렉터리인

community 디렉터리에 파일을 업로드한 뒤, 실행하겠다.

파일은 community 디렉터리에 정상적으로 업로드 되었으나 파일을 실행할 수 없다. 추측하건대 톰캣 서버는 대문자로 작성된 jsp 파일을 실행하지 않는 것 같다.

jsp 확장자는 블랙리스트 필터링으로 차단하고 대문자와 소문자를 섞어 업로드하면 톰캣 서버가 실행하지 않는 것 같다. jspf 와 같은 다른 확장자를 사용할 수 있지만 서버 측에서 차단하고 있을 수 있어 이번에는 톰캣이 지원하는 실행 파일 중 하나인 WAR 파일을 업로드하겠다. WAR 파일은 Web Archive의 약자로 웹 애플리케이션을 배포하는 데 사용되는 Java EE 표준 아카이브 파일 형식이다. Reverse Shell JSP 파일을 포함한 WAR 파일을 톰캣 서버의 webapps 디렉터리에 배포하면 톰캣 서버는 파일을 압축 해제해 JSP 파일 즉, JSP 웹 애플리케이션을 실행한다. 따라서 공격자는 배포한 WAR 파일의 컨텍스트 루트 경로에 있는 Reverse Shell JSP 파일을 서버에 요청하면 파일이 실행되어 쉘을 획득할 수 있다.

War 파일 업로드 및 익스플로잇

글쓰기 페이지 경로는 /hackthebox/community/write 이다. Directory Traversal 공격으로 톰캣의 webapps 디렉터리에 접근해 war 파일을 업로드하겠다. Directory Traversal 공격은 공격자가 웹 서버의 파일 시스템에서 의도하지 않은 위치로 이동하여 민감한 정보를 획득하거나 웹 서버를 공격하는 공격이다. 공격자는 Directory Traversal 공격을 통해 웹 서버에 저장된 파일, 디렉터리, 시스템 명령을 실행할 수 있고 현재 경로에서 상위 디렉터리로 이동하는 명령어, ../ 를 사용한다.

배포한 war 파일의 index page를 요청하니 아래와 같이 정상적으로 접속한다.

공격자 PC, 칼리 리눅스에서 netcat 을 실행해 5000번 포트를 열어둔 뒤, 배포 파일에 미리 만들어 둔 리버스 쉘 파일을 실행하여 쉘을 얻는다.

쉘을 얻으면 아래와 같이 연결된 화면을 볼 수 있다.

pwdls 명령어로 현재 경로와 디렉터리 목록을 확인하니 아래 그림과 같다.

webapps 디렉터리로 이동하니 hackthebox 디렉터리가 있다. hackthebox 디렉터리로 이동해 목록을 확인하니 처음에 추측한 것처럼 uploads, js, index.jsp 등 웹 애플리케이션 파일이 모두 존재한다.

이제 index.jsp 파일을 변조하는 Deface 공격을 시도하겠다. Deface란 해커가 서버의 권한을 탈취한 후 웹사이트 화면을 변조하는 공격이다.

Fully Interactive shell (Full TTYs)

현재 연결된 리버스 쉘은 완전한 쉘이 아니어서 파일을 수정하거나 다운로드 할 수 없다. 그래서 Fully Interactive shell로 업그레이드 해야 한다. Fully Interactive shell 즉, 완전 대화형 쉘은 사용자가 시스템 또는 애플리케이션과 포괄적이고 동적인 방식으로 상호 작용할 수 있는 쉘을 말한다. 명령 기록, 탭 완성, 사용자 입력이 필요한 명령 실행 기능을 제공한다. 간단한 쉘을 완전한 대화형 쉘로 업그레이드하면 더 많은 유연성과 제어가 필요한 작업에 유용하게 사용 가능하다. full tty 사용법은 아래와 같다.

Netcat Shell에서 Full TTYs 업그레이드 방법

  1. 연결된 쉘에서 python3 -c 'import pty; pty.spawn("/bin/bash")' 명령어를 실행하면 그림과 같이 쉘이 변경된다.

  2. 변경된 쉘에서 ctrl+z 명령어를 실행해 쉘을 빠져나온다.

  3. stty -a | head -n1 | cut -d ';' -f 2-3 | cut -b2- | sed 's/; /\n/' 명령어를 실행해 rows, columns 값을 확인한다. 그리고 echo $TERM 명령어를 입력해 터미널 타입을 확인한다.

  4. stty raw -echo; fg 명령어를 실행해 다시 리버스 쉘로 복귀한다.

  5. 복귀했으면 reset 명령어를 입력해 칼리 리눅스 터미널 타입 xterm-256color 을 입력한다.

  6. python3 -c 'import pty; pty.spawn("/bin/bash")' 명령어를 입력했을 때처럼 쉘이 변경된다. 아까 얻은 rows 52; columns 235; 값을 입력하면 Full TTYs 업그레이드에 성공한다.

쉘을 업그레이드 했으니 deface 공격을 시도한다. 변조할 index.jsp 파일은 공격자의 깃허브에 있다. hackthebox 디렉터리로 이동해 wget 도구로 깃허브에 있는 파일을 다운로드한다. 바인드 쉘을 열어 파일을 다운로드 할 수 있으나 공격자 측에서 침투한 서버 측으로 파일을 전송하면 탐지 될 확률이 높다. 침투한 서버에서 80, 443 포트는 사용 중인 포트라 열 수 없고 FTP 포트는 방화벽에서 막기 때문이다. 그리고 일반적인 경우 방화벽에서 80, 443 포트 외에는 서버 내부로 들어올 수 없게 막고 있어 다른 포트를 여는 것도 무의미하다. 그래서 wget 도구로 깃허브에 있는 파일을 다운로드한다. 이미 사용 중인 443 포트와 의심 받을 확률이 적은 깃허브에서 다운로드하기 때문에 탐지 될 확률이 낮다.

cat 명령어로 확인하니 정상적으로 다운로드 되었다.

index.jsp 파일이 2개여서 파일 이름이 변경되었다. 기존 index 파일을 삭제하고 다운로드 한 파일 이름을 변경한다.

Deface 공격

deface 공격으로 index page를 변조하였다.

변경 전

변경 후

취약점 원인

파일 검증이 제대로 이뤄지지 않아 취약점이 발생하였다. 소스 코드를 살펴보며 취약점 발생 원인을 확인하겠다.

코드를 보면 파일 이름에 jsp , jspf 확장자가 있는지 블랙리스트 필터링으로 검증한다. 두 가지 확장자만 검증하기 때문에 war 파일을 업로드 해 리버스 쉘을 연결할 수 있었다. 블랙리스트 필터링은 허용되지 않는 리스트만 지정하고, 그 리스트에 포함되지 않은 요소는 모두 허용하는 방식이다. 반면에 화이트리스트 필터링은 허용되는 리스트만 지정하고, 그 리스트에 포함되지 않은 요소는 모두 거부하는 방식이다.

대응 방안

가장 확실한 방법은 DB 서버에 파일을 CLOB 또는 BLOB 타입으로 업로드 해 저장한다. DB에 저장할 수 없다면 업로드 파일이 저장되는 서버를 웹 서버와 분리한다. 단, php, jsp와 같은 서버 엔진이 설치되어 있으면 안된다. 두 방법을 사용할 수 없다면 화이트 리스트로 확장자 검증, 파일 시그니처 검증, MIME TYPE 검증을 통해 대응해야 한다.

Reference

Upgrade a Dumb Reverse Shell into a Fully Functional Terminal [Tutorial]

Building a simple reverse shell on Windows with Netcat (Part 1)

JSP-Reverse-and-Web-Shell/shell.jsp at 30ae24510b81f2825779ae7551d28ec57d057fc4 · LaiKash/JSP-Reverse-and-Web-Shell

[시스템] 바인드 쉘[Bind Shell], 리버스 쉘[Reverse Shell]

웹사이트 권한까지 탈취 당한 deface 사이트, title 필터로 탐지 (title:"hacked by")

Upgrading Simple Shells to Fully Interactive TTYs

What is File Upload?

profile
하루하루 성실하게, 인생 전체는 되는대로.

0개의 댓글