Skip to content

Dave Bland

My blog about SQL Server and related technologies

  • Home
  • View All Posts
  • Azure Data Studio
  • SQL Server User Groups
  • Upcoming Events
  • Presentation Materials
  • Code Samples
  • Contact Me
  • About me

Recent Posts

  • Summary of 2020
  • A Faster Alternative to sp_helpdb
  • 100th Blog Post: What I learned along the Way
  • SQL Server Assessment Using SSMS and SSRS
  • Ambiguous column name error when only using one Table

Archives

  • January 2021
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Tag: fn_get_audit_file

How to Capture Failed Logins using Extended Events

As many of you know, a data breach is a big deal. Not only do they place your customers at risk, a data breach can also have a very negative impact on the reputation of the company you work for.  As a DBA, I teach my students that we are the last line of defense against a breach.  I feel that an important part of protecting the data is to investigate failed logins.  However, in order to investigate them, we need to find the failed logins first. You may be asking, if investigating failed logins is important, how did I find them?  There are few methods we can use, including reading the log, SQL Server Audit and using Extended Events.  We will cover each of these including how to set it up and read the data.

This will be a three part series covering each of the methods to capture failed logins.

Find Failed Logins Using Error Log

Find Failed Logins Using SQL Server Audit

Find Failed Logins Using Extended Events

Extended Events

So far we have covered two methods of capturing failed logins in previous posts.  Both are viable options, depending on what you are attempting to accomplish.  The third option above is the first that will also work in an Azure SQL DB.  This third option is Extended Events.  Unlike SQL Server Audit, there is NOT a failed login event.  We will need to use the Error_Reported event instead.

When looking at the image of the error log below, you can see the error number, severity and state of a failed login.  These numbers will be critical when setting up the Failed Login Extended Event session.

This is the code needed to create the Extended Event session. Although, there are several targets that can be used for storage, I think that the file is the best target to use.  You will need to change the path to one that is suitable for your environment.  Notice the WHERE clause, the Error, severity and state all match the above image.

CREATE EVENT SESSION [FailedLogins] ON SERVER
ADD EVENT sqlserver.error_reported(
    ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.nt_username)
    WHERE ([severity]=(14) AND [error_number]=(18456) AND [state]>(1)))
