일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- ctf player
- hacking game
- python
- Wargame
- System Hacking
- dreamhack
- 워게임
- crypto
- WEB
- writeup
- CTF
- hacking
- h4cking game
- 웹해킹
- KAIST
- webhacking.kr
- Gon
- 2022 Fall GoN Open Qual CTF
- Wreckctf
- got overwrite
- Buffer Overflow
- deayzl
- christmas ctf
- hack
- reversing
- 해킹
- cryptography
- TeamH4C
- pwnable
- webhacking
- Today
- Total
deayzl's blog
[Webhacking.kr] Orange 🍊 (hint) (feat. a new era of SSRF + php-src parse_url c code analyze) 본문
[Webhacking.kr] Orange 🍊 (hint) (feat. a new era of SSRF + php-src parse_url c code analyze)
deayzl 2022. 7. 9. 02:06writeup 이라기 보단 hint 를 써놓도록 하겠다.
처음 이 문제를 풀 때 도움이 됐던 것은
PHP SSRF Techniques. How to bypass filter_var()… | by theMiddle | secjuice™ | Medium
A New Era of SSRF - Exploiting URL Parser in Trending Programming Lan… (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 의 일부이고, 그 중 parse_url 함수의 정의 부분인 것 같다.
밑의 switch case 문은 대충 resource 의 scheme, host, port 등을 str copy 하는 모습이니
내가 찾는 코드는 그 전에 있는 듯 하여, php_url_parse_ex() 함수 내부로 따라갔다.
처음에 parse_scheme 하는 코드를 볼 수 있다.
대충 : (colon) 문자 위치를 찾고 처음 시작 포인터부터 : 문자까지 한번 반복문 돌리는 모습을 볼 수 있다.
그리고 scheme 에서 허용되는 문자를 알 수 있다. (alphabet, digit, +, -, .)
즉, url 을 parse 할 때 : 콜론 문자 앞을 scheme 으로 본다는 것을 알 수 있으니, : 콜론 문자를 빼먹으면 안된다는 것을 알 수 있다.
이제 host 분석으로 넘어가자면 (그 바로 다음 내용은 no scheme, relative scheme url 확인인지라 필요없다)
/ (slash) 나 ? , # 문자의 위치를 찾고 그 부분에 e ("end" i guess?) pointer 를 두는 모습을 볼 수 있다.
어차피 이 challenge 에서 ? # 문자는 preg_match regex 에서 걸러질테니 입력 못한다. 그러니 신경쓰지 말고
scheme 뒤 / 슬래쉬 두 개 뒤에서부터 / 슬래쉬 문자 앞 부분까지의 범위를 분석하여 host 와 port 를 뽑아 낸다는 것을 알 수 있다.
(s pointer 는 앞 부분에서 scheme 분석 뒤 // 슬래쉬 문자 뒤를 가리키게끔 연산을 한다.
궁금하면 직접 다운 받아서 분석해보길 바란다)
그리고 port 를 뽑아낼 때 그 가운데에서 : 콜론 문자를 찾아낸다는 것을 알 수 있다.
그 앞은 host, 뒤는 port 라는 식으로 분석한다는 것을 유츄해 볼 수 있다.
port 부분을 str to long 으로 바꿔서 넣는 모습이다.
그 다음 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. 아직 초보 해커이므로 틀린 내용이 있다면, 알려주시면 감사하겠습니다.