VPN Attempts from Rotating IPs and Generic Usernames

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Please sign in to see details of an important advisory in our Customer Advisories area.

VPN Attempts from Rotating IPs and Generic Usernames

L0 Member

Hello all,

 

For several weeks, I have been getting many VPN login attempts from different IPs trying to login using generic usernames, like "guest", "support", "admin", etc.

 

Is this normal? Is there anything that I can do to stop this from happening?

 

I have attached a screenshot for additional context.

 

Thanks.

5 REPLIES 5

L6 Presenter

Welcome to the internet.... Yep, that is completely normal and expected with any internet connected device. On any given public connection there will be continuous stream of connections attempts to different services (VPN, SMTP, IMAP/POP, SSH, telnet, etc.) trying default userIDs and passwords as scammers and criminals attempt to find vulnerable services to exploit. These connection attempts will come from all over the world and may or may not be related to each other. There are certain geographic regions and host networks that are far more likely to source this traffic, though it is not strictly limited to a particular source.

 

If you are able, it is best to apply a Security Policy that limits source IPs/countries from Untrust to your GlobalProtect/VPN addresses (or the specific source addresses of IPSec tunnels if all you have is point-to-point VPNs). If all your users are in the US, for example, then limiting sources to US addresses will dramatically cut down noise and connection attempts (with perhaps a second Security Policy that can be enabled/disabled for employees on foreign travel). You can also try applying a initial Security Policy that drops all inbound traffic from sources in one or more of the dynamic blacklists (EDL) available from many different sources (such as the PaloAlto "High Risk" and "Known Malicious" IP lists, Firehol, SORBs, etc.). Other than that... you just sort of have to deal with the noise.

Cyber Elite
Cyber Elite

@mdmartin,

In addition to what @Adrian_Jensen already mentioned, I would highly recommend setting up automated remediation for failed login events if you have scripting knowledge. It's relatively easily to build a report of failed logins and analyze the login count and username attempted to automatically block source IPs sending invalid credentials. 

Is there an option to do directly in PAN-OS? Or is it limited to XD/Cortex integration, a manual report, or some other external processing to feed back into PAN-OS as an EDL?

How would this be done? Palo API?

Cyber Elite
Cyber Elite

I'm pretty sure I've detailed this previously but you would want to create a custom report on your firewall that you could trigger and pull via the API. Something like this:

      <entry name="Failed_GP_Login">
        <type>
          <globalprotect>
            <sortby>repeatcnt</sortby>
            <aggregate-by>
              <member>public_ip</member>
              <member>srcuser</member>
            </aggregate-by>
            <values>
              <member>repeatcnt</member>
            </values>
          </globalprotect>
        </type>
        <period>last-15-minutes</period>
        <topn>5000</topn>
        <topm>50</topm>
        <caption>Failed_GP_Login</caption>
        <query>( error eq 'Authentication failed: Invalid username or password' )</query>
      </entry>

 

Then the actual script as an example could utilize the following as a base template:

run_report = requests.post('https://' + str(firewall) + '/api?type=report&async=yes&reporttype=custom&reportname=Failed_GP_Login',headers=headers, verify=False)
# Note that this specific example utilizes the X-PAN-KEY header option. If you don't utilize that simply change it out to the following#
run_report = requests.post('https://' + str(firewall) + '/api?type=report&async=yes&reporttype=custom&reportname=Failed_GP_Login&key=' + str(key), verify=False)

report_dict = xmltodict.parse(run_report.content)
job_id = report_dict['response']['result']['job']
time.sleep(60) # Allow time for report to run #
request_report = requests.get('https://' + str(firewall) +'/api?type=op&cmd=<show><report><id>' + str(job_id) + '</id></report></show>',headers=headers,verify=False)
report_dict = xmltodict.parse(request_report.content)
OrdDict = report_dict['response']['result']['report']['entry']
root = OrdDict
for element in root:
    recorded_session = [(element['public_ip']),(element['srcuser']),(element['repeatcnt'])]
    public_ip = recorded_session[0]
    src_user = recorded_session[1]
    repeat_count = recorded_session[2]

 

The above at least gives you a basic outline that you can utilize and customize to get to what you want. Keep in mind that this strips out any error handling or logging that you'd want to implement in a production script. With the retrieved information you can setup remediation however you want. That might be simply tossing every public_ip that failed to login into an EDL to be blocked on the firewall after running some checks, or that could be utilizing the repeatcnt so that someone is only blocked if the same address fails to login like 5 times or something like that.

 

Also as a note on what I've provided as the script example, it's meant to give you the information you need to make a proper script to support something like this, what is shared is not a working solution if you just copy and paste it expecting it to work. It's meant to provide you an outline of what's possible.

  • 2377 Views
  • 5 replies
  • 0 Likes
Like what you see?

Show your appreciation!

Click Like if a post is helpful to you or if you just want to show your support.

Click Accept as Solution to acknowledge that the answer to your question has been provided.

The button appears next to the replies on topics you’ve started. The member who gave the solution and all future visitors to this topic will appreciate it!

These simple actions take just seconds of your time, but go a long way in showing appreciation for community members and the LIVEcommunity as a whole!

The LIVEcommunity thanks you for your participation!