Backend Development

ReCAPTCHA Headache

Submitted by Gummy, , Thread ID: 105864

Thread Closed
Gummy
Verified Rad Pirate Dad
Supreme
Level:
5
Reputation:
60
Posts:
1.39K
Likes:
85
Credits:
49
09-11-2018, 07:44 PM
#1
I don't know if anyone here is interested/proficient in PHP but I'm throwing Google's ReCAPTCHA on our
website because we've been getting a lot of spam lately and I can't figure this thing out for the life of me.

Apparently, according to [@18568], our contact form backend is full of vulns as well as the functionality
of the PHP script itself is just ass. Here is the code...

PHP Code:
<?php
// Your Email
$recipient "[email protected]"// PLEASE SET YOUR EMAIL ADDRESS
$recaptcha_secret_key '-HIDDEN-'// PLEASE SET YOUR GOOGLE RECAPTCHA API KEY.

// Recaptcha check up
// Requires curl. If your server does not support curl, this script does not work.
if(isset($_POST["g-recaptcha-response"]) && $recaptcha_secret_key !== '') {
$endpoint 'https://www.google.com/recaptcha/api/siteverify?secret=' $recaptcha_secret_key '&response=' $_POST['g-recaptcha-response'] ;
$curl curl_init() ;
curl_setopt$curl CURLOPT_URL $endpoint ) ;
curl_setopt$curl CURLOPT_SSL_VERIFYPEER false ) ;
curl_setopt$curl CURLOPT_RETURNTRANSFER true ) ;
curl_setopt$curl CURLOPT_TIMEOUT ) ;
$json curl_exec$curl ) ;
curl_close$curl ) ;

if(
json_decode($json)->success === false) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'RECAPTCHA_FAILED',
array(
'error_message'=> 'RECAPTCHA_FAILED')
)
);
}

$json json_decode($json);

if(
json_decode($json)->success === false) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'RECAPTCHA_FAIL_RESPONSE',
array(
'error_message'=> 'Recaptcha response is not valid.')
)
);
}
}

// Check $recipient
if($recipient === '') {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'RECIPIENT_IS_NOT_SET',
array(
'error_message'=> 'RECIPIENT email address is not set. Please configure the script.')
)
);
}

// Check for empty required field
if(!isset($_POST["email"]) || !isset($_POST["fname"]) || !isset($_POST["message"])) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'MISSING_REQUIRED_FIELDS',
array(
'error_message'=> 'MISSING_REQUIRED_FIELDS should not be occurred.')
)
);
}

// Sanitize input
$fnamefilter_var($_POST["fname"], FILTER_SANITIZE_STRING);
$lnamefilter_var($_POST["lname"], FILTER_SANITIZE_EMAIL);
$website $_POST["website"];
if (!
preg_match("~^(?:f|ht)tps?://~i"$website)) $website "http://" $website;
$website filter_var($websiteFILTER_VALIDATE_URL);
$email filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
$company filter_var($_POST["company"], FILTER_SANITIZE_STRING);
$department filter_var($_POST["department"], FILTER_SANITIZE_STRING);
$message filter_var($_POST["message"], FILTER_SANITIZE_STRINGFILTER_FLAG_NO_ENCODE_QUOTES);

// If non required fields are empty
if ( empty($lname) ){
$lname "No last name entered.";
}
if ( empty(
$website) ){
$website "No website entered.";
}
if ( empty(
$company) ){
$company "No company entered."
}

// Headers
$headers 'From: '.$fname.' <'.$email.'>' "\r\n";
$headers .= 'Reply-To: '.$email.'' "\r\n";
$headers .= 'X-Mailer: PHP/' phpversion();

// Subject
$subject "Contact Form Response";

// Build Message
$email_content "First Name: $fname\n";
$email_content .= "Last Name: $lname\n";
$email_content .= "Company: $company\n";
$email_content .= "Department: $department\n";
$email_content .= "Website: $website\n";
$email_content .= "Email: $email\n\n";
$email_content .= "Message:\n$message\n\n\n";
$email_content .= "CLIENT IP:\n".get_client_ip()."\n";
$email_content .= "HOST IP:\n".$_SERVER['SERVER_ADDR']."\n";

