Introduction to Hacking Thick Clients is a series of blog posts that will outline many of the tools and methodologies used when performing thick client security assessments. In conjunction with these posts, NetSPI has released two vulnerable thick clients: BetaFast, a premier Betamax movie rental service, and Beta Bank, a premier finance application for the elite. Many examples in this series will be taken directly from these applications, which can be downloaded from the BetaFast GitHub repo. A brief overview is covered in a previous blog post.
When testing any application, it’s important to have a good understanding of what’s going on beneath the surface. Consider the largest desktop application you’ve ever seen – that’s like half of the thick client applications I test. They’re monuments to teamwork and the human spirit. I once had six hours of demos for a test, and the scope didn’t even cover the entire application. Even if the code isn’t obfuscated, there’s no way I can read through and understand everything that’s going on. Thankfully, people have made tools to help.
API Monitor
One tool in our arsenal is API Monitor. This application monitors all of the API calls in a process and displays their parameters. In this example, the Summary is a list of API calls made during the authentication to BetaFast. Note the API Filter on the left. When I had all of them checked and authenticated to BetaFast, the Summary almost immediately had over 500,000 API calls logged. And that takes up some serious resources.
Monitoring BetaFast with API Monitor didn’t highlight any particular vulnerabilities from my experience, and almost all of the main functionality is contained to a single assembly, so API monitor won’t find the most sensitive data being sent between libraries. But it’s a valuable tool for displaying information on which system resources are being used, which files are being referenced or created, network calls, security calls, etc. Moving beyond information gathering and into attacks, it is possible to intercept and modify data before encryption, or to gather cleartext passwords and connection strings as they’re passed between libraries.
Issuing Calls
Welcome back to the high level. It’s much nicer up here. There’s a tool called .net SmokeTest that can be used to load and run individual method calls. No need to load the program and search for where a method call takes place, attach the application to a debugger, or write a single line of code. If a test requires writing a method, .net SmokeTest is an easy way to execute it rather than finding the right spot for it to be called in the application. But it’s especially useful for testing various data inputs in prewritten methods.
Take this encrypt method . . . please! Using a decompiler as outlined in the previous blog post, I found a hardcoded encrypted password in BetaFast.exe. Specifically, in the LoginViewModel class. Upon login, the password from the login form is encrypted and compared to this stored value.
The method is written below.
Even further below is a Decrypt method, but it’s never called in the application. Since the IV and Key are hardcoded in the application, it just needs a ciphertext input.
It makes sense that the next step would be calling Decrypt on the hardcoded encrypted password. First, start up .net SmokeTest and create an instance of the LoginViewModel class.
Open the LoginViewModel class and enter the stored password as the ciphertext parameter in the Decrypt method. The plaintext password is then displayed below.
There’s a NetSPI blog post from years back that highlights a Powershell alternative. The following code can be run in to call specific methods.
# Load Assembly
$Assembly = [System.Reflection.Assembly]::LoadFile("C:UsersnetspiDesktopExamples3-TierBetaFast.exe")
# Create binding
$BindingFlags= [Reflection.BindingFlags] "NonPublic,Instance"
# Target the class
$Instance = new-object "BetaFast.ViewModel.LoginViewModel"
# Call the methods
$Instance.GetType().GetMethod("Encrypt",$BindingFlags).Invoke($Instance,"Spring1980!")
$Instance.GetType().GetMethod("Decrypt",$BindingFlags).Invoke($Instance,"PE/jSP7tOGDLoZLXRvPtlA==")
Spring1980! is encrypted, and PE/jSP7tOGDLoZLXRvPtlA== is decrypted.
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.
Name
Domain
Purpose
Expiry
Type
YSC
youtube.com
YouTube session cookie.
52 years
HTTP
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.
Name
Domain
Purpose
Expiry
Type
VISITOR_INFO1_LIVE
youtube.com
YouTube cookie.
6 months
HTTP
Analytics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.
We do not use cookies of this type.
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.
We do not use cookies of this type.
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
We do not use cookies of this type.
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.
Cookie Settings
Discover why security operations teams choose NetSPI.