Last active
October 31, 2023 16:05
-
-
Save NTICompass/06eb0e60f004a073833d to your computer and use it in GitHub Desktop.
Bulk-remove Mandrill sending domains
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Quick and dirty script to remove spam domains from our mandrill account | |
define('API_KEY', ''); | |
// Their API doesn't offer a "delete" method, so I'm using their website | |
define('USERNAME', ''); | |
define('PASSWORD', ''); | |
echo 'Downloading domain list...'; | |
// Step 1, get all "sending domains" via their API | |
$jsonKey = json_encode(['key' => API_KEY]); | |
$api = curl_init('https://mandrillapp.com/api/1.0/senders/domains.json'); | |
curl_setopt_array($api, [ | |
CURLOPT_POST => TRUE, | |
CURLOPT_RETURNTRANSFER => TRUE, | |
CURLOPT_POSTFIELDS => $jsonKey, | |
CURLOPT_HTTPHEADER => [ | |
'Content-type: application/json', | |
'Content-length: '.strlen($jsonKey) | |
] | |
]); | |
if(($jsonDomains = curl_exec($api)) === FALSE){ | |
die("cURL error\n".curl_error($api)."\n"); | |
} | |
echo "done.\n"; | |
$domains = json_decode($jsonDomains, TRUE); | |
curl_close($api); | |
echo count($domains)." domains found\n"; | |
// Step 2: Filter out *valid* domains! | |
echo "\n"; | |
$badDomains = []; | |
foreach($domains as $domain){ | |
if($domain['spf']['valid'] || $domain['dkim']['valid'] || $domain['valid_signing']){ | |
echo "Keeping {$domain['domain']}\n"; | |
} | |
else{ | |
$badDomains[] = $domain['domain']; | |
} | |
} | |
echo "\nRemoving ".count($badDomains)." domains\n"; | |
// Step 3: Login to MailChimp's website | |
$siteCookies = tempnam(sys_get_temp_dir(), 'mandrill'); | |
// To do this, we need to scrape the '__csrf_token' from the form | |
$login = curl_init('https://login.mailchimp.com/'); | |
curl_setopt_array($login, [ | |
CURLOPT_HTTPGET => TRUE, | |
CURLOPT_RETURNTRANSFER => TRUE, | |
CURLOPT_FOLLOWLOCATION => TRUE, | |
CURLOPT_AUTOREFERER => TRUE, | |
CURLOPT_COOKIEFILE => $siteCookies, | |
CURLOPT_COOKIEJAR => $siteCookies, | |
CURLOPT_HTTPHEADER => [ | |
'Accept-Encoding: gzip, deflate', | |
] | |
]); | |
if(($html = curl_exec($login)) === FALSE){ | |
die("cURL error\n".curl_error($login)."\n"); | |
} | |
curl_close($login); | |
$web = new DOMDocument; | |
libxml_use_internal_errors(TRUE); | |
$web->loadHTML(gzdecode($html)); | |
$xpath = new DOMXpath($web); | |
$csrf_el = $xpath->query("//input[@name='__csrf_token']/@value"); | |
$csrf = count($csrf_el) > 0 ? $csrf_el->item(0)->nodeValue : ''; | |
echo "Captured __csrf_token={$csrf}\n"; | |
$website = curl_init('https://login.mailchimp.com/login/post'); | |
curl_setopt_array($website, [ | |
#CURLOPT_VERBOSE => TRUE, | |
CURLOPT_POST => TRUE, | |
CURLOPT_RETURNTRANSFER => TRUE, | |
CURLOPT_POSTFIELDS => http_build_query([ | |
'referrer' => '/transactional/launch', | |
'username' => USERNAME, | |
'password' => PASSWORD, | |
'__csrf_token' => $csrf, | |
'from' => '', | |
'auth_token' => '', | |
'auth_system' => '', | |
]), | |
CURLOPT_FOLLOWLOCATION => TRUE, | |
CURLOPT_AUTOREFERER => TRUE, | |
CURLOPT_COOKIEFILE => $siteCookies, | |
CURLOPT_COOKIEJAR => $siteCookies, | |
CURLOPT_REFERER => 'https://login.mailchimp.com/', | |
CURLOPT_HTTPHEADER => [ | |
'Origin: https://login.mailchimp.com', | |
'Accept-Encoding: gzip, deflate', | |
] | |
]); | |
if(($x = curl_exec($website)) === FALSE){ | |
echo "Cannot login to Mandrill\n"; | |
die("cURL error\n".curl_error($website)."\n"); | |
} | |
curl_close($website); | |
// MailChimp is doing something "fun", | |
// it's returning a form you need to submit... after posting the login form | |
$loginForm = new DOMDocument; | |
$loginForm->loadHTML(gzdecode($x)); | |
$formData = $loginForm->getElementsByTagName('form'); | |
if (count($formData)) { | |
$loginUrl = $formData->item(0)->getAttribute('action'); | |
$loginFormData = []; | |
foreach ($formData->item(0)->getElementsByTagName('input') as $field) { | |
$loginFormData[$field->getAttribute('name')] = $field->getAttribute('value'); | |
} | |
$website = curl_init($loginUrl); | |
curl_setopt_array($website, [ | |
#CURLOPT_VERBOSE => TRUE, | |
CURLOPT_POST => TRUE, | |
CURLOPT_RETURNTRANSFER => TRUE, | |
CURLOPT_POSTFIELDS => http_build_query($loginFormData), | |
CURLOPT_FOLLOWLOCATION => TRUE, | |
CURLOPT_AUTOREFERER => TRUE, | |
CURLOPT_COOKIEFILE => $siteCookies, | |
CURLOPT_COOKIEJAR => $siteCookies, | |
CURLOPT_REFERER => 'https://login.mailchimp.com/login/post/', | |
CURLOPT_HTTPHEADER => [ | |
'Origin: https://login.mailchimp.com', | |
'Accept-Encoding: gzip, deflate', | |
] | |
]); | |
if(($x = curl_exec($website)) === FALSE){ | |
echo "Cannot login to Mandrill\n"; | |
die("cURL error\n".curl_error($website)."\n"); | |
} | |
curl_close($website); | |
// After posting this login form, we redirect to Mandrill | |
// And guess what, another form to post... | |
$mandrillForm = new DOMDocument; | |
$mandrillForm->loadHTML(gzdecode($x)); | |
$formData = $mandrillForm->getElementsByTagName('form'); | |
if (count($formData)) { | |
$adminDomain = parse_url($loginUrl, PHP_URL_HOST); | |
$loginFormData = []; | |
foreach ($formData->item(0)->getElementsByTagName('input') as $field) { | |
$loginFormData[$field->getAttribute('name')] = $field->getAttribute('value'); | |
} | |
$website = curl_init($formData->item(0)->getAttribute('action')); | |
curl_setopt_array($website, [ | |
#CURLOPT_VERBOSE => TRUE, | |
CURLOPT_POST => TRUE, | |
CURLOPT_RETURNTRANSFER => TRUE, | |
CURLOPT_POSTFIELDS => http_build_query($loginFormData), | |
CURLOPT_FOLLOWLOCATION => TRUE, | |
CURLOPT_AUTOREFERER => TRUE, | |
CURLOPT_COOKIEFILE => $siteCookies, | |
CURLOPT_COOKIEJAR => $siteCookies, | |
CURLOPT_REFERER => "https://{$adminDomain}/transactional/launch", | |
CURLOPT_HTTPHEADER => [ | |
"Origin: https://{$adminDomain}", | |
'Accept-Encoding: gzip, deflate', | |
] | |
]); | |
if(($x = curl_exec($website)) === FALSE){ | |
echo "Cannot login to Mandrill\n"; | |
die("cURL error\n".curl_error($website)."\n"); | |
} | |
curl_close($website); | |
} | |
} | |
echo "Logged into Mandrill website\n"; | |
echo "Removing domains via website...\n"; | |
foreach($badDomains as $domain){ | |
echo "\t{$domain}..."; | |
$query = http_build_query([ | |
'domain' => $domain | |
]); | |
$website = curl_init("https://mandrillapp.com/settings/delete-domain?{$query}"); | |
curl_setopt_array($website, [ | |
CURLOPT_HTTPGET => TRUE, | |
CURLOPT_RETURNTRANSFER => TRUE, | |
CURLOPT_FOLLOWLOCATION => TRUE, | |
CURLOPT_AUTOREFERER => TRUE, | |
CURLOPT_COOKIEFILE => $siteCookies, | |
CURLOPT_COOKIEJAR => $siteCookies, | |
CURLOPT_REFERER => 'https://mandrillapp.com/settings/sending-domains', | |
]); | |
if(($x = curl_exec($website)) === FALSE){ | |
echo "Cannot remove {$domain}\n"; | |
die("cURL error\n".curl_error($website)."\n"); | |
} | |
curl_close($website); | |
echo "done\n"; | |
} | |
echo "\ndone\n"; |
Since logging in is difficult since they combined it with Mailchimp, the easiest way is to login, and extract the session cookie and then set it using define('COOKIE', 'PHPSESSID=XXX')
.
Then, replace the CURLOPT_COOKIE*
arguments with:
CURLOPT_HTTPHEADER => array("Cookie: ".COOKIE, 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36'),
You need to set the User-Agent
header or it doesn't work.
Here's the updated script:
<?php
// Quick and dirty script to remove spam domains from our mandrill account
define('API_KEY', '');
define('COOKIE', '');
echo 'Downloading domain list...';
// Step 1, get all "sending domains" via their API
$jsonKey = json_encode(['key' => API_KEY]);
$api = curl_init('https://mandrillapp.com/api/1.0/senders/domains.json');
curl_setopt_array($api, [
CURLOPT_POST => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_POSTFIELDS => $jsonKey,
CURLOPT_HTTPHEADER => [
'Content-type: application/json',
'Content-length: '.strlen($jsonKey)
]
]);
if(($jsonDomains = curl_exec($api)) === FALSE){
die("cURL error\n".curl_error($api)."\n");
}
echo "done.\n";
$domains = json_decode($jsonDomains, TRUE);
curl_close($api);
echo count($domains)." domains found\n";
// Step 2: Filter out *valid* domains!
echo "\n";
$badDomains = [];
foreach($domains as $domain){
if($domain['verified_at']){
echo "Keeping {$domain['domain']}\n";
}
else{
$badDomains[] = $domain['domain'];
}
}
echo "\nRemoving ".count($badDomains)." domains\n";
echo "Logged into Mandrill website\n";
echo "Removing domains via website...\n";
foreach($badDomains as $domain){
echo "\t{$domain}...";
$query = http_build_query([
'domain' => $domain
]);
$website = curl_init("https://mandrillapp.com/settings/delete-domain?{$query}");
curl_setopt_array($website, [
CURLOPT_HTTPGET => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_AUTOREFERER => TRUE,
CURLOPT_HTTPHEADER => array("Cookie: ".COOKIE, 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36'),
CURLOPT_REFERER => 'https://mandrillapp.com/settings/sending-domains',
]);
if(($x = curl_exec($website)) === FALSE){
echo "Cannot remove {$domain}\n";
die("cURL error\n".curl_error($website)."\n");
}
curl_close($website);
echo "done\n";
}
echo "\ndone\n";
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Finally got around to trying it again. Doesn't work yet unfortunately. No worries if you don't feel like updating this. ;-)