<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SQL Assess Archives - The SERO Group</title>
	<atom:link href="https://theserogroup.com/tag/sql-assess/feed/" rel="self" type="application/rss+xml" />
	<link>https://theserogroup.com/tag/sql-assess/</link>
	<description>SQL Servers Healthy, Secure, And Reliable</description>
	<lastBuildDate>Wed, 21 Jul 2021 20:02:38 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://theserogroup.com/wp-content/uploads/2024/07/cropped-Canister-only-1-32x32.png</url>
	<title>SQL Assess Archives - The SERO Group</title>
	<link>https://theserogroup.com/tag/sql-assess/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">121220030</site>	<item>
		<title>Vollgar: 6 Scripts to Help Review Your SQL Servers</title>
		<link>https://theserogroup.com/sql-server/vollgar-6-scripts-to-help-review-your-sql-servers/</link>
					<comments>https://theserogroup.com/sql-server/vollgar-6-scripts-to-help-review-your-sql-servers/#comments</comments>
		
		<dc:creator><![CDATA[Joe Webb]]></dc:creator>
		<pubDate>Tue, 07 Apr 2020 19:49:02 +0000</pubDate>
				<category><![CDATA[SQL Assess]]></category>
		<category><![CDATA[SQL Audit]]></category>
		<category><![CDATA[SQL Script Library]]></category>
		<category><![CDATA[SQL Security]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Script Library]]></category>
		<guid isPermaLink="false">http://theserogroup.com/?p=2747</guid>

					<description><![CDATA[<p>Last week, Guardicore released information about a newly discovered attack that uses SQL Servers to compromise servers and networks. Here&#8217;s a link; I&#8217;d really encourage you to read it. The attack known as Vollgar uses a simple brute force attack to gain access to SQL Servers exposed to the internet. It then uses the elevated&#8230; <br /> <a class="read-more" href="https://theserogroup.com/sql-server/vollgar-6-scripts-to-help-review-your-sql-servers/">Read more</a></p>
<p>The post <a href="https://theserogroup.com/sql-server/vollgar-6-scripts-to-help-review-your-sql-servers/">Vollgar: 6 Scripts to Help Review Your SQL Servers</a> appeared first on <a href="https://theserogroup.com">The SERO Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Last week, Guardicore released information about a newly discovered attack that uses SQL Servers to compromise servers and networks. Here&#8217;s a <a aria-label="link (opens in a new tab)" rel="noreferrer noopener" href="https://www.guardicore.com/2020/04/vollgar-ms-sql-servers-under-attack/" target="_blank">link</a>; I&#8217;d really encourage you to read it. The attack known as Vollgar uses a simple brute force attack to gain access to SQL Servers exposed to the internet. It then uses the elevated permissions of the compromised logins (sysadmin or serveradmin) to modify the capabilities of SQL Server and extended its access. </p>



<p><a rel="noreferrer noopener" aria-label="Guardicore has released a PowerShell script (opens in a new tab)" href="https://github.com/guardicore/labs_campaigns/tree/master/Vollgar" target="_blank">Guardicore has released a PowerShell script</a> that examines servers to determine if they’ve been infected.&nbsp;We’ve safely run the scripts on SQL Servers in our lab environment and for many of our clients. </p>



<p>If you routinely apply regular updates to your servers, practice the Principle of Least Privilege, regularly change critical passwords, have stringent password complexity requirements, and don&#8217;t expose your SQL Servers directly to the internet, the likelihood of a brute force attack succeeding is greatly reduced. </p>



<p>Here are six scripts that can help determine your level of potential exposure.</p>



<h3 class="wp-block-heading">Who Has sysadmin or serveradmin Privileges?</h3>



<p>The Vollgar attack is a brute force attack that attempts to guess the password for SQL Logins with elevated privileges. To be successful it needs logins that can execute <a rel="noreferrer noopener" aria-label="sp_configure (opens in a new tab)" href="https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-configure-transact-sql?view=sql-server-ver15" target="_blank">sp_configure</a> to change server-level settings. This are implicitly held by the sysadmin and serveradmin fixed server roles. </p>



<p>So, the first step in determining your exposure to Vollgar is to discover the members of the sysadmin and serveradmin roles. The following script will show you the members of each role. </p>



<pre class="wp-block-code"><code>USE master; 
GO

EXEC sp_helpsrvrolemember
	'sysadmin';

EXEC sp_helpsrvrolemember
	'serveradmin';</code></pre>



<p>In my sample database, the following is returned. </p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="941" height="518" src="http://theserogroup.com/wp-content/uploads/2020/04/server_role_members-1.png" alt="" class="wp-image-2771" srcset="https://theserogroup.com/wp-content/uploads/2020/04/server_role_members-1.png 941w, https://theserogroup.com/wp-content/uploads/2020/04/server_role_members-1-300x165.png 300w, https://theserogroup.com/wp-content/uploads/2020/04/server_role_members-1-768x423.png 768w" sizes="(max-width: 941px) 100vw, 941px" /></figure>



<p>Another approach to retrieving the same information in one consolidated result set is to use the following script. </p>



<pre class="wp-block-code"><code>--list of logins that are members of the sysadmin or serveradmin roles
SELECT SP1.&#91;name] AS 'Login',
	SP2.&#91;name] AS 'ServerRole'
FROM sys.server_principals AS SP1
	JOIN sys.server_role_members AS SRM 
		ON SP1.principal_id = SRM.member_principal_id
	JOIN sys.server_principals AS SP2 
		ON SRM.role_principal_id = SP2.principal_id
WHERE SP2.&#91;name] IN ('sysadmin', 'serveradmin')
ORDER BY SP2.&#91;name],
	 SP1.&#91;name];</code></pre>



<p>As expected, this script produces the same results. </p>



<figure class="wp-block-image size-large"><img decoding="async" width="594" height="325" src="http://theserogroup.com/wp-content/uploads/2020/04/server_role_members_v2-1.png" alt="" class="wp-image-2772" srcset="https://theserogroup.com/wp-content/uploads/2020/04/server_role_members_v2-1.png 594w, https://theserogroup.com/wp-content/uploads/2020/04/server_role_members_v2-1-300x164.png 300w" sizes="(max-width: 594px) 100vw, 594px" /></figure>



<p>Of course, it&#8217;s best practice to only grant the minimum rights required by each login, a practice known as least privilege. If these queries return more logins than absolutely necessary, it&#8217;s time to review your security practices. </p>



<h3 class="wp-block-heading">Who has Passwords that Do Not Expire and without Password Complexity Requirements?</h3>



<p>Having a complex password and changing it regularly is part of the basic blocking and tackling of security. Passwords like &#8220;Password123&#8221;, &#8220;Qwerty&#8221;, and &#8220;Puddles!&#8221; can be cracked in very short order using tools freely available on the web. And if these passwords never expire, users have no reason to change them regularly, making them even more of a liability.</p>



<p>For Windows Integrated Authentication, password complexity and expiration is handled at the network domain level. For SQL logins, these are enforced inside of SQL Server. </p>



<p>To find active SQL logins (e.g. not disabled) that do not require a basic level of complexity and are set to not expired, run the following script.</p>



<pre class="wp-block-code"><code>--Active SQL Logins where passwords do not expire
--and do not have complexity requirements 
SELECT name, 
	type_desc, 
	create_date, 
	modify_date, 
	default_database_name
FROM sys.sql_logins
WHERE is_expiration_checked = 0
	 AND is_disabled = 0 
	 AND is_policy_checked = 0 ; </code></pre>



<p>In my sample system, the script produces the following list. </p>



<figure class="wp-block-image size-large"><img decoding="async" width="956" height="330" src="http://theserogroup.com/wp-content/uploads/2020/04/password_dont_expire-1.png" alt="" class="wp-image-2773" srcset="https://theserogroup.com/wp-content/uploads/2020/04/password_dont_expire-1.png 956w, https://theserogroup.com/wp-content/uploads/2020/04/password_dont_expire-1-300x104.png 300w, https://theserogroup.com/wp-content/uploads/2020/04/password_dont_expire-1-768x265.png 768w" sizes="(max-width: 956px) 100vw, 956px" /></figure>



<p>Regularly changing passwords creates a moving target for potential attackers. If you have SQL logins that do not expire and do not have minimum complexity requirements, consider turning these features on for all your logins. </p>



<p>Putting some of the above queries together will give us a list of all active SQL logins that are members of the sysadmin or serveradmin fixed server roles along with whether their logins adhere to password complexity and expiration policies. </p>



<pre class="wp-block-code"><code>--list of SQL logins that are members of the sysadmin or serveradmin roles
SELECT SP1.&#91;name] AS 'Login',
	SP2.&#91;name] AS 'ServerRole',
	CASE l.is_disabled WHEN 1 THEN 'No' ELSE 'Yes' END AS Is_Enabled,
	CASE l.is_expiration_checked WHEN 1 THEN 'Yes' ELSE 'No' End AS Pwd_Expires,
	CASE l.is_policy_checked WHEN 1 THEN 'Yes' ELSE 'No' END AS Pwd_Complexity_Reqs
FROM sys.server_principals AS SP1
	JOIN sys.server_role_members AS SRM
	ON SP1.principal_id = SRM.member_principal_id
	JOIN sys.server_principals AS SP2
	ON SRM.role_principal_id = SP2.principal_id
	JOIN sys.sql_logins AS l
	ON l.principal_id = SRM.member_principal_id
WHERE SP2.&#91;name] IN ('sysadmin', 'serveradmin')
ORDER BY SP2.&#91;name],
	 SP1.&#91;name];</code></pre>



<p>The following results are returned on my test system.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="802" height="274" src="http://theserogroup.com/wp-content/uploads/2020/04/elevated_privileges.png" alt="" class="wp-image-2783" srcset="https://theserogroup.com/wp-content/uploads/2020/04/elevated_privileges.png 802w, https://theserogroup.com/wp-content/uploads/2020/04/elevated_privileges-300x102.png 300w, https://theserogroup.com/wp-content/uploads/2020/04/elevated_privileges-768x262.png 768w" sizes="auto, (max-width: 802px) 100vw, 802px" /></figure>



<h3 class="wp-block-heading">When was a SQL Login Password Changed?</h3>



<p>From the prior two queries, we can see that Alice and Donnie are both active members of the sysadmin fixed server role. Donnie&#8217;s password doesn&#8217;t expire and doesn&#8217;t have to meet any password complexity requirements. Of course, this is a big red flag for security. Alice&#8217;s login, on the other hand, is set to adhere to complexity and expiration requirements. That&#8217;s good. </p>



<p>But how long has it been since Alice actually changed her password? We can use the <a rel="noreferrer noopener" aria-label="LOGINPROPERTY() (opens in a new tab)" href="https://docs.microsoft.com/en-us/sql/t-sql/functions/loginproperty-transact-sql?view=sql-server-ver15" target="_blank">LOGINPROPERTY()</a> function to help us. Note: that for the function to return meaningful information, both  CHECK_POLICY and CHECK_EXPIRATION must be enabled for the login.</p>



<pre class="wp-block-code"><code>--when was a login's password last changed?
SELECT 'Alice' AS username,
	LOGINPROPERTY('Alice', 'PasswordLastSetTime') AS PasswordLastSetTime;</code></pre>



<p>In this case, we can see that Alice last set her password on March 26, 2020. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="435" height="110" src="http://theserogroup.com/wp-content/uploads/2020/04/password_last_changed-1.png" alt="" class="wp-image-2774" srcset="https://theserogroup.com/wp-content/uploads/2020/04/password_last_changed-1.png 435w, https://theserogroup.com/wp-content/uploads/2020/04/password_last_changed-1-300x76.png 300w" sizes="auto, (max-width: 435px) 100vw, 435px" /></figure>



<p>We can use other properties in the LOGINPROPERTY() function, such as BadPasswordCount and BadPasswordTime.  I wouldn&#8217;t rely too heavily on the results, though. The BadPasswordCount is reset to 0 as soon as Alice successfully logs in. And, just as importantly, it&#8217;s only relevant for those SQL Logins who have  CHECK_POLICY and CHECK_EXPIRATION enabled. </p>



<pre class="wp-block-code"><code>--bad password attempts
SELECT name, 
	LOGINPROPERTY(name, 'BadPasswordCount') AS BadPasswordCount,
	LOGINPROPERTY(name, 'BadPasswordTime') AS BadPasswordTime
FROM sys.sql_logins 
WHERE is_expiration_checked = 1
	AND is_disabled = 0 
	AND is_policy_checked = 1; </code></pre>



<p>The results from my test system are shown below. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="693" height="490" src="http://theserogroup.com/wp-content/uploads/2020/04/bad_attempts-1.png" alt="" class="wp-image-2768" srcset="https://theserogroup.com/wp-content/uploads/2020/04/bad_attempts-1.png 693w, https://theserogroup.com/wp-content/uploads/2020/04/bad_attempts-1-300x212.png 300w" sizes="auto, (max-width: 693px) 100vw, 693px" /></figure>



<h3 class="wp-block-heading">How to See Failed Login Attempts</h3>



<p>Assuming your SQL Server is configured to log failed login attempts, and of course it should be, you can query the error log files using the sp_readerrorlog procedure to see the failed attempts. </p>



<pre class="wp-block-code"><code>EXEC sp_readerrorlog 0, 1, 'Login failed' ;</code></pre>



<p>The following is returned on my test system.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="862" height="273" src="http://theserogroup.com/wp-content/uploads/2020/04/error_log_files-1.png" alt="" class="wp-image-2769" srcset="https://theserogroup.com/wp-content/uploads/2020/04/error_log_files-1.png 862w, https://theserogroup.com/wp-content/uploads/2020/04/error_log_files-1-300x95.png 300w, https://theserogroup.com/wp-content/uploads/2020/04/error_log_files-1-768x243.png 768w" sizes="auto, (max-width: 862px) 100vw, 862px" /></figure>



<p>Better yet, use a monitoring tool to proactively monitor failed login attempts and alert when a minimum threshold is exceeded. For our <a rel="noreferrer noopener" aria-label="DBA as a Service (opens in a new tab)" href="http://theserogroup.com/#how-we-help" target="_blank">DBA as a Service</a> clients, we provide <a rel="noreferrer noopener" aria-label="SentryOne (opens in a new tab)" href="https://www.sentryone.com/" target="_blank">SentryOne</a>&#8216;s <a rel="noreferrer noopener" aria-label="SQLSentry  (opens in a new tab)" href="https://www.sentryone.com/products/sentryone-platform/sql-sentry/sql-server-performance-monitoring" target="_blank">SQLSentry </a>monitoring tool to help with this and other events that should be monitored.</p>



<h3 class="wp-block-heading">Parting Thoughts</h3>



<p>Many years ago, I set up a test system for a writing project I was involved with. As part of the test, I set the sa password to something like &#8220;Cat123Dog!&#8221; The password met most requirements of the day &#8211; upper and lower case, at least one number and one letter, and a special symbol. &#8220;Not bad,&#8221; I thought to myself.</p>



<p>Then I downloaded <a rel="noreferrer noopener" aria-label="Ophcrack (opens in a new tab)" href="https://ophcrack.sourceforge.io/" target="_blank">Ophcrack</a>, a free Windows password cracker, and released it on my unsuspecting SQL Server. Expecting the utility to run for hours, if not days, I returned to work. </p>



<p>A few minutes later, I decided to check on it, wanting to make sure it wasn&#8217;t hung for some reason. I was stunned. Ophcrack had already found the password! That was at least 10 years ago. I&#8217;m sure the tools of the hacker trade have gotten much better since then. </p>



<p>Recently, I&#8217;ve read where most breaches are a result of social engineering &#8211; someone receives an e-Card from a secret admirer, finds a thumb drive in the parking lot, or clicks an email link. &#8220;The days of brute force attacks are over,&#8221; they say. </p>



<p>Vollgar has proven them wrong. Basic security measures are still best practice. You owe it to yourself to make sure you&#8217;re doing it well. Here are a few links that may help.</p>



<ul class="wp-block-list"><li><a rel="noreferrer noopener" aria-label="Introduction to SQL Server Security (opens in a new tab)" href="https://www.red-gate.com/simple-talk/sysadmin/data-protection-and-privacy/introduction-to-sql-server-security-part-1/" target="_blank">Introduction to SQL Server Security</a></li><li><a rel="noreferrer noopener" aria-label="Securing SQL Server (opens in a new tab)" href="https://docs.microsoft.com/en-us/sql/relational-databases/security/securing-sql-server?view=sql-server-ver15" target="_blank">Securing SQL Server</a></li><li><a href="https://www.mssqltips.com/sqlservertip/3159/sql-server-security-checklist/" target="_blank" rel="noreferrer noopener" aria-label="SQL Server Security Checklist (opens in a new tab)">SQL Server Security Checklist</a></li></ul>
<p>The post <a href="https://theserogroup.com/sql-server/vollgar-6-scripts-to-help-review-your-sql-servers/">Vollgar: 6 Scripts to Help Review Your SQL Servers</a> appeared first on <a href="https://theserogroup.com">The SERO Group</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://theserogroup.com/sql-server/vollgar-6-scripts-to-help-review-your-sql-servers/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2747</post-id>	</item>
	</channel>
</rss>
