
Decrypting IIS Passwords to Break Out of the DMZ: Part 1
From the perspective of a penetration tester, it would be nice if every vulnerability provided a direct path to high-value systems on the internal network. However, the reality is that we aren’t always that lucky, and sometimes we land on an application server in the DMZ network first. In this blog I’ll cover how to use native IIS tools to recover encrypted database passwords from web.config files and leverage them to break into the internal network from the DMZ. This should be interesting to penetration testers, developers, and system administrators trying to gain a better understanding of the value and limitations of passwords encrypted in IIS configuration files. Below is an overview of what will be covered.
- Web.config Overview
- Finding web.config Files
- Finding Connection Strings in the web.config
- Decrypting Connection Strings in the web.config
- Connecting to the Backend Database
- Wrap Up
Web.config Overview
Web.config is an XML configuration file that is used to control ASP.NET servers, applications, and pages. As an attacker, web.config files are incredibly valuable because they often contain connection strings that can be used to access databases on the internal network. Usually holes are poked through the DMZ firewall that allows the application server to access backend database servers. So connecting through the firewall boundary usually isn’t a problem. Once the attacker has successfully connected to a database server on the internal network it is possible escalate to the operating system level and in a few short steps obtain Domain Admin privileges. Below I’ll cover how to find and decrypt connection strings in web.config files.
Finding web.config Files
Before the connection strings can be extracted, the web.config files will need to be located. They can be found in multiple locations, but are typically located in the web root of each application directory. For example: “c:inetpubwwwrootMyAppweb.config”. As it turns out, IIS application directories are not always in the inetpub directory, and may not be located on the C drive at all. Thankfully there is a native command that can help. The appcmd.exe command is installed along with IIS 7 and can search, view, and modify IIS configurations (assuming you’re an admin). So we can run the command below to find the application directories we are looking for.
%windir%system32inetsrvappcmd list vdir

From there it’s possible to quickly recursively search the directories for web.config files with the command below:
dir /s /b c:MyTestSite | find /I "web.config"

