Created
August 31, 2023 09:55
-
-
Save two06/237398c143120beb8139577bf0d27b91 to your computer and use it in GitHub Desktop.
Python tool for interacting with Excel Python container (preview release)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import requests | |
import sys | |
import uuid | |
from requests.packages.urllib3.exceptions import InsecureRequestWarning | |
#Disable annoying warnings about using burp proxy. | |
requests.packages.urllib3.disable_warnings(InsecureRequestWarning) | |
http_proxy = "http://127.0.0.1:8080" | |
https_proxy = "http://127.0.0.1:8080" | |
proxies = { | |
"http" : http_proxy, | |
"https" : https_proxy | |
} | |
bearer_token = "Bearer <REDACTED>" | |
session_id = str(uuid.uuid4()) | |
correlation_ID = str(uuid.uuid4()) | |
headers = { | |
"Connection": "Keep-Alive", | |
"Content-Type": "application/json", | |
"Authorization": bearer_token, | |
"User-Agent": "Microsoft Office/16.0 (Windows NT 10.0; Microsoft Excel 16.0.16818; Pro)", | |
"SessionId": session_id, | |
"X-Correlation-ID": correlation_ID | |
} | |
headersFileSend = { | |
"Connection": "Keep-Alive", | |
"Authorization": bearer_token, | |
"User-Agent": "Microsoft Office/16.0 (Windows NT 10.0; Microsoft Excel 16.0.16818; Pro)", | |
"SessionId": session_id, | |
"X-Correlation-ID": correlation_ID | |
} | |
def send_initial_request(): | |
url = "https://service-preview.officepy.microsoftusercontent.com/" | |
response = requests.post(url, headers=headers, proxies=proxies, verify=False) | |
if response.status_code == 201: | |
try: | |
jsonResponse = response.json() | |
return jsonResponse["url"] | |
except Exception as err: | |
print(f"[!] Exception occured: {err}") | |
return | |
else: | |
print("[!] Error status code: " + str(response.status_code) ) | |
def send_stage_2_request(url): | |
json_data = {"zone":0,"zoneId":""+ str(uuid.uuid4()) +"","definitionId":"00000000-0000-0000-0000-000000000000","connectionId":""+str(uuid.uuid4())+""} | |
rUrl = url + "/api/environments" | |
response = requests.post(rUrl, headers=headers, json=json_data, allow_redirects=False, proxies=proxies, verify=False) | |
if response.status_code == 201: | |
try: | |
jsonResponse = response.json() | |
return jsonResponse["id"] | |
except Exception as err: | |
print(f"[!] Exception occured: {err}") | |
return | |
else: | |
print("[!] Error status code: " + str(response.status_code) ) | |
def send_stage_3_request(url, id): | |
rUrl = url + "/proxy/api/environments/" + str(id) + "/runtimes" | |
response = requests.post(rUrl, headers=headers, allow_redirects=False, proxies=proxies, verify=False) | |
if response.status_code == 201: | |
try: | |
jsonResponse = response.json() | |
return jsonResponse["id"] | |
except Exception as err: | |
print(f"[!] Exception occured: {err}") | |
return | |
else: | |
print("[!] Error status code: " + str(response.status_code) ) | |
def send_setup_code_request(url, environmentID, runtimeID): | |
rUrl = url + "/proxy/api/environments/" + environmentID + "/runtimes/" + runtimeID + "/execute2?flags=0" | |
fileName = "code.txt" | |
fileContent = """ | |
for __var__ in list(globals().keys()): | |
if not __var__.startswith('__') and not __var__.startswith('_'): | |
del globals()[__var__] | |
del __var__ | |
import numpy as np | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
import seaborn as sns | |
import statsmodels as sm | |
import excel | |
import warnings | |
warnings.simplefilter('ignore') | |
from excel import client_timezone, client_locale | |
excel.set_xl_scalar_conversion(excel.convert_to_scalar) | |
excel.set_xl_array_conversion(excel.convert_to_dataframe) | |
""" | |
files = {'code': ('code.txt', fileContent)} | |
#do multipart post here | |
response = requests.post(rUrl, headers=headersFileSend, files=files, proxies=proxies, verify=False) | |
if response.status_code == 200: | |
return True | |
else: | |
print("[!] Error status code: " + str(response.status_code) ) | |
return False | |
def run_code(url, environmentID, runtimeID, code, data, precode): | |
rUrl = url + "/proxy/api/environments/" + environmentID + "/runtimes/" + runtimeID + "/executelongoperation2?flags=2&timeout=30" | |
dataFileName = "data.json" | |
precodeFileName = "precode.txt" | |
codeFileName = "code.txt" | |
files = { | |
'data': ('data.json', data), | |
'precode': ('precode.txt', precode), | |
'code': ('code.txt', code) | |
} | |
#do multipart post here | |
response = requests.post(rUrl, headers=headersFileSend, files=files, proxies=proxies, verify=False) | |
if response.status_code == 200: | |
return response.content | |
else: | |
print("[!] Error status code: " + str(response.status_code) ) | |
return "" | |
if __name__ == "__main__": | |
print("PyCel - Excel Python interface by @two06") | |
print("") | |
print("[+] Making initial request...") | |
url = send_initial_request() | |
print("[+] Fetching environmentID ...") | |
environmentID = send_stage_2_request(url) | |
print("[+] Fetching resource ID...") | |
id = send_stage_3_request(url, environmentID) | |
#send our intitial setup file | |
print("[+] Performing setup request...") | |
res = send_setup_code_request(url, environmentID, id) | |
if res == False: | |
print("[!] sending setup file data") | |
sys.exit() | |
#send our code to run | |
data = '{"B1":"foobar"}' | |
precode = """ | |
from excel import xl_ref as xl | |
import excel | |
_ref_context = excel.get_ref_context() | |
_ref_context.clear() | |
_ref_context["B1"] = excel.get_ref_context_data("B1") | |
""" | |
code = """ | |
X = 1 | |
Y = 2 | |
print(xl("B1")) | |
X + Y | |
""" | |
print("[*] Running code...") | |
res = run_code(url, environmentID, id, code, data, precode) | |
print(res) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment