domingo, 20 de octubre de 2019

Gamehosting Hacking: Hackeando un VPS gracias a Open Game Panel.


¡Hola, muy buenas!

Ante todo, me disculpo por la prolongada ausencia de publicaciones, debido a complicaciones personales, Rolo y yo no pudimos escribir durante este tiempo. Me agrada informar que, por mi parte, puede resolver dichas complicaciones y estaré publicando contenido de forma más seguida.

No me enrollo más. En esta ocasión les vengo a compartir una experiencia personal que tuve, y de la cual pensé: Oye, que va, que podría ser una buena entrada pa'l blog.

Hace unos días un amigo me pidió si podía realizar un pentest sencillo para constatar si su VPS tenía fallos de seguridad, mediante los cuales puedan tomar control de su servidor de juego. Mi respuesta fue afirmativa, al fin de cuentas es un amigo, y toda práctica es buena.


¿Qué es Open Game Panel?
De ahora en más OGP, es un panel de control diseñado para controlar servidores de juego y voz a través de una interfaz web, sin necesidad de ejecutar comandos.

Realizando un poco de investigación, puede notar que para realizar la instalación de OGP hacen falta dos partes: Panel y Agent.

·         El panel es la interfaz web, el panel de control en sí. Contiene el código backend y frontend.

·         El agent o agente es el "controlador", es la parte que controla las acciones realizadas desde el panel. Según la Wiki de OGP, es posible instalar ambas partes en un mismo VPS, pero no es recomendable.

Desde el mismo panel tenemos diversas opciones para interactuar con nuestros servidores, desde un lector de logs hasta un cliente FTP incorporado. Todo proceso que se ejecuta a través del panel, corre bajo un usuario llamado ogpagent, y el mismo tiene permisos de sudo.

El panel no te deja ingresar comandos de ningún tipo, y dado a que estaba ejecutando la última versión, no había vulnerabilidades conocidas. Mi amigo estaba ejecutando un servidor de un juego llamado San Andreas Multiplayer. Dicho juego se trata de una modificación multijugador del famoso juego de Rockstar Games, Grand Theft Auto: San Andreas.


Investigando sobre dicho juego, averigüé que los servidores corren bajo "gamemodes" o modos de juego, que son programados bajo un lenguaje de scripting llamado Pawn. A esto se le suma la posibilidad de añadir plugins, desarrollados en algún lenguaje de programación, usualmente C++,

Si el mismo juego nos da la posibilidad de ejecutar un código nuestro, todo se resume a una simple tarea: Un plugin que nos permita ejecutar comandos del sistema, a través de la instrucción system() de C++.

Para suerte y comodidad del Nobody vago, ya existe un plugin desarrollado con las características que requería, era cuestión de subirlo a través del panel y ejecutar.

Me dispuse a programar un pequeño gamemode o filterscript, utilizando la librería recién descargada.


Con el plugin cargado y el código ejecutado, era cuestión de ingresar al juego y ejecutar una reverse shell con netcat.

¡Eureka! La reverse shell se había ejecutado, y ya disponía de una sesión por consola para ejecutar comandos.

Mediante el módulo pty de Python, logré ejecutar una shell interactiva, la cual me permitía ejecutar comandos como “sudo su”.
Para el interesado, el comando de Python que utilicé fue el siguiente:
python -c 'import pty; pty.spawn("/bin/bash")'

Investigando un poco más sobre OGP, encontré una carpeta donde posiblemente se guardaban archivos de configuración, la ruta era /usr/share/ogp_agent/Cfg.

Dentro de dicha carpeta, se encontraba un archivo con el nombre “Config.pm”, y su contenido era el siguiente:


¿sudo_password? ¿Realmente OGP guardaba una contraseña de un usuario con permisos sudo en texto plano? Para mi suerte y de poca fortuna para el resto, esto era afirmativo. Pude loguearme como root utilizando el usuario con los permisos de sudo.

En cierto punto de mi investigación, podría concluir en que realmente el servicio era vulnerable, ya que, vamos, logré obtener acceso root. Pero aún sentía que me faltaba algo, ya que si pude conseguir acceso root tan fácilmente, seguramente había más información que extraer (obviamente, en texto plano jeje).

Dentro del panel, existía un archivo de configuración (/var/www/html/includes/config.inc.php), con credenciales de acceso para una cuenta MySQL no privilegiada. Para resumir, puedo decir que OGP almacena la contraseña del usuario root de MySQL en texto plano, dentro de la base de datos accesible por el usuario no privilegiado. Aunque ya teniendo acceso root al VPS, esto no me servía de mucho.

¿Sería posible acceder a más información? Recordé que aún me faltaba por investigar el servidor de San Andreas Multiplayer de mi amigo.

Antes de seguir quiero hacer un alto, ya que la siguiente parte de la publicación va más allá de las “vulnerabilidades” de OGP, ya que esto era posible realizarse sin acceso root al VPS, y solo contando con acceso al usuario OGP correspondiente. Aún así, me parecía prudente escribir sobre esto, ya que demostraré que es posible acceder a “más”.

El servidor de mi amigo contaba con un plugin de MySQL, y una base de datos en un servidor remoto. Los datos de conexión MySQL estaban embebidos o hardcodeados dentro del código de la gamemode, del cual yo no disponía. Cabe destacar que esa información tampoco era visible, a simple vista, desensamblando el compilado de la gamemode o extrayendo la lista de strings de la misma.

Pensé en que era posible sniffear el tráfico utilizando tshark, pero luego iba a tener que romper la contraseña hasheada de todas formas, no era lo más recomendable.

Esta es la parte de la historia donde se me iluminó mi cabecita y saqué mi programador interior: El plugin de MySQL era de código abierto, simplemente tenia que modificarlo y hacer que guarde un registro de los datos de conexión. Averigüé que la versión del plugin ejecutada era la R39-6, un tanto vieja para la fecha, pero aún así el código se encuentra disponible en GitHub.

Encontré que la función de conexión se encontraba en el archivo CScripting.cpp, y ya disponía de una función de “log” de depuración, el cuál guardaba el host, usuario y base de datos, pero no la contraseña (por lógicas razones).


Editando levemente el código, reemplazando los asteriscos por el format specifier correspondiente, logré que él registro de depuración de MySQL muestre la contraseña en texto plano.

Nota: Existe una función dentro del plugin la cual permite desactivar todos los registros, o al menos el de depuración. Es posible ignorar dicha función, simplemente forzando LOG_DEBUG desde el código, esto se encuentra en el archivo CLog.h).


Ya con los datos de acceso MySQL, mi trabajo había finalizado: Había logrado ingresar a una base de datos externa al VPS. Pero, ¿qué secretos guardaba la base de datos?

La misma incluía tablas personalizadas sobre el servidor del juego, pero además contenía las tablas de un foro SMF. Recordemos que mediante el acceso al panel administrativo de SMF, podemos subir un backdoor PHP utilizando la función de “modificaciones” o “editar tema”.


Es precisamente lo que hice, y ahora sí, mi trabajo había terminado: Había conseguido acceso root a un VPS y acceso a un Webhost ajeno a dicho VPS.

Espero que esta publicación haya sido informativa, y me disculpo por la carencia de redacción. Espero haber sido suficientemente claro explicando los conceptos sobre esta “vulnerabilidad”.

También cabe destacar que no se trata de una vulnerabilidad en sí, simplemente es una forma incorrecta de guardar una contraseña.

¡Saludos desde el más allá!
Nobody.
¡Pssst! Os recuerdo que también podéis seguirme en Twitter :-).