반응형

바로 전 포스팅에서 parse_url의 버그를 이용하여 파라미터 내 값 체크를 우회하는 것을 정리하였다.

https://rootable.tistory.com/entry/websecfr-level-25-writeup-with-parseurl-bug


그런데 오늘 CTF 문제를 풀다 parse_url 관련 문제가 나왔는데 이번엔 파라미터 내 값이 아닌 host를 우회하는 문제가 제출되어 이에 대해 정리도 할겸 포스팅한다.



해당 문제이다. 간단하게 봤을 때 parse_url 을 잘 이용해서 https://localhost/key 를 확인하면 flag를 얻을 수 있을 것 같다.




문제에 접근하여 텍스트 부분에 scheme을 포함하여 작성한 뒤 제출을 누르면 해당 사이트에 접근되는 Link를 만들어준다.


하지만 문제에서 원하는 https://localhost/key에 대한 링크를 만드려고 하면 내부 URL들은 allow되지 않는다고 한다.


이 때 이전 포스팅에서 발견한 parse_url과 관련된 bug들은 query와 관련된 버그이기 때문에 이번 문제를 해결할 때는 도움되지 않는다.

그래서 이와 관련하여 구글링을 한 결과 아래와 같은 버그를 발견하였다.


https://bugs.php.net/bug.php?id=73192


해당 버그는 url이 아래와 같을 때 parse_url이 잘못된 host를 리턴한다고 한다.


- http://example.com:80#@google.com/

- http://example.com:80?@google.com/


위와 같이 작성할 경우 host가 example.com이 아닌 google.com으로 착각하는 버그이다.


이를 이용하여 문제를 해결해보았다.


위의 사진과 같이 버그에서 말한 두가지를 해보았을 때 ?@는 되지 않았지만 #@을 했을 때 parse_url이 host를 잘못 인식하여 내부의 key값을 가져온 것을 볼 수 있다.


해당 버그는 Real World에서 사용될 수도 있다고 판단된다.


아래와 같을 때 잘 활용해보자

- bypass authentication protocol (verify hostname of callback url by parse_url)

- open redirector (verify hostname by parse_url)

- server-side request forgery (verify hostname by parse_url and get_content)



반응형

'Hacking Contest' 카테고리의 다른 글

[ByteBandits CTF 2019] Online Previewer 1  (0) 2019.04.13
[ByteBandits CTF 2019] EasyPHP  (0) 2019.04.13
[2019 Encrypt CTF] vault  (0) 2019.04.03
[2019 Encrypt CTF] Sweeeeeet  (0) 2019.04.03
[2019 Encrypt CTF] repeaaaaaat  (0) 2019.04.03
블로그 이미지

rootable

,
반응형

해당 문제는 PHP의 parse_url 에서 발생하는 취약점을 이용하는 문제이다.

CTF에서도 자주 나오는 문제이므로 추후 한번 정리하여 포스팅을 할까 한다.

일단 문제를 확인해보면 flag.txt 안에 flag가 존재하는데 page 파라미터에 flag를 넣으면 된다.

 

코드를 확인해보자.

<?php
	parse_str(parse_url($_SERVER['REQUEST_URI'])['query'], $query);
	foreach ($query as $k => $v) {
		if (stripos($v, 'flag') !== false)
			die('You are not allowed to get the flag, sorry :/');
		}

	include $_GET['page'] . '.txt';
?>

코드를 확인해보면 REQUEST_URI를 parse_url한 뒤 그 중 query 부분에 대하여 값에 flag가 들어가면 die() 시켜버리는 것을 볼 수 있다.

 

따라서 parse_url의 취약점을 이용하여 제대로 파싱하지 못하도록 만들어주면 된다.

일단 아래 테스트한 사진들을 보자.

 

1. 기본

가장 기본적인 것으로 단순히 flag를 제출했을 때 parse_url 결과 각각 어떻게 되는지 볼 수 있다.

세번째 query 부분을 level 24 문제의 관점에서 봤을 때 $k에 page가, $v에 flag가 들어가서 die 함수에 의해 실행이 종료되는 것을 볼 수 있다.

 

2. double slash(//) 이용

이번엔 host와 path 사이에 double slash를 넣어보았다. 이전 사진과 비교해봤을 때 달라지는 것은 바로 websec.php가 path가 아닌 host가 되었다는 것이다. 

이것은 //가 기본적으로 http://로 동작하기 때문에 이런 현상이 나오는 것이다. 이것은 보통 홈페이지 작성 시 리소스 부분을 보면 src="//rootable.tistory.com/1.png" 과 같이 사용되는 것으로도 자주 볼 수 있다.

 

하지만 여전히 query 부분에 page=flag가 되어있기 때문에 solve할 수는 없다.

 

3. triple slash(///) 이용

이번엔 double이 아닌 triple로 해보았다.

이번엔 parse_url이 제대로 파싱하지 못했기 때문에 parse_url의 결과가 false로 떴다. 그 이유는 // 이후 다음에 나올 / 전에 문자열이 존재해야 host로 파싱을 해야하는데 그 사이에 문자열이 존재하지 않기 때문에 host가 존재하지 않다고 판단을 하고 false로 리턴하는 것이다.

그 결과, query 부분에 flag가 들어가지 않았으며 따라서 $v에 path가 존재하지 않다는 뜻이므로 if문을 넘어 flag.txt를 include하여 문제가 풀린다.

 

파싱이 제대로 되지 않도록만 하면 되기 때문에 /// 뿐만 아니라 4개, 5개를 활용해도 제대로 파싱되지 않아 문제는 풀린다.


(기타) 또 다른 방법

그렇다면 다른 방법이 더 존재하지 않을까?

이를 위해 parse_url의 포트를 활용하는 방법도 있다.

 

이는 PHP 5.4.7 미만의 버전일 때만 가능하다.

자세한 정보는 https://bugs.php.net/bug.php?id=74780 를 참고하길 바란다.

 

만약 query 부분에 콜론이 들어갈 경우 5.4.7 이전의 버전일 경우에는 parse_url이 파싱에 실패한다고 한다.

물론 이 때 콜론 뒤에 숫자형태로 와서 포트로 인식되도록 해야 한다.

 

websec.fr level25에 적용해보면 send 뒤에 :80 을 넣어서 문제가 solve가 된 것을 볼 수 있다.

이는 websec.fr/level25/index.php?page=flag&:1과 같이 반드시 파라미터형태로 전달해주지 않아도 bug가 발생한다.

반응형

'Hacking > Web' 카테고리의 다른 글

[JAVA] AES256 decrypt Code  (0) 2019.04.25
[Websec.fr] level 8 Writeup  (0) 2019.04.11
[WebSec.fr] level 17 writeup  (0) 2019.03.28
PHP Object Injection with websec level 4  (0) 2019.03.26
WAS별 default로 허용되어있는 jsp 관련 확장자  (0) 2019.03.26
블로그 이미지

rootable

,