0%

SSRF란?, SSRF 대응방안, SSRF 예제, SSRF / CSRF 차이

ssrf

SSRF란?

SSRF(Server-Side Request Forgery)는 서버 측 요청 위조라는 의미로,
공격자가 서버의 취약한 부분을 액세스하여 공격하는 기법을 말합니다.
공격자는 이를 통해 시스템의 정보를 탈취하거나, 시스템을 조작하는 등의 악의적인 행동을 할 수 있습니다.
이러한 공격은 대체로 웹 애플리케이션이 사용자로부터 URL을 받아 그 URL에 요청을 보내는 경우에 발생합니다.

SSRF(Server-Side Request Forgery) 대표적인 공격 시나리오를 표현하면 아래와 같습니다.
ssrf

@startuml actor Attacker participant Server database InternalSystem

Attacker -> Server: Sends malicious URL
Server -> InternalSystem: Sends request to malicious URL
InternalSystem -> Server: Sends response
Server -> Attacker: Sends response

hide footbox
@enduml

  1. 공격자(Attacker)가 취약한 서버(Server)에 악의적인 URL을 보냅니다.
  2. 서버는 이 URL에 요청(request)을 보냅니다.
  3. 내부 시스템(InternalSystem)은 이 요청에 대한 응답(response)을 서버에 보냅니다.
  4. 서버는 이 응답을 공격자에게 보냅니다.
  5. 이런 방식으로 공격자는 내부 시스템에 대한 정보를 얻거나 조작할 수 있습니다.

SSRF 예제 / 공격 실습1

1.c:\file폴더를 넣어주고, test.txt을 만들어줍니다.

2.c:\에 no.txt 파일을 만들어줍니다.
file

3.c:\에 아래 내용으로 test.py 파일을 만들어주고, python test.py 와 같이 명령어를 실행해줍니다.
그러면 flask 웹 서버가 뜨게 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from flask import Flask, request, send_file
import urllib.request


app = Flask(__name__)

@app.route('/')
def helloworld():
return 'use /file?filename='

@app.route('/file')
def get_url():
filename = request.args.get('filename', '')

if filename:
path = 'c:\\file\\'
return send_file(path+filename, as_attachment=True)

return "no param"

if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, debug=True)

  1. 웹브라우저에서 http://127.0.0.1:8000/file?filename=test.txt 를 입력하면
    C:\file 아래에 있는 test.txt파일이 다운 됩니다.
    개발자의 의도는 사용자가 파일이름을 요청하면, c:\file에 있는 파일을 다운로드 받게 하는 것이지요.

  2. 하지만, 악의적인 사용자가 아래와 같이 ../no.txt를 요청한다면 c:\file 밖에 있는 파일도 접근가능한 것을 확인할 수 있습니다.
    http://127.0.0.1:8000/file?filename=../no.txt
    악의적인요청으로 서버의 취약점을 파고드는 이것이 SSRF입니다.

SSRF 예제 / 공격 실습2

SSRF의 대표적인 사례로는 sql injection이 있습니다.
아래와 같이 userlevel 1인 사용자를 insert하는 로직이 있다고 칩시다.
일반적인경우 username = “james” 와 같이 parameter를 입력해주면
INSERT INTO USER(username, userlevel) VALUES(‘james’, 1) 가 실행이 됩니다.

1
2
3
4
5
6
7
8

@app.route('/insert')
def get_url():
username = request.args.get('username', '')
sql = "INSERT INTO USER(username, userlevel) VALUES('"+username+"', 1)"
database.execute(sql)
return "ok"

만일, 악의적인 사용자가 /insert?username=james’,2)– 와 같이 입력하면 어떻게 될까요?
내부적으로 sql은 아래와 같이 변환이 됩니다.

1
INSERT INTO USER(username, userlevel) VALUES('james',2)--', 1)" 

‘–’ 부분이후로는 주석이 됨으로써, james라는 사용자는 level이 2가 됩니다.