// Check if sent
try {
$sendmailResult mail($recipient$subject$email_content$headers);
if( 
$sendmailResult === TRUE ) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
TRUE
)
);
} else {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'ERROR_AT_PHPMAIL',
array(
'error_information'=> error_get_last() )
)
);
}
} catch (
Exception $_e) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
TRUE,
'ERROR_AT_PHPMAIL',
array(
'error_message'=> $_e->getMessage())
)
);
}

/*
Construct ajax response array
Input: Result (bool), Message (optional), Data to be sent back in array
*/
function constructAjaxResponseArray ($_response$_message ''$_json null) {
$_responseArray = array();
$_response = ( $_response === TRUE ) ? TRUE FALSE;
$_responseArray['response'] = $_response;
if(isset(
$_message)) $_responseArray['message'] = $_message;
if(isset(
$_json)) $_responseArray['json'] = $_json;

return 
$_responseArray;
}
/*
Returns in the Gframe ajax format.
Input: data array processed by constructAjaxResponseArray ()
Outputs as a html stream then exits.
*/
function returnAndExitAjaxResponse ($_ajaxResponse) {
if(!
$_ajaxResponse){
$_ajaxResponse = array('response'=>false,'message'=>'Unknown error occurred.');
}
header("Content-Type: application/json; charset=utf-8");
echo 
json_encode($_ajaxResponse);
die();
}


// Function to get the client IP address
function get_client_ip() {
    
$ipaddress '';
    if (isset(
$_SERVER['HTTP_CLIENT_IP'])) {
        
$ipaddress $_SERVER['HTTP_CLIENT_IP'];
    } else if(isset(
$_SERVER['HTTP_X_FORWARDED_FOR'])) {
        
$ipaddress $_SERVER['HTTP_X_FORWARDED_FOR'];
    } else if(isset(
$_SERVER['HTTP_X_FORWARDED'])) {
        
$ipaddress $_SERVER['HTTP_X_FORWARDED'];
    } else if(isset(
$_SERVER['HTTP_FORWARDED_FOR'])) {
        
$ipaddress $_SERVER['HTTP_FORWARDED_FOR'];
    } else if(isset(
$_SERVER['HTTP_FORWARDED'])) {
        
$ipaddress $_SERVER['HTTP_FORWARDED'];
    } else if(isset(
$_SERVER['REMOTE_ADDR'])) {
        
$ipaddress $_SERVER['REMOTE_ADDR'];
    } else {
        
$ipaddress 'UNKNOWN';
    }
    return 
$ipaddress;
}
?>

If anyone has a solution to this let me know! However I got someone messaging me
right now on Discord about the issue. Smile
[Image: giphy.gif]

RE: ReCAPTCHA Headache

Quietz
YOUR FRIENDLY MEMBER
Prime
Level:
0
Reputation:
24
Posts:
221
Likes:
19
Credits:
0
09-11-2018, 08:18 PM
This post was last modified: 09-11-2018, 08:18 PM by Quietz
#2
Damn Nolan, I told you like 3 times to NOT use it. Probably with a LITTLE bit of knowledge will telll you that.

RE: ReCAPTCHA Headache

Gummy
Verified Rad Pirate Dad
Supreme
Level:
5
Reputation:
60
Posts:
1.39K
Likes:
85
Credits:
49
OP
09-11-2018, 08:23 PM
#3
09-11-2018, 08:18 PM
Quietz Wrote:
Damn Nolan, I told you like 3 times to NOT use it. Probably with a LITTLE bit of knowledge will telll you that.

"Don't use it" it's already in place wtf XD
[Image: giphy.gif]

RE: ReCAPTCHA Headache

Quietz
YOUR FRIENDLY MEMBER
Prime
Level:
0
Reputation:
24
Posts:
221
Likes:
19
Credits:
0
09-11-2018, 08:23 PM
#4
09-11-2018, 08:23 PM
Gummy Wrote:
"Don't use it" it's already in place wtf XD

Running exploit rn






jk

RE: ReCAPTCHA Headache