ADD TARGET package0.event_file(SET filename=N’C:\temp\FailedLogins.xel’)
GO
Like the audits, the Extended Event session will need to be enabled before it can collect the desired data.  To start a session, simply right click on the session and go to “Start Session”.  By looking at the session in SSMS, you can easily tell of the session is enabled or not.
Once the session is started, SQL Server will create a .xel file in the destination location.  Once you go to the location, you will notice something a bit unusual about the file names.  Look at the huge number at the end. I have looked and looked and the only thing I can find is that this number is the number of seconds since some date in the 1600’s, but not sure if that is true or not.
Because this is an XML based document, it would be logical to think we can read the data we could simply open the document it in Notepad as you will see below.  Well, that is not the case. If you try to open one of these files with Notepad, it will look something like this.  Not exactly useful.
Well, if I can’t open the file with Notepad, how can I read the data.  With Extended Events there are two methods. The first one is the easiest.  In SQL Server Management Studio, navigate to the Extended Events and find the session.  Then right click on the target and go to “View Target Data…”.  Just as below.
When you view target data, it will look similar to below.
Once you are here you can view the data, sort it and even group it.  One additional task you can do that I would like to mention is the ability to export the data.  While Extended Events does not allow for the direct input of the data to a SQL Server database table, it be exported into a table using SSMS.  Now that it is in a table the data is easier to analyze.
When viewing Extended Event data, a new menu item will appear in SSMS, Extended Events. At the bottom of this menu are the menu items that can be used to export the data.  There are three options, .XEL file, Table or CSV file.
While view target data as described above is very useful, it would be something that would be very difficult to automate in any way, especially if you would like to move that data collected to a table.  This is where the sys.fn_xe_file_target_read_file function comes into play.  This function works very much like the sys.fn_get_audit_file function used to read SQL Audit files.
Below is the code you could use to read the XML based extended event file.  Using the example we used earlier posts looking for failed logins with the SA account, this bit of code does the same.
This code breaks the reading of the data into a few steps.  The first step pull the data into a temporary table with a column that has a datatype of XML.  Then the second select statement breaks the XML into more readable columns that will allow us to use more traditional TSQL to read the data.
SELECT FailedLoginData = CONVERT(XML, event_data)
INTO #FailedLogin
FROM sys.fn_xe_file_target_read_file(N’C:\temp\FailedLogin*.xel’, NULL, NULL, NULL);
SELECT
EventDate    = FailedLoginData.value(N'(event/@timestamp)[1]’, N’datetime’),
Message  = FailedLoginData.value(N'(event/data[@name=”message”]/value)[1]’, N’varchar(100)’)
FROM #FailedLogin
WHERE FailedLoginData.value(N'(event/data[@name=”message”]/value)[1]’, N’varchar(100)’) LIKE ‘Login failed for user ”sa”%’
ORDER BY Eventdate DESC
DROP TABLE #FailedLogin
Of  course you will need to update the path to the .XEL file to the path for your environment.  When you run the above query, the image below shows what your data set should look like.
Now you can take the query and modify it so you can build some type of alerting.
Hopefully this can help you find failed logins.
Thanks for visiting by blog!!
Posted on February 24, 2020February 27, 2020Categories UncategorizedTags audit, Audit specification, extended events, failed login, fn_get_audit_file, sql server

How to Capture Failed Logins using SQL Server Audit

As many of you know, a data breach is a big deal. Not only do they place your customers at risk, a data breach can also have a very negative impact on the reputation of the company you work for.  As a DBA, I teach my students that we are the last line of defense against a breach.  I feel that an important part of protecting the data is to investigate failed logins.  However, in order to investigate them, we need to find the failed logins first. You may be asking, if investigating failed logins is important, how did I find them?  There are few methods we can use, including reading the log, SQL Server Audit and using Extended Events.  We will cover each of these including how to set it up and read the data.

This will be a three part series covering each of the methods to capture failed logins.

Find Failed Logins Using Error Log

Find Failed Logins Using SQL Server Audit

Find Failed Logins Using Extended Events

SQL Server Audit

While using the Error log to capture failed logins is configured by default, using SQL Server Audit is not and will need to be configured.  Before we get too deep into how to configure audit, let’s go over a few of the basics.

SQL Server audit is broken up into two parts, Audit and Audit Specification.  The Audit can be summarized as the place where are we are going to store the data.  While the Audit Specification can be viewed as what we want to capture and to be stored in the Audit location.

To set up an audit…the first thing we need to set up in the Audit itself.  This can be found under Security.

To create an audit all you need to do is right click on Audits and go to New Audit.  When you do you will see something similar to what is below.

While this is not a post about how to create an audit there are few properties that I think are important to cover.

The first property is “On Audit Log on Failure”.  Depending on your environment and audit requirements, you may need to shut the server down if the audit is not working properly.  That is what this property is intended to do.  As you can see there are three options. You will just need to set it to something that meets the needs of your company.

The next property is “Audit Destination”.  As expected, this is where the data collected will be stored.  You have three options here: file, Security Log and Application log.   You will then need to pick a local of the files, assuming you picked File for the destination.  Next you need pick the max number of files and files size.  As well as a few other properties that are pretty straight forward.  Once you have set everything, click OK and now you have your audit.

What you don’t have is the Audit Specification.  There are two locations an Audit Specification can be set up.  One is at the server level and the other is at the database level.  In this case because we are looking for failed logins, we will need to utilize the server level audit specification.

The create an Audit Specification, simply right click on Audit Specification just below the Audit item.

You will probably want to provide a more appropriate name and you will need to pick the Audit from the drop down box.  Because of this, the Audit must be created before the Audit Specification.

Which brings us to the final piece of the pie so to speak.  We need to identify what data we want to capture.  For the purposes of this blog post, we are only looking for failed logins.  Under the “Audit Action Type” you will need to pick “Failed_Login_Group”.  Once you click OK…both the audit and audit specification have been created.  You will need to check them though.  When both an Audit and an Audit Specification are first created they are disabled.  You will need to enable them by right clicking on them.

Once both the Audit and Audit Specification have been created.  Before they will start collecting data, they will both need to be enabled.  You can easily see in the image below how to tell if the Audit or Audit Specification are enabled or disabled.

Now to read the data we have collected.  There are two methods that can be used to read audit data. The easiest was is to use SSMS and right click on the audit.  Make sure you clicking on the Audit and not the Audit Specification.  Remember, the data is stored in the Audit and the Audit Specification is used to identify what you want to capture.

When you right click on the Audit and go to “View Audit Logs”, you will see something like this.

This is very much like the other log viewers we use on a regular basis, job history and Error logs.  The data can be filtered, searched and exported.

This is a great way to view the audit data, however what if I want to automate that process so I can build alerts around it.  Well can’t really do that using the above method.  However, there is a function, sys.fn_get_audit_file, that you can use.  Here is a link to Microsoft’s documentation, click here.

If you look at the documentation you will see that there are three arguments for this function.  However for our purposes, we really only need to use the first one. In the sample below you will see that the we are indeed only using the first argument. The other two we just put the word Default in.   As far as the filename, you can put a specific file name, however, if there is a file rollover, the code will not work.  Notice I placed the start of the file name and then and asterisk.  In this case we will read from all files in the C:\Test location that start with “FailedLogin” and have a file extension of .sqlaudit.

sys.fn_get_audit_file (‘C:\Test\FailedLogin*.sqlaudit’,default,default)

Below is a more complete sample script.  While the function returns many more columns, these are the ones I think we need.  Notice the where clause is looking for an action_is that equals LGIF.  This will be useful if you use the same audit to collect more than just failed logins.

SELECT event_time
, action_id
, succeeded
, server_principal_name
, server_instance_name
, statement
, file_name
, application_name
FROM sys.fn_get_audit_file (‘C:\Test\FailedLogin*.sqlaudit’, default, default)
WHERE action_id = ‘LGIF’
ORDER BY event_time DESC

The code below looks for failed logins using the SA account for the past hour.

SELECT server_principal_name
  , COUNT(server_principal_name) AS ‘NumberOfFailedLogins’
FROM sys.fn_get_audit_file (‘C:\Test\FailedLogin*.sqlaudit’,default,default)
WHERE action_id = ‘LGIF’
AND server_principal_name = ‘sa’
AND event_time > DATEADD(HOUR, -1, GETDATE())
GROUP BY server_principal_name

Of course you will need to change the path to the file that matches yours. If you are using an Azure SQLDB, audit as defined above is not an option.

Thanks for visiting my blog!!

Posted on February 24, 2020February 27, 2020Categories UncategorizedTags audit, Audit specification, extended events, failed login, fn_get_audit_file, sql server
Proudly powered by WordPress