https://github.com/gnuboard/gnuboard5/blob/master/shop/kakaopay/pc_pay_result.php#L65 를 보게되면, HttpClient
클래스를 이용해서 $authUrl
에 통신을 시도한다. 여기서 $authUrl
은 $_REQUEST
를 통해서 전달되며 (https://github.com/gnuboard/gnuboard5/blob/master/shop/kakaopay/pc_pay_result.php#L33) 우리가 컨트롤 가능한 값이다. https://github.com/gnuboard/gnuboard5/blob/master/shop/kakaopay/pc_pay_result.php#L176를 보면 리퀘스트를 보내고, 실패했을 경우 response body를 $netcancelResultString
에 저장한다. 이후, https://github.com/gnuboard/gnuboard5/blob/master/shop/kakaopay/pc_pay_result.php#L186-L187에서 str_replace를 해주는데 여기서 취약점이 발생하게 된다. PHP의 특성상 $$변수
의 형태로 값을 사용할 경우, $변수내용
을 참조한 것과 같은 행동을 취하게 된다. 따라서, 첫번째 str_replace에서 $body내용
을 참고하게 하고, 두번째 str_replace에서는 우리가 원하는 변수에 접근하게 된다. 여기서, $authToken
은 우리가 컨트롤 가능한 값이므로 (https://github.com/gnuboard/gnuboard5/blob/master/shop/kakaopay/pc_pay_result.php#L31), 해당 변수를 이용하기로 했다. authToken=flag
로 주고, HttpClient->body에서 authToken
을 리턴한다고 가정하자. str_replace 과정에서 $$Http->body
== $authToken
이 될 것이다. 즉, $netcancelResultString
은 $authToken
의 값을 가지게 된다. 두번째 str_replace에 들어가면서, 마찬가지로 $$netcancelResultString
== $flag
가 되므로, $netcancelResultString
은 $flag변수의 값을 가져오게 된다. 따라서 https://github.com/gnuboard/gnuboard5/blob/master/shop/kakaopay/pc_pay_result.php#L189에서 에러를 이용해 임의 변수를 출력시킬 수 있다.
Payload:
Flag:
hsctf{799c12711fd9d697a00ae3e6329a7979cc648d7cdae0fbb3d62f23a1f7c7f544}