twhiting9275 Posted July 19, 2016 Share Posted July 19, 2016 (edited) Dealing with spam / malware is never easy. When dealing with a cPanel/WHMCS combination, welll, it's a bit more complicated. It often goes a bit like this. Login via SSH Find out which user is causing spam Suspend account Clean out spam Login to WHM Find out what user owns said spamming account Login to WHMCS Find out what billing user is associated with said user Send out lengthy notification of abuse and suspension It would really be nice if this could all be done in a condensed version, right? RIGHT? Well, here you go (you're welcome). This will require a few steps initially, but in the end, it will pay off with one simple command to suspend/notify the user. Step 1: Place the following code in a file. This is an sh file #!/usr/bin/env bash #Command line tool to suspend account and notify user via ticket shopt -s extglob args=("$@") user=${args[0]} date=`date +%F-%k%M` function show_usage { echo -e "Syntax: suspendacct.sh user"; exit 1 } if [ -z "$user" ] then show_usage fi echo -e "Working with:\t $user"; /scripts/suspendacct $user 'spamming' 1 reseller=$(whmapi1 accountsummary user=$user | grep owner) output="${reseller##*( )}" realseller=${output:7} echo -e "Reseller is:\t $realseller"; suspdomain=$(whmapi1 accountsummary user=$user | grep "domain:") output3="${suspdomain##*( )}" realdomain=${output3:8} echo -e "Domain is:\t $realdomain"; owneremail=$(whmapi1 accountsummary user=$realseller | grep "email:") output2="${owneremail##*( )}" realemail=${output2:7} echo -e "Owner Email is:\t $realemail"; ownerdomain=$(whmapi1 accountsummary user=$reseller | grep "domain:") output4="${ownerdomain##*( )}" ownerdomain=${output4:8} echo -e "Owner Domain:\t$ownerdomain"; echo -e "Creating Ticket for $realdomain [$realemail]"; php /path/to/filename $realdomain $realemail $realseller $ownerdomain The only thing you need to modify is the /path/to/filename . That is where you're going to place Step 2: Place the following code in a php file on your server somewhere. <?php require_once("whmcs_abuse.inc"); $domain = $argv['1']; $email = $argv['2']; $email = str_replace(' ', '', $email); $reseller = $argv['3']; $odomain = $argv['4']; print"Domain:\t $domain\n"; print"Email:\t $email\n"; $ticketsubject .= " $domain"; print "$ticketsubject" ; $postfields = array( 'username' => $username, 'password' => md5($password), 'action' => 'getclientsproducts', 'username2' => $reseller, 'domain' => $odomain, 'responsetype' => 'json', ); // Call the API $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url . 'includes/api.php'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields)); $response = curl_exec($ch); if (curl_error($ch)) { die('Unable to connect: ' . curl_errno($ch) . ' - ' . curl_error($ch)); } curl_close($ch); $jsonData = json_decode($response, true); $array1 = $jsonData['products']; $array2 = $array1['product']; $array3 = $array2['0']; //print_r($array3); $clientid= $array3['clientid']; print ("\nClient id: $clientid\n"); if (empty($clientid)) { die("I cannot open a ticket. Please manually lookup reseller $reseller\n"); } // Set post values $postfields = array( 'username' => $username, 'password' => md5($password), 'action' => 'OpenTicket', 'clientid' => $clientid, 'markdown' => 1, 'email' => $email, 'deptid' => $deptid, 'subject' => $ticketsubject, 'message' => $ticketbody, 'priority' => 'high', 'responsetype' => 'json', ); // Call the API $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url . 'includes/api.php'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields)); $response = curl_exec($ch); if (curl_error($ch)) { die('Unable to connect: ' . curl_errno($ch) . ' - ' . curl_error($ch)); } curl_close($ch); // print_r($response); // Attempt to decode response as json $jsonData = json_decode($response, true); $ticketid = $jsonData['id']; print "Ticket id:\t $ticketid"; /* Update the ticket to the necesary status. Must be done after ticket submission Anything below here is optional */ $postfields = array( 'username' => $username, 'password' => md5($password), 'action' => 'updateticket', 'ticketid' => $ticketid, 'status' => $ticketstatus, 'responsetype' => 'json', ); // Call the API $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url . 'includes/api.php'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields)); $response = curl_exec($ch); if (curl_error($ch)) { die('Unable to connect: ' . curl_errno($ch) . ' - ' . curl_error($ch)); } curl_close($ch); $jsonData = json_decode($response, true); ?> Now, edit the first file. Point to this file in the last line. Step 3: One last file here. Call this whmcs_abuse.inc. Place it in the same directory as the file from step 2 <?php $url = "; # WHMCS url $username = ""; # Admin username goes here $password = ""; # Admin password goes here $ticketsubject = "Abuse notification for"; $deptid = ""; #what department do you want this in $ticketstatus = "Customer To Reply"; #what status do you want to place this in $ticketbody = "Hello, It's come to our attention that your domain has been the target of some very abusive activity, causing your server to have an excessive email queue Due to the excessive amount of spam coming from this domain, we've had to suspend this account. Please note that you may unsuspend this, but we do require that until you resolve the issue, you make this site available to you and your employees only. To do this, you may add the following to your .htaccess file. ``` <Limit GET POST> order deny,allow deny from all ALLOW FROM your ip </Limit> ``` Please note that you **must** run a full scan and update any vulnerable software, themes, plugins, or code in order to ensure that this does not continue. This activity is most often caused by out of date, or vulnerable plugins , software, or templates. Please do ensure that your software, templates and plugins are all at the latest version and not vulnerable to any sort of hacking activity in order to ensure that this does not happen again."; Step 4: Add your server's IP to the API IP Access Restriction list (admin -> setup -> security, toward the bottom of the page). Make sure to save your settings Now, you have a working script. Assuming you've edited the first script, you've saved yourself a ton of time, and you can simply do the following to investigate and suspend spammers, assuming you named the script suspendacct.sh suspendacct.sh username This will suspend the account, send the informational email to the client, and save you a few steps in the process. Note: This line from the first script will remove the ability for the reseller to unsuspend this account: /scripts/suspendacct $user 'spamming' 1 This is somewhat necessary I've found, as resellers tend to unsuspend and then not address the problem. This will force them to reply to the ticket, acknowledge the problem and let you know what they plan on doing to fix the issue. You can change this to /scripts/suspendacct $user 'spamming' 0 to avoid this behavior. Edited July 19, 2016 by twhiting9275 0 Quote Link to comment Share on other sites More sharing options...
twhiting9275 Posted December 24, 2016 Author Share Posted December 24, 2016 Merry Christmas, I've taken a bit of time and updated this so that it will actually work properly . While it worked before, there were a few issues with it Bug Fixes -- WHMCS wouldn't notify if a direct customer (not reseller) was suspended -- Fixed -- Correct domain in subject. Previously , the script went off of the account's main domain. Now a second argument is required and passed to the php script. This will reflect in the ticket subject New Features -- Added logs for staff viewing . 3 notes will be added after ticket creation -- exigrep /home/user -- exigrep $abusedomain -- exim -bp | grep $abusedomain This should help resolve, or identify issues -- Added ID / server /domain to ticket as a staff note for quick reference -- New ticket no longer created if client has an open ticket for this same domain , ticket is replied to instead. -- Universal CurlPost, cleaning up the code a good bit. Files are included in the zip file attached. You'll have to change the file called (last line of the bash script), and edit whmcs_abuse.inc for your own personal taste, but this should be all that's needed. As always, if problems, let me know and I'll see if I can fix them for you Suspend.zip 0 Quote Link to comment Share on other sites More sharing options...
ranlie Posted December 2, 2017 Share Posted December 2, 2017 (edited) Hi thank you so much for this useful scrop by the way how about if the account was from the master reseller how can i edit the scrip to locate the mater reseller i am getting this error [root@sv2 ~]# sh suspendacct.sh sinergiahumana sinergiahumana.net Working with: sinergiahumana Changing Shell to /bin/false...Done Locking Password...Done Suspending email account logins for sinergiahumana.net .... Done Suspending mysql users Account previously suspended (password was locked). Suspending websites... Suspending outgoing email....Done sinergiahumana's account has been suspended Reseller is: hostserv Domain is: <removed Personal INformation> Owner Email is: <removed Personal INformation> Owner Domain: Creating Ticket for<removed Personal INformation> Content-type: text/html; charset=UTF-8 I'm sorry, I'm unable to open a ticket for hostserv. Please double check the username or WHMCS database for sinergiahumana.net Edited December 17, 2017 by WHMCS ChrisD Removed PII 0 Quote Link to comment Share on other sites More sharing options...
MYGSG - Nicholas S Posted June 24, 2019 Share Posted June 24, 2019 @twhiting9275 - Is this still working? 0 Quote Link to comment Share on other sites More sharing options...
mauwiks Posted February 11, 2021 Share Posted February 11, 2021 I have contacted the developer and hopefully he would answer for an updated paid version 0 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.