diff --git a/data/post/zip/zip.js b/data/post/zip/zip.js new file mode 100644 index 0000000000..7dd04f6911 --- /dev/null +++ b/data/post/zip/zip.js @@ -0,0 +1,65 @@ +function create_zip(dst) +{ + var header = "\x50\x4b\x05\x06" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + + var outw = new ActiveXObject("ADODB.Stream"); + outw.Type = 2; + outw.Open(); + outw.WriteText(header); + outw.Position = 0; + + var outa = new ActiveXObject("ADODB.Stream"); + outa.Type = 2; + outa.Charset = "windows-1252"; + outa.Open() + + outw.CopyTo(outa); + outa.SaveToFile(dst, 2); + + outw.Close(); + outa.Close(); +} + +function basename(path) +{ + var a = path.split("\\"); + var b = a.slice(-1); + return b[0]; +} + +function fileeq(a, b) +{ + return basename(a).toLowerCase() == basename(b).toLowerCase(); +} + +function zip(src, dst) +{ + var shell = new ActiveXObject('Shell.Application'); + var fso = new ActiveXObject('Scripting.FileSystemObject'); + src = fso.GetAbsolutePathName(src); + dst = fso.GetAbsolutePathName(dst); + + if (!fso.FileExists(dst)) { + create_zip(dst); + } + + var zipfile = shell.Namespace(dst); + var files = zipfile.items(); + var count = files.Count; + for (var i = 0; i < files.Count; i++) { + if (fileeq(files.Item(i).Name, src)) { + return; + } + } + + zipfile.CopyHere(src); + var max_tries = 50; + while (count == zipfile.items().Count) { + WScript.Sleep(100); + if (max_tries-- == 0) { + return; + } + } +} diff --git a/data/post/zip/zip.vbs b/data/post/zip/zip.vbs deleted file mode 100644 index 8ae2cfbbf3..0000000000 --- a/data/post/zip/zip.vbs +++ /dev/null @@ -1,62 +0,0 @@ -On Error Resume Next - -Function WindowsZip(sFile, sZipFile) - 'This script is provided under the Creative Commons license located - 'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not - 'be used for commercial purposes with out the expressed written consent - 'of NateRice.com - - Set oZipShell = CreateObject("WScript.Shell") - Set oZipFSO = CreateObject("Scripting.FileSystemObject") - - If Not oZipFSO.FileExists(sZipFile) Then - NewZip(sZipFile) - End If - - Set oZipApp = CreateObject("Shell.Application") - - sZipFileCount = oZipApp.NameSpace(sZipFile).items.Count - - aFileName = Split(sFile, "\") - sFileName = (aFileName(Ubound(aFileName))) - - 'listfiles - sDupe = False - For Each sFileNameInZip In oZipApp.NameSpace(sZipFile).items - If LCase(sFileName) = LCase(sFileNameInZip) Then - sDupe = True - Exit For - End If - Next - - If Not sDupe Then - oZipApp.NameSpace(sZipFile).Copyhere sFile - - 'Keep script waiting until Compressing is done - On Error Resume Next - sLoop = 0 - Do Until sZipFileCount < oZipApp.NameSpace(sZipFile).Items.Count - Wscript.Sleep(100) - sLoop = sLoop + 1 - Loop - On Error GoTo 0 - End If -End Function - -Sub NewZip(sNewZip) - 'This script is provided under the Creative Commons license located - 'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not - 'be used for commercial purposes with out the expressed written consent - 'of NateRice.com - - Set oNewZipFSO = CreateObject("Scripting.FileSystemObject") - Set oNewZipFile = oNewZipFSO.CreateTextFile(sNewZip) - - oNewZipFile.Write Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0) - - oNewZipFile.Close - Set oNewZipFSO = Nothing - - Wscript.Sleep(500) -End Sub - diff --git a/modules/post/multi/manage/zip.rb b/modules/post/multi/manage/zip.rb index c4cf15091f..198734c0d2 100644 --- a/modules/post/multi/manage/zip.rb +++ b/modules/post/multi/manage/zip.rb @@ -16,7 +16,7 @@ class MetasploitModule < Msf::Post 'Description' => %q{ This module zips a file or a directory. On Linux, it uses the zip command. On Windows, it will try to use remote target's 7Zip if found. If not, it falls - back to its own VBScript. + back to its Windows Scripting Host. }, 'License' => MSF_LICENSE, 'Author' => [ 'sinn3r' ], @@ -39,10 +39,12 @@ class MetasploitModule < Msf::Post file?("#{get_program_file_path}\\7-Zip\\7z.exe") end - def vbs(dest, src) - vbs_file = File.read(File.join(Msf::Config.data_directory, "post", "zip", "zip.vbs")) - vbs_file << "WindowsZip \"#{src}\",\"#{dest}\"" - vbs_file + def wsh_script(dst, src) + script_file = File.read(File.join(Msf::Config.data_directory, "post", "zip", "zip.js")) + src.gsub!("\\", "\\\\\\") + dst.gsub!("\\", "\\\\\\") + script_file << "zip(\"#{src}\",\"#{dst}\");" + script_file end def find_pid_by_user(username) @@ -62,7 +64,7 @@ class MetasploitModule < Msf::Post pid = find_pid_by_user(current_user) unless pid - fail_with(Failure::Unknown, "Unable to find a PID for #{current_user} to execute .vbs") + fail_with(Failure::Unknown, "Unable to find a PID for #{current_user} to execute WSH") end print_status("Stealing token from PID #{pid} for #{current_user}") @@ -77,21 +79,21 @@ class MetasploitModule < Msf::Post @token_stolen = true end - def upload_exec_vbs_zip + def upload_exec_wsh_script_zip if is_system? unless session - print_error('Unable to decompress with VBS technique without Meterpreter') + print_error('Unable to compress with WSH technique without Meterpreter') return end steal_token end - script = vbs(datastore['DESTINATION'], datastore['SOURCE']) - tmp_path = "#{get_env('TEMP')}\\zip.vbs" - print_status("VBS file uploaded to #{tmp_path}") + script = wsh_script(datastore['DESTINATION'], datastore['SOURCE']) + tmp_path = "#{get_env('TEMP')}\\zip.js" + print_status("script file uploaded to #{tmp_path}") write_file(tmp_path, script) - cmd_exec("wscript.exe #{tmp_path}") + cmd_exec("cscript.exe #{tmp_path}") end def do_7zip @@ -110,8 +112,8 @@ class MetasploitModule < Msf::Post print_status("Compressing #{datastore['DESTINATION']} via 7zip") do_7zip else - print_status("Compressing #{datastore['DESTINATION']} via VBS") - upload_exec_vbs_zip + print_status("Compressing #{datastore['DESTINATION']} via WSH") + upload_exec_wsh_script_zip end end