Extract Credentials In Memory From A .NET Application

Overview

A recent project had me looking through a homegrown application. The application was small and didn’t contain much functionality. It would query the system for information such as hostname, username, and general system data which was used for troubleshooting by a remote tech support service. The application would gather the data and send it to a Microsoft SQL database somewhere on the network.

Approach

  1. Testing the app
  2. Check local storage & register keys
  3. Check network traffic generated by the application
  4. Attempt to view the source code of the application
  5. Deobfuscate the application & View the source code again
  6. View the application’s memory for cleartext credentials

Initial testing

I began testing by exploring all of the functionality of the application. The application was able to copy system information displayed on the gui to a clipboard, and recheck the system. Next, I checked the install directory (which only had the executable) and registry keys for anything sensitive, but I was unable to find anything useful. With nothing useful on disk, I then decide to examine the network traffic. The laptop I was given did not have Wireshark installed so I used netstat to view the application’s network connection. Using the command netstat -ano 1 | find “PID”, I saw a network connection to another ip address. I scanned the host using nmap and discovered that it had MSSQL running. The server did not have default SA credentials, and because of my previous discoveries, I assumed the database password had to be stored on the executable.

Source Code Review

I took the executable and examined it using dnSpy. Immediately after opening the executable I saw using SmartAssembly. SmartAssembly, which is a .Net obfuscation library created by redgate which made looking through the code extremely difficult.

Obfuscated EXE

I also attempted to attach (Debug -> Attach to process) to the running process to see the various states and variables of the application, but I received the error “Cannot obtain value of the local variable or argument because it is not available at this instruction pointer, possibly because it has been optimized away.”

After some searching, I discovered a tool called de4dot which claimed it could be used to deobfuscate dotnet code, and they supported SmartAssembly obfuscation. I used the powershell script provided with de4dot to build the executable. After the executable was built, I dragged my obfuscated exe onto the de4dot executable. This created a less deobfuscated executable, but the source code was still hard to read.

Memory

Next I decided to view the content of the application’s memory while it was still running. I used a tool called Process Hacker which enabled me to attach to the running process and examine its memory. From there I went to the memory tab and clicked on strings.

Process Hacker

From there I set the minimum string length to 4 characters and enabled Detect Unicode and search in the Private memory regions.

This gave me a bunch of results to check through, but I knew this application was sending data to a SQL server, so I used the filter to look for the keyword SQL. This limited the results to a manageable amount and searching through all of it revealed something called function ConnectToSQL.

Process Hacker Creds

I copied the results to a txt file and saw 2 base64 string variables called eun and epw. I used powershell to deobfuscate the results ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("BASE64"))) and from there I gained the username and password which was used to connect to the SQL server.


Tools: