
Sure, let's start. So, um this presentation is about a desktop application testing framework that we called uh star recon exploit. My name is Santiago Himeano. I'm a staff security engineer at Ptorian. I've been at Ptorian for more than four years and done more than 65 security engagements and mostly I focus on product security. Um, I have a masters in computer science, a number of certifications, and I'd like to contribute to the community by participating in DC45 up in Logan, Utah, and as the Saint Scon Hugger Challenge. Hello everyone. Uh, I'm Ryan. I'm also a security engineer at Ptorian. I'm a reverse engineering enthusiast and cryptography enthusiast. I also do more of the product security type
engagements, web, mobile, desktop. Uh, as far as education goes, bachelors in computer science, bachelors in math, I own Alphabet Soup of certifications. Uh, as far as community stuff goes, I'm a volunteer redteamer for the, uh, Midwest Collegiate Cyber Defense Competition as well as the Department of Energy Cyber Force competition. So the goal for this presentation is to talk about uh the differences between a desktop security assessment versus a web and mobile one and then introduce this systemic approach for desktop application security assessments. Uh the approach will in involve three steps thread modeling enumeration and exploitation and we will cover the fundamentals of uh Windows sorry for Windows Mac OS and Linux platforms. Hopefully at the end of this
presentation you will have actionable knowledge to identify and assess critical vulnerability vulnerabilities in desktop applications. So uh before we dive in into the framework, let's do a quick introduction. What is a desktop application? Uh it's a piece of software that is compiled and run on Windows, Mac OS or or Linux platforms. Uh they are normally executed by a local user and might not or might have uh exposed uh ports to the internet. uh this application might include a UI and CLI with parameter supports. Something that um is common in web applications is the concept of thick versus thin client. A thick client does all the processing locally and then connects to a backend server uh versus a thin client that
connects to the back backend service and then lets the back end do all the processing. If we want to compare the different assessments uh web, mobile and desktop uh we can use different aspects. So for example when it comes to users a web application will have multiple users but we don't consider an operating system user. On a mobile application assessment we will consider one application user and one OS user. And in a desktop application there are multiple users with multiple OS users. In terms of resources, web applications um run in the cloud. They are ephemeral and consume large resources. Mobile applications only run on one uh mobile device with limited resources and desktop applications run on computers
with medium resources. In terms of uh access to those um applications for web, we will only have network access. For mobile it it desktop we we will need physical access to the um either mobile device or the computer to access the application. Finally um in terms of OS integrity we consider that the web um operating system and the mobile are guarantee um integrity and the desk of applications does not guarantee integrity in terms of architecture. we have um for web we have multiple services or a monolithic application approach. In mobile we will have a monolithic approach and for desktop we can have multiple applications running in parallel or a single application. So now let's dive in a
little bit on this testing framework. As we said we will use three steps start recon exploit. In the first step we will do some thread modeling. In the second one we will do application enumeration. And in the last one we will do vulnerability exploitation. So let's start with start let's do thread modeling. There are multiple ways to do thread modeling. Here we present a very simple approach with four steps. Um identifying the attack surface, the user roles and thread actors, the critical assets and the attacker goals. The attack surface is are all the components and features that are directly accessible by an attacker. The users roles and thread actors are all the security relevant uh privileges that an
attacker can assume. The critical assets are the social components considering the business uh risks. And then the attacker goals is what an attacker wants to do with each of those critical assets. So if we consider uh an example of a desktop application used by um a hospital that has two roles um and that stores data locally in a database that then is migrated or syn synchronized with a database in the back end. we can focus on a desktop application that has two privileges uh that stores a local copy of that database with sensitive information and that synchronization in in the back end. If we want to make a diagram of that application, we can see a simple
application with a local database running on a local machine. We can see how the application connects to the back end and then we can see the application user interacting with the desktop application and we see the local um user interacting with the local machine. For our thread modeling uh our attack surface will be files library and drivers in that internal communication between the application and the database and the communication between the application and the back end. If we consider roles, we will see that we have a couple of authenticated users, but also we can see that there might be a local attacker and a network attacker. For critical assets, all confidential information, if we think about the
hospital application, all the patients data, all the um administrative data is confidential information and also the hardware resources. So what the attacker wants to do? Well, their goals are uh very simple. either abuse the UI, the local database or that communication to access that confidential information or abuse the UI to um control those hardware resources. If we rethink our diagram, we can see that now we can we have a malicious application user interacting with the desktop application. We have a local attacker interacting with the local machine and we have a network attacker uh interacting with the communication between the application and the back end. Cool. Yeah. And so once we've actually spent time going through our
threat model and understanding what it is the application is supposed to be doing, we go into the recon step where we're really focused on enumerating all aspects of the attack surface that would tell us what vulnerabilities make sense to do and what vulnerabilities don't make sense that exist. And we can really break down all the techniques that we're going to use here into two main categories. Dynamic testing and static testing. Dynamic testing involves when we're running the application and observing what behavior it's doing, right? So some of your first thoughts might be, oh, you're going to run it through a debugger and check it out step by step. True. But there's also other things we can check. Network traffic
analysis is super important in modern applications. So is uh looking at memory for what uh secrets might be in there as well as some injection testing as well as examining the file system. As for static testing, that's when we're going to be examining what it is we actually have on disk. So while we might see certain activities with dynamic testing, it's only when we go in and actually try and do some static reverse engineering or source code review that we might find hidden functionality that wasn't immediately obvious. This step will also involve some sort of dependency analysis. and binary analysis as well. Starting on the dynamic side, for network traffic analysis, we're going to be looking at what traffic is happening
internally and externally. In the example we have above, we have a demo app called patient data downloader that's going to that when we go to fetch patient data, it's going to go and make a HTTP request to a server and pull down that patient data.zip. Obviously oversimplification on how things actually work but from this we see that we're using clear text HTTP traffic which will come into play later. Um we can use netstat to evaluate open ports and active connections as well as using TCP dump or wireark uh to view those packets in transit. Now these days I'll be honest I don't think I've seen a desktop application that doesn't make some kind of external connection. So
using a proxy such as Burp, KO, Zap, you name it. uh just like web and mobile testing using a proxy to examine that uh HTTPS traffic as unencrypted and modifying it, tampering it uh seeing what happens with backend APIs and how that might be reflected in your desktop application. Moving right along, we have debuggers and system calls. So on screen here, we have a screenshot from LLDB. It looks a little intimidating, but that's because we're actually looking at the assembly instructions going step by step through the binary. Now, not every application is going to require you to dig into such a low level of code. Um, certain languages and frameworks will have their own uh debuggers that will be
much easier to use. For instance, uh the .NET framework with C uh using DNS Spy uh will essentially reverse engineer and show you that compiled uh executable as the original source code due to nuances with the programming language. However, on top of just debugging the binary, there's other things we can look at as well. Tracing system calls and file interactions using tools like process monitor, srace, or drust for their respective operating systems will give us more information as to maybe like what system calls or like functions of the operating system for those you don't know. Um, what system calls are being invoked, what parameters are being passed to them, what file handles are being opened. All of these give us a
sense of what things are happening on the system that we can potentially mess with. Speaking of the file system, the file system as we mentioned should be considered as part of the attack surface for a desktop application. As you know, people will be signing in locally and then using the application. Frequently we see that desktop applications will use files for local credential storage such as through uh file you know such as storing credentials and whatnot. So looking at the file permissions, database access and encrypted storage validation are all important steps here. Specific abuse cases here kind of depend on the implementation. But what's important here is you take the time to first identify what files are being used
by the application. Uh then what is actually in those files and finally if there's anything else you can do with it. So the file tool is very useful for that first step using strings and binwalk and other reverse engineering techniques to understand what those files are. uh as well as using LSOF to identify or process monitor to identify open files. Suppose an application restricts your access to one part uh because you don't have the right authorization level. If you can just read that file on disk, that that's a bypass. That's Yeah. Um but moving now from more of the dynamic testing to the static testing, we have reverse engineering, right? All code is open source if you're really good at reverse
engineering, and that is especially true here. Um suppose we don't have access to source code which is often the case with a lot of uh bug bounty programs and even blackbox desktop assessments. So taking the time to open it in gedra IDA or radar uh can give you great insight into what is actually happening behind the scenes and can give you uh a look at maybe some hidden functionality that you weren't previously aware of. On screen here you can see that just by opening this app in this demo app in Gedra we see a hard-coded license key. Maybe this is something that is included in every distribution of the executable and we could point that out as being like hey
if somebody finds this they could just activate whatever products they want. Uh again like the debuggers we have language and framework specific uh versions. So fornet we have dnspy x and for java any number of tools these days jadex jdgey uh recap all of this in the name of really understanding what it is our application's doing and whether you've obtained source code through your engagement or you've reverse engineered it it's important to take time to actually review it um frequently what we end up finding here for one hard-coded secrets in the source code as I mentioned earlier hard-coded license keys but other things such as you know AWS credentials possibly or uh other relevant secrets that could
be abused. Using a tool such as Nosy Parker is especially useful in automatically sifting and scanning through maybe hundreds of line hundreds and thousands of lines of code uh for you know secrets using known regular expressions. Additionally, one weird thing that I find in a lot of desktop tests is weak cryptography. Um for some reason people are still trying to roll their own crypto. Do not do that. You will not win. You will not succeed. um you know weak or custom algorithms to store uh credentials oftentimes can easily be reverse engineered or debugged in such a way that they can get leaked. Uh so it's important to keep an eye out for those. And as with any application
test, taking the time to identify your syncs, that is your insecure functions leading to vulnerabilities such as you know buffer overflows, insecure des serialization, database injection, file manipulation, command injection, you name it, right? So using a static analysis tool, a static uh code analysis tool such as Smrg, CodeQL uh to go through and identify that lowhanging fruit can be especially useful to find a place to start. That said, don't rely on these tools to be like your sole source of truth for any vulnerabilities as these tools are known to provide many false positives and false negatives. So manual review can also show you maybe more of like the business logic related vulnerabilities. Additionally, worth taking the time to
look at vulnerable dependencies. There are automated tools out there like dependency check or depth scan which will take time to identify what libraries might be in use. Many applications end up using dependencies that are maybe like a decade old. And while a lot of them don't end up doing that much, you might find one that has a vulnerability in it. And now we move to the exploitation fade that everyone's been waiting for. So in this section we will talk about uh specific um desktop vulnerabilities. We want to start the first one talking about uh injection. Injection is the most important risk in OAS uh top 10 desktop from 2021 and it can include a a wide
number of of uh examples. So such as SQL injection, LDAP injection, XML injection or and OS command injections. These type of injections normally depend on the type of programming language and technologies used by the application and normally there are two uh ways to to test uh for injection. One is manually by um sending uh special characters and seeing how the application behaves trying to identify error messages and the second one is automatically using a technique called passing uh with tools such as AFL++ or win AFL. The next uh vulnerability we want to discuss is in unqued path uh services path. So in Windows uh you have the concept of services they have this that that have this uh property called path
to executable. Um if this if the value of this uh path to executable does is not enclosed in quotation marks windows will break that uh at spaces and look for uh executables in after those spaces. So for example, if we have the the path with program files and security demo with spaces, Windows will attempt to execute program.exe program files/security.exe and then the full path. An attacker with uh access to the system and that can place those executables where Windows is going to search for it can abuse the application and um escalate privileges. If you want to find all services with unqued past, we just put a little command on the slide. Another interesting uh approach
is library hijacking which is uh replacing legitimate uh legitimate libraries with malicious ones. Uh specifically for Windows, we can see that um an application will try to find DLS in many um places. If an attacker can modify those DLS or can place a DL in one of those places um the attacker can again escalate privileges by having those DL being executed by the application. If if we want to detect these type of vulnerabilities we can use process monitor or accentur uh sparticus. Yeah. And then the next class of vulnerabilities we want to talk about is related to IPC. Now IPC stands for inner process communication which essentially describes any functionality where processes are ch or exchanging data or
sharing data with each other. Now with how generic that definition is of course the actual exploitation details will depend on what IPC actually is for your application. Um some examples include net remoting in Java remote method invocation. Um both of these are for two different frameworks but it's essentially the same feature where you can essentially uh invoke in the current running process some kind of arbitrary code uh which ends up being a super juicy target uh for a lot of testing. Additionally, Unix sockets are named pipes that is you know uh mechanisms on the operating system that allow you to pass data in and then read from it later. Many applications will assume that the application is the only thing
that can send data or read data from uh those pipes. But if permissions are not properly configured, you might find some way uh something some unsafe function on the other side of it that you can abuse or potentially some data leak uh coming from it. On screen here, we specifically have uh a rough diagram of the Electron process model. Now, Electron is a framework that allows you to effectively run web apps as desktop applications by packaging that JavaScript into a local executable. And frankly, it works very similar uh to web itself. I do have a laser pointer. Cool. Um so the renderer process is effectively the browser that the user is going to be interacting
with. So you have this browser window and IPC listeners that are ready to send off uh IPC connections. This flowing from the electron IPC goes to the main process which is effectively your backend for the application. The main process is going to be responsible for uh you know window management the application life cycle but for our purposes uh more importantly native APIs and IPC handlers. Now what you see on screen is probably a lot of information but hopefully I'll be able to break it down. Um here is a vulnerable code snippet where we're defining a new IPC channel for our application. we define uh ipc main on new window. So we're creating a new channel called new window and when it's
invoked it'll pass this the URL parameter into uh shell.open external. Now on windows specifically un uh if unfiltered inputed allowed to come to this function you can easily get remote code execution. So for a second suppose your application has a cross-sight scripting vulnerability that is you're able to inject arbitrary JavaScript right not only can you do what you would normally be able to do with a cross-sight scripting attack that is steal cookies hijack session you know maybe a key logger but you can also if electron is exposed in the renderer process which it usually is the case and you know lots of this could be a talk on its own um if that is the case you could use the
JavaScript to invoke an arbitrary IPC channel. So in this case we inject JavaScript. Uh we see that electron event send uh new window and we use this to open the calculator app on Mac. Now on Mac of course this only opens a file so it'll require some social engineering to actually get true code execution. But on Windows pointless to a remote file share that you maybe have sitting on an EC2. Guess what? Code execution like that. Another sort of fuzzier vulnerability category than some of the other ones we've talked about are machine in the middle or attacker in the middle attacks. This requires the attacker to be able to sniff or uh modify traffic on the wire as the name
would suggest which is inherently a bit trickier of a position to sort of assess the risk and impact. But that's why we emphasized threat modeling at the beginning of this talk. So remember that desktop application from earlier the patient data downloader. We said that it was using clear text HTTP bad. Suppose you have an attacker sitting in between the connection of the client and the uh you know backend server then they could switch out the response that's received from the server for anything else. Now suppose this application has a zip slip vulnerability which essentially uh does not properly check the zip file. So when the zip file is extracted it will unpack a file somewhere unexpected on disk
effectively giving you arbitrary write. We can replace the zip file that the application expects to receive with our own zip slip payload. And while the application says error, I can't find the JSON file in the zip folder. Guess what? We've already written the file to disk. And on top of that, now suppose that we have a library hijacking vulnerability, too, where we see that there's a DLL it like looks for but doesn't actually find. If we can write a DLL to disk, guess what? We now go from man-in-the-middle all the way to remote code execution, which is pretty cool, if I'd say so myself. But keeping it moving right along, another class of vulnerabilities relates
to uninstall scripts or pre-install scripts. So, Linux and Mac OS applications frequently come with their own scripts and application users. Uh, in our case, our example is the IT support user uh that can run uh this insecure run this uninstall insecure Mac app script as root. Now, you'll notice the script here seems pretty innocuous. just runs an echo command, removes a bunch of stuff with our favorite RM executable. Uh, seems pretty straightforward, can't be hacked. Um, notice that these are being called as echo pkill and not with absolute path. That is instead of uh slashbin/echo, it's just echo or slb binrm, it's just rm. If we get code execution as it support through some other
vulnerability, we could create rm in the temp directory and modify our path so that it expects to find executables in temp and then checks every other thing. So when we go back to the script, it'll go to echo and it'll be like, okay, echo's in bin. It'll go to pkill, be like, okay, pkill's in bin. And then it'll go to RM and it'll see RM in the temp directory, but guess what? RM runs bash. And since we're running it with pseudo, that's a root shell. So that now we found a chain to essentially get us to local privilege escalation just through you know something that you would do haphazardly while writing this code. The last vulnerability we want to
talk about is uh secrets in the registry. This is specific to Windows. Um an application a desktop application might store uh secrets in the registry and we can um see that behavior by using reshot to take a registry snapshot. The meth the method to do that is very straightforward. Before installation, after installation, after the first run and after we uninstall the application, we take a snapshot. Then we compare uh all the uh different changes. So in conclusion, uh we talked about what makes a a desktop application assessment different than a web and a mobile one. We introduced a systemic approach uh to desktop application security assessments. It's based on thread modeling and enumeration and we
think that by investing time in these two steps uh you can have a very good understanding and clear picture of what uh risk is on the application. Finally we cover some vulnerabilities for Windows, Mac OS and Linux platforms. [Applause]