SSRF 대응방안

  1. URL 필터링: 서버가 내부 URL로의 요청을 보내지 않도록 필터링 합니다.
    가능한 경우 외부 URL로의 요청도 제한할 수 있습니다.

  2. 입력 검증: 사용자로부터 받은 입력을 꼼꼼히 검증합니다.

  3. 네트워크 분리: 내부 시스템과 외부 시스템을 물리적으로 분리하거나,
    방화벽 등을 이용해 두 시스템 간의 통신을 제한합니다.

  4. 최소 권한 원칙: 시스템이 가진 권한을 최소한으로 하여, 공격자가 시스템을 조작하는 것을 방지합니다.

  5. 보안 패치 및 업데이트: 시스템의 보안 패치와 업데이트를 꾸준히 진행하여, 새로운 보안 취약점을 미리 차단합니다.

  6. 보안 교육: 개발자 및 운영자에게 SSRF 공격에 대한 이해를 높이고, 보안을 고려한 개발 및 운영 방법을 교육합니다.

SSRF / CSRF 차이

https://devscb.com/post/123 에서 CSRF가 무엇인지 설명을 하였었습니다.

SSRF와 CSRF를 비교하면 아래와 같이 표현할 수 있습니다.

항목SSRF (서버 측 요청 위조)CSRF (교차 사이트 요청 위조)
공격 대상서버 측 애플리케이션/서비스사용자의 웹 브라우저
공격 목표서버 자원 악용 또는 내부 시스템 및 데이터 액세스인증된 사용자를 대신하여 권한 없는 작업 수행
실행 위치서버 측에서 수행클라이언트 측(브라우저)에서 수행
공격 트리거조작된 URL 또는 매개변수를 통해 서버에 대한 공격자의 입력에 의해 트리거됨악의적인 웹 페이지 또는 링크와의 피해자의 상호 작용에 의해 트리거됨
인증 요구 사항일반적으로 인증이 필요하지 않음인증된 사용자 세션이 필요함
피해자 참여피해자는 종종 공격을 인지하지 못함피해자는 자신의 동의 없이 행동을 실행하도록 속임
대상 애플리케이션HTTP 요청을 포함하여 내부 또는 외부 서비스를 대상으로 할 수 있음일반적으로 웹 애플리케이션을 대상으로 하며, 웹사이트에서 사용자의 작업에 영향을 미침
공격 변형블라인드 SSRF, 시간 기반 SSRF, 아웃 오브 밴드 SSRF기본 CSRF, 세션 라이딩, 클릭재킹
악용 난이도SSRF는 악용하기 복잡하고 내부 네트워크 구조 및 서비스에 대한 지식이 필요할 수 있습니다.CSRF는 사용자를 속여 특정 행동을 취하도록 의존하기 때문에 상대적으로 실행하기 쉽습니다.
영향데이터 노출, 서비스 조작, 네트워크 내 잠재적 측방향 이동으로 이어질 수 있음피해자 사용자를 대신하여 암호 변경, 권한 없는 거래 등의 작업을 수행할 수 있음
방어 메커니즘입력 유효성 검사 및 화이트리스팅, 네트워크 수준 보호(방화벽), 호스트 강화CSRF 토큰, 동일 출처 정책, 리퍼러 헤더
공격 시나리오 예시공격자는 서버에 요청을 보내 민감한 내부 리소스, 예를 들어 메타데이터 엔드포인트, 로컬 파일 또는 내부 서비스에 액세스합니다.공격자는 로그인된 사용자를 속여 다른 웹사이트에서 자신도 모르게 이메일 주소나 비밀번호를 변경하는 등의 작업을 실행하도록 속입니다.
일반적인 완화 기법민감한 내부 리소스에 대한 나가는 요청을 차단하는 보안 서버 구성, 입력 유효성 검사, 방화벽CSRF 토큰, 동일 사이트 쿠키, 들어오는 요청의 출처 검증
심각도데이터 유출 및 잠재적 원격 코드 실행으로 이어질 수 있으므로 심각할 수 있음CSRF를 통해 수행할 수 있는 작업에 따라 심각도가 다르지만 사용자 계정에서 권한 없는 작업을 수행할 수 있음