Retrieve password from exe(3)
This article is part three of “Extract/Dump/Retrieve password from exe” series. Previously, we have discussed unpack/decompile an executable back to script in part one and dumping connection string credentials in part two. In this article, we will explore how we can retrieve passwords from exe using other techniques and tools such as Process Monitor from Sysinternals and debugger x64dbg.
In short, we are going to examine a sample application named LaunchProgram.exe
developed in Delphi, which aimed to perform a similar function as runas with embedded credentials.
How did this sample application work?
The workflow of this application is described as follows:
- Firstly, this software will read several encrypted parameters including password from a file named
config.ini
. - Secondly, the program will rebuild the decryption key, which is further broken down into 4 parts inside the source code. 2 of them are plain text, and another 2 of them are encrypted internally. For instance, the full encryption key used is
AAAAA_BBBBB_CCCCC_DDDDD
.AAAAA_ & _CCCCC_
is defined as plain text inside the source codeBBBBB & DDDDD
is encrypted inside the source code
- Thirdly, this application will decrypt all needed parameters including the password.
- Finally, the software will call another process under the context of another user using either
CreateProcessWithLogon API call
orPsExec from Sysinternals
.
The following table shows the initial value for this application, but that credential information is NOT what we actually need.
Parameters | Default Values |
---|---|
system_user | K-Sec_Default_User |
system_domain | K-Sec_Default_Domain |
system_password | K-Sec_Default_Password |
system_currentDirectory | C:\tools\SysinternalsSuite |
system_program | C:\tools\SysinternalsSuite\PsExec.exe |
system_program_parameters | C:\windows\system32\calc.exe |
UseShellExecute_And_PsExec | 1 |
In fact, the developer has some sense of security and he/she is trying to protect the credential by encrypting those values using AES.
We have also uploaded the source code of the sample application to our Git Hub here.
Detect it easy
As usual, we will check the executable using Detect it Easy first.
Retrieve password from exe
So, we will start the actual work to retrieve the password from exe. In our first example, the program will launch another executable using ShellExecute
function. In the second example, the program will launch another executable using CreateProcessWithLogon API call
.
Evaluate ShellExecute
function
In order to give more visualization of how this application works, a screenshot of another executable named LaunchProgram_Config.exe
is shown below. Please also note “Use ShellExecute and PsExec” checkbox option. Later on, we will examine both option and its difference. In our exercise, we will assume LaunchProgram_Config.exe
is protected by the developer and therefore we do not have a copy of it.
So, the actual configuration in plain text format is listed below:
Parameters | Values |
---|---|
system_user | K-Sec_User |
system_domain | .\ |
system_password | K-Sec_Password |
system_currentDirectory | C:\tools\SysinternalsSuite |
system_program | C:\tools\SysinternalsSuite\PsExec.exe |
system_program_parameters | notepad.exe |
UseShellExecute_And_PsExec | 1 |
In brief, LaunchProgram_Config.exe
will encrypt those parameters and save those encrypted values into the file config.ini
as shown below.
[SYS_UserInfo]
system_user=JiqPyt5ljy2oGvcUYEZRFKB3JYs=
system_domain=QzX/ZQ==
system_password=JiqPyt5ljy2oGvcUZcZ7zxUuQWRPHBp85VemXg==
system_currentDirectory=LsJaz8lpRl1/R9Y9GVDZqstqA31Uv5LfXBl89IjSZOkL7oXuH2JaC/X/GJaXqeWlEewoYdNJ
system_program=LsJaz8lpRl1/R9Y9GVDZqstqA31Uv5LfXBl89IjSZOkL7oXuH2JaC/X/GJaXqeWlEewoYdNJkAF4He0eMtrUD3s4jvQQlMPcxb4=
system_program_parameters=AyqdX7sgUjEpdIuYYh7nrJRRJjh62w==
UseShellExecute_And_PsExec=1
Firstly, we are going examine the process using Process Monitor. After launch Process Monitor, we applied a filter to examine only “Command Line” contains LaunchProgram
.
Then, we started LaunchProgram.exe
and saw there are too many results. Therefore, we decided to further filter the results using Operation is “Process Create“. This technique is also useful when performing malware analysis.
Finally, we get the password as shown below. It is important to realize that the function ShellExecute
actually ask the OS to fork a new process with the requested parameters. Therefore, Process Monitor is able to capture the full Command Line.
Evaluate CreateProcessWithLogon API call
Next, we will de-select the “Use ShellExecute and PsExec
” option. This options effectively make the program to execute notepad using CreateProcessWithLogon API call
.
So, the actual configuration in plain text format is listed below:
Parameters | Values |
---|---|
system_user | K-Sec_User |
system_domain | .\ |
system_password | K-Sec_Password |
system_currentDirectory | C:\ |
system_program | notepad.exe |
system_program_parameters | C:\K-Sec\Retrieve_password_from_exe\test.txt |
UseShellExecute_And_PsExec | 0 |
In brief, LaunchProgram_Config.exe
will encrypt those parameters and save those encrypted values into the file config.ini
as shown below.
[SYS_UserInfo]
system_user=JiqPyt5ljy2oGvcUYEZRFKB3JYs=
system_domain=QzX/ZQ==
system_password=JiqPyt5ljy2oGvcUZcZ7zxUuQWRPHBp85VemXg==
system_currentDirectory=DpYG5JHx
system_program=AyqdX7sgUjEpdIuYYh7nrJRRJjh62w==
system_program_parameters=LsJaz8lpeaNbV+DGcxzX5MmWpBfXD01yJMTPFryBWvjF9Ug6BXu9G2lQR4+FTdrlRgKRzyB/2rt05JnZD5NKOVAiTBo7rUeep1AbwZ1gAj224d2+J61oTw==
UseShellExecute_And_PsExec=0
Again, we will also examine the program using Process Monitor with the following options:
- “Command Line” contains
LaunchProgram
- Operation is “Process Create”
The following screenshot shown that notepad.exe was launched by LaunchProgram.exe. However, the user is not K-Sec_User
.
Then, we try to filter by Command Line contains notepad. Afterwards, we now know that LaunchProgram.exe
will execute notepad under the security context of user K-Sec_User
. However, the command line do not reveal the actual password.
Debug using x64dbg
Now, we will further evaluate our sample program using x64dbg because we cannot find credential from Process Monitor. We can just open the LaunchProgram.exe
by File -> Open
. Then, you should see something like below image.
Secondly, press “F9” to reach the EntryPoint
as shown below.
Thirdly, right click the EntryPoint
, go to “Search for -> Current Module -> String references
“.
Below shown the result of all string in the executable, which should be the same as what we can get from strings.exe.
Fourthly, we will try to locate some interesting keyword and insert our breakpoint. Here we need to guess the program logic and workflow. At this point, what we actually know is this program will get the encrypted values from config.ini
and execute notepad. So, we know that there is a parameter name “system_password
” inside the config.ini
. Therefore, we will use “password” as our keyword to search.
Next, we will toggle breakpoint(s) by pressing “F2”. So, why do we only select 2 breakpoints here ? It is because we guess these 2 instruction sets are more closer to what we are looking for. In reality, locating the right breakpoint may involve a lot of trial and error effort. After setting our breakpoint, press “F9” again, and then continue press “F8” (Step over) to see if we can locate the password we are looking for. It is also important to realize that “Step over” may not the right choice every time. Sometimes, you may need to “Step Into” which will take more time to evaluate the instruction.
Finally, we have locate our password “K-Sec_Password
” as shown below.
If you miss the first one, we may still find the password when we continue our Step Over evaluation.
If we keep Step Over, we will reach a point that the memory stack stored almost all decrypted parameters. At this point, it is more easier to discover the password.
UPX Packer
UPX Packer is one of packer aimed at compress an executable file. In fact, it is not an anti-debugging technique, but the compressed executable cannot be directly debugged by debugger. Let’s check our sample executable packed by UPX using Detect it Easy.
Let’s checkout the EntryPoint
of upx packed executable, but the EntryPoint becomes pushad
. What we have to do is find out the Original EntryPoint (OEP).
So, what we are looking for is the jmp/call instruction after popad instruction. In general, that jmp instruction will jump into a memory location far away, and it should be the original EntryPoint. Now, we have set a breakpoint to that jmp instruction. After press “F9” to run, then press “F7” (Step Into), and finally, we will go back to the Original EntryPoint.
Summary
With right skill and knowledge of reverse engineering, we are able to retrieve all the decrypted content inside memory. Therefore, we should not assume any executable file can protect our secrets. Think about the executable file is the encryption key and the configuration file (config.ini) is the encrypted content. With this in mind, you definitely need to deploy some more compensating control if you have a program logic similar to this.