모의해킹&웹취약점진단/OWASP TOP 10

SSRF(Server Side Request Forgery) 취약점

sheow13 2023. 12. 7. 15:53
728x90

 

 개요

- SSRF(Server Side Request Forgery) 취약점은 적절한 검증 절차를 거치지 않은 사용자 입력값을 내부 서버간의 요청에 사용해 악의적인 행위가 발생할 수 있다. 외부에 노출된 웹 서버가 취약한 어플리케이션을 포함하는 경우 공격자는 URL 또는 요청문을 위조해 접근통제를 우회하는 방식으로 비정상적인 동작을 유도하거나 신뢰된 네트워크에 있는 데이터를 획득할 수 있는 취약점 

-  OWASP TOP 10 2021에서는 A10(Server Side Request Forgery)에 해당

 

 

SSRF Cheat Sheet

※ KISA에서 발행한 Python_시큐어코딩_가이드 참조

설명 삽입 코드의 예
내부망 중요 정보 획득 http://sample_site.com/connect?url=http://192.168.0.45/member/list.json
외부 접근 차단된 admin 페이지 접근 http://sample_site.com/connect?url=http://192.168.0.45/admin
도메인 체크를 우회하여 중요 정보 획득 http://sample_site.com/connect?url=http://sample_site.com:x@192.168.0.45/member/list.json
단축 URL을 이용한 Filter 우회 http://sample_site.com/connect?url=http://bit.ly/sdjk3kjhkl3
도메인을 사설IP로 설정해 중요정보 획득 http://sample_site.com/connect?url=http://192.168.0.45/member/list.json
서버내 파일 열람 http://sample_site.com/connect?url=file:///etc/passwd

 

 

실습 환경

-PortSwigger Web Academy

 

 SSRF  취약점 실습1

Step 1) PortSwigger Web Academy에 SSRF Lab 접근. LAB 목표는 'http://localhost/admin' 경로로 접근하여 'carlos' 계정을 삭제해야 CLEAR. 바로 admin 페이지로 접근 시, admin 계정만 접근 및 사용할 수 있는 것을 확인.

[SSRF LAB으로 이동]

 

['admin' 페이지로 접근 시, 관리자만 접근할 수 있다는 사실 확인]

 

Step 2) SSRF 취약점이 가능한 경로를 찾던 도중, 재고 체크 하는 버튼에서 URL 경로로 API를 호출하는 것을 확인. 해당 HTTP Body값에 'http://localhost/admin' 경로 입력 시, 관리자 페이지를 호출하는 것을 확인

 

[제품 재고 체크하는 버튼 클릭]

 

[요청값에 URL을 통해 API값을 호출하는 것을 확인]

 

[URL에 'localhost/admin' 경로를 호출 시, 정상적으로 불러오는 것을 확인]

 

[admin 페이지 정상적으로 불러오는 것을 확인]

 

Step 3) 관리자 페이지에서 'carlos' 계정을 삭제하려 했으나, 권한이 admin이 아니라 삭제 불가능 확인. 삭제 하는 방법을 찾는 도중 재고 버튼 클릭 했을 때, URL에 localhost/admin 경로를 요청하면 응답값 내에 'carlos' 계정 삭제 링크 경로가 기재된 것을 확인. 해당 경로를 HTTP Body 값에 넣으면 'carlos' 계정 삭제된 것을 확인

[호출한 admin 페이지에서 삭제가 불가능하여 확인 도중, HTTP 응답값에 'carlos' 계정 삭제하는 링크 경로가 기재된 것을 확인 ]

 

['carlos' 계정 삭제하는 링크 경로를 HTTP Body값에 입력 후 요청 시 정상적으로 삭제된 것을 확인]
['carlos' 계정 삭제 확인]

 

 

SSRF  취약점 실습2

Step 1) PortSwiggerWeb Academy에 SSRF Lab 접근. LAB 목표는 '192.168.0.0/24' 대역을 스캔하여 admin페이지로 접근 후  'carlos' 계정을 삭제해야 CLEAR. 바로 admin 페이지로 접근 시, 해당 페이지는 없는 것으로 확인

[PortSwiggerWeb Academy Lab 접근]

 

[해당 페이지는 'admin' 경로가 없는 것으로 확인]

 

 

Step 2) 재고 체크하는 버튼 클릭 시, URL 경로로 API를 호출하는 것을 확인. Lab에서 내부 대역('192.168.0.0/24)에서 관리자 페이지를 찾으라는 과제가 있어 Burp suite Intruder 기능을 사용하여 내부 대역 스캔 시, '192.168.10.66' IP를 사용하고 있음을 확인.

 

[재고 체크하는 버튼 클릭]

 

[내부 대역 스캔을 위해 Burp Suite Intruder에서 IP D클래스를 설정]

 

[내부 대역 스캔을 위해 Payload 설정]

 

[응답값 길이가 다르며, status값이 다른 내부 IP 확인]

 

[식별된 내부 IP로 admin 경로로 접근 시 정상 접근 확인]

 

[SSRF를 통해 관리자 페이지 접근 가능 확인]

 

 

Step 3) 삭제를 시도하였으나 권한이 없어 삭제 불가한 것으로 확인. HTTP 응답코드 내 삭제 링크 확인되어, HTTP Body 값에 해당 삭제 경로 전달 시 'carlos' 계정 삭제 확인

 

[HTTP 응답 코드 내 'carlos' 계정 삭제 링크 확인]

 

[계정 삭제하는 경로로 요청 시, 정상 동작 확인]

 

['carlos' 계정 삭제 확인]

 

SSRF 대응 방안

- 시큐어코딩을 통해 사전에 정의된 서버 목록을 정의하고 매칭되는 URL만 사용할 수 있도록 설정

from django.shortcuts import render
import requests


# 허용하는 도메인을 화이트리스트에 정의할 경우 DNS rebinding 공격 등에
# 노출될 위험이 있어 신뢰할 수 있는 자원에 대한 IP를 사용해
# 검증하는 것이 조금 더 안전

ALLOW_SERVER_LIST = [
    "https://127.0.0.1/latest/',
    "https://192.168.0.1/user_data',
    "https://192.168.0.100/v1/public',
]

def call_third_party_api(request):
    addr = request.POST.get('address', ")

    # 사용자가 입력한 URL을 화이트리스트로 검증한 후 그 결과를 반환하여
    # 검증되지 않은 주소로 요청을 보내지 않도록 제한한다
    if addr in ALLOW_SERVER_LIST:
       return render(request, '/error.html', {'error' = '허용되지 않는 서버입니다.'})

    result = requests.get(addr).text
    return render(request, '/result.html', {'result':result})

 

'모의해킹&웹취약점진단 > OWASP TOP 10' 카테고리의 다른 글

XXE 취약점  (0) 2023.12.07