Postfix Vulnerable via postfix/pickup

Discussion in 'Server Operation' started by girthh, Dec 7, 2019.

  1. girthh

    girthh New Member

    Firstly, following perfect server tutorials has been a great learning opportunity and I want to still believe that all hope is not lost with creating a very secure server for all of these websites I want to change the world with.


    Problem #1: Some hacker is successfully sending mail with my mail server via POSTFIX/PICKUP (some "[email protected]" email), which isn't listed on my ISPCONFIG 3 emails. The mail is getting passed to amavis then injected into postfix to be sent. P.S. There is no wordpress on the previously mentioned "@site" but there is a wordpress on a different website built through ISPCONFIG (same server).

    Problem #2: I was previously under the impression that the only way to access Postfix was via Roundcube-Password-Login or SSH. Maybe even some site-side PHP Mail vulnerabilities (if there were any).

    Problem #3: I do not understand fully what postfix's anvil "max connection rate 1/60s" is actually limiting.


    ------------------------------------------------

    Server Specs: Perfect server tutorial (Debian 10, Nginx, ISPconfig, roundcube, postfix, dovecot, mariadb). I skipped and successfully disabled clamav for the memory. All the passwords are randomly generated and 256 character where permissible length. Fail2Ban is very strict. SSH-only root access with private key on computer. Dhparams 4096.

    Roundcube Config Specs:
    (defaults.inc.php)
    $config['force_https'] = true;
    $config['smtp_port'] = 25;
    $config['smtp_server'] = 'tls://localhost';

    Some Mail.log data: (postfix/pickup/amavis gateway)(note: mydomain2 is a domain on ISPconfig; mydomain1 is the main /etc/hosts domain without the hostname)
    Master.cf:
    Main.cf:


    Let's solve some issues for everyone here, and thank you to the major names who I have seen over the years helping many many people with their servers here on Howtoforge, from ISPconfig to Postfix and everything in between. It would be an honor to even see your names popping up in my issue. Thank Devs and Super Mods! You guys keep the world spinning!

    >>About me<<
    Ive been learning how to forge a perfect server for two years straight; trying to perfect a server for so long now that it's mind blowing. I am running into spam folder issues and vulnerabilities which land my URL's into blacklists for many a year now. I really need help from the experts. I am so tired of spending weeks and weeks and month after month, all day every day trying to learn and fix servers just for them not to be up to par. I am very grateful for the thousands of forums I have read, I have learned a lot, but its time to get the server walking on its own two feet. Oops, did I say walking? I meant working. Cuz that's why I made this child. To work for me. For ever. Thank you robots: You are humans' best friends.
     
    Last edited: Dec 7, 2019
  2. girthh

    girthh New Member

    Thanks again in advance dev team: you have my faith
     
  3. Taleman

    Taleman Well-Known Member HowtoForge Supporter

    Are you running an open relay?
    When I have installed ISPConfig using the Perfect Server Guides, the e-mail server has not been an open relay. Do you have some addtitional settings that would cause open relay? Use Internet Search Engines with
    Code:
    postfix check for open relay
    For example:
    https://www.howtoforge.com/community/threads/how-to-disable-open-relay-on-postfix.44338/
     
    girthh likes this.
  4. girthh

    girthh New Member

    MXtoolbox says its not an open relay (image atached below).
    I also followed the link you sent, it led me to changing some main.cf paramenters in Postfix:
    smtpd_recipient_restrictions =
    -> added "permit_sasl_authenticated"
    -> removed "permit" from the bottom
    smtpd_sender_restrictions =
    -> removed "permit_mynetworks" and "permit" from the bottom​
    I will tail the mail logs for a while and get back to update everyone.
    If you think of anything else let me know!

     

    Attached Files:

  5. Steini86

    Steini86 Active Member

    The pickup daemon picks up messages put into the maildrop queue by the local sendmail user client program. (basically it watches the maildrop directory for any files placed there) The pickup daemon does not interact with the outside world. (http://www.postfix.org/pickup.8.html)
    This is necessary, so that local programs (like automated upgrade, cron, ispconfig, etc) can send mails without having a mailbox. It is also used for example by maildrop or others.
    So something runs on your server which is sending mails. This is not a postfix problem, but probably some service got hacked.
    I would suggest to refer to other logfiles (start with webserver) for log entries at the same time the mails are injected to postfix.

    Just shows you the statistics, that 1 message was sent in the last 60s. Usually the postfix standard settings are good. You could change them, but that is not connected to your problem:
    http://www.postfix.org/postconf.5.html#anvil_rate_time_unit
    http://www.postfix.org/postconf.5.html#smtpd_client_connection_rate_limit
     
    girthh likes this.
  6. till

    till Super Moderator Staff Member ISPConfig Developer

    The first thing that needs to be said is that postfix is not vulnerable trough postfix/pickup on your system, @Steini86 explained that in detail above. I just mention this as other readers might believe otherwise that there is an issue in the setup.

    Back to your original problem, a program or website on your server got hacked and is now sending emails locally. The most likely case here is that it's a hacked website, this can happen trough a vulnerability in the cms or a cms plugin. To narrow down the issue, you can do these steps:

    1) If you don't have many websites, then check with 'top' command if you see an unusual high load for a webXX user, the XX is the ID of the website. You can also check the access.log files of the sites if you see many POST requests in there as probably each spam mail is sent by a POST request to one of your sites.
    2) Scan your server for malware: https://www.howtoforge.com/tutorial/how-to-scan-linux-for-malware-and-rootkits/
    3) if you still have spam emails in the mailqueue (command: postqueue -p), then get the heaers of such an email with the command: postcat -q ID
    Where ID is that cryptic char/id that postqueue displays for each email. The postcat command will show the whole email, what is needed to analyze this is just the while header section at the beginning of the email.
     
    girthh likes this.
  7. girthh

    girthh New Member

    Potential problem cause: The access log for the website "/var/www/website/log" is filled with get requests. I found one POST request among others from my "contactpage.php" at the exact time when the attack happened. I am assuming that there is a vulnerability in my php code on the contact form php/html page.
    The form on the page uses "echo htmlspecialchars($_SERVER["PHP_SELF"])", and here is the page code if anyone has any suggestions for a more secure way/confirmation that we may have found the problem:
    Code:
    <?php
    
    $nameErr = $emailErr = $passwordErr = "";
    $email = $who = $subjectline = $name = $details = $attachment =  "";
    
    
    if($_SERVER["REQUEST_METHOD"] == "POST")
     {
         require_once 'contactus.php';
        $mwerrorimage = '<span><img class="shift1" src="mw-logo-warning-55.png" alt="" style="height:32px;"></span>';
        $name = $_POST['name'];
        $subjectline = $_POST['subjectline'];
        $who = $_POST['who'];
        $details = $_POST['details'];
        $attachment = $_POST['attachment'];
        $email = $_POST['email'];
      
        // check the bear
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
          $emailErr = $mwerrorimage . "Wrong Email.";
        // clean the bear
        }
        else{
            function test_input($email) {
            $email = trim($email);
            $email = stripslashes($email);
            $email = htmlspecialchars($email);
            return $email;
            }
            $to = $email;
            $subject = 'Service Request | MYWEBSITENAME ';
            $message[] = '
    <html>
    <head>
      <title>Request for MYWEBSITENAME </title>
    </head>
    <body>
      <br>
      <div style="border: 2px solid #ADB9FF;
        outline: #E0E0E0 solid 10px;padding:13px 5% 13px 5%;background: #000000;background: linear-gradient(60deg, #000005, #000005); color:#F7F8FF;">
        <div style="margin:auto;text-align:center;"><img src="MYWEBSITENAMElogo.png" style="margin:auto;text-align:center;height:54px;margin-bottom:33px;" /></div>
    <div style="color:#F7F8FF;font-size:12px;">
    We have recieved your service request '.$name.'. Someone should be in contact with your shortly.</div>
    <div style="color:#F7F8FF;padding-left:33%;font-size:12px;">-MYWEBSITENAME support team</div>
    
    </div>
    <br><br>
    <div style="position:absolute;margin:auto;text-align:center;bottom:5%; left:45%;right:20%;font-size:12px;color:#00A5FF;">MYWEBSITENAME copyright</div><br><br>
    </body>
    </html>
    ';
    $headers[] = 'MIME-Version: 1.0';
    $headers[] = 'Content-type: text/html; charset=iso-8859-1';
    $headers[] = 'From: [email protected]';
    $headers[] = 'Reply-To: [email protected]';
    $headers[] = 'Return-Path: [email protected]';
    $headers[] = 'Organization: MYWEBSITENAME';
    $headers[] = 'X-Mailer: PHP/';
            mail($to, $subject, implode("\r\n", $message), implode("\r\n", $headers));
    
            $stmt = $db_con->prepare("INSERT INTO MYWEBSITEDDATABASE (name, email, subjectline, who, details, attachment) VALUES (:name, :email, :subjectline, :who, :details, :attachment)");
            $stmt->bindParam(':name', $name);
            $stmt->bindParam(':email', $email);
            $stmt->bindParam(':subjectline', $subjectline);
            $stmt->bindParam(':who', $who);
            $stmt->bindParam(':details', $details);
            $stmt->bindParam(':attachment', $attachment);
                  
            $stmt->execute();
          
            $confirm = "We have received your service request.";
            }  
    }
    
    $conn=null;
    ?>
    
    <form name="login" class="sticky" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post" enctype="multipart/form-data">
    
     Name<br>
    <input type="text" name="name" id="name" placeholder="Name" value="<?php echo $name;?>" required>
    <input type="text" name="email" id="email" placeholder="Email" required> <span style="color: #FF0000;"></span>
    <input type="text" name="subjectline" id="subjectline" placeholder="Subject" value="<?php echo $subjectline;?>"  required> <span style="color: #FF0000;"><?php echo $subjectErr;?></span>
    <input type="text" name="phone" id="phone" placeholder="Phone Number"  >
    <select name="who" id="who">
      <option value="user" selected>User</option>
      <option value="manager">Manager</option>
      <option value="company">Company</option>
      <option value="affiliate partner">Affiliate Partner</option>
      <option value="prospective client">Prospective Client</option>
      <option value="shareholder/investor">Shareholder/Investor</option>
      <option value="press/media">Press/Media</option>
      <option value="other">Other</option>
    </select><br><br>
    Additional Details<br>
     <textarea name="details" id="details" style="width:81%;max-width:369px;" placeholder="Please describe why you are writing us." rows="21" cols="21"><?php echo $details;?></textarea>
    <br><br>
    Attachments<br>
    <input type="file" style="margin:auto;text-align:center;" accept="media_type" name="attachment" id="attachment" value="attachment"placeholder="attachment" value="<?php echo $attachment;?>" accept="text/*, image/*, application/pdf, application/vnd.ms-powerpoint, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.presentationml.presentation, video/*">
    
    <button type="submit">Submit</button>
    
    </form>
    

    **On another note, I learned about the TOP command just now, and its a useful command to view real-time memory/CPU usage for anyone else reading this: Definitely need to learn more about this...
    Code:
    TOP
    top -u usersnamehere
    Press 'h' for help.
    Press ā€˜cā€˜ option in running top command, it will display absolute path of running process.
    Press (Shift+P) to sort processes as per CPU utilization.
    default screen refresh interval is 3.0 seconds, same can be change pressing ā€˜dā€˜ option.
    

    mailq and postqueue -p both say "Mail queue is empty", so I am not sure how to view headers on already-sent mail to go back and inspect them, if this is even possible?



    On another note, I started a new thread about why the tail is filled with:
    Code:
    Dec  9 12:09:56 nyc postfix/smtpd[10113]: disconnect from unknown[185.234.216.87] ehlo=1 auth=0/1 commands=1/2
    Dec  9 12:09:56 nyc postfix/smtpd[10113]: connect from unknown[185.234.216.87]
    Dec  9 12:09:57 nyc postfix/smtpd[10113]: lost connection after AUTH from unknown[185.234.216.87]
    Dec  9 12:09:57 nyc postfix/smtpd[10113]: disconnect from unknown[185.234.216.87] ehlo=1 auth=0/1 commands=1/2
    Dec  9 12:09:57 nyc postfix/smtpd[10113]: connect from unknown[185.234.216.87]
    Dec  9 12:09:57 nyc postfix/smtpd[10113]: lost connection after AUTH from unknown[185.234.216.87]
    Dec  9 12:09:57 nyc postfix/smtpd[10113]: disconnect from unknown[185.234.216.87] ehlo=1 auth=0/1 commands=1/2
    Dec  9 12:09:57 nyc postfix/smtpd[10113]: connect from unknown[185.234.216.87]
    Dec  9 12:09:58 nyc postfix/smtpd[10113]: lost connection after AUTH from unknown[185.234.216.87]
    Dec  9 12:09:58 nyc postfix/smtpd[10113]: disconnect from unknown[185.234.216.87] ehlo=1 auth=0/1 commands=1/2
    Dec  9 12:09:58 nyc postfix/smtpd[10113]: connect from unknown[185.234.216.87]
    Dec  9 12:09:58 nyc postfix/smtpd[10113]: lost connection after AUTH from unknown[185.234.216.87]
    
    and
    Code:
    Dec  9 10:25:03 nyc postfix/smtpd[5977]: connect from localhost[127.0.0.1]
    Dec  9 10:25:03 nyc postfix/smtpd[5977]: lost connection after CONNECT from localhost[127.0.0.1]
    Dec  9 10:25:03 nyc postfix/smtpd[5977]: disconnect from localhost[127.0.0.1] commands=0/0
    Dec  9 10:25:03 nyc dovecot: imap-login: Disconnected (no auth attempts in 0 secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, secured, session=<pp/m/0aZOs9/AAAB>
    Dec  9 10:25:03 nyc dovecot: pop3-login: Disconnected (no auth attempts in 0 secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, secured, session=<Sh3n/0aZ8t5/AAAB>
    Dec  9 10:28:23 nyc postfix/anvil[5979]: statistics: max connection rate 1/60s for (smtp:185.234.219.81) at Dec  9 10:24:02
    Dec  9 10:28:23 nyc postfix/anvil[5979]: statistics: max connection count 1 for (smtp:185.234.219.81) at Dec  9 10:24:02
    Dec  9 10:28:23 nyc postfix/anvil[5979]: statistics: max cache size 1 at Dec  9 10:24:02
    Dec  9 10:30:02 nyc dovecot: imap-login: Disconnected (disconnected before auth was ready, waited 0 secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, secured, session=<CKO9EUeZSM9/AAAB>
    Dec  9 10:30:03 nyc postfix/smtpd[6214]: connect from localhost[127.0.0.1]
    Dec  9 10:30:03 nyc postfix/smtpd[6214]: lost connection after CONNECT from localhost[127.0.0.1]
    Dec  9 10:30:03 nyc postfix/smtpd[6214]: disconnect from localhost[127.0.0.1] commands=0/0
    Dec  9 10:30:03 nyc dovecot: pop3-login: Disconnected (no auth attempts in 1 secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, secured, session=<iHjBEUeZAN9/AAAB>
    Dec  9 10:30:52 nyc postfix/smtpd[6214]: connect from unknown[185.234.219.82]
    Dec  9 10:30:53 nyc postfix/smtpd[6214]: lost connection after AUTH from unknown[185.234.219.82]
    Dec  9 10:30:53 nyc postfix/smtpd[6214]: disconnect from unknown[185.234.219.82] ehlo=1 auth=0/1 commands=1/2
    Dec  9 10:34:13 nyc postfix/anvil[6220]: statistics: max connection rate 1/60s for (smtp:185.234.219.82) at Dec  9 10:30:52
    Dec  9 10:34:13 nyc postfix/anvil[6220]: statistics: max connection count 1 for (smtp:185.234.219.82) at Dec  9 10:30:52
    Dec  9 10:34:13 nyc postfix/anvil[6220]: statistics: max cache size 1 at Dec  9 10:30:52
    Dec  9 10:35:02 nyc dovecot: imap-login: Disconnected (disconnected before auth was ready, waited 0 secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, secured, session=<WlyfI0eZWM9/AAAB>
    
    because I do not understand why or if this is normal.
    That thread is here: https://www.howtoforge.com/communit...onnection-after-auth-and-localhost-too.83402/
     
  8. Steini86

    Steini86 Active Member

    girthh likes this.
  9. Taleman

    Taleman Well-Known Member HowtoForge Supporter

    If you have plain HTML form that allows sending e-mails that certainly gets exploited by spammers. You have to use some secure way to implement the form. I have used formmail in the past: https://www.formmail.com/
    However, if you on purpose allow the form user to write in any e-mail address and send it away, your e-mail host ends up on e-mail blacklists.
     
    girthh likes this.
  10. till

    till Super Moderator Staff Member ISPConfig Developer

    You should consider to add a captcha to your contact form.
     
    girthh likes this.
  11. girthh

    girthh New Member

    UPDATE::SOLVED

    contact_us_page.php was inserting data into database and ALSO sending an email directly with php mail() to confirm their submission was received. This blacklisted the IP.

    On another note, I updated Fail2ban a little stronger for added security, because im not sure if the php mail() function was hackable, or if it was just sending the correct confirmation messages to users signing up (I cant seem to find a place where sent mails are logged on the server).

    Thanks Devs!
     

Share This Page