- Android 6.0
- Xamarin 분석
- UnCrackable
- Directory traversal
- XALZ 압축해제
- blind sql injection
- mongoDB
- MariaDB
- CVE-2022-22965
- getCachedIntrospectionResults
- Hackthebox cat
- nginx
- UnCrackable level 1
- login form
- File Upload
- CVE-2014-0094
- xss
- DOM
- mstg
- JAVA ClassLoader 취약점
- Android Backup
- Frida
- PortSwigger
- SeeTheSharpFlag
- JSP
- NoSQL
- HackTheBox APKey
- HackTheBox
- HacktheBox Mobile
- CVE-2010-1622
- Today
- Total
끄적끄적
[vulnerability] File Upload 본문
개요
파일 업로드 취약점은 사용자가 업로드 하고자하는 파일명, 유형(MIME), 콘텐츠(Content-Type), 크기 등을 웹 서버에서 충분히 검증하지 않아 발생하는 취약점이다.
취약점의 영향
취약점의 영향도는 아래 두가지 요소에 따라 다르다.
- 파일의 크기, 유형, 내용 등에 대한 유효성 검증 미흡
- 파일 업로드 시 파일에 적용되는 제한 사항
서버 구성의 특정 유형 파일(웹셸: .php, .jsp 등)이 업로드 가능하고 파일에 제한 사항이 없을 경우, 공격자는 서버측 소스코드 파일을 업로드할 수 있다. 웹셸을 업로드 하였을 경우, 웹 서버가 동작 중인 SID에 따른 권한을 획득할 수 있다.
파일 이름의 유효성 검증이 미흡할 경우, 공격자가 동일한 이름의 파일을 업로드하여 중요 파일을 덮어 씌울 수 있으며 디렉토리 탐색(Directory Traversal) 취약점이 함께 존재하는 경우 공격자는 개발자가 예상치 못한 위치에 파일을 업로드할 수 있다.
공격자가 서버에서 예상하는 임계값 이상의 파일 크기를 업로드할 경우, 서버가 사용가능한 디스크 공간을 채워 DoS 공격으로 이어질 수 있다.
Exploting unrestricted file uploads to deploy a web shell
PHP, Java, Python와 같은 서버측 스크립트 코드를 업로드할 수 있고, 코드로 실행할 수 있도록 구성된 경우이다.
PHP의 경우 아래의 함수를 사용할 수 있으며, 서버측 스크립트 코드마다 웹셸 코드는 상이하니 별도로 검색해보길 바란다.
- file_get_contents: 특정 파일 읽기
- system: 시스템 명령어 실행
실습 URI
Flawed file type validation
이미지 파일이나 PDF 문서와 같은 대용량의 바이너리 데이터를 보내기 위해 "multipart/form-data" Content-Type을 사용하게 된다.
multipart/form-data은 "boundary" 기준으로 메시지를 분할한다.
POST /images HTTP/1.1
Host: normal-website.com
Content-Length: 12345
Content-Type: multipart/form-data; boundary=---------------------------012345678901234567890123456
---------------------------012345678901234567890123456
Content-Disposition: form-data; name="image"; filename="example.jpg"
Content-Type: image/jpeg
[...binary content of example.jpg...]
---------------------------012345678901234567890123456
Content-Disposition: form-data; name="description"
This is an interesting description of my image.
---------------------------012345678901234567890123456
Content-Disposition: form-data; name="username"
wiener
---------------------------012345678901234567890123456--
boundary로 분할된 메시지의 각 부문에는 "Content-Disposition" 필드가 존재한다. Content-Disposition의 Content-Type를 사용하여 사용자가 업로드하고자 하는 데이터의 MIME 유형을 서버에게 알려줄 수 있다.
서버측에서 파일의 유효성을 검증하기 위해 Content-Disposition 필드의 Content-Type만을 사용할 경우, 프록시로 Content-Type을 수정하여 임의의 파일을 업로드할 수 있다.
실습 URI
웹셸 파일을 업로드하는 요청 중 Content-Type을 서버측에서 올바르게 판단하는 타입(이미지 등)으로 변조하여 전송
Preventing file execution in user-accessiable directories
업로드된 파일을 관리하는 디렉토리에서 파일 실행을 방지하여 서버측 스크립트가 동작하지 않도록 하는 방법이다. 이 경우 명시적으로 구성된 Content-Type의 MIME 유형의 스크립트만을 실행하도록 설정한다.
// MIME: text/plain 타입만을 허용
GET /static/exploit.php?command=id HTTP/1.1
Host: normal-website.com
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 39
<?php echo system($_GET['command']); ?>
명시적인 MIME 유형이 아닐 경우(.jsp, .php, .asp 등), 오류 메시지를 반환하거나 파일 내용을 일반 텍스트로 제공할 수 있다. 일반 파일 내용을 텍스트로 제공할 경우 소스코드가 노출될 수 있으나, 웹셸 동작이 불가능하다.
이와 같은 구성은 디렉토리마다 다르게 적용되는 경우가 있는데, 공격자가 다른 디렉토리에 웹셸을 업로드할 수 있는 방법을 찾는다면 서버는 스크립트를 실행하게 된다.
실습 URI
Directory Traversal 취약점과 연계하여 웹셸 업로드: https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-path-traversal
웹 서버는 종종 filename 필드를 사용하여 파일을 저장하는 이름과 위치를 결정한다.
로드밸런서와 같은 리버스 프록시가 설정되어 있을 경우, 타겟으로 설정한 서버가 아닌 다른 서버에 파일이 업로드되어 웹셸이 실행될 수 있다.
Insufficent blacklisting of dangerous file types
사용자가 업로드하는 파일 형식을 블랙리스트로 구성할 경우, 다양한 결함이 발생할 수 있다. 예를들어 php 확장자만을 필터링으로 구성하였을 때 php3, php5 등 서버에서 서버 사이드 스크립트로 동작할 수 있다.
Overriding the server configuration
서버에서 개발자가 하나 이상의 전역 설정을 무시하거나 추가하기 위해 개별 디렉토리 내에 특수 구성 파일을 만들 수 있다. Apache의 경우 ".htaccess"를 이용하여 디렉토리별 구성을 달리한다.
일반적으로는 HTTP 요청을 통해 접근할 수 없지만, 종종 악성 구성 파일을 막지 못하는 서버가 존재한다.
실습 URI
서버 구성 파일 업로드를 통한 블랙리스트 필터링 우회 및 웹셸 업로드: https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-path-traversal
".htaccess" 파일을 "text/plain" 형식으로 업로드 Payload는 아래와 같음
AddType application/x-httpd-php .l33t
이후, 웹셸 파일을 ".php" 확장자가 아닌 ".l33t" 확장자로 업로드
Obfuscationg file extentions
서버측에서 사용자가 업로드한 파일의 이름을 통해 블랙리스트 필터링을 구성한 경우 아래와 같은 우회가 존재할 수 있다.
이 경우엔 개발자가 서버측에서 필터링을 어떻게 구성하였는지에 따라 다른 결과를 보인다.
- "exploit.php.jpg": 파일명을 구문 분석하는데 사용하는 알고리즘에 따라 PHP 또는 JPG로 해석될 수 있다.
- "exploit.php.": 일부 구성 요소에서는 후행 공백, 점 등을 제거하거나 무시한다.
- "exploit.2Ephp": 파일 확장자의 유효성을 검사할 때 값이 디코딩되지 않고 서버측에서 디코딩되는 경우, 악성 파일을 업로드할 수 있다.
- "exploit.asp;.jpg", "exploit.asp%00.jpg": C/C++등 Low 함수를 이용하여 파일을 처리하는 경우 파일 이름의 끝으로 처리되는 항목에서 불일치가 발생하여 파일이 업로드될 수 있다.
실습 URI
난독화된 파일 확장자를 통한 웹셸 업로드(널바이트): https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-obfuscated-file-extension
Flawed validation of the file's contents
앞서 언급한 "파일 유형 유효성 검사 미흡"에서 발생한 Content-Type 우회를 방지하기 위해 서버측에선 이미지 파일 바이너리의 시그니처를 검사하는 방법을 추가할 수 있다. 이 경우, 서버측에서 허용한 파일이 아닐 경우 업로드를 거부할 수 있다(파일 크기가 0으로 설정되어 응답할 수 있음).
하지만 ExifTool와 같은 도구를 사용하여 메타 데이터 안에 악성 코드가 포함된 다중 언어 이미지 파일을 생성하는 것이 가능하다
실습 URI
ExifTool 명령어
exiftool -Comment="<?php echo 'START ' . file_get_contents('/home/carlos/secret') . ' END'; ?>" [YOUR-INPUT-IMAGE].jpg -o polyglot.php
Exploiting file upload race conditions
최신 프레임워크에서는 임시 샌드박스 디렉토리에 파일을 먼저 업로드하고 이름을 무작위로 지정하는 등의 예방 조치를 취한다. 이후 이 임시 파일에 대한 유효성 검사를 수행하고 안전하다고 판단되면 대상을 전송한다.
일부 웹 사이트에서는 파일을 샌드박스 디렉토리가 아닌 기본 파일 시스템에 업로드 후, 유효성 검사를 통과하지 못하면 제거하도록 구성하는 경우가 있다. 이때 서버측에서 업로드 파일을 제거하기 전에 파일 요청 패킷을 전송하여 해당 스크립트가 동작하게 할 수 있다.
실습 URI
Burp Suite Trubo Intruder 기능 사용
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=10,)
request1 = '''<YOUR-POST-REQUEST>'''
request2 = '''<YOUR-GET-REQUEST>'''
# the 'gate' argument blocks the final byte of each request until openGate is invoked
engine.queue(request1, gate='race1')
for x in range(5):
engine.queue(request2, gate='race1')
# wait until every 'race1' tagged request is ready
# then send the final byte of each request
# (this method is non-blocking, just like queue)
engine.openGate('race1')
engine.complete(timeout=60)
def handleResponse(req, interesting):
table.add(req)
Exploiting file upload vulnerabilites without remote code execution
Client Side Script Upload
서버사이드 스크립트 언어 외에 HTML 파일이나 SVG 이미지를 업로드할 수 있는 경우 <script> 태그를 사용하여 Stored XSS 페이로드를 작성할 수 있다.
Exploiting vulnerabilities on the parsing of uploaded files
XML 파일 구문을 분석하는 로직이 존재할 경우 XXE Injection 공격을 수행할 수 있다. XXE Injection의 경우 서버측에서 XML Parser을 이용하여 데이터를 처리해야만 발현될 수 있다.
Uploading files using PUT
서버측에서 PUT Method를 통해 파일 업로드 기능을 지원할 경우 악성 파일을 업로드하는데 사용할 수 있다. OPTION Method를 사용하여 PUT Method 지원 여부를 확인할 수 있다.
Solution
- BlackList 방식이 아닌 WhiteList 방식으로 확장자를 필터링
- 파일 이름에 Directory Traversal 시퀸스(../)가 포함되어 있는지 확인
- 업로드 파일 이름에 난독화 적용
- 파일이 완전히 검증되기 전까지 서버 파일시스템에 업로드 금지(샌드박스 파일 시스템에서 확인)
- 유효 검사 메커니즘에 기존 확릭된 프레임워크 사용
Reference
[1] PortSwigger: https://portswigger.net/web-security/file-upload
[2] exiftool: https://exiftool.org/
'Security > Web' 카테고리의 다른 글
[취약점 진단] HTTPS 사용 (0) | 2022.05.15 |
---|---|
[Spring4Shell] CVE-2022-22965 (0) | 2022.05.02 |
[Exploit] 예제 코드 (0) | 2022.03.03 |
[Secure Coding] Prepared Statement 훑어보기 (1) | 2022.01.17 |
[vulnerability] Nginx alias traversal (0) | 2021.10.07 |