Finding Connection Strings in the web.config
Now that we know where the web.config files are, we can start searching for connection strings. Luckily they are pretty easy to find because they are contained within the “connectionstrings” XML tag. Below is a basic example of what an unencrypted connection string might look like in a web.config file.
<connectionStrings> <add name="MyConnectionString" connectionString="Data Source=PRDSQLSRV1; Initial Catalog=Northwind; Persist Security Info=True; User ID=sa; Password=Password1" providerName="System.Data.SqlClient" > </add> </connectionstrings>
Appcmd can be used to streamline the recovery of connection strings if they are not encrypted. Below is a little script example:
for /f %i in ('%systemroot%system32inetsrvappcmd list site /text:name') DO %systemroot%system32inetsrvappcmd list config "%i" -section:connectionstrings
Decrypting Connection Strings in the web.config
From an attacker’s perspective it’s nice if connection strings are not encrypted. The reality is that it’s becoming more and more common for the strings to be encrypted (which is good for admins). Encrypting web.config files is useful for protecting connection strings when they have been backed up. However, once an attacker has administrative access to an IIS server it is possible to use the same methods the developers use to decrypt the connection strings. Aspnet_regiis.exe is another native tool which is installed by default with .Net for IIS. In this example we are going to use it to decrypt our web.config. Below are the basic steps.
1. Copy the web.config out of the application directory.
copy "c:inetpubwwwrootMyAppweb.config" c:temp
2. View the file to verify the connection strings are encrypted. The connection strings should be encrypted in the “cipherdata” and “ciphervalue” tags within the “connectionStrings” tab.
type c:tempweb.config
3. Decrypt the connection string in the web.config with aspnet_regiis.exe. Make sure to use the most recent version found in the Framework folder. The newest version is typically backwards compatible and should be able to decrypt connection strings that were encrypted with an older version.
C:WindowsMicrosoft.NETFrameworkv2.0.50727aspnet_regiis.exe -pdf "connectionStrings" C:temp
4. Recover the unencrypted connection strings from the web.config file. The cleartext connection strings should look like the example shown in the last section.
type c:tempweb.config
To automated the entire process I’ve write a small Powershell script called “get-webconfig.ps1” with Antti Rantasaari. It can be downloaded from github HERE. It’s also been added to the Posh-SecMod Powershell project owned by Carlos Perez. The toolkit has a ton of handy scripts for all sorts of things – go check it out at https://github.com/darkoperator/Posh-SecMod. Ok, back on track…
Don’t forget to run as an administrator or system. Below is an example of the output. It will show the username, password, database server, IIS virtual directory, full path to the web.config, and indicate if it was found encrypted.
PS C:<get-webconfig.ps1 | Format-Table -Autosize user pass dbserv vdir path encr ---- ---- ------ ---- ---- ---- s1admin s1password 192.168.1.101server1 C:App1 C:App1web.config No s1user s1password 192.168.1.101server1 C:inetpubwwwroot C:inetpubwwwrootweb.config No s2user s2password 192.168.1.102server2 C:App2 C:App2testweb.config No s2user s2password 192.168.1.102server2 C:App2 C:App2web.config Yes s3user s3password 192.168.1.103server3 D:App3 D:App3web.config No
Connecting to the Backend Database
Now that we have decrypted the database connection strings let’s use them. In most cases, web applications hosted on an IIS server connect to a Microsoft SQL Server on the backend. In some cases the command line SQL client tools are already installed on the IIS server. Those can be leveraged to access the database without too much effort. Below are some basic examples.
isql.exe –S PRDSRV1 –U sa –P Password1 –Q “SELECT name FROM master..sysdatabases”
osql.exe –S PRDSRV1 –U sa –P Password1 –Q “SELECT name FROM master..sysdatabases”
sqlcmd.exe –S PRDSRV1 –U sa –P Password1 –Q “SELECT name FROM master..sysdatabases”
If command line SQL clients are not on the server, then PowerShell can be used to accomplish the same goal. Antti Rantasaari made a great web shell that will do all of this for you. He also wrote a nice little blog to go with it that you can find here. Below is a basic example showing how to list all of the databases on the remote server if you want to experiment on your own. However, during a real attack you would most likely use the xp_cmdshell and xp_dirtree stored procedures to pivot into the internal network. Antti and I put together a presentation a while back the covers those topics in more detail. You can download it from slideshare here.
$conn = New-Object System.Data.SqlClient.SqlConnection $conn.ConnectionString = "Server=PRDSRV1;Database=master;User ID=sa;Password=Password1;" $conn.Open() $sql = "SELECT name from master..sysdatabases" $cmd = New-Object System.Data.SqlClient.SqlCommand($sql,$conn) $rdr = $cmd.ExecuteReader() $test = @() while($rdr.Read()) { $test += ($rdr["name"].ToString()) } Write-Output $test
Wrap Up
Encrypting passwords in the web.config does help reduce risk related to read-only attacks and access to backup files. However, if an attacker is able to gain administrative access to a system they will be able to use administrative tools or Windows APIs such as crypt32.dll to decrypt protected passwords. As a result, attackers may be able to break out of the DMZ zone and into the internal network. That is why it is very important to also make sure that all accounts are configured with least privilege, proper network zone isolation is enforced, and sensitive accounts are being audited. Hopefully this was helpful. Have fun and hack responsibly!
Resources
- https://msdn.microsoft.com/en-us/library/aa306178.aspx
- https://msdn.microsoft.com/en-s/library/bb986792.aspx
- https://msdn.microsoft.com/en-s/library/ms178411.aspx
- https://msdn.microsoft.com/en-us/library/zhhddkxy%28v=vs.100%29.aspx
- https://technet.microsoft.com/en-us/library/cc735247%28v=ws.10%29.aspx
- https://technet.microsoft.com/en-us/library/cc753449%28v=ws.10%29.aspx
- https://technet.microsoft.com/en-us/library/cc771170%28v=ws.10%29.aspx
- https://www.iis.net/learn/get-started/planning-your-iis-architecture/the-configuration-system-in-iis-7
- https://www.iis.net/learn/get-started/planning-your-iis-architecture/introduction-to-applicationhostconfig
- https://social.technet.microsoft.com/wiki/contents/articles/5065.how-to-retrieve-or-decrypt-a-password-of-an-application-pool-in-iis-7-0-or-7-5.aspx
Explore more blog posts

NetSPI Wins First Place at SHARE Mainframe Capture the Flag Event
Learn how NetSPI's Mainframe Pentesting team claimed first place at SHARE's inaugural Capture the Flag event, showcasing elite z/OS security expertise.

Key Strategies for Tackling External Attack Surface Visibility
Hear from NetSPI Partners on how they tackle external attack surface visibility. These expert insights will help secure assets and boost cyber defense.

CVE-2024-28989: Weak Encryption Key Management in Solar Winds Web Help Desk
Learn how an attacker with access to a backup file could potentially recover certain encrypted passwords.