Common SSRF

서버가 직접 접근해서 데이터를 가져오는 ssrf.php 라는 페이지가 있다고 칩시다.
ssrf.php?u=https://www.hahwul.com

사용자 입력 구간에 있는 데이터를 기반으로 도메인을 비추는 경우(iframe이 아닌 직접 접근해서 뿌려주는 형태)

이런 페이지에는 일반적으로 아래 형태로 SSRF가 가능합니다.
ssrf.php?u=http://127.0.0.1/server-status
ssrf.php?u=https://internal_domain
ssrf.php?u=ssh://~~~

우회패턴들도 제가 정리해둔거보다 훨씬 많을거구요(한번 싹 정리해야하는데 왜이리 귀찮을까요..)
https://www.hahwul.com/p/ssrf-open-redirect-cheat-sheet.html

보다보니 DNS CNAME, A Recode를 이용해서 우회 가능할 것 같았고, 테스트해보니 되어서 블로그 포스팅으로 작성해봅니다.

CNAME, A Record?

CNAME(Canonical Name): 도메인에 여러 별칭(?)을 부여함
e.g
abcd.test.com => test.com
efgh.test.com => test.com

acde, efgh 모두 test.com의 이름 중 하나로 인식됩니다. abcd.test.com으로 접근시 test.com으로 붙은 것과 동일한 효과

A record는 도메인과 이를 매핑하는 IP
abcd.test.com => 192.168.0.2
efgh.test.com => 192.168.0.3

이런식으로 도메인 별 IP를 매핑하여 사용

Bypass SSRF Protection using CNAME

이런 CNAME과 A Record는 각각 도메인에 매핑된 다른 도메인, IP를 가리키기 때문에 내부주소나 사설 대역 IP를 지정해서 SSRF의 방어로직을 우회하고 내부망으로 접근 시도를 할 수 있습니다.
localhost.hahwul.com이라고 하나 만들었는데요,

$ nslookup localhost.hahwul.com
.....

Non-authoritative answer:
localhost.hahwul.com    canonical name = localhost.
Name:    localhost
Address: 127.0.0.1

과 같이 127.0.0.1을 바라보게 CNAME을 설정해두었습니다.
SSRF 쿼리를 지정한 도메인으로 날려보면..

ssrf.php?u=http://localhost.hahwul.com:3000

와아아아아아

Is Secure?

솔직히 정확한 답을 드리기 어렵습니다. 아무래도 CNAME과 A Record에 사설 주소나 도메인이 노출될 수 있는 부분들이다 보니 정보가 노출될 수 있는 우려도 있습니다. 우선은 localhost, 127.0.0.1 정도만 추가하고 해보는건 어떨까 합니다.

한번에 CNAME 리스트를 조회할 수 없다는 가정하엔, BruteForce를 막기 위해 굉장히 어려운 도메인 주소를 주는것도 한 방법으로 생각되네요.

댓글 없음:

댓글 쓰기