Extract password from exe(1)
Extract password from exe – Part 1
Extract password from exe is one of the techniques that we may use during our red team engagement. Actually, there are tons of information that is available in an executable file. This information may include credentials, keys, database information, IP address, etc. Although we will use the red team’s perspective to extract information such as credentials in this article. The key techniques still apply to malware sample analysis.
In this part 1 series, we will focus on some popular script-to-executable file converters including py2exe, PyInstaller, and AutoIT. As you may also be aware, many Anti-Virus evasion tools such as Veil Evasion can generate executable files in these formats.
So, we start with some basic script and our goal is to bypass the authentication. For each of the script converters, our flow of discussion is to write a simple script, discuss how to convert it to an executable file, analyze of executable file, and lastly how to decompile it. Of course, you may say I can bypass authentication using disassemblers such as OllyDbg, Immunity Debugger, x64dbg or IDA Pro. However, we try to do it more simply and effectively.
PyInstaller
The first one we are going to discuss is pyinstaller, which is a popular Python script converter. Now, we start with a simple Python script called “my_secret_pyinstaller.py“.
import sys
MyPassword = 'AAAABB'
# Python2
#password = raw_input("Enter Password: ")
password = input("Enter Password: ")
if password.rstrip(' \n\t') != MyPassword:
print("Wrong Password")
sys.exit()
else:
print("Welcome!")
In order to install pyinstaller, we can use command pip install pyinstaller
command. After installation, we can compile the script using pyinstaller, and the output “my_secret_pyinstaller.exe” will be generated under dist/ folder. Below is the command to generate the executable file.
pyinstaller -F my_secret_pyinstaller.py
Identification of PyInstaller executable
Whenever I get an executable on hand, the first step is always to check what can we deduce from the executable file. From a blue team’s perspective, we will first try to find IP address or malicious domain. On the other hand, extract password from exe files is always one of our key goals during red team engagement. Strings.exe is an effective way to extract text strings from any executable file. In this case, seems we are not able to find the password string.
Then, we move on to check the executable file using Detect it Easy, and it is identified as Visual C/C++ compiled program.
Let’s further analysis it by attaching my_secret_pyinstaller.exe to x64dbg. When you navigate to “Symbols” tab, it shows that python36.dll is a loaded module.
So, we know the executable is somehow related to python. If the executable file contains the keyword “pyi-windows-manifest-filename”, then we can confirm it is a pyinstaller compiled executable. Obviously, it is!
Decompile pyinstaller executable
Since we know it is a pyinstaller executable, the next step is to decompile it back to a python script. Basically, it involves 2 steps.
Step 1 – Extract
We will use pyinstxtractor to extract executable file into my_secret_pyinstaller.exe_extracted/ folder using the following command:
python pyinstxtractor.py my_secret_pyinstaller.exe
Then, a new file “my_secret_pyinstaller.pyc” will be be generated inside my_secret_pyinstaller.exe_extracted/ folder.
Step 2 – Decompile
Next, we move on and decompile it using uncompyle6. You can easily install it by pip install uncompyle6
. The following command can be used to decompile the script source code.
uncompyle6.exe my_secret_pyinstaller.pyc
In some cases, you will find the following error message because the magic number is incorrect.
Traceback (most recent call last):
File "c:\python27\lib\site-packages\xdis\load.py", line 293, in load_module_from_file_object
co = marshal.loads(bytecode)
ValueError: bad marshal data (unknown type code)
Traceback (most recent call last):
File "c:\python27\lib\runpy.py", line 174, in run_module_as_main "main", fname, loader, pkg_name) File "c:\python27\lib\runpy.py", line 72, in _run_code exec code in run_globals File "C:\Python27\Scripts\uncompyle6.exe__main_.py", line 9, in
File "c:\python27\lib\site-packages\uncompyle6\bin\uncompile.py", line 194, in main_bin
**options)
File "c:\python27\lib\site-packages\uncompyle6\main.py", line 324, in main
do_fragments,
File "c:\python27\lib\site-packages\uncompyle6\main.py", line 184, in decompile_file
filename, code_objects
File "c:\python27\lib\site-packages\xdis\load.py", line 168, in load_module
get_code=get_code,
File "c:\python27\lib\site-packages\xdis\load.py", line 307, in load_module_from_file_object
"Ill-formed bytecode file %s\n%s; %s" % (filename, kind, msg)
ImportError: Ill-formed bytecode file my_secret_pyinstaller.pyc
; bad marshal data (unknown type code)
We can easily fix it by edit my_secret_pyinstaller.myc with HxD, and make sure the magic number is “33 0D 0D 0A 00 00 00 00 00 00 00 00” as following.
When we rerun uncompyle6.exe my_secret_pyinstaller.pyc
the source code will be displayed on screen, and we successfully extract password from exe file.
Py2exe
The second python script converter we are going to discuss is py2exe. The latest version py2exe supports is Python version 3.4.4. Basically, we will use 2 scripts to convert python script to py2exe format. The first script is my_secret_py2exe.py, which is shown as following:
import sys
MyPassword = 'AAAABB'
# Python2
#password = raw_input("Enter Password: ")
password = input("Enter Password: ")
if password.rstrip(' \n\t') != MyPassword:
print("Wrong Password")
sys.exit()
else:
print("Welcome!")
Another simple script setup.py which is used as a wrapper script.
from distutils.core import setup
import py2exe
setup(console=['my_secret_py2exe.py'])
To use py2exe, you can simply install it using the command pip install pefile
and pip install py2exe
. Then, we can compile the script, and the output “my_secret_py2exe.exe” will be generated under dist/ folder.
c:\Python34\python.exe setup.py install
c:\Python34\python.exe setup.py py2exe
As you can see below, the output folder dist/ contains several different files and you may also notice that the output executable has a relative small file size compared to pyinstaller.
Identification of py2exe executable
In this section, we will follow the flow as previous pyinstaller section. Strings.exe shows that password text is available inside the executable.
strings64.exe ../source/dist/my_secret_py2exe.exe
Detect it Easy also identified it as Visual C/C++ compiled program, but this time it is Visual C/C++ 2010 SP1.
Again, when we attach my_secret_py2exe.exe to x64dbg. When you navigate to “Symbols” tab, it shows that python34.dll is a loaded module.
The magic keyword for py2exe compiled file is “PYTHONSCRIPT“. Certainly, we can try “pyi-windows-manifest-filename” and “PYTHONSCRIPT” to confirm the script converter in use.
Decompile py2exe executable
So, moving on we will decompile the exeuctable. This time, we will use decompile-py2exe.py available here. We use Python 3.4.4 in our lab and encountered the following error.
c:\K-Sec\Extract_password_from_exe>c:\python34\python.exe decompile-py2exe.py source/dist/my_secret_py2exe.exe
Unable to detect Python version
Now, we modified the python script a little bit, change pythonversion = 0.0
to pythonversion = 3.4
in line 98. Finally, we successfully decompile and extract the source code.
AutoIt
Finally, we will explore the last script converter named AutoIT, which is a popular tools to used by sysadmin. Let’s see the script “my_secret_autoit.au3“.
Global $MyPassword = 'AAAABB'
CheckPassword()
Func CheckPassword()
Local $password = InputBox("Security Check", "Enter your password.", "", "*")
if $password == $MyPassword Then
MsgBox(4096, "Message", "Welcome!")
Else
MsgBox(4096, "Message", "Wrong Password")
EndIf
EndFunc
It is fairly easy to compile script into exe. Just launch “Aut2Exe“, just input the source and destination and click Convert will generate the executable file.
Identification of AutoIt executable
The first thing still strings.exe, nothing found.
Detect it Easy identified it as Visual C/C++ 2013.
No specific characteristic found via x64dbg this time.
Finally, we try to grep some keyword of AutoIt. You can try “compiled AutoIt script” or “AU3!EA06“. In general, the most common 2 strings are “This is a compiled AutoIt script” and “This is a third-party compiled AutoIt script“
strings64.exe ../source/my_secret_autoit.exe | findstr AutoIt
strings64.exe ../source/my_secret_autoit.exe | findstr AU3!EA06
Decompile AutoIt executable
Once we identified the executable file is AutoIt generated exe, we can start to decompile the file. If it is a 32-bit executable file, we just need Exe2Aut. Our example here is a 64-bit executable, therefore we also need Resource Hacker. Take a special care when decompile AutoIt executable file using Exe2Aut because it may lead to code execution. Palo Alto had a great article describe this here.
Step 1 – Save RCData to a *.au3 file
The first step is open the my_secret_autoit.exe in Resource Hacker. Then we navigate to RCData “SCRIPT“, and right click to “Save Resource to a BIN file“. Make sure the extension is .au3.
Step 2 – Compile *.au3 file to 32bit exe using “Aut2Exe“
Next, we will compile the output *.au3 file to a 32-bit executable file.
Step 3 – Decompile exe with Exe2Aut
Finally, we just drag the exe into Exe2Aut to decompile the AutoIt script.
Alterative – myaut2exe
Another alternative is myaut2exe available here. It will not lead to code execution during de-compilation. However, seems it does not successfully decompile the latest version of AutoIt executable file.
Conclusion
In this post, we have explore some of reverse engineering technique that can lead us successfully extract password from exe file. The discussed script converter includes pyinstaller, py2exe and AutoIt.
So, how can we protect the information inside the executable file ? If you really need to embed some credential information inside an executable file, one option is to put the encrypted credential inside the script, and ask for decryption key at runtime.
We will discuss other compiler and options to protect executable files in the coming article. Stay tuned! Stay safe!