Gummy
Verified Rad Pirate Dad
Supreme
Level:
5
Reputation:
60
Posts:
1.39K
Likes:
85
Credits:
49
OP
09-11-2018, 08:24 PM
#5
09-11-2018, 08:23 PM
Quietz Wrote:
Running exploit rn






jk

>:C quit being a meanie.
[Image: giphy.gif]

RE: ReCAPTCHA Headache

lucasbarin
Newbie
Level:
0
Reputation:
0
Posts:
14
Likes:
0
Credits:
16
13-11-2018, 02:03 PM
#6
In anyone having troubleshots with the version 3.0 of the recapctha? What do you thnk about keep using the 2.0 version (I am not a robot)?

RE: ReCAPTCHA Headache

shawpon2010
Lurker
Level:
0
Reputation:
0
Posts:
1
Likes:
0
Credits:
1
18-11-2018, 08:52 PM
#7
Running exploit rn , google recaptha is a headache

RE: ReCAPTCHA Headache

fergvrfv
Newbie
Level:
0
Reputation:
0
Posts:
15
Likes:
0
Credits:
23
20-01-2019, 12:45 PM
#8
your method it is very original to share things thank you very much

RE: ReCAPTCHA Headache

zSonntag
Newbie
Level:
0
Reputation:
0
Posts:
15
Likes:
1
Credits:
30
22-01-2019, 04:36 AM
#9
Look's very nice, will I look at site without registration?

RE: ReCAPTCHA Headache

Tapsix
Newbie
Level:
0
Reputation:
0
Posts:
14
Likes:
1
Credits:
15
04-08-2019, 12:26 AM
#10
09-11-2018, 07:44 PM
makasih ya gan , thanks Wrote:
I don't know if anyone here is interested/proficient in PHP but I'm throwing Google's ReCAPTCHA on our
website because we've been getting a lot of spam lately and I can't figure this thing out for the life of me.

Apparently, according to [@18568], our contact form backend is full of vulns as well as the functionality
of the PHP script itself is just ass. Here is the code...

PHP Code:
<?php
// Your Email
$recipient "[email protected]"// PLEASE SET YOUR EMAIL ADDRESS
$recaptcha_secret_key '-HIDDEN-'// PLEASE SET YOUR GOOGLE RECAPTCHA API KEY.

// Recaptcha check up
// Requires curl. If your server does not support curl, this script does not work.
if(isset($_POST["g-recaptcha-response"]) && $recaptcha_secret_key !== '') {
$endpoint 'https://www.google.com/recaptcha/api/siteverify?secret=' $recaptcha_secret_key '&response=' $_POST['g-recaptcha-response'] ;
$curl curl_init() ;
curl_setopt$curl CURLOPT_URL $endpoint ) ;
curl_setopt$curl CURLOPT_SSL_VERIFYPEER false ) ;
curl_setopt$curl CURLOPT_RETURNTRANSFER true ) ;
curl_setopt$curl CURLOPT_TIMEOUT ) ;
$json curl_exec$curl ) ;
curl_close$curl ) ;

if(
json_decode($json)->success === false) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'RECAPTCHA_FAILED',
array(
'error_message'=> 'RECAPTCHA_FAILED')
)
);
}

$json json_decode($json);

if(
json_decode($json)->success === false) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'RECAPTCHA_FAIL_RESPONSE',
array(
'error_message'=> 'Recaptcha response is not valid.')
)
);
}
}

// Check $recipient
if($recipient === '') {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'RECIPIENT_IS_NOT_SET',
array(
'error_message'=> 'RECIPIENT email address is not set. Please configure the script.')
)
);
}

// Check for empty required field
if(!isset($_POST["email"]) || !isset($_POST["fname"]) || !isset($_POST["message"])) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'MISSING_REQUIRED_FIELDS',
array(
'error_message'=> 'MISSING_REQUIRED_FIELDS should not be occurred.')
)
);
}

