1. File Upload Vulnerability (파일 업로드 취약점)
- 공격자의 파일을 웹 서비스의 파일 시스템에 업로드하는 과정에서 발생하는 보안 취약점이다.
- 파일 시스템 상 임의 경로에 원하는 파일을 업로드하거나 악성 확장자를 갖는 파일을 업로드할 수 있을 때 발생한다.
- 원하는 시스템 커맨드를 실행하는 원격 코드 실행 취약점을 유발할 수 있다.
- 이용자가 업로드될 파일의 이름을 임의로 정할 수 있을 때 발생
- 파일 이름에 이용자가 입력한 문자열을 그대로 사용하거나, 이용자의 이메일, 닉네임 등을 포함시키는 등의 소스 코드 패턴이 이러한 취약점을 발생
- 파일 업로드를 허용하는 대개의 서비스는 보안을 위해 특정 디렉터리에만 업로드를 허용
파일 업로드 취약점 분류
- Path Traversal
- 악성 파일 업로드
1) Path Traversal
- 업로드에 존재하는 제약을 우회하여, 임의 디렉터리에 파일을 업로드할 수 있는 취약점
- 공격자가 ../와 같은 메타문자를 사용하면 지정된 업로드 폴더를 벗어나 상위 디렉터리에도 파일을 업로드할 수 있다.문자 설명 Example
. 현재 디렉터리를 나타냅니다. /var/www/./html --> /var/www/html .. 상위 디렉터리를 나태냅니다. /var/www/../html --> /var/html - ex) filename="../hack.py” : 상위 디렉토리에 파일 저장
- 만약 app.py를 덮어쓴다면, 서버가 재실행될 때 임의의 파이썬 코드를 실행할 수 있다.
2) 악성 파일 업로드
- 이용자가 파일을 업로드할 때, 이를 제대로 검사하지 않아서 발생하는 취약점
- 웹셸
- 웹 셸: 임의 시스템 명령어를 실행해주는 웹 리소스
- 웹 서버는 .php, .jsp, .asp와 같은 확장자의 파일을 **Common Gateway Interface(CGI)**로 실행하고, 그 결과를 이용자에게 반환한다.
- 공격자가 임의의 php 소스 파일을 .php 확장자로 업로드하고, GET 요청을 보낼 수 있다면 CGI에 의해 해당 코드가 실행되도록 할 수 있다.
- CGI : 동적인 컨텐츠를 처리하기 위해서 웹 서버와 php 같은 외부의 프로그램에 사이에서 인터페이스를 제공하는 프로토콜
- 악의적인 웹 리소스
- 웹 브라우저는 파일의 확장자나 응답의 Content-Type에 따라 요청을 다양하게 처리한다.
- 만약 요청한 파일의 확장자가 .html 이거나, 반환된 Content-Type 헤더가 text/html일 경우 응답은 HTML 엔진으로 처리됨.
- 파일의 확장자가 .png, .jpg등의 이미지 확장자이거나, Content-Type이 image/png일 경우에는 이미지로 렌더링됨.
- 만약 공격자가 서버에 exploit.html을 업로드하고, 이에 접근하는 URL이 https://dreamhack.io/uploads/exploit.html이라면, 브라우저는 이를 HTML로 해석. exploit.html에 악의적인 스크립트를 삽입하면, Cross-Site-Scripting (XSS) 공격으로 이어질 수 있다.
- 웹 브라우저는 파일의 확장자나 응답의 Content-Type에 따라 요청을 다양하게 처리한다.
예제
파일 이름을 임의의 파일명+"."+확장자으로 생성
—> Path Traversal을 이용한 공격은 불가능.
하지만, 이용자가 올린 확장자를 별다른 검사없이 사용하므로 php 웹셸을 업로드할 수 있다.
그리고 html파일을 업로드하여 Stored XSS를 수행할 수도 있다.
- 웹셸 업로드 ) 아래 내용의 exploit.php 업로드
<?php system("ls"); system($_GET[x]); ?>
- Stored XSS 시도 ) 아래 내용의 **HTML 파일(exploit.html)**을 업로드
<script>alert(1);</script>
업로드 취약점 방지 방법
- 업로드 디렉터리를 웹 서버에서 직접 접근할 수 없도록 하거나,
- 업로드 디렉터리에서는 CGI가 실행되지 않도록 해야 하고
- 업로드된 파일 이름을 그대로 사용하지 않고 basepath와 같은 함수를 통해 파일 이름을 검증한 후 사용해야 합니다.
- 또한 허용할 확장자를 명시해 그 외 확장자는 업로드될 수 없도록 해야 합니다.
- AWS, Azure, GCP 등의 정적 스토리지를 이용하는 것입니다.
- 서버의 파일 시스템을 이용하지 않기 때문에 파일 업로드 취약점이 웹 서버 공격으로 이어지는 것을 예방할 수 있다.
리눅스 정보
- /proc/self/maps : 파일을 이용하여 실행중인 시스템 메모리 주소 확인하기
- /proc 프로세스 정보
- /proc/[pid]/ : 구동중인 해당 프로세스의 정보
- /proc/self : 현재 실행중인 프로세스의 디렉토리 표시
- /proc/[pid]/maps : 해당 프로세스가 mapping 된 메모리 주소 공간
추가자료
2. File Download Vulnerability (파일 다운로드 취약점)
- 웹 서비스의 파일 시스템에 존재하는 파일을 다운로드 하는 과정에서 발생하는 보안 취약점이다.
- 공격자는 웹 서비스의 파일 시스템에 존재하는 임의 파일을 다운로드 받을 수 있다.
- 설정 파일, 패스워드 파일, 데이터 베이스 백업 본 등을 다운로드 하여 민감한 정보를 탈취할 수 있고 2차 공격을 수행할 수 있다.
- 이용자가 다운로드할 파일의 이름을 임의로 정할 수 있을 때 발생
- 파일 다운로드 취약점이 자주 발생하는 URL 패턴
예제
실습 서버 코드
# ...
Secret = os.environ("Secret")
# ...
@app.route("/download")
def download():
filename = request.args.get("filename")
content = open("./uploads/" + filename, "rb").read()
return content
# ...
환경 변수로부터 가지고 오는 Secret 값을 파일 다운로드 취약점을 이용해 획득하기
- 프로세스의 환경 변수는 /proc/[pid]/environ, /proc/self/environ에서 확인할 수 있다.
- 만약 이용자가 프로세스를 호출하기 전에 환경 변수를 bash의 명령어로 설정했다면, .bash_history에서도 이를 알 수 있다.
- .bash_history를 읽으면, 다음과 같이 이용자가 export 명령어로 설정한 Secret 값을 알 수 있다.
다운로드 취약점 방지 방법
- 요청된 파일 이름을 basepath과 같은 함수를 통해 검증
- 파일 이름과 1:1 맵핑되는 키를 만들어 이용자로부터 파일 이름이 아닌 키를 요청하도록 해야 한다.
Reference
드림핵 Stage 8 https://dreamhack.io/lecture/courses/202