deayzl's blog

[Webhacking.kr] Orange 🍊 (hint) (feat. a new era of SSRF + php-src parse_url c code analyze) 본문

wargame writeup | hint/Webhacking.kr

[Webhacking.kr] Orange 🍊 (hint) (feat. a new era of SSRF + php-src parse_url c code analyze)

deayzl 2022. 7. 9. 02:06

writeup 이라기 보단 hint 를 써놓도록 하겠다.

 

처음 이 문제를 풀 때 도움이 됐던 것은

PHP SSRF Techniques. How to bypass filter_var()… | by theMiddle | secjuice™ | Medium

 

PHP SSRF Techniques

How to bypass filter_var(), preg_match() and parse_url()

medium.com

A New Era of SSRF - Exploiting URL Parser in Trending Programming Lan… (slideshare.net)

 

A New Era of SSRF - Exploiting URL Parser in Trending Programming Lan…

We propose a new exploit technique that brings a whole-new attack surface to bypass SSRF (Server Side Request Forgery) protections. This is a very general atta…

www.slideshare.net

 

이 두 개의 글이었다.

이 글들을 읽어 보면 php parse_url 의 host 와 port 를 내 마음대로 설정하는 게 가능하다는 것을 알 수 있다.

이것만으로 문제를 풀 수 있다면 시도해보길 권한다. 그래도 모르겠다면 잠깐 아래 내용을 참고하자.

 

 

 

 

 

 

내가 이 문제를 풀 당시, 이 글들을 읽기 전에 잠깐 소스코드 분석을 한 적이 있다. (잘 안풀려서)

그리고 나는 내 눈으로 정확하게 도는 코드를 보지못하면, 답답해 하는 성격인지라 분석을 하게 됐다.

(그래서 내가 blackbox challenge 를 안좋아한다)

 

그 내용을 잠깐 써놓겠다. 보면 저런 취약점이 어떻게 나왔는 지 조금 이해할 수 있다.

 

 

구글에 php-src 라고 나와있으며, 원하는 키워드를 옆에 띄워서 써주면 구글이 repository 내부의 파일을 보여준다.

parse_url 관련 파일을 검색했고 구글이 url.c 라는 파일을 알려주었다.

(php version 7.3.8 의 php src 전체를 다운받아 visual studio code 로 열어주었다)

 

url.c

url.c 의 일부이고, 그 중 parse_url 함수의 정의 부분인 것 같다.

밑의 switch case 문은 대충 resource 의 scheme, host, port 등을 str copy 하는 모습이니

내가 찾는 코드는 그 전에 있는 듯 하여, php_url_parse_ex() 함수 내부로 따라갔다.

 

url.c

처음에 parse_scheme 하는 코드를 볼 수 있다.

대충 : (colon) 문자 위치를 찾고 처음 시작 포인터부터 : 문자까지 한번 반복문 돌리는 모습을 볼 수 있다.

그리고 scheme 에서 허용되는 문자를 알 수 있다. (alphabet, digit, +, -, .)

 

즉, url 을 parse 할 때 : 콜론 문자 앞을 scheme 으로 본다는 것을 알 수 있으니, : 콜론 문자를 빼먹으면 안된다는 것을 알 수 있다.

이제 host 분석으로 넘어가자면 (그 바로 다음 내용은 no scheme, relative scheme url 확인인지라 필요없다)

 

url.c

/ (slash) 나 ? , # 문자의 위치를 찾고 그 부분에 e ("end" i guess?) pointer 를 두는 모습을 볼 수 있다.

어차피 이 challenge 에서 ? # 문자는 preg_match regex 에서 걸러질테니 입력 못한다. 그러니 신경쓰지 말고

scheme 뒤 / 슬래쉬 두 개 뒤에서부터 / 슬래쉬 문자 앞 부분까지의 범위를 분석하여 host 와 port 를 뽑아 낸다는 것을 알 수 있다.

(s pointer 는 앞 부분에서 scheme 분석 뒤 // 슬래쉬 문자 뒤를 가리키게끔 연산을 한다.

궁금하면 직접 다운 받아서 분석해보길 바란다)

 

그리고 port 를 뽑아낼 때 그 가운데에서 : 콜론 문자를 찾아낸다는 것을 알 수 있다.

그 앞은 host, 뒤는 port 라는 식으로 분석한다는 것을 유츄해 볼 수 있다.

 

url.c

port 부분을 str to long 으로 바꿔서 넣는 모습이다.

 

url.c

그 다음 path analyze 를 하는 것을 볼 수 있다.

다시 한번 더 말하지만, ? # 은 무시해도 된다. 어차피 입력하면 걸러진다.

여기서 host, port 를 분석한 후, 그 뒷 부분을 path 로 정한다는 것을 알 수 있다.

그 후 return 하면 함수는 끝이 나게 된다.

 

 

최종적으로, php 의 parse_url 로 host 에 "webhacking.kr", port 에 "10009" 를 어떻게 넣을지 알 수 있다.

payload 를 구성할 때 "그" 부분은 delimiter 문자가 무엇이며 또한 그 속은 host port 로 채워져야 함을 알 수 있을 것이다.

 

 

 

이제 남은건 어떻게 그 확정되지 않은, 나머지 payload 부분을 가지고 regex 로 http://webhacking.kr:10009/ 체크하는 것을 어떻게 bypass 하고 파일을 읽던 뭐던 하느냐의 문제이다.

 

 

여기서 글을 끊을 것이나, 이후의 문제에 대해 하나 더 힌트를 남기자면 delimiter 의 문제는 아니다.

앞에서 소개했던 글이나 다른 글에서 나오는 reserved char 를 넣어서 뭐 어떻게 하는 방식이 아니다.

나는 결국 어떤 rfc 를 읽다가 아이디어가 떠올라서 어찌저찌 풀게 되었는데 건투를 빈다.

(과연 어떤 rfc 일까?)

 

 

 

 

 

 

 

 

 

 

ps. 아직 초보 해커이므로 틀린 내용이 있다면, 알려주시면 감사하겠습니다.

Comments