// Sanitize input
$fnamefilter_var($_POST["fname"], FILTER_SANITIZE_STRING);
$lnamefilter_var($_POST["lname"], FILTER_SANITIZE_EMAIL);
$website $_POST["website"];
if (!
preg_match("~^(?:f|ht)tps?://~i"$website)) $website "http://" $website;
$website filter_var($websiteFILTER_VALIDATE_URL);
$email filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
$company filter_var($_POST["company"], FILTER_SANITIZE_STRING);
$department filter_var($_POST["department"], FILTER_SANITIZE_STRING);
$message filter_var($_POST["message"], FILTER_SANITIZE_STRINGFILTER_FLAG_NO_ENCODE_QUOTES);

// If non required fields are empty
if ( empty($lname) ){
$lname "No last name entered.";
}
if ( empty(
$website) ){
$website "No website entered.";
}
if ( empty(
$company) ){
$company "No company entered."
}

// Headers
$headers 'From: '.$fname.' <'.$email.'>' "\r\n";
$headers .= 'Reply-To: '.$email.'' "\r\n";
$headers .= 'X-Mailer: PHP/' phpversion();

// Subject
$subject "Contact Form Response";

// Build Message
$email_content "First Name: $fname\n";
$email_content .= "Last Name: $lname\n";
$email_content .= "Company: $company\n";
$email_content .= "Department: $department\n";
$email_content .= "Website: $website\n";
$email_content .= "Email: $email\n\n";
$email_content .= "Message:\n$message\n\n\n";
$email_content .= "CLIENT IP:\n".get_client_ip()."\n";
$email_content .= "HOST IP:\n".$_SERVER['SERVER_ADDR']."\n";

// Check if sent
try {
$sendmailResult mail($recipient$subject$email_content$headers);
if( 
$sendmailResult === TRUE ) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
TRUE
)
);
} else {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
FALSE,
'ERROR_AT_PHPMAIL',
array(
'error_information'=> error_get_last() )
)
);
}
} catch (
Exception $_e) {
returnAndExitAjaxResponse(
constructAjaxResponseArray(
TRUE,
'ERROR_AT_PHPMAIL',
array(
'error_message'=> $_e->getMessage())
)
);
}

/*
Construct ajax response array
Input: Result (bool), Message (optional), Data to be sent back in array
*/
function constructAjaxResponseArray ($_response$_message ''$_json null) {
$_responseArray = array();
$_response = ( $_response === TRUE ) ? TRUE FALSE;
$_responseArray['response'] = $_response;
if(isset(
$_message)) $_responseArray['message'] = $_message;
if(isset(
$_json)) $_responseArray['json'] = $_json;

return 
$_responseArray;
}
/*
Returns in the Gframe ajax format.
Input: data array processed by constructAjaxResponseArray ()
Outputs as a html stream then exits.
*/
function returnAndExitAjaxResponse ($_ajaxResponse) {
if(!
$_ajaxResponse){
$_ajaxResponse = array('response'=>false,'message'=>'Unknown error occurred.');
}
header("Content-Type: application/json; charset=utf-8");
echo 
json_encode($_ajaxResponse);
die();
}


// Function to get the client IP address
function get_client_ip() {
  
$ipaddress '';
  if (isset(
$_SERVER['HTTP_CLIENT_IP'])) {
    
$ipaddress $_SERVER['HTTP_CLIENT_IP'];
  } else if(isset(
$_SERVER['HTTP_X_FORWARDED_FOR'])) {
    
$ipaddress $_SERVER['HTTP_X_FORWARDED_FOR'];
  } else if(isset(
$_SERVER['HTTP_X_FORWARDED'])) {
    
$ipaddress $_SERVER['HTTP_X_FORWARDED'];
  } else if(isset(
$_SERVER['HTTP_FORWARDED_FOR'])) {
    
$ipaddress $_SERVER['HTTP_FORWARDED_FOR'];
  } else if(isset(
$_SERVER['HTTP_FORWARDED'])) {
    
$ipaddress $_SERVER['HTTP_FORWARDED'];
  } else if(isset(
$_SERVER['REMOTE_ADDR'])) {
    
$ipaddress $_SERVER['REMOTE_ADDR'];
  } else {
    
$ipaddress 'UNKNOWN';
  }
  return 
$ipaddress;
}
?>

If anyone has a solution to this let me know! However I got someone messaging me
right now on Discord about the issue. Smile

Users browsing this thread: 1 Guest(s)