Information security used to be all about networks and protecting the network perimeter. Today, however, applications are the new battleground for the protection of digital assets. While the concept of software security has been around for a long time, the evolution of mobile technologies and the universal accessibility of applications is requiring organizations to work on improving the maturity of their application security practices. To help with this initiative, many organizations developed their own methodologies. Some of these are too complex and difficult to implement, others are proprietary and expensive. However, there is one framework that stands out among the crowd.
The Open Software Assurance Maturity Model (OpenSAMM) was developed by OWASP back in 2009, and is currently undergoing many updates. Like all OWASP projects, this one is free and has been adopted by many organizations around the world. OpenSAMM is very comprehensive in nature, covers all aspects of application security, and still allows each application to be evaluated in under one hour. On the whole, I would recommend any organization that develops its own software to take a look at OpenSAMM website and try it out.
In order to get started, you need to compile a list of applications and subject-matter experts for each application who can provide answers regarding the way the application was developed. Once compiled, you should review the “Assessment Interview Template” and the “Assessment Worksheet”, both downloads from the Open SAMM’s website. These documents help break down Open SAMM into a series of interview questions, making the process of collecting and normalizing information easier. Once answers have been gathered, OpenSAMM maturity scores can be calculated.
Governance: The way application security is managed in the organization
Construction: The way applications are built
Verification: The way security of the application is tested
Deployment: How the application is deployed and supported in production
Additionally, each business function breaks down into three “security practices”. For example, “Verification” splits up into:
Design Review: Activities such as attack surface analysis
Code Review: Activities such as peer and 3rd party code reviews
Security Testing: Activities such as penetration testing
Once all the questions have been answered, each “security practice” will receive a score ranging from 0 to 3. This score represents the maturity of each “security practice,” and provides a snapshot of the security practices around each application. Understanding what each metric means to the organization, well that requires additional analysis.
Applications developed in certain high-security industries or environments may require achieving the maximum maturity level at each “security practice,” however this is not necessary for most of the organizations. OpenSAMM provides sample “security profiles” that show suggested maturity ratings for organizations within different industries, but these should be viewed as recommendations only. Each organization should perform its own risk analysis and determine their own acceptable maturity levels in different “security practices” and different applications. In order to better understand different maturity ratings and objectives, Open SAMM provides additional guidance in each area, including suggested security metrics. All of this information should be evaluated collectively, in order to establish the right maturity level objectives for different applications.
The OpenSAMM framework is quick to deploy, provides actionable recommendations for improving application security, and does not dwell in a lot of risk management terminology. I recommend everyone responsible for managing application security to check it out.
During many of our penetration tests, we gather domain password hashes (with permission of the client) for offline cracking and analysis. This blog is a quick summary of the hashes that we attempted to crack in the third quarter of 2014 (and so far for this year). The plan is continue doing this again at the end of the year to see how we did overall for the year (three quarters down, one to go). Please keep in mind that this is not an all-encompassing sample. We do not collect domain hashes during every single penetration test, as some clients do not want us to.
The sample for this quarter included three sets of domain hashes that added up to 26,692 hashes. Two of the three sets had some LM hashes stored along with the NTLM hashes, but none of the LM stored passwords were that complicated. Just like last quarter, it wasn’t a huge advantage. Of the hashes, 11,776 were duplicates, leaving 14,916 unique hashes. Of the 26,692 hashes, we were able to crack 21,955 (82.25%).
Cracked Password Length Breakdown:
As you can see, the cracked passwords peak at the eight character length. This is pretty common for a minimum password length, so it’s not a big surprise that this is the most common length cracked. It’s also been the peak every quarter this year. It should also be noted that since we’re able to get through the entire eight character keyspace in about two and a half days, which may be influencing the peak.
Some interesting finds:
Most Common Password (1120 instances): A Client Specific Default Account Password
Top Mask Pattern: ?u?l?l?l?l?l?d?d (3,068 instances)
I put together an hcmask file (to use with oclHashcat) of our top forty password patterns that were identified for this quarter. Additionally, I put together one for everything that we’ve cracked for the first half of the year. You can download them here – Q3 Hcmask File – Q1,Q2,Q3 Hcmask File. I plan on wrapping this up next quarter, so check back to see how this mask files have changed and to see how well we’ve done across the year.
For more information on how we built our GPU-enhanced password cracking box, check out our slides.
For a general outline of our password cracking methodology check out this post.
Application developers often use SQL Server stored procedures to make their code more modular, and help apply the principle of least privilege. Occasionally those stored procedures need to access resources external to their application’s database. In order to satisfy that requirement sometimes developers use the IMPERSONATE privilege and the EXECUTE AS function to allow the impersonation of other logins on demand. Although this isn’t really a vulnerability, this type of weak configuration often leads to privilege escalation. This blog provides a lab guide and attack walk-through that can be used to gain a better understanding of how the IMPERSONATE privilege can lead to privilege escalation in SQL Server.
This should be interesting to penetration testers, application developers, and dev-ops. However, it will most likely be pretty boring to DBAs that know what they’re doing. Below is a summary of the topics being covered:
Provide the MyUser1 login with permissions to impersonate MyUser2, MyUser3, and sa.
-- Grant myuser1 impersonate privilege on myuser2, myuser3, and sa
GRANT IMPERSONATE ON LOGIN::sa to [MyUser1];
GRANT IMPERSONATE ON LOGIN::MyUser2 to [MyUser1];
GRANT IMPERSONATE ON LOGIN::MyUser3 to [MyUser1];
Finding SQL Server Logins that can be impersonated
The first step to impersonating another login is findings which ones your account is allowed to impersonate. By default, sysadmins can impersonate anyone, but normal logins must be assigned privileges to impersonate specific users. Below are the instructions for finding out what users you can impersonate.
Log into the SQL Server as the MyUser1 login using SQL Server Management Studio.
Run the query below to get a list of logins that can be impersonated by the “MyUser1” login.
-- Find users that can be impersonated
SELECT distinct b.name
FROM sys.server_permissions a
INNER JOIN sys.server_principals b
ON a.grantor_principal_id = b.principal_id
WHERE a.permission_name = 'IMPERSONATE'
Below is a screenshot of the expected results.
Note: In the example above, the query is being executed via a direct database connection, but in the real world external attackers are more likely to execute it via SQL injection.
Impersonating SQL Logins and Domain Accounts
Now that we have a list of logins that we know we can impersonate we can start escalating privileges. J In this section I’ll show how to impersonate users, revert to your original user, and impersonate domain users (like the domain admin). Fun fun fun…
Impersonating SQL Server Logins
Log into the SQL Server using the MyUser1 login (if you’re not already).
Verify that you are running as a SQL login that does not have the sysadmin role. Then run EXECTUTE AS to impersonate the sa login that was identified in the last section.
-- Verify you are still running as the myuser1 login
-- Impersonate the sa login
EXECUTE AS LOGIN = 'sa'
-- Verify you are now running as the sa login
Below is an example of the expected output.
Now you should be able to access any database and enable/run xp_cmdshell to execute commands on the operating system as the SQL Service service account (LocalSystem). Below is some example code.
-- Enable show options
EXEC sp_configure 'show advanced options',1
-- Enable xp_cmdshell
EXEC sp_configure 'xp_cmdshell',1
-- Quickly check what the service account is via xp_cmdshell
EXEC master..xp_cmdshell 'whoami'
Below is an example of the expected output:
Tada! In this scenario we were able to become the sysadmin “sa”. You may not always get a sysadmin account right out of the gate, but at a minimum you should get additional data access when impersonating other logins.
Note: Even a small increase in privileges can provide the first step in an escalation chain. For example, if you have the rights to impersonate a db_owner you may be able to escalate to a syadmin using the attack I covered in my last blog. It can be found here.
Impersonating SQL Logins as Sysadmin
Once you’ve obtained a sysadmin account you have the ability to impersonate database login you want. You can grab a full list of logins from the .
-- Get a list of logins
SELECT * FROM master.sys.sysusers
WHERE islogin = 1
Once you have the list it’s pretty easy to become anyone. Below is an example of impersonating the MyUser4 login.
-- Verify you are still impersonating sa
-- Impersonate MyUser4
EXECUTE AS LOGIN = 'MyUser4'
-- Verify you are now running as the the MyUser4 login
-- Change back to sa
Below is a screenshot:
Note: Make sure to REVERT back to the sysadmin account when you’re done. Otherwise you’ll continue to run under the context of the MyUser4 login.
Impersonating Domain Admins as a Sysadmin
Did I mention that you can impersonate any user in Active Directory? As it turns out it doesn’t even have to be mapped to an SQL Server login. However, the a catch is that it only applies to the SQL Server. That’s mostly because the SQL Server has no way to authenticate the Domain User to another system…that I’m aware of. So it’s not actually as cool as it sounds, but still kind of fun.
Note: Another important note is that when you run xp_cmdshell while impersonating a user all of the commands are still executed as the SQL Server service account, NOT the SQL Server login or impersonated domain user.
Below is a basic example of how to do it:
-- Get the domain of the SQL Server
-- Impersonate the domain administrator
EXECUTE AS LOGIN = 'DEMOAdministrator'
-- Verify you are now running as the Domain Admin
Note: Remember that the domain will be different for everyone. In my example the domain is “DEMO”.
Below is an example of the expected output.
Revert to the original Login
If you get sick of being a sysadmin or a Pseudo Domain Admin you can always REVERT to your original login again. Just be aware that if you run the impersonation multiple times you may have to run REVERT multiple times.
-- Revert to your original login
-- Verify you are now running as the MyUser1 login
1.5 Automating Escalation with Metasploit and PowerShell
Since I’m lazy and don’t like to type more that I have to, I wrote a Metasploit module and PowerShell script to automate the attack for direct database connections. I also wrote a Metasploit module to execute the escalation via error based SQL injection. Big thanks to guys on the Metasploit team who helped me get the modules into the framework.
Metasploit Module: mssql_escalate_executeas
Below is an example of the mssql_escalate_executeas module being used to escalate the privileges of the myuser1 login using a direct database connection. Typically this would happen during an internal penetration test after guessing database user/passwords or finding database connection strings.
Metasploit Module: mssql_escalate_executeas_sqli
Below is an example of the mssql_escalate_executeas_sqli module being used to escalate the privileges of the myuser1 login using error based SQL injection. This is more practical during external network penetration tests. Mostly because SQL injection is pretty common and database ports usually are not exposed to the internet. Anyway pretty screenshot below…
Below is a basic screenshot of what it looks like when it runs.
Alternatives to Impersonation
There quite a few options for providing stored procedures with access to external resources without providing SQL logins with the privileges to impersonate other users at will. However, they all come with their own risks and implementation challenges. Hopefully, I’ll have some time in the near future to cover each in more depth, but below is a summary of common options.
Create roles with the required privileges on external objects. This doesn’t always make least privilege easy, and can generally be a management pain.
Use cross local/database ownership chaining. This one can end in escalation paths as well. More information can be found at https://msdn.microsoft.com/en-us/library/ms188694.aspx.
Use EXECUTE WITH in the stored procedure to run as the stored procedure owner. This isn’t all bad, but can result in escalation paths if the store procedure is vulnerable to SQL injection, or is simply written to allow users to take arbitrary actions.
Use signed stored procedures that have been assigned access to external objects. This seems like the most secure option with the least amount of management overhead. Similar to the EXECUTE WITH option, this can result in escalation paths if the store procedure is vulnerable to SQL injection, or is simply written to allow users to take arbitrary actions. More information at https://msdn.microsoft.com/en-us/library/bb283630.aspx.
The issues covered in this blog/lab were intended to help pentesters, developers, and dev-ops gain a better understanding of how the IMPERSONATE privilege can be used an abused. Hopefully the information is useful. Have fun with it, but don’t forget to hack responsibly. 🙂
Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.
YouTube session cookie.
Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.
Analytics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.
Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in.
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
Cookies are small text files that can be used by websites to make a user's experience more efficient. The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies we need your permission. This site uses different types of cookies. Some cookies are placed by third party services that appear on our pages.